예제 #1
0
파일: taskTest.php 프로젝트: nemein/openpsa
 public function testCRUD()
 {
     midcom::get('auth')->request_sudo('org.openpsa.projects');
     $task = new org_openpsa_projects_task_dba();
     if (extension_loaded('midgard2')) {
         $stat = $task->create();
         $this->assertFalse($stat);
     }
     $project = $this->create_object('org_openpsa_projects_project');
     $task->project = $project->id;
     $stat = $task->create();
     $this->assertTrue($stat, midcom_connection::get_error_string());
     $this->register_object($task);
     $this->assertEquals(ORG_OPENPSA_OBTYPE_TASK, $task->orgOpenpsaObtype);
     $task->refresh();
     $this->assertEquals('Task #' . $task->id, $task->title);
     $this->assertEquals(org_openpsa_projects_task_status_dba::PROPOSED, $task->status);
     $task->title = 'Test Task';
     $stat = $task->update();
     $this->assertTrue($stat);
     $this->assertEquals('Test Task', $task->title);
     $stat = $task->delete();
     $this->assertTrue($stat);
     midcom::get('auth')->drop_sudo();
 }
예제 #2
0
파일: projects.php 프로젝트: nemein/openpsa
 /**
  * @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_uninvoiced($handler_id, array $args, array &$data)
 {
     midcom::get('auth')->require_valid_user();
     midcom::get('auth')->require_user_do('midgard:create', null, 'org_openpsa_invoices_invoice_dba');
     $qb = org_openpsa_projects_task_dba::new_query_builder();
     $qb->add_constraint('status', '>=', org_openpsa_projects_task_status_dba::COMPLETED);
     $qb->begin_group('OR');
     $qb->add_constraint('invoiceableHours', '>', 0);
     $qb->begin_group('AND');
     $qb->add_constraint('agreement.invoiceByActualUnits', '=', false);
     $qb->add_constraint('agreement.state', '=', org_openpsa_sales_salesproject_deliverable_dba::STATUS_DELIVERED);
     $qb->add_constraint('agreement.price', '>', 0);
     $qb->end_group();
     $qb->end_group();
     $tasks = $qb->execute();
     foreach ($tasks as $task) {
         $this->_tasks[$task->id] = $task;
         if (!array_key_exists($task->customer, $this->_customers)) {
             $this->_customers[$task->customer] = array();
         }
         $this->_customers[$task->customer][$task->id] =& $this->_tasks[$task->id];
     }
     // Check if we're sending an invoice here
     if (array_key_exists('org_openpsa_invoices_invoice', $_POST)) {
         $this->_generate_invoice();
     }
     $this->add_stylesheet(MIDCOM_STATIC_URL . "/org.openpsa.core/list.css");
     midcom::get('head')->enable_jquery();
     midcom::get('head')->add_jsfile(MIDCOM_STATIC_URL . '/org.openpsa.invoices/invoices.js');
     $title = $this->_l10n->get('project invoicing');
     midcom::get('head')->set_pagetitle($title);
     $this->add_breadcrumb("", $title);
 }
예제 #3
0
파일: index.php 프로젝트: nemein/openpsa
 /**
  * Sort the reports by task and day
  */
 private function _get_sorted_reports($hours_mc)
 {
     $reports = array();
     $hours = $hours_mc->list_keys();
     $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX);
     foreach ($hours as $guid => $empty) {
         $task_id = $hours_mc->get_subkey($guid, 'task');
         try {
             $task = org_openpsa_projects_task_dba::get_cached($task_id);
         } catch (midcom_error $e) {
             // Task couldn't be loaded, probably because of ACL
             continue;
         }
         $person = $hours_mc->get_subkey($guid, 'person');
         $date = $hours_mc->get_subkey($guid, 'date');
         $date_identifier = date('Y-m-d', $date);
         $row_identifier = $task->id . '-' . $person;
         if (!isset($reports[$row_identifier])) {
             $reports[$row_identifier] = array($date_identifier => 0, 'task' => "<a href=\"{$prefix}hours/task/{$task->guid}/\">" . $task->get_label() . "</a>", 'task_index' => $task->get_label());
             try {
                 $person = org_openpsa_contacts_person_dba::get_cached($person);
                 $reports[$row_identifier]['person'] = $person->name;
             } catch (midcom_error $e) {
                 $reports[$row_identifier]['person'] = $this->_l10n->get('no person');
             }
         }
         if (!isset($reports[$row_identifier][$date_identifier])) {
             $reports[$row_identifier][$date_identifier] = 0;
         }
         $reports[$row_identifier][$date_identifier] += $hours_mc->get_subkey($guid, 'hours');
     }
     return array_values($reports);
 }
