public static function get_invoice_items($invoice_id, $invoice = array()) { $invoice_id = (int) $invoice_id; $invoice_items = array(); if (!$invoice_id && isset($_REQUEST['job_id']) && (int) $_REQUEST['job_id'] > 0) { // hack for half completed invoices if (isset($_REQUEST['amount_due']) && $_REQUEST['amount_due'] > 0) { $amount = (double) $_REQUEST['amount_due']; $invoice_items = array('new0' => array('description' => isset($_REQUEST['description']) ? $_REQUEST['description'] : _l('Invoice Item'), 'custom_description' => '', 'long_description' => '', 'custom_long_description' => '', 'amount' => $amount, 'manual_task_type' => _TASK_TYPE_AMOUNT_ONLY, 'hours' => 0, 'taxable' => false, 'task_id' => 0)); } else { $job_id = (int) $_REQUEST['job_id']; if ($job_id > 0) { // we return the items from the job rather than the items from the invoice. // for new invoice creation. $tasks = module_job::get_invoicable_tasks($job_id); $x = 0; $job = module_job::get_job($job_id, false); $invoice['hourly_rate'] = $job['hourly_rate']; foreach ($tasks as $task) { if (!isset($task['custom_description'])) { $task['custom_description'] = ''; } if (!isset($task['custom_long_description'])) { $task['custom_long_description'] = ''; } //$task['task_id'] = 'new'.$x; // the 'hourly_rate' column will hold either // = for hours/amount the default hourly rate from the job // = for qty/amount the raw amount that will multiplu hours by // = for amount only will be the raw amount. $invoice_task_type = isset($task['manual_task_type']) && $task['manual_task_type'] >= 0 ? $task['manual_task_type'] : $job['default_task_type']; if ($invoice_task_type == _TASK_TYPE_QTY_AMOUNT) { $task['hourly_rate'] = $task['amount']; $task['amount'] = 0; // this forces our calc below to calculate teh amount for us. } else { $task['hourly_rate'] = $job['hourly_rate']; } $invoice_items['new' . $x] = $task; $x++; } //print_r($tasks);exit; } } } else { if ($invoice_id) { if (!$invoice) { $invoice = self::get_invoice($invoice_id, true); } $sql = "SELECT ii.invoice_item_id AS id, ii.*, t.job_id, t.description AS description, ii.description as custom_description, ii.long_description as custom_long_description, t.task_order, ii.task_order AS custom_task_order "; // , j.hourly_rate $sql .= ", t.date_done AS task_date_done "; $sql .= ", t.task_id "; $sql .= " FROM `" . _DB_PREFIX . "invoice_item` ii "; $sql .= " LEFT JOIN `" . _DB_PREFIX . "task` t ON ii.task_id = t.task_id "; $sql .= " LEFT JOIN `" . _DB_PREFIX . "job` j ON t.job_id = j.job_id "; $sql .= " WHERE ii.invoice_id = {$invoice_id}"; $sql .= " ORDER BY t.task_order "; $invoice_items = qa($sql); } } // print_r($invoice_items); // DAVE READ THIS: tasks come in with 'hours' and 'amount' and 'manual_task_type' // calculate the 'task_hourly_rate' and 'invoite_item_amount' based on this. // 'amount' is NOT used in invoice items. only 'invoice_item_amount' //echo '<pre>';print_r($invoice_items);echo '</pre>'; foreach ($invoice_items as $invoice_item_id => $invoice_item_data) { $invoice_item_data['task_hours'] = ''; $invoice_item_data['task_hours_completed'] = ''; if (isset($invoice_item_data['job_id']) && $invoice_item_data['task_id'] && $invoice_item_data['job_id'] && $invoice_item_data['task_id']) { $job_tasks = module_job::get_tasks($invoice_item_data['job_id']); if (isset($job_tasks[$invoice_item_data['task_id']])) { // copied from ajax_task_edit.php: if (function_exists('decimal_time_out')) { $completed_value = decimal_time_out($job_tasks[$invoice_item_data['task_id']]['completed']); $hours_value = decimal_time_out($job_tasks[$invoice_item_data['task_id']]['hours']); } else { $completed_value = number_out($job_tasks[$invoice_item_data['task_id']]['completed'], true); $hours_value = number_out($job_tasks[$invoice_item_data['task_id']]['hours'], true); } $invoice_item_data['task_hours'] = $hours_value; $invoice_item_data['task_hours_completed'] = $completed_value; } } // new feature, task type. $invoice_item_data['manual_task_type_real'] = $invoice_item_data['manual_task_type']; if ($invoice_item_data['manual_task_type'] < 0 && isset($invoice['default_task_type'])) { $invoice_item_data['manual_task_type'] = $invoice['default_task_type']; } if (isset($invoice_item_data['hours_mins'])) { if ($invoice_item_data['hours_mins'] == 0) { $invoice_item_data['hours_mins'] = 0; } else { $invoice_item_data['hours_mins'] = str_replace(".", ":", $invoice_item_data['hours_mins']); } } // if there are no hours logged against this task if (!$invoice_item_data['hours']) { //$invoice_item_data['task_hourly_rate']=0; } // task_hourly_rate is used for calculations, if the hourly_rate is -1 then we use the default invoice hourly rate $invoice_item_data['task_hourly_rate'] = isset($invoice_item_data['hourly_rate']) && $invoice_item_data['hourly_rate'] != 0 && $invoice_item_data['hourly_rate'] != -1 ? $invoice_item_data['hourly_rate'] : $invoice['hourly_rate']; // if we have a custom price for this task if ($invoice_item_data['manual_task_type'] == _TASK_TYPE_HOURS_AMOUNT) { if ($invoice_item_data['amount'] != 0) { $invoice_item_data['invoice_item_amount'] = $invoice_item_data['amount']; if ($invoice_item_data['hours'] == 0) { // hack to fix $0 invoices $invoice_item_data['hours'] = 1; $invoice_item_data['task_hourly_rate'] = $invoice_item_data['amount']; } //echo '<pre>';print_r($invoice_items);echo '</pre>'; if (isset($invoice_item_data['hours_mins']) && !empty($invoice_item_data['hours_mins']) && function_exists('decimal_time_in')) { $invoice_item_data['hours'] = decimal_time_in($invoice_item_data['hours_mins']); } if ($invoice_item_data['task_hourly_rate'] * $invoice_item_data['hours'] != $invoice_item_data['amount']) { // check the rounding, just to be sure. if (round($invoice_item_data['task_hourly_rate'] * $invoice_item_data['hours'], 2) == round($invoice_item_data['amount'], 2)) { // all good } else { // hack to fix manual amount with non-matching hours. $invoice_item_data['task_hourly_rate'] = $invoice_item_data['amount'] / $invoice_item_data['hours']; } } } else { $invoice_item_data['invoice_item_amount'] = $invoice_item_data['task_hourly_rate'] * $invoice_item_data['hours']; } } else { if ($invoice_item_data['manual_task_type'] == _TASK_TYPE_QTY_AMOUNT) { if ($invoice_item_data['amount'] != 0) { $invoice_item_data['invoice_item_amount'] = $invoice_item_data['amount']; } else { $invoice_item_data['invoice_item_amount'] = $invoice_item_data['task_hourly_rate'] * $invoice_item_data['hours']; } //$invoice_item_data['amount'] = $invoice_item_data['hourly_rate'] * $invoice_item_data['hours']; //$invoice_item_data['invoice_item_amount'] = $invoice_item_data['amount']; //$invoice_item_data['task_hourly_rate'] = $invoice_item_data['hourly_rate']; /*if($invoice_item_data['hours']>0){ $invoice_item_data['task_hourly_rate'] = round($invoice_item_data['invoice_item_amount']/$invoice_item_data['hours'],module_config::c('currency_decimal_places',2)); }else{ }*/ } else { // this item is an 'amount only' column. // no calculations based on quantity and hours. if ($invoice_item_data['amount'] != 0) { $invoice_item_data['task_hourly_rate'] = $invoice_item_data['amount']; $invoice_item_data['invoice_item_amount'] = $invoice_item_data['amount']; } else { $invoice_item_data['task_hourly_rate'] = 0; $invoice_item_data['invoice_item_amount'] = 0; } /* $invoice_item_data['task_hourly_rate'] = isset($invoice_item_data['hourly_rate']) && $invoice_item_data['hourly_rate']>0 ? $invoice_item_data['hourly_rate'] : $invoice['hourly_rate']; if($invoice_item_data['amount']!=0 && $invoice_item_data['amount'] != ($invoice_item_data['hours']*$invoice_item_data['task_hourly_rate'])){ $invoice_item_data['invoice_item_amount'] = $invoice_item_data['amount']; if(module_config::c('invoice_calculate_item_price_auto',1) && $invoice_item_data['hours'] > 0){ $invoice_item_data['task_hourly_rate'] = round($invoice_item_data['invoice_item_amount']/$invoice_item_data['hours'],module_config::c('currency_decimal_places',2)); }else{ $invoice_item_data['task_hourly_rate'] = false; } }else if($invoice_item_data['hours']>0){ $invoice_item_data['invoice_item_amount'] = $invoice_item_data['hours']*$invoice_item_data['task_hourly_rate']; }else{ $invoice_item_data['invoice_item_amount'] = 0; $invoice_item_data['task_hourly_rate'] = false; }*/ } } /*$invoice_item_amount = $invoice_item_data['amount'] > 0 ? $invoice_item_data['amount'] : $invoice_item_data['hours']*$task_hourly_rate; if($invoice_item_data['amount']>0 && !$invoice_item_data['hours']){ $invoice_item_amount = $invoice_item_data['amount']; $invoice_item_data['hours'] = 1; $task_hourly_rate = $invoice_item_data['amount']; // not sure if this will be buggy }else{ $invoice_item_amount = $invoice_item_data['hours']*$task_hourly_rate; }*/ // new feature, date done. if (isset($invoice_item_data['date_done']) && $invoice_item_data['date_done'] != '0000-00-00') { // $invoice_item_data['date_done'] is ok to print! } else { $invoice_item_data['date_done'] = '0000-00-00'; // check if this is linked to a task. if ($invoice_item_data['task_id']) { if (isset($invoice_item_data['task_date_done'])) { // moved it into SQL above, instead of doing a get_single() call below for each invoice line item if ($invoice_item_data['task_date_done'] && $invoice_item_data['task_date_done'] != '0000-00-00') { $invoice_item_data['date_done'] = $invoice_item_data['task_date_done']; } else { if (isset($invoice['date_create']) && $invoice['date_create'] != '0000-00-00') { $invoice_item_data['date_done'] = $invoice['date_create']; } } } else { $task = get_single('task', 'task_id', $invoice_item_data['task_id']); if ($task && isset($task['date_done']) && $task['date_done'] != '0000-00-00') { $invoice_item_data['date_done'] = $task['date_done']; // move it over ready for printing below } else { if (isset($invoice['date_create']) && $invoice['date_create'] != '0000-00-00') { $invoice_item_data['date_done'] = $invoice['date_create']; } } } } } // set a default taxes to match the invoice taxes if none defined if ((!isset($invoice_item_data['taxes']) || !count($invoice_item_data['taxes'])) && isset($invoice_item_data['taxable']) && $invoice_item_data['taxable'] && isset($invoice['taxes']) && count($invoice['taxes'])) { $invoice_item_data['taxes'] = $invoice['taxes']; } if (!isset($invoice_item_data['taxes'])) { $invoice_item_data['taxes'] = array(); } $invoice_items[$invoice_item_id] = $invoice_item_data; } //print_r($invoice_items);exit; return $invoice_items; }