示例#1
0
 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();
 }
示例#2
0
 /**
  * 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;
     }
 }
示例#3
0
文件: add.php 项目: nemein/openpsa
 /**
  * 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;
 }
示例#4
0
 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;
 }
示例#5
0
文件: admin.php 项目: nemein/openpsa
 /**
  * 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);
 }
示例#6
0
文件: view.php 项目: nemein/openpsa
 /**
  * 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',
           ));
       }*/
 }
示例#7
0
 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();
 }
示例#8
0
文件: item.php 项目: nemein/openpsa
 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();
     }
 }
示例#9
0
                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";
示例#10
0
文件: report.php 项目: nemein/openpsa
 /**
  *
  * @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');
 }
示例#11
0
 /**
  * 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;
 }
示例#12
0
 /**
  * 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);
 }
示例#13
0
文件: report.php 项目: nemein/openpsa
 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;
 }
示例#14
0
文件: task.php 项目: nemein/openpsa
 /**
  * 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;
 }
示例#15
0
 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;
 }
示例#16
0
 /**
  *
  * @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');
 }
示例#17
0
文件: action.php 项目: nemein/openpsa
 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));
 }
示例#18
0
文件: view.php 项目: nemein/openpsa
 /**
  * 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;
     }
 }
示例#19
0
文件: list.php 项目: nemein/openpsa
 /**
  * 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';
 }
示例#20
0
 /**
  * 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();
     }
 }
示例#21
0
<?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();
}