예제 #4
0
파일: report.php 프로젝트: nemein/openpsa
 /**
  * Get array of IDs of all tasks in subtree
  */
 private function _expand_task($task, $ret = array())
 {
     //When recursing we get object, otherwise GUID
     if (!is_object($task)) {
         try {
             $task = new org_openpsa_projects_task_dba($task);
         } catch (midcom_error $e) {
             //Something went seriously wrong, abort as cleanly as possible
             debug_add('Could not get task object, aborting', MIDCOM_LOG_ERROR);
             return $ret;
         }
     }
     org_openpsa_reports_handler_projects_report::_verify_cache('tasks', $this->_request_data);
     $this->_request_data['object_cache'][$task->guid] = $task;
     $this->_request_data['object_cache']['tasks'][$task->id] =& $this->_request_data['object_cache'][$task->guid];
     //Add current ID
     debug_add(sprintf('Adding task % (id: %s)', $task->title, $task->id));
     $ret[] = $task->id;
     //Get list of children and recurse
     //We pop already here due to recursion
     debug_add('Checking for children & recursing them');
     $qb = org_openpsa_projects_task_dba::new_query_builder();
     $qb->add_constraint('up', '=', $task->id);
     $results = $qb->execute();
     if (is_array($results)) {
         foreach ($results as $child_task) {
             $ret = $this->_expand_task($child_task, $ret);
         }
     }
     return $ret;
 }
예제 #5
0
파일: item.php 프로젝트: nemein/openpsa
 public function render_link()
 {
     $url = '';
     $link = nl2br($this->description);
     $siteconfig = org_openpsa_core_siteconfig::get_instance();
     $projects_url = $siteconfig->get_node_full_url('org.openpsa.projects');
     $sales_url = $siteconfig->get_node_full_url('org.openpsa.sales');
     if ($projects_url) {
         try {
             $task = org_openpsa_projects_task_dba::get_cached($this->task);
             $url = $projects_url . 'task/' . $task->guid . '/';
         } catch (midcom_error $e) {
         }
     }
     if ($url == '' && $sales_url) {
         try {
             $deliverable = org_openpsa_sales_salesproject_deliverable_dba::get_cached($this->deliverable);
             $url = $sales_url . 'deliverable/' . $deliverable->guid . '/';
         } catch (midcom_error $e) {
         }
     }
     if ($url != '') {
         $link = '<a href="' . $url . '">' . $link . '</a>';
     }
     return $link;
 }
예제 #6
0
파일: action.php 프로젝트: nemein/openpsa
 /**
  * @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_action($handler_id, array $args, array &$data)
 {
     midcom::get('auth')->require_valid_user();
     // Check if we get the task
     $task = new org_openpsa_projects_task_dba($args[0]);
     $task->require_do('midgard:update');
     // Check if the action is a valid one
     switch ($args[1]) {
         case 'reopen':
             org_openpsa_projects_workflow::reopen($task);
             return new midcom_response_relocate("task/{$task->guid}/");
         case 'complete':
             org_openpsa_projects_workflow::complete($task);
             return new midcom_response_relocate("task/{$task->guid}/");
         default:
             throw new midcom_error('Unknown action ' . $args[1]);
     }
 }
예제 #7
0
 /**
  * @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_prospect_slots($handler_id, array $args, array &$data)
 {
     $data['prospect'] = new org_openpsa_projects_task_resource_dba($args[0]);
     $data['person'] = new org_openpsa_contacts_person_dba($data['prospect']->person);
     $this->_task = new org_openpsa_projects_task_dba($data['prospect']->task);
     $this->_task->require_do('midgard:create');
     $projectbroker = new org_openpsa_projects_projectbroker();
     $data['slots'] = $projectbroker->resolve_person_timeslots($data['person'], $this->_task);
     midcom::get()->skip_page_style = true;
 }
예제 #8
0
파일: report.php 프로젝트: nemein/openpsa
 /**
  * function checks if hour_report is invoiceable & applies minimum time slot
  */
 function modify_hours_by_time_slot($update = true)
 {
     if ($this->invoiceable) {
         $task = new org_openpsa_projects_task_dba($this->task);
         $time_slot = (double) $task->get_parameter('org.openpsa.projects.projectbroker', 'minimum_slot');
         if (empty($time_slot) || $time_slot == 0) {
             $time_slot = (double) midcom_baseclasses_components_configuration::get('org.openpsa.projects', 'config')->get('default_minimum_time_slot');
             if (empty($time_slot) || $time_slot == 0) {
                 $time_slot = 1;
             }
         }
         $time_slot_amount = $this->hours / $time_slot;
         $time_slot_amount_int = intval($time_slot_amount);
         $difference = $time_slot_amount - (double) $time_slot_amount_int;
         if ($difference > 0.5 || $time_slot_amount_int == 0) {
             $time_slot_amount_int++;
         }
         $this->hours = $time_slot_amount_int * $time_slot;
         if ($update) {
             $this->update();
         }
     }
 }
