public function testCRUD() { midcom::get('auth')->request_sudo('org.openpsa.sales'); $deliverable = new org_openpsa_sales_salesproject_deliverable_dba(); $deliverable->salesproject = $this->_salesproject->id; $deliverable->plannedUnits = 2.5; $deliverable->pricePerUnit = 100; $stat = $deliverable->create(); $this->assertTrue($stat, midcom_connection::get_error_string()); $this->register_object($deliverable); $this->assertEquals($deliverable->price, 250); $parent = $deliverable->get_parent(); $this->assertEquals($parent->guid, $this->_salesproject->guid); $this->_salesproject->refresh(); $this->assertEquals($this->_salesproject->value, 250); $this->assertEquals($this->_salesproject->profit, 250); $deliverable->plannedUnits = 2; $stat = $deliverable->update(); $this->assertTrue($stat); $this->_salesproject->refresh(); $this->assertEquals($this->_salesproject->value, 200); $this->assertEquals($this->_salesproject->profit, 200); $stat = $deliverable->delete(); $this->assertTrue($stat); $this->_salesproject->calculate_price(); $this->assertEquals($this->_salesproject->value, 0); $this->assertEquals($this->_salesproject->profit, 0); midcom::get('auth')->drop_sudo(); }
/** * Initiates a new subscription cycle and registers a midcom.services.at call for the next cycle. * * The subscription cycles rely on midcom.services.at. I'm not sure if it is wise to rely on it for such * a totally mission critical part of OpenPSA. Some safeguards might be wise to add. */ function run_cycle($cycle_number, $send_invoice = true) { if (time() < $this->_deliverable->start) { debug_add('Subscription hasn\'t started yet, register the start-up event to $start'); return $this->_create_at_entry($cycle_number, $this->_deliverable->start); } debug_add('Running cycle ' . $cycle_number . ' for deliverable "' . $this->_deliverable->title . '"'); $this_cycle_start = $this->get_cycle_start($cycle_number, time()); $next_cycle_start = $this->calculate_cycle_next($this_cycle_start); $product = org_openpsa_products_product_dba::get_cached($this->_deliverable->product); if ($this->_deliverable->state < org_openpsa_sales_salesproject_deliverable_dba::STATUS_STARTED) { $this->_deliverable->state = org_openpsa_sales_salesproject_deliverable_dba::STATUS_STARTED; $this->_deliverable->update(); } if ($send_invoice) { $calculator = new org_openpsa_invoices_calculator(); $this_cycle_amount = $calculator->process_deliverable($this->_deliverable, $cycle_number); } $tasks_completed = array(); $tasks_not_completed = array(); if ($product->orgOpenpsaObtype == org_openpsa_products_product_dba::TYPE_SERVICE) { // Close previous task(s) $last_task = null; $new_task = null; $task_qb = org_openpsa_projects_task_dba::new_query_builder(); $task_qb->add_constraint('agreement', '=', $this->_deliverable->id); $task_qb->add_constraint('status', '<', org_openpsa_projects_task_status_dba::CLOSED); $tasks = $task_qb->execute(); foreach ($tasks as $task) { $stat = org_openpsa_projects_workflow::complete($task, sprintf(midcom::get('i18n')->get_string('completed by subscription %s', 'org.openpsa.sales'), $cycle_number)); if ($stat) { $tasks_completed[] = $task; } else { $tasks_not_completed[] = $task; } $last_task = $task; } // Create task for the duration of this cycle $task_title = sprintf('%s %s', $this->_deliverable->title, $this->get_cycle_identifier($this_cycle_start)); $new_task = $this->create_task($this_cycle_start, $next_cycle_start - 1, $task_title, $last_task); } // TODO: Warehouse management: create new order if ($this->_deliverable->end < $next_cycle_start && $this->_deliverable->end != 0) { debug_add('Do not register next cycle, the contract ends before'); return true; } if ($this->_create_at_entry($cycle_number + 1, $next_cycle_start)) { if ($send_invoice) { $this->_notify_owner($calculator, $cycle_number, $next_cycle_start, $this_cycle_amount, $tasks_completed, $tasks_not_completed); } return true; } else { return false; } }
/** * DM2 creation callback, binds to the current content topic. */ public function &dm2_create_callback(&$controller) { $this->_deliverable = new org_openpsa_sales_salesproject_deliverable_dba(); $this->_deliverable->salesproject = $this->_salesproject->id; $this->_deliverable->state = org_openpsa_sales_salesproject_deliverable_dba::STATUS_NEW; $this->_deliverable->orgOpenpsaObtype = $this->_product->delivery; if (!$this->_deliverable->create()) { debug_print_r('We operated on this object:', $this->_deliverable); throw new midcom_error('Failed to create a new deliverable. Last Midgard error was: ' . midcom_connection::get_error_string()); } return $this->_deliverable; }
public function get_row(midcom_core_dbaobject $at_entry) { $invoice = array('time' => strftime('%Y-%m-%d %H:%M:%S', $at_entry->start)); try { $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($at_entry->arguments['deliverable']); $salesproject = org_openpsa_sales_salesproject_dba::get_cached($deliverable->salesproject); } catch (midcom_error $e) { $e->log(); return $invoice; } if ($deliverable->invoiceByActualUnits) { $type = midcom::get('i18n')->get_l10n('org.openpsa.expenses')->get('invoiceable reports'); $invoice_sum = $deliverable->units * $deliverable->pricePerUnit; } else { $invoice_sum = $deliverable->price; $type = midcom::get('i18n')->get_l10n('org.openpsa.reports')->get('fixed price'); } $invoice['sum'] = $invoice_sum; $invoice['deliverable'] = $deliverable->title; $invoice['index_deliverable'] = $deliverable->title; $invoice['type'] = $type; $invoice = $this->_render_contact_field($salesproject->customer, 'customer', $invoice, 'org_openpsa_contacts_group_dba'); $invoice = $this->_render_contact_field($salesproject->customerContact, 'customerContact', $invoice); $invoice = $this->_render_contact_field($salesproject->owner, 'owner', $invoice); if (!empty($this->_sales_url)) { $invoice['deliverable'] = '<a href="' . $this->_sales_url . 'deliverable/' . $deliverable->guid . '/">' . $invoice['deliverable'] . '</a>'; } return $invoice; }
/** * Displays a deliverable delete confirmation view. * * Note, that the deliverable for non-index mode operation is automatically determined in the can_handle * phase. * * If create privileges apply, we relocate to the index creation deliverable * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_delete($handler_id, array $args, array &$data) { $this->_deliverable = new org_openpsa_sales_salesproject_deliverable_dba($args[0]); $this->_deliverable->require_do('midgard:delete'); $this->_load_datamanager(); if (array_key_exists('org_openpsa_sales_deleteok', $_REQUEST)) { // Deletion confirmed. if (!$this->_deliverable->delete()) { throw new midcom_error("Failed to delete deliverable {$args[0]}, last Midgard error was: " . midcom_connection::get_error_string()); } // Update the index $indexer = midcom::get('indexer'); $indexer->delete($this->_deliverable->guid); // Delete ok, relocating to welcome. return new midcom_response_relocate(''); } if (array_key_exists('org_openpsa_sales_deletecancel', $_REQUEST)) { // Redirect to view page. return new midcom_response_relocate("deliverable/{$this->_deliverable->guid}/"); } $this->_prepare_request_data($handler_id); midcom::get('head')->set_pagetitle($this->_deliverable->title); $this->bind_view_to_object($this->_deliverable, $this->_request_data['controller']->datamanager->schema->title); $this->_update_breadcrumb_line($handler_id); }
/** * Simple helper which references all important members to the request data listing * for usage within the style listing. */ private function _prepare_request_data() { $this->_request_data['deliverable'] =& $this->_deliverable; $this->_request_data['salesproject'] =& $this->_salesproject; // Populate the toolbar $this->_view_toolbar->add_item(array(MIDCOM_TOOLBAR_URL => "deliverable/edit/{$this->_deliverable->guid}/", MIDCOM_TOOLBAR_LABEL => $this->_l10n_midcom->get('edit'), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/edit.png', MIDCOM_TOOLBAR_ENABLED => $this->_deliverable->can_do('midgard:update'), MIDCOM_TOOLBAR_ACCESSKEY => 'e')); $siteconfig = org_openpsa_core_siteconfig::get_instance(); $this->_request_data['projects_url'] = $siteconfig->get_node_relative_url('org.openpsa.projects'); $this->_request_data['invoices_url'] = $siteconfig->get_node_relative_url('org.openpsa.invoices'); /*if ($this->_salesproject->can_do('midgard:delete')) { $this->_view_toolbar->add_item(Array( MIDCOM_TOOLBAR_URL => "salesproject/delete/{$this->_salesproject->guid}/", MIDCOM_TOOLBAR_LABEL => $this->_l10n_midcom->get('delete'), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/trash.png', )); }*/ }
public function testHandler_add_create_subscription() { midcom::get('auth')->request_sudo('org.openpsa.sales'); $this->_product->delivery = org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION; $this->_product->update(); $formdata = array('title' => 'TEST ' . __CLASS__ . '_' . time(), 'continuous' => true, 'start_date' => strftime('%Y-%m-%d')); $url = $this->submit_dm2_form('controller', $formdata, 'org.openpsa.sales', array('deliverable', 'add', $this->_salesproject->guid)); $this->assertEquals('salesproject/' . $this->_salesproject->guid . '/', $url); $qb = org_openpsa_sales_salesproject_deliverable_dba::new_query_builder(); $qb->add_constraint('salesproject', '=', $this->_salesproject->id); $results = $qb->execute(); $this->assertEquals(1, sizeof($results)); $deliverable = $results[0]; $this->register_object($deliverable); $this->assertEquals(org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION, $deliverable->orgOpenpsaObtype); midcom::get('auth')->drop_sudo(); }
public static function update_deliverable(org_openpsa_sales_salesproject_deliverable_dba $deliverable) { $invoiced = self::get_sum(array('deliverable' => $deliverable->id)); if ($invoiced != $deliverable->invoiced) { $deliverable->invoiced = $invoiced; if ($deliverable->orgOpenpsaObtype == org_openpsa_products_product_dba::DELIVERY_SINGLE && $deliverable->state < org_openpsa_sales_salesproject_deliverable_dba::STATUS_INVOICED) { $deliverable->state = org_openpsa_sales_salesproject_deliverable_dba::STATUS_INVOICED; } $deliverable->update(); } }
echo "Could not identify invoice item for task " . $task->get_label() . " on invoice " . $invoice->get_label() . ", creating empty item\n"; flush(); $item = new org_openpsa_invoices_invoice_item_dba(); $item->invoice = $invoice->id; $item->task = $task->id; $item->deliverable = $task->agreement; $item->pricePerUnit = 0; $item->units = 1; $item->description = $task->title . ' (auto-generated)'; $item->create(); } } $relatedto->delete(); } } $deliverable_qb = org_openpsa_sales_salesproject_deliverable_dba::new_query_builder(); $deliverables = $deliverable_qb->execute(); foreach ($deliverables as $deliverable) { $relatedto_qb = org_openpsa_relatedto_dba::new_query_builder(); $relatedto_qb->add_constraint('toGuid', '=', $deliverable->guid); $relatedto_qb->add_constraint('fromClass', '=', 'org_openpsa_invoices_invoice_dba'); $relatedtos = $relatedto_qb->execute(); if (sizeof($relatedtos) == 0) { echo "Deliverable " . $deliverable->title . " has no invoice relatedtos, skipping\n"; flush(); } foreach ($relatedtos as $relatedto) { $invoice = new org_openpsa_invoices_invoice_dba($relatedto->fromGuid); $items = $invoice->get_invoice_items(); if (sizeof($items) == 0) { echo "Invoice " . $invoice->get_label() . " has no items, creating one for deliverable\n";
/** * * @param mixed $handler_id The ID of the handler. * @param array &$data The local request data. */ public function _show_generator($handler_id, array &$data) { midcom_show_style('sales_report-deliverable-start'); // Quick workaround to Bergies lazy determination of whether this is user's or everyone's report... if ($this->_request_data['query_data']['resource'] == 'user:'******'auth')->user->guid) { // My report $data['handler_id'] = 'deliverable_report'; } else { // Generic report $data['handler_id'] = 'sales_report'; } /*** Copied from sales/handler/deliverable/report.php ***/ midcom_show_style('sales_report-deliverable-header'); $invoices_node = midcom_helper_misc::find_node_by_component('org.openpsa.invoices'); $sums_per_person = array(); $sums_all = array('price' => 0, 'cost' => 0, 'profit' => 0); $odd = true; foreach ($data['invoices'] as $deliverable_guid => $invoices) { if (count($invoices) == 0) { // No invoices sent in this project, skip continue; } try { $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($deliverable_guid); $product = org_openpsa_products_product_dba::get_cached($deliverable->product); $salesproject = org_openpsa_sales_salesproject_dba::get_cached($deliverable->salesproject); $customer = midcom_db_group::get_cached($salesproject->customer); } catch (midcom_error $e) { continue; } if (!array_key_exists($salesproject->owner, $sums_per_person)) { $sums_per_person[$salesproject->owner] = array('price' => 0, 'cost' => 0, 'profit' => 0); } // Calculate the price and cost from invoices $invoice_price = 0; $data['invoice_string'] = ''; $invoice_cycle_numbers = array(); foreach ($invoices as $invoice) { $invoice_price += $invoice->sum; $invoice_class = $invoice->get_status(); if ($invoices_node) { $invoice_label = "<a class=\"{$invoice_class}\" href=\"{$invoices_node[MIDCOM_NAV_FULLURL]}invoice/{$invoice->guid}/\">" . $invoice->get_label() . "</a>"; } else { $invoice_label = $invoice->get_label(); } if ($product->delivery == org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION) { $invoice_cycle_numbers[] = (int) $invoice->parameter('org.openpsa.sales', 'cycle_number'); } $data['invoice_string'] .= "<li class=\"{$invoice_class}\">{$invoice_label}</li>\n"; } if ($product->delivery == org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION) { // This is a subscription, it should be shown only if it is the first invoice if (!in_array(1, $invoice_cycle_numbers)) { continue; // This will skip to next deliverable } $scheduler = new org_openpsa_invoices_scheduler($deliverable); if ($deliverable->end == 0) { // Subscription doesn't have an end date, use specified amount of months for calculation $cycles = $scheduler->calculate_cycles($this->_config->get('subscription_profit_months')); $data['calculation_basis'] = sprintf($data['l10n']->get('%s cycles in %s months'), $cycles, $this->_config->get('subscription_profit_months')); } else { $cycles = $scheduler->calculate_cycles(); $data['calculation_basis'] = sprintf($data['l10n']->get('%s cycles, %s - %s'), $cycles, strftime('%x', $deliverable->start), strftime('%x', $deliverable->end)); } $price = $deliverable->price * $cycles; $cost = $deliverable->cost * $cycles; } else { // This is a single delivery, calculate cost as percentage as it may be invoiced in pieces if ($deliverable->price) { $cost_percentage = 100 / $deliverable->price * $invoice_price; $cost = $deliverable->cost / 100 * $cost_percentage; } else { $cost_percentage = 100; $cost = $deliverable->cost; } $price = $invoice_price; $data['calculation_basis'] = sprintf($data['l10n']->get('%s%% of %s'), round($cost_percentage), $deliverable->price); } // And now just count the profit $profit = $price - $cost; $data['customer'] = $customer; $data['salesproject'] = $salesproject; $data['deliverable'] = $deliverable; $data['price'] = $price; $sums_per_person[$salesproject->owner]['price'] += $price; $sums_all['price'] += $price; $data['cost'] = $cost; $sums_per_person[$salesproject->owner]['cost'] += $cost; $sums_all['cost'] += $cost; $data['profit'] = $profit; $sums_per_person[$salesproject->owner]['profit'] += $profit; $sums_all['profit'] += $profit; if ($odd) { $data['row_class'] = ''; $odd = false; } else { $data['row_class'] = ' class="even"'; $odd = true; } midcom_show_style('sales_report-deliverable-item'); } $data['sums_per_person'] = $sums_per_person; $data['sums_all'] = $sums_all; midcom_show_style('sales_report-deliverable-footer'); /*** /Copied from sales/handler/deliverable/report.php ***/ midcom_show_style('sales_report-deliverable-end'); }
/** * 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; }
/** * Helper function that tries to locate unsent invoices for deliverables in the same salesproject * * Example use case: A support contract with multiple hourly rates (defined * as deliverables) for different types of work. Instead of sending the customer * one invoice per hourly rate per month, one composite invoice for all fees is generated */ private function _probe_invoice($cycle_number) { $deliverable_mc = org_openpsa_sales_salesproject_deliverable_dba::new_collector('salesproject', $this->_deliverable->salesproject); $deliverable_mc->add_constraint('state', '>', org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED); $deliverable_mc->add_constraint('product.delivery', '=', org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION); $deliverables = $deliverable_mc->get_values('id'); $item_mc = org_openpsa_invoices_invoice_item_dba::new_collector('metadata.deleted', false); $item_mc->add_constraint('deliverable.salesproject', '=', $this->_deliverable->salesproject); $item_mc->add_constraint('invoice.sent', '=', 0); $suspects = $item_mc->get_values('invoice'); if (sizeof($suspects) > 0) { return new org_openpsa_invoices_invoice_dba(array_pop($suspects)); } //Nothing found, create a new invoice return $this->_create_invoice($cycle_number); }
private function _get_scheduled_invoices() { $invoices = array(); $at_qb = midcom_services_at_entry_dba::new_query_builder(); $at_qb->add_constraint('method', '=', 'new_subscription_cycle'); $at_qb->add_constraint('component', '=', 'org.openpsa.sales'); $at_entries = $at_qb->execute(); foreach ($at_entries as $at_entry) { try { $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($at_entry->arguments['deliverable']); if ($deliverable->continuous || $deliverable->start < $this->_request_data['end'] && $deliverable->end > $this->_request_data['start']) { $invoices = array_merge($invoices, $this->_get_invoices_for_subscription($deliverable, $at_entry)); } } catch (midcom_error $e) { } } $invoices = array_filter($invoices, array($this, '_filter_by_date')); usort($invoices, array($this, '_sort_by_date')); return $invoices; }
/** * Update hour report caches */ function update_cache($update = true) { if (!$this->id) { return false; } debug_add("updating hour caches"); $hours = $this->list_hours(); $stat = true; $this->reportedHours = $hours['reported']; $this->approvedHours = $hours['approved']; $this->invoicedHours = $hours['invoiced']; $this->invoiceableHours = $hours['invoiceable']; try { $agreement = new org_openpsa_sales_salesproject_deliverable_dba($this->agreement); $agreement->update_units($this->id, $hours); } catch (midcom_error $e) { } if ($update) { $this->_use_rcs = false; $this->_use_activitystream = false; $this->_skip_acl_refresh = true; $this->_skip_parent_refresh = true; $stat = $this->update(); debug_add("saving updated values to database returned {$stat}"); } return $stat; }
function decline() { if ($this->state >= org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED) { return false; } $this->state = org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED; if ($this->update()) { // Update sales project if it doesn't have any open deliverables $qb = org_openpsa_sales_salesproject_deliverable_dba::new_query_builder(); $qb->add_constraint('salesproject', '=', $this->salesproject); $qb->add_constraint('state', '<>', org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED); if ($qb->count() == 0) { // No proposals that are not declined $salesproject = new org_openpsa_sales_salesproject_dba($this->salesproject); $salesproject->status = org_openpsa_sales_salesproject_dba::STATUS_LOST; $salesproject->update(); } return true; } return false; }
/** * * @param mixed $handler_id The ID of the handler. * @param array &$data The local request data. */ public function _show_uninvoiced($handler_id, array &$data) { $siteconfig = org_openpsa_core_siteconfig::get_instance(); $data['projects_url'] = $siteconfig->get_node_full_url('org.openpsa.projects'); midcom_show_style('show-projects-header'); foreach ($this->_customers as $customer_id => $tasks) { $data['customer'] = $customer_id; try { $customer = org_openpsa_contacts_group_dba::get_cached($customer_id); $data['customer_label'] = $customer->official; $data['disabled'] = ''; } catch (midcom_error $e) { $data['customer_label'] = $this->_l10n->get('no customer'); $data['disabled'] = ' disabled="disabled"'; } midcom_show_style('show-projects-customer-header'); $class = "even"; foreach ($tasks as $task) { $data['task'] = $task; if ($class == "even") { $class = ""; } else { $class = "even"; } $data['class'] = $class; $data['reported_hours'] = $task->reportedHours; try { $deliverable = new org_openpsa_sales_salesproject_deliverable_dba($task->agreement); $deliverable->calculate_price(false); $data['default_price'] = $deliverable->pricePerUnit; if ($deliverable->invoiceByActualUnits) { $data['invoiceable_units'] = $task->invoiceableHours; } else { $data['invoiceable_units'] = $task->plannedHours; } } catch (midcom_error $e) { $e->log(); if ($this->_config->get('default_hourly_price')) { $data['default_price'] = $this->_config->get('default_hourly_price'); $data['invoiceable_units'] = $task->invoiceableHours; } else { $data['default_price'] = ''; } } midcom_show_style('show-projects-customer-task'); } midcom_show_style('show-projects-customer-footer'); } midcom_show_style('show-projects-footer'); }
private function _prepare_grid_data() { $this->_request_data['grid'] = new org_openpsa_widgets_grid('invoice_items', 'local'); $entries = array(); $invoice_sum = 0; foreach ($this->_request_data['invoice_items'] as $item) { $entry = array(); $entry['id'] = $item->id; try { $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($item->deliverable); $entry['deliverable'] = $deliverable->title; } catch (midcom_error $e) { $entry['deliverable'] = ''; } try { $task = org_openpsa_projects_task_dba::get_cached($item->task); $entry['task'] = $task->title; } catch (midcom_error $e) { $entry['task'] = ''; } $entry['description'] = $item->description; $entry['price'] = $item->pricePerUnit; $entry['quantity'] = $item->units; $entry['position'] = $item->position; $item_sum = $item->units * $item->pricePerUnit; $invoice_sum += $item_sum; $entry['sum'] = $item_sum; $entry['action'] = ''; $entries[] = $entry; } $this->_request_data['entries'] = $entries; $this->_request_data['grid']->set_footer_data(array('sum' => $invoice_sum)); }
/** * Helper that lists all deliverables belonging to the current project */ private function _list_deliverables() { $qb = org_openpsa_sales_salesproject_deliverable_dba::new_query_builder(); $qb->add_constraint('salesproject', '=', $this->_salesproject->id); $qb->add_constraint('up', '=', 0); if ($this->_salesproject->status != org_openpsa_sales_salesproject_dba::STATUS_LOST) { $qb->add_constraint('state', '<>', org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED); } $qb->add_order('state'); $qb->add_order('metadata.created', 'DESC'); $deliverables = $qb->execute(); foreach ($deliverables as $deliverable) { $this->_controllers[$deliverable->id] = midcom_helper_datamanager2_controller::create('ajax'); $this->_controllers[$deliverable->id]->schemadb =& $this->_request_data['schemadb_salesproject_deliverable']; $this->_controllers[$deliverable->id]->set_storage($deliverable); $this->_controllers[$deliverable->id]->process_ajax(); $this->_request_data['deliverables_objects'][$deliverable->guid] = $deliverable; } }
/** * List all tasks, optionally filtered by status */ private function _handler_list_all($args) { // Default to open tasks list if none specified if (!isset($args[1]) || empty($args[1])) { $this->_request_data['view_identifier'] = 'open'; $args[1] = 'open'; } switch ($args[1]) { case 'agreement': if (!$args[2]) { throw new midcom_error('Invalid arguments for agreement filter'); } $agreement_id = (int) $args[2]; $this->_request_data['agreement'] = $agreement_id; $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($agreement_id); $title = sprintf($this->_l10n->get('tasks for agreement %s'), $deliverable->title); midcom::get('head')->set_pagetitle($title); $this->add_breadcrumb("", $title); $this->_qb->add_constraint('agreement', '=', $deliverable->id); $this->_provider->add_order('end', 'DESC'); break; case 'all': case 'both': $args[1] = 'all'; $this->_provider->add_order('end', 'DESC'); break; case 'open': $this->set_active_leaf($this->_topic->id . ':tasks_open'); $this->_qb->add_constraint('status', '<', org_openpsa_projects_task_status_dba::CLOSED); $this->_provider->add_order('end'); break; case 'closed': $this->set_active_leaf($this->_topic->id . ':tasks_closed'); $this->_qb->add_constraint('status', '=', org_openpsa_projects_task_status_dba::CLOSED); $this->_provider->add_order('end', 'DESC'); break; case 'current': $this->_qb->add_constraint('status', 'IN', array(org_openpsa_projects_task_status_dba::ACCEPTED, org_openpsa_projects_task_status_dba::STARTED, org_openpsa_projects_task_status_dba::REJECTED, org_openpsa_projects_task_status_dba::REOPENED)); $this->_provider->add_order('end'); break; case 'invoiceable': $this->set_active_leaf($this->_topic->id . ':tasks_invoiceable'); $this->_qb->add_constraint('invoiceableHours', '>', 0); $this->_provider->add_order('end'); break; case 'invoiced': $this->set_active_leaf($this->_topic->id . ':tasks_invoiced'); $this->_qb->add_constraint('invoicedHours', '>', 0); $this->_provider->add_order('end', 'DESC'); break; default: throw new midcom_error("Filter {$args[1]} not recognized"); } $qf = new org_openpsa_core_queryfilter('org_openpsa_task_list_' . $args[1]); $qf->add_filter(new org_openpsa_core_filter('priority', '<=', $this->_request_data['priority_array'])); $date_filter = new org_openpsa_core_filter('timeframe'); $date_filter->set('mode', 'timeframe'); $date_filter->set('helptext', $this->_l10n->get("timeframe")); $date_filter->set('fieldname', array('start' => 'start', 'end' => 'end')); $qf->add_filter($date_filter); $qf->apply_filters($this->_qb); $this->_request_data["qf"] = $qf; $this->_request_data['table-heading'] = $args[1] . ' tasks'; $this->_request_data['view'] = 'grid'; }
/** * Marks the salesproject as invoiced if no pending deliverables are left */ public function mark_invoiced() { if ($this->status >= self::STATUS_INVOICED) { return; } $mc = org_openpsa_sales_salesproject_deliverable_dba::new_collector('salesproject', $this->id); $mc->add_constraint('state', '<', org_openpsa_sales_salesproject_deliverable_dba::STATUS_INVOICED); $mc->add_constraint('state', '<>', org_openpsa_sales_salesproject_deliverable_dba::STATUS_DECLINED); $mc->execute(); if ($mc->count() == 0) { $this->status = self::STATUS_INVOICED; $this->update(); } }
<?php $view_task =& $data['object_view']; $task =& $data['object']; $task->get_members(); $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX); $siteconfig = org_openpsa_core_siteconfig::get_instance(); $sales_url = $siteconfig->get_node_full_url('org.openpsa.sales'); $expenses_url = $siteconfig->get_node_relative_url('org.openpsa.expenses'); ?> <div class="org_openpsa_projects_task"> <div class="sidebar"> <?php if ($task->agreement) { try { $agreement = org_openpsa_sales_salesproject_deliverable_dba::get_cached($task->agreement); $output = $agreement->deliverable_html; if ($sales_url) { $salesproject = org_openpsa_sales_salesproject_dba::get_cached($agreement->salesproject); $output = "<a href=\"{$sales_url}salesproject/{$salesproject->guid}/#{$agreement->guid}/\">{$output}</a>\n"; } echo "<h2>" . $data['l10n']->get('agreement') . "</h2>\n"; echo $output; } catch (midcom_error $e) { } } if ($task->manager) { echo "<h2>" . $data['l10n']->get('manager') . "</h2>\n"; $contact = org_openpsa_widgets_contact::get($task->manager); echo $contact->show_inline(); }