/** * Makes and executes querybuilder for filtering hour_reports */ private function _get_hour_reports() { //Create queries to get data $qb_hr = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb_hr->add_constraint('date', '<=', (int) $this->_request_data['query_data']['end']); $qb_hr->add_constraint('date', '>=', (int) $this->_request_data['query_data']['start']); if (array_key_exists('invoiceable_filter', $this->_request_data['query_data']) && $this->_request_data['query_data']['invoiceable_filter'] != -1) { $qb_hr->add_constraint('invoiceable', '=', (bool) $this->_request_data['query_data']['invoiceable_filter']); } debug_add('checking for approved_filter'); if (array_key_exists('approved_filter', $this->_request_data['query_data'])) { debug_add('approved_filter detected, raw value: ' . $this->_request_data['query_data']['approved_filter']); if ($this->_request_data['query_data']['approved_filter'] != -1) { if ((int) $this->_request_data['query_data']['approved_filter']) { debug_add('approved_filter parsed as only approved, adding constraint'); $qb_hr->add_constraint('metadata.approved', '<>', '0000-00-00 00:00:00'); } else { debug_add('approved_filter parsed as only NOT approved, adding constraint'); $qb_hr->add_constraint('metadata.approved', '=', '0000-00-00 00:00:00'); } } else { debug_add('approved_filter parsed as BOTH, do not add any constraints'); } } debug_add('checking for invoiced_filter'); if (array_key_exists('invoiced_filter', $this->_request_data['query_data'])) { debug_add('invoiced_filter detected, raw value: ' . $this->_request_data['query_data']['invoiced_filter']); if ($this->_request_data['query_data']['invoiced_filter'] != -1) { if ((int) $this->_request_data['query_data']['invoiced_filter']) { debug_add('invoiced_filter parsed as only invoiced, adding constraint'); $qb_hr->add_constraint('invoice', '<>', 0); } else { debug_add('invoiced_filter parsed as only NOT invoiced, adding constraint'); $qb_hr->add_constraint('invoice', '=', 0); } } else { debug_add('invoiced_filter parsed as BOTH, do not add any constraints'); } } if ($this->_request_data['query_data']['resource'] != 'all') { $this->_request_data['query_data']['resource_expanded'] = $this->_expand_resource($this->_request_data['query_data']['resource']); $qb_hr->add_constraint('person', 'IN', $this->_request_data['query_data']['resource_expanded']); } if ($this->_request_data['query_data']['task'] != 'all') { $tasks = $this->_expand_task($this->_request_data['query_data']['task']); $qb_hr->add_constraint('task', 'IN', $tasks); } if (array_key_exists('hour_type_filter', $this->_request_data['query_data']) && $this->_request_data['query_data']['hour_type_filter'] != 'builtin:all') { $qb_hr->add_constraint('reportType', '=', $this->_request_data['query_data']['hour_type_filter']); } return $qb_hr->execute(); }
function _load_data($handler_id, &$args, &$data) { midcom::get('auth')->require_valid_user(); if (empty($_POST['guids']) || !is_array($_POST['guids'])) { throw new midcom_error("No GUIDs found, aborting."); } $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb->add_constraint('guid', 'IN', $_POST['guids']); if (isset($_POST['order']) && is_array($_POST['order'])) { foreach ($_POST['order'] as $field => $order) { $qb->add_order($field, $order); } } return $qb->execute(); }
public function testHandler_hours_create() { midcom::get('auth')->request_sudo('org.openpsa.expenses'); $data = $this->run_handler('org.openpsa.expenses', array('hours', 'create', 'hour_report')); $this->assertEquals('hours_create', $data['handler_id']); $person = $this->create_object('midcom_db_person'); $formdata = array('description' => __CLASS__ . '::' . __FUNCTION__, 'hours' => '2', 'org_openpsa_expenses_person_chooser_selections' => array($person->id), 'org_openpsa_expenses_task_chooser_selections' => array(self::$_task->id)); $url = $this->submit_dm2_form('controller', $formdata, 'org.openpsa.expenses', array('hours', 'create', 'hour_report')); $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb->add_constraint('task', '=', self::$_task->id); $qb->add_constraint('description', '=', __CLASS__ . '::' . __FUNCTION__); $results = $qb->execute(); $this->register_objects($results); $this->assertEquals(1, sizeof($results)); $this->assertEquals('hours/task/' . self::$_task->guid . '/', $url); midcom::get('auth')->drop_sudo(); }
/** * The handler for the list view * * @param mixed $handler_id the array key from the request array * @param array $args the arguments given to the handler * @param Array &$data The local request data. */ public function _handler_list($handler_id, array $args, array &$data) { midcom::get('auth')->require_valid_user(); // List hours $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $mode = 'full'; //url for batch_handler $this->_request_data['action_target_url'] = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX) . "hours/task/batch/"; switch ($handler_id) { case 'list_hours': $this->_master->add_list_filter($qb); $data['view_title'] = $data['l10n']->get('hour reports'); $data['breadcrumb_title'] = $data['view_title']; break; case 'list_hours_task': $this->_master->add_list_filter($qb); // Fallthrough // Fallthrough case 'list_hours_task_all': $task = new org_openpsa_projects_task_dba($args[0]); $qb->add_constraint('task', '=', $task->id); $mode = 'simple'; $data['view_title'] = sprintf($data['l10n']->get($handler_id . " %s"), $task->title); $data['breadcrumb_title'] = $task->get_label(); $siteconfig = org_openpsa_core_siteconfig::get_instance(); $projects_url = $siteconfig->get_node_full_url('org.openpsa.projects'); if ($projects_url) { $this->_view_toolbar->add_item(array(MIDCOM_TOOLBAR_URL => $projects_url . "task/{$task->guid}/", MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('show task %s'), $task->title), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/jump-to.png', MIDCOM_TOOLBAR_ACCESSKEY => 'g')); } break; } $qb->add_order('date', 'DESC'); $data['hours'] = $qb->execute(); $this->_load_hour_data($data['hours']); $data['mode'] = $mode; $data['tasks'] = $this->tasks; $data['qb'] = $qb; org_openpsa_widgets_grid::add_head_elements(); midcom_helper_datamanager2_widget_autocomplete::add_head_elements(); org_openpsa_widgets_contact::add_head_elements(); midcom::get('head')->set_pagetitle($data['view_title']); $this->add_breadcrumb('', $data['breadcrumb_title']); }
private function _list_hour_reports_between(&$data_array, $person, $from, $to) { // List user's hour reports $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb->add_constraint('date', '>=', $from); $qb->add_constraint('date', '<=', $to); $qb->add_constraint('person', '=', $person); $hour_reports = $qb->execute(); foreach ($hour_reports as $hour_report) { $time = mktime(date('H', $hour_report->metadata->created), date('i', $hour_report->metadata->created), date('s', $hour_report->metadata->created), date('m', $hour_report->date), date('d', $hour_report->date), date('Y', $hour_report->date)); $date = date('Y-m-d', $time); if (!array_key_exists($date, $data_array)) { $data_array[$date] = array(); } if (!array_key_exists($time, $data_array[$date])) { $data_array[$date][$time] = array(); } $data_array[$date][$time][$hour_report->guid] = $hour_report; } }
/** * Connect the task hour reports to an invoice * * @param org_openpsa_projects_task_dba &$task The task we're working on * @param org_openpsa_invoices_invoice_dba &$invoice The invoice we're working on */ static function mark_invoiced(&$task, &$invoice) { debug_add("task->mark_invoiced() called with user #" . midcom_connection::get_user()); try { $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($task->agreement); } catch (midcom_error $e) { $e->log(); } // Mark the hour reports invoiced $hours_marked = 0; $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb->add_constraint('task', '=', $task->id); $qb->add_constraint('invoice', '=', 0); $qb->add_constraint('invoiceable', '=', true); // Check how the agreement deals with hour reports if ($deliverable && $deliverable->invoiceApprovedOnly) { // The agreement allows invoicing only approved hours, therefore don't mark unapproved $qb->add_constraint('metadata.isapproved', '=', true); } $reports = $qb->execute(); foreach ($reports as $report) { $report->invoice = $invoice->id; $report->_skip_parent_refresh = true; if ($report->update()) { $hours_marked += $report->hours; } } // Update hour caches to agreement if (!$task->update_cache()) { debug_add('Failed to update task hour caches, last Midgard error: ' . midcom_connection::get_error_string(), MIDCOM_LOG_WARN); } // Notify user midcom::get('uimessages')->add(midcom::get('i18n')->get_string('org.openpsa.projects', 'org.openpsa.projects'), sprintf(midcom::get('i18n')->get_string('marked %s hours as invoiced in task "%s"', 'org.openpsa.projects'), $hours_marked, $task->title), 'ok'); return $hours_marked; }
private function _count_invoice_hours() { $qb = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb->add_constraint('invoice', '=', $this->_object->id); $qb->add_order('date', 'ASC'); $reports = $qb->execute(); if (!is_array($reports) || sizeof($reports) < 1) { return false; } $this->_request_data['sorted_reports'] = array('reports' => array(), 'approved' => array('hours' => 0, 'reports' => array()), 'not_approved' => array('hours' => 0, 'reports' => array())); foreach ($reports as $report) { $this->_request_data['sorted_reports']['reports'][$report->guid] = $report; if ($report->is_approved()) { $sort =& $this->_request_data['sorted_reports']['approved']; } else { $sort =& $this->_request_data['sorted_reports']['not_approved']; } $sort['hours'] += $report->hours; // PHP5-TODO: Must be copy-by-value $sort['reports'][] =& $this->_request_data['sorted_reports']['reports'][$report->guid]; } return true; }
/** * Support for contacts person merge */ function org_openpsa_contacts_duplicates_merge_person(&$person1, &$person2, $mode) { switch ($mode) { case 'all': break; /* In theory we could have future things (like resource/manager ships), but now we don't support that mode, we just exit */ /* In theory we could have future things (like resource/manager ships), but now we don't support that mode, we just exit */ case 'future': return true; break; default: // Mode not implemented debug_add("mode {$mode} not implemented", MIDCOM_LOG_ERROR); return false; break; } // Transfer links from classes we drive // ** resources ** $qb_member = org_openpsa_projects_task_resource_dba::new_query_builder(); $qb_member->add_constraint('person', '=', $person2->id); $members = $qb_member->execute(); if ($members === false) { // Some error with QB debug_add('QB Error', MIDCOM_LOG_ERROR); return false; } // Transfer memberships foreach ($members as $member) { // TODO: figure out duplicate memberships and delete unneeded ones $member->person = $person1->id; debug_add("Transferred task resource #{$member->id} to person #{$person1->id} (from #{$member->person})", MIDCOM_LOG_INFO); if (!$member->update()) { debug_add("Failed to update task resource #{$member->id}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); return false; } } // ** task statuses ** $qb_receipt = org_openpsa_projects_task_status_dba::new_query_builder(); $qb_receipt->add_constraint('targetPerson', '=', $person2->id); $receipts = $qb_receipt->execute(); if ($receipts === false) { // Some error with QB debug_add('QB Error / status', MIDCOM_LOG_ERROR); return false; } foreach ($receipts as $receipt) { debug_add("Transferred task_status #{$receipt->id} to person #{$person1->id} (from #{$receipt->person})", MIDCOM_LOG_INFO); $receipt->targetPerson = $person1->id; if (!$receipt->update()) { // Error updating debug_add("Failed to update status #{$receipt->id}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); return false; } } // ** hour reports ** $qb_log = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb_log->add_constraint('person', '=', $person2->id); $logs = $qb_log->execute(); if ($logs === false) { // Some error with QB debug_add('QB Error / hours', MIDCOM_LOG_ERROR); return false; } foreach ($logs as $log) { debug_add("Transferred hour_report #{$log->id} to person #{$person1->id} (from #{$log->person})", MIDCOM_LOG_INFO); $log->person = $person1->id; if (!$log->update()) { // Error updating debug_add("Failed to update hour_report #{$log->id}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); return false; } } // ** Task managers ** $qb_task = org_openpsa_projects_task_dba::new_query_builder(); $qb_task->add_constraint('manager', '=', $person2->id); $tasks = $qb_task->execute(); if ($tasks === false) { // Some error with QB debug_add('QB Error / tasks', MIDCOM_LOG_ERROR); return false; } foreach ($tasks as $task) { debug_add("Transferred task #{$task->id} to person #{$person1->id} (from #{$task->person})", MIDCOM_LOG_INFO); $task->manager = $person1->id; if (!$task->update()) { // Error updating debug_add("Failed to update task #{$task->id}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); return false; } } // Transfer metadata dependencies from classes that we drive $classes = array('org_openpsa_projects_task_resource_dba', 'org_openpsa_projects_task_status_dba', 'org_openpsa_projects_task_dba', 'org_openpsa_projects_hour_report_dba'); $metadata_fields = array('creator' => 'guid', 'revisor' => 'guid'); foreach ($classes as $class) { $ret = org_openpsa_contacts_duplicates_merge::person_metadata_dependencies_helper($class, $person1, $person2, $metadata_fields); if (!$ret) { // Failure updating metadata debug_add("Failed to update metadata dependencies in class {$class}, errsrtr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); return false; } } // All done return true; }
/** * Helper function to create & recalculate existing invoice_items by tasks * * @param array $tasks array containing the task id's to recalculate for - if empty all tasks will be recalculated */ public function _recalculate_invoice_items($tasks = array(), $skip_invoice_update = false) { $result_items = array(); $result_tasks = array(); //get hour_reports for this invoice - mc ? $qb_hour_reports = org_openpsa_projects_hour_report_dba::new_query_builder(); $qb_hour_reports->add_constraint('invoice', '=', $this->id); if (!empty($tasks)) { $qb_hour_reports->add_constraint('task', 'IN', $tasks); //if there is a task passed it must be calculated even //if it doesn't have associated hour_reports foreach ($tasks as $task_id) { $result_tasks[$task_id] = 0; } } $hour_reports = $qb_hour_reports->execute(); // sums up the hours of hour_reports for each task foreach ($hour_reports as $hour_report) { if (!array_key_exists($hour_report->task, $result_tasks)) { $result_tasks[$hour_report->task] = 0; } //only add invoiceable hour_reports if ($hour_report->invoiceable) { $result_tasks[$hour_report->task] += $hour_report->hours; } } foreach ($result_tasks as $task_id => $hours) { $invoice_item = $this->_probe_invoice_item_for_task($task_id); //get deliverable for this task $mc_task_agreement = new midgard_collector('org_openpsa_task', 'id', $task_id); $mc_task_agreement->set_key_property('id'); $mc_task_agreement->add_value_property('title'); $mc_task_agreement->add_value_property('agreement'); $mc_task_agreement->add_constraint('agreement', '<>', 0); $mc_task_agreement->execute(); $mc_task_key = $mc_task_agreement->list_keys(); $deliverable = null; foreach ($mc_task_key as $key => $empty) { try { $deliverable = new org_openpsa_sales_salesproject_deliverable_dba((int) $mc_task_agreement->get_subkey($key, 'agreement')); $invoice_item->pricePerUnit = $deliverable->pricePerUnit; $invoice_item->deliverable = $deliverable->id; //calculate price if ($deliverable->invoiceByActualUnits || $deliverable->plannedUnits == 0) { $invoice_item->units = $hours; } else { $invoice_item->units = $deliverable->plannedUnits; } } catch (midcom_error $e) { $e->log(); $invoice_item->units = $hours; } } if ($invoice_item->description == '') { $invoice_item->description = $mc_task_agreement->get_subkey($task_id, 'title'); } $invoice_item->skip_invoice_update = $skip_invoice_update; $invoice_item->update(); $result_items[] = $invoice_item; } return $result_items; }