예제 #9
0
파일: status.php 프로젝트: nemein/openpsa
 private function _update_task()
 {
     $task = org_openpsa_projects_task_dba::get_cached($this->task);
     if ($this->type == org_openpsa_projects_task_status_dba::PROPOSED) {
         try {
             $recipient = midcom_db_person::get_cached($this->targetPerson);
             //Creator will naturally accept his own proposal...
             if ($recipient->guid == $this->metadata->creator) {
                 return org_openpsa_projects_workflow::accept($task, 0, $this->comment);
             }
         } catch (midcom_error $e) {
             $e->log();
         }
     }
     //See if the parent status needs updating
     if ($task->status == $this->type) {
         debug_add("Task status is up to date, returning");
         return;
     }
     $needs_update = false;
     if ($task->status < $this->type) {
         // This doesn't really do anything yet, it's moved here from workflow.php
         if ($this->type == org_openpsa_projects_task_status_dba::ACCEPTED) {
             switch ($task->acceptanceType) {
                 case ORG_OPENPSA_TASKACCEPTANCE_ALLACCEPT:
                 case ORG_OPENPSA_TASKACCEPTANCE_ONEACCEPTDROP:
                     debug_add('Acceptance mode not implemented', MIDCOM_LOG_ERROR);
                     return false;
                     break;
                 default:
                 case ORG_OPENPSA_TASKACCEPTANCE_ONEACCEPT:
                     //PONDER: Should this be superseded by generic method for querying the status objects to set the latest status ??
                     debug_add("Required accept received, setting task status to accepted");
                     //
                     $needs_update = true;
                     break;
             }
         } else {
             $needs_update = true;
         }
     } else {
         $needs_update = true;
     }
     if ($needs_update) {
         debug_add("Setting task status to {$this->type}");
         $task->status = $this->type;
         $task->_skip_acl_refresh = true;
         $task->update();
     }
 }
예제 #10
0
 /**
  * Prepare the indexer client
  */
 public function _on_reindex($topic, $config, &$indexer)
 {
     $qb_tasks = org_openpsa_projects_task_dba::new_query_builder();
     $schemadb_tasks = midcom_helper_datamanager2_schema::load_database($config->get('schemadb_task'));
     $qb_projects = org_openpsa_projects_project::new_query_builder();
     $schemadb_projects = midcom_helper_datamanager2_schema::load_database($config->get('schemadb_project'));
     $indexer = new org_openpsa_projects_midcom_indexer($topic, $indexer);
     $indexer->add_query('tasks', $qb_tasks, $schemadb_tasks);
     $indexer->add_query('projects', $qb_projects, $schemadb_projects);
     return $indexer;
 }
예제 #11
0
파일: default.php 프로젝트: nemein/openpsa
 private function _find_tasks()
 {
     $qb = org_openpsa_projects_task_dba::new_query_builder();
     $qb->add_constraint('agreement', '=', $this->_deliverable->id);
     if ($this->_deliverable->invoiceByActualUnits) {
         $qb->add_constraint('invoiceableHours', '>', 0);
     } else {
         $item_mc = org_openpsa_invoices_invoice_item_dba::new_collector('deliverable', $this->_deliverable->id);
         $skip_ids = $item_mc->get_values('task');
         if (sizeof($skip_ids) > 0) {
             $qb->add_constraint('id', 'NOT IN', $skip_ids);
         }
     }
     return $qb->execute();
 }
예제 #12
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));
 }
예제 #13
0
</strong></p>
        <?php 
    echo org_openpsa_helpers::render_fileinfo($invoice, 'pdf_file');
    ?>
    <?php 
}
// Display invoiced hours and tasks
if (isset($data['sorted_reports']) && count($data['sorted_reports']['reports']) > 0) {
    $grid_id = 'invoice_' . $invoice->number . '_hours_grid';
    $guids = array();
    $rows = array();
    foreach ($data['sorted_reports']['reports'] as $report) {
        $row = array();
        $guids[] = $report->guid;
        try {
            $task = org_openpsa_projects_task_dba::get_cached($report->task);
            $reporter = org_openpsa_contacts_person_dba::get_cached($report->person);
        } catch (midcom_error $e) {
            continue;
        }
        $reporter_card = org_openpsa_widgets_contact::get($report->person);
        $approved_img_src = MIDCOM_STATIC_URL . '/stock-icons/16x16/';
        if ($report->is_approved()) {
            $approved_text = $data['l10n']->get('approved');
            $approved_img_src .= 'page-approved.png';
        } else {
            $approved_text = $data['l10n']->get('not approved');
            $approved_img_src .= 'page-notapproved.png';
        }
        $approved_img = "<img src='{$approved_img_src}' alt='{$approved_text}' title='{$approved_text}' />";
        $row['id'] = $report->id;
예제 #14
0
파일: workflow.php 프로젝트: nemein/openpsa
 /**
  * Mark task as closed
  *
  * @param org_openpsa_projects_task_dba &$task The task we're working on
  */
 static function close(&$task, $comment = '')
 {
     debug_add("task->close() called with user #" . midcom_connection::get_user());
     //TODO: Check deliverables / require to be approved first
     //PONDER: Check ACL instead?
     if ($task->manager != 0 && midcom_connection::get_user() != $task->manager) {
         debug_add("Current user #" . midcom_connection::get_user() . " is not manager of task, thus cannot close", MIDCOM_LOG_ERROR);
         return false;
     }
     if (self::create_status($task, org_openpsa_projects_task_status_dba::CLOSED, 0, $comment)) {
         midcom::get('uimessages')->add(midcom::get('i18n')->get_string('org.openpsa.projects', 'org.openpsa.projects'), sprintf(midcom::get('i18n')->get_string('marked task "%s" closed', 'org.openpsa.projects'), $task->title), 'ok');
         if ($task->agreement) {
             $agreement = new org_openpsa_sales_salesproject_deliverable_dba($task->agreement);
             // Set agreement delivered if this is the only open task for it
             $task_qb = org_openpsa_projects_task_dba::new_query_builder();
             $task_qb->add_constraint('agreement', '=', $task->agreement);
             $task_qb->add_constraint('status', '<', org_openpsa_projects_task_status_dba::CLOSED);
             $task_qb->add_constraint('id', '<>', $task->id);
             $task_qb->add_constraint('orgOpenpsaObtype', '=', ORG_OPENPSA_OBTYPE_TASK);
             if ($task_qb->count() == 0) {
                 // No other open tasks, mark as delivered
                 $agreement->deliver(false);
             } else {
                 midcom::get('uimessages')->add(midcom::get('i18n')->get_string('org.openpsa.projects', 'org.openpsa.projects'), sprintf(midcom::get('i18n')->get_string('did not mark deliverable "%s" delivered due to other tasks', 'org.openpsa.sales'), $agreement->title), 'info');
             }
         }
         return true;
     }
     return false;
 }
예제 #15
0
파일: list.php 프로젝트: nemein/openpsa
 /**
  * Helper to load the data linked to the hour reports
  *
  * @param array $hours the hour reports we're working with
  */
 private function _load_hour_data(array $hours)
 {
     $reports = array('invoiceable' => array('hours' => 0, 'reports' => array()), 'uninvoiceable' => array('hours' => 0, 'reports' => array()), 'invoiced' => array('hours' => 0, 'reports' => array()));
     $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX);
     foreach ($hours as $report) {
         if (!array_key_exists($report->person, $this->reporters)) {
             try {
                 $reporter = new midcom_db_person($report->person);
                 $reporter_card = new org_openpsa_widgets_contact($reporter);
                 $this->reporters[$report->person] = $reporter_card->show_inline();
             } catch (midcom_error $e) {
                 $e->log();
                 $this->reporters[$report->person] = '';
             }
         }
         if (!array_key_exists($report->task, $this->tasks)) {
             $task = new org_openpsa_projects_task_dba($report->task);
             $task_html = "<a href=\"{$prefix}hours/task/{$task->guid}/\">" . $task->get_label() . "</a>";
             $this->tasks[$report->task] = $task_html;
         }
         switch (true) {
             case $report->invoice:
                 $category = 'invoiced';
                 break;
             case $report->invoiceable:
                 $category = 'invoiceable';
                 break;
             default:
                 $category = 'uninvoiceable';
                 break;
         }
         $reports[$category]['reports'][] = $report;
         $reports[$category]['hours'] += $report->hours;
     }
     $this->_request_data['sorted_reports'] = $reports;
 }
예제 #16
0
파일: resource.php 프로젝트: nemein/openpsa
 /**
  * Helper function that removes a member from parent resources if necessary
  *
  * @param org_openpsa_projects_task_dba $object The object for which we search the parent
  */
 function remove_resource_from_parent(&$object)
 {
     $parent = $object->get_parent();
     if (!$parent) {
         return;
     }
     $mc = self::new_collector('person', $this->person);
     $mc->add_constraint('orgOpenpsaObtype', '=', $this->orgOpenpsaObtype);
     $mc->add_constraint('task.project', 'INTREE', $parent->id);
     $mc->execute();
     if ($mc->count() > 0) {
         //Resource is still present in silbling tasks, aborting
         return;
     }
     $qb = self::new_query_builder();
     $qb->add_constraint('person', '=', $this->person);
     $qb->add_constraint('orgOpenpsaObtype', '=', $this->orgOpenpsaObtype);
     $qb->add_constraint('task', '=', $parent->id);
     $results = $qb->execute();
     foreach ($results as $result) {
         $result->delete();
     }
 }
예제 #17
0
 /**
  * @todo Check if we already have an open task for this delivery?
  */
 function create_task($start, $end, $title, $source_task = null)
 {
     $salesproject = org_openpsa_sales_salesproject_dba::get_cached($this->_deliverable->salesproject);
     $product = org_openpsa_products_product_dba::get_cached($this->_deliverable->product);
     // Check if we already have a project for the sales project
     $project = $salesproject->get_project();
     // Create the task
     $task = new org_openpsa_projects_task_dba();
     $task->agreement = $this->_deliverable->id;
     $task->customer = $salesproject->customer;
     $task->title = $title;
     $task->description = $this->_deliverable->description;
     $task->start = $start;
     $task->end = $end;
     $task->plannedHours = $this->_deliverable->plannedUnits;
     $task->manager = $salesproject->owner;
     if ($project) {
         $task->project = $project->id;
         $task->orgOpenpsaAccesstype = $project->orgOpenpsaAccesstype;
         $task->orgOpenpsaOwnerWg = $project->orgOpenpsaOwnerWg;
     }
     if (!empty($source_task)) {
         $task->priority = $source_task->priority;
         $task->manager = $source_task->manager;
     }
     // TODO: Figure out if we really want to keep this
     $task->hoursInvoiceableDefault = true;
     if ($task->create()) {
         $task->add_members('contacts', array_keys($salesproject->contacts));
         if (!empty($source_task)) {
             $source_task->get_members();
             $task->add_members('resources', array_keys($source_task->resources));
         }
         org_openpsa_relatedto_plugin::create($task, 'org.openpsa.projects', $product, 'org.openpsa.products');
         // Copy tags from deliverable so we can seek resources
         $tagger = new net_nemein_tag_handler();
         $tagger->copy_tags($this->_deliverable, $task);
         midcom::get('uimessages')->add(midcom::get('i18n')->get_string('org.openpsa.sales', 'org.openpsa.sales'), sprintf(midcom::get('i18n')->get_string('created task "%s"', 'org.openpsa.sales'), $task->title), 'ok');
         return $task;
     } else {
         throw new midcom_error("The task for this cycle could not be created. Last Midgard error was: " . midcom_connection::get_error_string());
     }
 }
예제 #18
0
 private function _verify_new_task()
 {
     $qb = org_openpsa_projects_task_dba::new_query_builder();
     $qb->add_constraint('guid', '<>', $this->_task->guid);
     $qb->add_constraint('project', '=', $this->_project->id);
     $results = $qb->execute();
     $this->register_objects($results);
     $this->assertEquals(1, sizeof($results));
     $new_task = $results[0];
     $this->assertEquals($this->_deliverable->id, $new_task->agreement);
     $this->assertEquals($this->_salesproject->customer, $new_task->customer);
     $this->assertEquals($this->_task->manager, $new_task->manager);
 }
예제 #19
0
파일: admin.php 프로젝트: nemein/openpsa
 /**
  * Helper, updates the context so that we get a complete breadcrumb line towards the current
  * location.
  *
  * @param string $handler_id The handler ID
  */
 private function _update_breadcrumb_line($handler_id)
 {
     $task = false;
     if (isset($this->_hour_report->task)) {
         $task = org_openpsa_projects_task_dba::get_cached($this->_hour_report->task);
     } else {
         if (!empty($this->_request_data['task'])) {
             $task = org_openpsa_projects_task_dba::get_cached($this->_request_data['task']);
         }
     }
     if ($task) {
         $this->add_breadcrumb("hours/task/" . $task->guid, $task->get_label());
         $this->add_breadcrumb("", $this->_l10n->get($handler_id));
     }
 }
예제 #20
0
 function deliver($update_deliveries = true)
 {
     if ($this->state > org_openpsa_sales_salesproject_deliverable_dba::STATUS_DELIVERED) {
         return false;
     }
     $product = org_openpsa_products_product_dba::get_cached($this->product);
     if ($product->delivery == org_openpsa_products_product_dba::DELIVERY_SUBSCRIPTION) {
         // Subscriptions are ongoing, not one delivery
         return false;
     }
     // Check if we need to create task or ship goods
     if ($update_deliveries) {
         switch ($product->orgOpenpsaObtype) {
             case org_openpsa_products_product_dba::TYPE_SERVICE:
                 // Change status of tasks connected to the deliverable
                 $task_qb = org_openpsa_projects_task_dba::new_query_builder();
                 $task_qb->add_constraint('agreement', '=', $this->id);
                 $task_qb->add_constraint('status', '<', org_openpsa_projects_task_status_dba::CLOSED);
                 $tasks = $task_qb->execute();
                 foreach ($tasks as $task) {
                     org_openpsa_projects_workflow::close($task, sprintf(midcom::get('i18n')->get_string('completed from deliverable %s', 'org.openpsa.sales'), $this->title));
                 }
                 break;
             case org_openpsa_products_product_dba::TYPE_GOODS:
                 // TODO: Warehouse management: mark product as shipped
             // TODO: Warehouse management: mark product as shipped
             default:
                 break;
         }
     }
     $this->state = org_openpsa_sales_salesproject_deliverable_dba::STATUS_DELIVERED;
     $this->end = time();
     if ($this->update()) {
         // Update sales project and mark as delivered (if no other deliverables are active)
         $salesproject = new org_openpsa_sales_salesproject_dba($this->salesproject);
         $salesproject->mark_delivered();
         midcom::get('uimessages')->add(midcom::get('i18n')->get_string('org.openpsa.sales', 'org.openpsa.sales'), sprintf(midcom::get('i18n')->get_string('marked deliverable "%s" delivered', 'org.openpsa.sales'), $this->title), 'ok');
         return true;
     }
     return false;
 }
예제 #21
0
파일: project.php 프로젝트: nemein/openpsa
 /**
  * This function sets project information according to the situation of its tasks
  *
  * This adjusts the timeframe if necessary and tries to determine the project's
  * status according to the current task situation
  */
 public function refresh_from_tasks()
 {
     $update_required = false;
     $task_statuses = array();
     $status_types = array();
     $task_qb = org_openpsa_projects_task_dba::new_query_builder();
     $task_qb->add_constraint('project', '=', $this->id);
     $ret = $task_qb->execute();
     if (sizeof($ret) == 0) {
         return;
     }
     foreach ($ret as $task) {
         if ($task->start < $this->start) {
             $this->start = $task->start;
             $update_required = true;
         }
         if ($task->end > $this->end) {
             $this->end = $task->end;
             $update_required = true;
         }
         if (!array_key_exists($task->status_type, $status_types)) {
             $status_types[$task->status_type] = true;
         }
         //Simple way to handle accepted and various "under work" statuses
         if (!array_key_exists($task->status, $task_statuses)) {
             $task_statuses[$task->status] = 0;
         }
         $task_statuses[$task->status]++;
     }
     $new_status = null;
     if (sizeof($task_statuses) == 1) {
         // If all tasks are of the same type, that is the type to use then
         $new_status = key($task_statuses);
     } else {
         switch ($this->status_type) {
             case 'rejected':
                 // If there's an ongoing task, the project seems to have resumed
                 if (array_key_exists('ongoing', $status_types)) {
                     $new_status = org_openpsa_projects_task_status_dba::REOPENED;
                 } else {
                     if (array_key_exists('not_started', $status_types)) {
                         $new_status = org_openpsa_projects_task_status_dba::PROPOSED;
                     } else {
                         if (!array_key_exists('rejected', $status_types)) {
                             //Blocker task
                             if (array_key_exists('on_hold', $status_types)) {
                                 $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                             } else {
                                 if (array_key_exists('closed', $status_types)) {
                                     $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                                 }
                             }
                         }
                     }
                 }
                 break;
             case 'not_started':
                 //Work seems to have been started
                 if (array_key_exists('ongoing', $status_types)) {
                     $new_status = org_openpsa_projects_task_status_dba::STARTED;
                 } else {
                     if (array_key_exists('on_hold', $status_types)) {
                         $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                     } else {
                         if (array_key_exists('closed', $status_types) && !array_key_exists('not_started', $status_types)) {
                             $new_status = org_openpsa_projects_task_status_dba::COMPLETED;
                         }
                     }
                 }
                 break;
             case 'ongoing':
                 //Only do something if there are no ongoing tasks
                 if (!array_key_exists('ongoing', $status_types)) {
                     //Blocker task
                     if (array_key_exists('on_hold', $status_types)) {
                         $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                     } else {
                         if (array_key_exists('not_started', $status_types) || array_key_exists('closed', $status_types)) {
                             $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                         } else {
                             if (array_key_exists('not_started', $status_types)) {
                                 $new_status = org_openpsa_projects_task_status_dba::PROPOSED;
                             } else {
                                 if (array_key_exists('closed', $status_types)) {
                                     $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                                 }
                             }
                         }
                     }
                 }
                 break;
             case 'closed':
                 //Something new came up, reopen
                 if (array_key_exists('not_started', $status_types) || array_key_exists('ongoing', $status_types)) {
                     $new_status = org_openpsa_projects_task_status_dba::REOPENED;
                 } else {
                     if (!array_key_exists('closed', $status_types)) {
                         if (array_key_exists('on_hold', $status_types)) {
                             $new_status = org_openpsa_projects_task_status_dba::ONHOLD;
                         }
                     }
                 }
                 break;
             case 'on_hold':
                 //If no task is on hold, we have to look for something else
                 if (!array_key_exists('on_hold', $status_types)) {
                     // check if work has resumed
                     if (array_key_exists('ongoing', $status_types)) {
                         $new_status = org_openpsa_projects_task_status_dba::STARTED;
                     } else {
                         if (array_key_exists('not_started', $status_types) && !array_key_exists('closed', $status_types)) {
                             $new_status = org_openpsa_projects_task_status_dba::PROPOSED;
                         } else {
                             if (array_key_exists('closed', $status_types) && !array_key_exists('not_started', $status_types)) {
                                 $new_status = org_openpsa_projects_task_status_dba::COMPLETED;
                             }
                         }
                     }
                 }
         }
     }
     if (!is_null($new_status) && $this->status != $new_status) {
         $this->status = $new_status;
         $update_required = true;
     }
     if ($update_required) {
         debug_add("Some project information needs to be updated, skipping ACL refresh");
         $this->_skip_acl_refresh = true;
         $this->_use_rcs = false;
         $this->_use_activitystream = false;
         return $this->update();
     } else {
         debug_add("All project information is up-to-date");
         return true;
     }
 }
예제 #22
0
파일: list.php 프로젝트: nemein/openpsa
 public function _handler_list_user($handler_id, array $args, array &$data)
 {
     midcom::get('auth')->require_valid_user();
     $this->_request_data['view'] = 'grid';
     $this->_request_data['view_identifier'] = 'my_tasks';
     $siteconfig = org_openpsa_core_siteconfig::get_instance();
     $this->_request_data['contacts_url'] = $siteconfig->get_node_full_url('org.openpsa.contacts');
     //get possible priorities from schema
     $this->_get_priorities();
     $this->_provider = new org_openpsa_widgets_grid_provider($this, 'local');
     $resource_statuses = array(org_openpsa_projects_task_status_dba::PROPOSED, org_openpsa_projects_task_status_dba::ACCEPTED, org_openpsa_projects_task_status_dba::STARTED, org_openpsa_projects_task_status_dba::REOPENED, org_openpsa_projects_task_status_dba::COMPLETED);
     $task_statuses = array(org_openpsa_projects_task_status_dba::PROPOSED, org_openpsa_projects_task_status_dba::DECLINED, org_openpsa_projects_task_status_dba::COMPLETED, org_openpsa_projects_task_status_dba::ONHOLD);
     $mc = org_openpsa_projects_task_resource_dba::new_collector('person', midcom_connection::get_user());
     $mc->add_constraint('orgOpenpsaObtype', '=', ORG_OPENPSA_OBTYPE_PROJECTRESOURCE);
     $mc->add_constraint('task.orgOpenpsaObtype', '=', ORG_OPENPSA_OBTYPE_TASK);
     $mc->add_constraint('task.status', 'IN', $resource_statuses);
     $resource_tasks = $mc->get_values('task');
     $this->_qb = org_openpsa_projects_task_dba::new_query_builder();
     $this->_qb->add_constraint('orgOpenpsaObtype', '=', ORG_OPENPSA_OBTYPE_TASK);
     $this->_qb->begin_group('OR');
     if (!empty($resource_tasks)) {
         //Get active tasks where user is a resource
         $this->_qb->add_constraint('id', 'IN', $resource_tasks);
     }
     //Get relevant tasks where user is manager
     $this->_qb->begin_group('AND');
     $this->_qb->add_constraint('manager', '=', midcom_connection::get_user());
     $this->_qb->add_constraint('status', 'IN', $task_statuses);
     $this->_qb->end_group();
     $this->_qb->end_group();
     org_openpsa_widgets_grid::add_head_elements();
 }
예제 #23
0
<?php

/**
 * Converter script that transfers old-style relatedto connections to invoice_items. Handle with care!
 */
midcom::get('auth')->require_admin_user();
midcom::get()->disable_limits();
while (@ob_end_flush()) {
}
echo "<pre>\n";
$task_qb = org_openpsa_projects_task_dba::new_query_builder();
$tasks = $task_qb->execute();
foreach ($tasks as $task) {
    $relatedto_qb = org_openpsa_relatedto_dba::new_query_builder();
    $relatedto_qb->add_constraint('toGuid', '=', $task->guid);
    $relatedto_qb->add_constraint('fromClass', '=', 'org_openpsa_invoices_invoice_dba');
    $relatedtos = $relatedto_qb->execute();
    if (sizeof($relatedtos) == 0) {
        echo "Task " . $task->get_label() . " 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 task\n";
            flush();
            $item = new org_openpsa_invoices_invoice_item_dba();
            $item->invoice = $invoice->id;
            $item->task = $task->id;
            $item->deliverable = $task->agreement;
예제 #24
0
파일: invoice.php 프로젝트: nemein/openpsa
 /**
  * Deletes all invoice_hours related to the invoice
  */
 public function _on_deleting()
 {
     if (!midcom::get('auth')->request_sudo('org.openpsa.invoices')) {
         debug_add('Failed to get SUDO privileges, skipping invoice hour deletion silently.', MIDCOM_LOG_ERROR);
         return false;
     }
     // Delete invoice_hours
     $tasks_to_update = array();
     $qb = org_openpsa_projects_hour_report_dba::new_query_builder();
     $qb->add_constraint('invoice', '=', $this->id);
     $hours = $qb->execute();
     foreach ($hours as $hour) {
         $hour->invoice = 0;
         $hour->_skip_parent_refresh = true;
         $tasks_to_update[$hour->task] = true;
         if (!$hour->update()) {
             debug_add("Failed to remove invoice hour record {$hour->id}, last Midgard error was: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR);
         }
     }
     foreach ($tasks_to_update as $id => $boolean) {
         try {
             $task = new org_openpsa_projects_task_dba($id);
             $task->update_cache();
         } catch (midcom_error $e) {
         }
     }
     midcom::get('auth')->drop_sudo();
     return parent::_on_deleting();
 }
예제 #25
0
파일: crud.php 프로젝트: nemein/openpsa
 /**
  * This is what Datamanager calls to actually create a task
  */
 function &dm2_create_callback(&$controller)
 {
     $task = new org_openpsa_projects_task_dba();
     if ($this->_parent) {
         // Add the task to the project
         $task->project = (int) $this->_parent->id;
         // Populate some default data from parent as needed
         $task->orgOpenpsaAccesstype = $this->_parent->orgOpenpsaAccesstype;
         $task->orgOpenpsaOwnerWg = $this->_parent->orgOpenpsaOwnerWg;
     }
     if (!$task->create()) {
         debug_print_r('We operated on this object:', $task);
         throw new midcom_error("Failed to create a new task under project #{$this->_request_data['project']->id}. Error: " . midcom_connection::get_error_string());
     }
     $this->_object = new org_openpsa_projects_task_dba($task->id);
     return $this->_object;
 }
if ($task_status->targetPerson) {
    $target_person = org_openpsa_widgets_contact::get($task_status->targetPerson);
    $target_person_label = $target_person->show_inline();
}
$message = sprintf(midcom::get('i18n')->get_string($task_status->get_status_message(), 'org.openpsa.projects'), $status_changer_label, $target_person_label);
?>
<tr class="hour_report &(data['class']);">
    <td class="time">
        <?php 
echo date('H:i', $data['time']);
?>
    </td>
    <td>
        <?php 
try {
    $task = org_openpsa_projects_task_dba::get_cached($task_status->task);
    $task_label = $task->get_label();
    if ($data['projects_url']) {
        $task_label = "<a href=\"{$data['projects_url']}task/{$task->guid}/\">{$task_label}</a>";
    }
    echo $task_label;
} catch (midcom_error $e) {
}
?>
    </td>
    <td class="multivalue">
        <?php 
echo "{$message}";
?>
    </td>
    <td>&nbsp;</td>