コード例 #1
0
ファイル: note.php プロジェクト: sgh1986915/php-crm
 function handle_hook($hook, $calling_module = false, $owner_table = false, $key_name = false, $key_value = false, $rel_data = false)
 {
     switch ($hook) {
         case "home_alerts":
             $alerts = array();
             if (module_config::c('allow_note_reminders', 1)) {
                 // find any jobs that are past the due date and dont have a finished date.
                 $key = _l('Note Reminder');
                 if (class_exists('module_dashboard', false)) {
                     module_dashboard::register_group($key, array('columns' => array('name' => _l('Reminder'), 'type' => _l('Type'), 'full_link' => _l('Link'), 'date' => _l('Date'), 'days' => _l('Date'))));
                 }
                 $sql = "SELECT * FROM `" . _DB_PREFIX . "note` n ";
                 $sql .= " WHERE n.`reminder` = 1 AND n.note_time < " . (int) strtotime('+' . module_config::c('alert_days_in_future', 5) . ' days') . "";
                 $sql .= " AND ( n.`user_id` = 0 OR n.`user_id` = " . module_security::get_loggedin_id() . ")";
                 $sql .= " ORDER BY n.note_time ASC";
                 $tasks = qa($sql);
                 foreach ($tasks as $task) {
                     $alert_res = process_alert(date('Y-m-d', $task['note_time']), $key);
                     if ($alert_res) {
                         $alert_res['link'] = $task['rel_data'];
                         // fix for linking when changing folder.
                         $alert_res['type'] = _l(ucwords($task['owner_table']));
                         switch ($task['owner_table']) {
                             case 'user':
                                 $user = module_user::get_user($task['owner_id']);
                                 if ($user['customer_id'] || $user['vendor_id']) {
                                     $alert_res['link'] = module_user::link_open_contact($task['owner_id'], false, $user);
                                     $alert_res['full_link'] = module_user::link_open_contact($task['owner_id'], true, $user);
                                     $alert_res['type'] = _l('Contact');
                                 } else {
                                     $alert_res['link'] = module_user::link_open($task['owner_id'], false, $user);
                                     $alert_res['full_link'] = module_user::link_open($task['owner_id'], true, $user);
                                 }
                                 break;
                             case 'invoice':
                                 $invoice_data = module_invoice::get_invoice($task['owner_id'], true);
                                 if (!$invoice_data || !isset($invoice_data['invoice_id']) || $invoice_data['invoice_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_invoice::link_open($task['owner_id'], false, $invoice_data);
                                 $alert_res['full_link'] = module_invoice::link_open($task['owner_id'], true, $invoice_data);
                                 break;
                             case 'quote':
                                 $quote_data = module_quote::get_quote($task['owner_id'], true);
                                 if (!$quote_data || !isset($quote_data['quote_id']) || $quote_data['quote_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_quote::link_open($task['owner_id'], false, $quote_data);
                                 $alert_res['full_link'] = module_quote::link_open($task['owner_id'], true, $quote_data);
                                 break;
                             case 'website':
                                 $website_data = module_website::get_website($task['owner_id']);
                                 if (!$website_data || !isset($website_data['website_id']) || $website_data['website_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_website::link_open($task['owner_id'], false);
                                 $alert_res['full_link'] = module_website::link_open($task['owner_id'], true);
                                 break;
                             case 'customer':
                                 $customer_data = module_customer::get_customer($task['owner_id']);
                                 if (!$customer_data || !isset($customer_data['customer_id']) || $customer_data['customer_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_customer::link_open($task['owner_id'], false, $customer_data);
                                 $alert_res['full_link'] = module_customer::link_open($task['owner_id'], true, $customer_data);
                                 break;
                             case 'vendor':
                                 $vendor_data = module_vendor::get_vendor($task['owner_id']);
                                 if (!$vendor_data || !isset($vendor_data['vendor_id']) || $vendor_data['vendor_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_vendor::link_open($task['owner_id'], false, $vendor_data);
                                 $alert_res['full_link'] = module_vendor::link_open($task['owner_id'], true, $vendor_data);
                                 break;
                             case 'job':
                                 $job_data = module_job::get_job($task['owner_id']);
                                 if (!$job_data || !isset($job_data['job_id']) || $job_data['job_id'] != $task['owner_id']) {
                                     continue 2;
                                 }
                                 $alert_res['link'] = module_job::link_open($task['owner_id'], false, $job_data);
                                 $alert_res['full_link'] = module_job::link_open($task['owner_id'], true, $job_data);
                                 break;
                                 // todo - add others.
                         }
                         $alert_res['name'] = $task['note'];
                         $alert_res['date'] = print_date($alert_res['date']);
                         $alert_res['time'] = $task['note_time'];
                         $alerts[] = $alert_res;
                     }
                 }
             }
             return $alerts;
             break;
             /*case "note_list":
             				if($owner_id && $owner_id != 'new'){
             
             					$note_items = $this->get_notes(array("owner_table"=>$owner_table,"owner_id"=>$owner_id));
             					foreach($note_items as &$note_item){
             						// do it in loop here because of $this issues in static method below.
             						// instead of include file below.
             						$note_item['html'] = $this->print_note($note_item['note_id']);
             					}
             					include("pages/note_list.php");
             				}else{
             					echo 'Please save first before creating notes.';
             				}
             				break;*/
         /*case "note_list":
         				if($owner_id && $owner_id != 'new'){
         
         					$note_items = $this->get_notes(array("owner_table"=>$owner_table,"owner_id"=>$owner_id));
         					foreach($note_items as &$note_item){
         						// do it in loop here because of $this issues in static method below.
         						// instead of include file below.
         						$note_item['html'] = $this->print_note($note_item['note_id']);
         					}
         					include("pages/note_list.php");
         				}else{
         					echo 'Please save first before creating notes.';
         				}
         				break;*/
         case "note_delete":
             // find the key we are saving this address against.
             $owner_id = (int) $key_value;
             if (!$owner_id || $owner_id == 'new') {
                 // find one in the post data.
                 if (isset($_REQUEST[$key_name])) {
                     $owner_id = $_REQUEST[$key_name];
                 }
             }
             $note_hash = md5($owner_id . '|' . $owner_table);
             // just for posting unique arrays.
             if ($owner_table && $owner_id) {
                 $this->note_delete($owner_table, $owner_id);
             }
             break;
     }
 }
コード例 #2
0
            }
        });
    }
}
if (class_exists('module_group', false)) {
    $columns['group'] = array('title' => 'Group', 'callback' => function ($quote) {
        $groups = module_group::get_groups_search(array('owner_table' => 'quote', 'owner_id' => $quote['quote_id']));
        $g = array();
        foreach ($groups as $group) {
            $g[] = $group['name'];
        }
        echo implode(', ', $g);
    });
}
$table_manager->set_columns($columns);
$table_manager->row_callback = function ($row_data) {
    // load the full vendor data before displaying each row so we have access to more details
    return module_quote::get_quote($row_data['quote_id']);
};
$table_manager->set_rows($quotes);
if (class_exists('module_extra', false)) {
    $table_manager->display_extra('quote', function ($quote) {
        module_extra::print_table_data('quote', $quote['quote_id']);
    });
}
$table_manager->pagination = true;
$table_manager->print_table();
?>


</form>
コード例 #3
0
 * Copyright: dtbaker 2012
 * Licence: Please check CodeCanyon.net for licence details. 
 * More licence clarification available here:  http://codecanyon.net/wiki/support/legal-terms/licensing-terms/ 
 * Deploy: 9809 f200f46c2a19bb98d112f2d32a8de0c4
 * Envato: 4ffca17e-861e-4921-86c3-8931978c40ca
 * Package Date: 2015-11-25 02:55:20 
 * IP Address: 67.79.165.254
 */
if (!$quote_safe) {
    die('failed');
}
if (!module_quote::can_i('edit', 'Quotes')) {
    die('no perms');
}
$quote_id = (int) $_REQUEST['quote_id'];
$quote = module_quote::get_quote($quote_id);
// template for sending emails.
// are we sending the paid one? or the dueone.
//$template_name = 'quote_email';
$template_name = isset($_REQUEST['template_name']) ? $_REQUEST['template_name'] : 'quote_email';
$template = module_template::get_template_by_key($template_name);
$quote['total_amount_print'] = dollar($quote['total_amount'], true, $quote['currency_id']);
$quote['total_amount_due_print'] = dollar($quote['total_amount_due'], true, $quote['currency_id']);
$quote['quote_name'] = $quote['name'];
$quote['from_name'] = module_security::get_loggedin_name();
$quote['quote_url'] = module_quote::link_public($quote_id);
ob_start();
include module_theme::include_ucm('includes/plugin_quote/template/quote_task_list.php');
$public_html = ob_get_clean();
$quote['task_list'] = $public_html;
/*ob_start();
コード例 #4
0
								    <th>
									    <?php 
                    _e('Amount');
                    ?>

								    </th>
							    <?php 
                }
                ?>

						    </tr>
						    </thead>
						    <tbody>
						    <?php 
                foreach ($quotes as $quote) {
                    $quote = module_quote::get_quote($quote['quote_id']);
                    ?>

							    <tr class="<?php 
                    echo $c++ % 2 ? "odd" : "even";
                    ?>
">
								    <td class="row_action">
									    <?php 
                    echo module_quote::link_open($quote['quote_id'], true);
                    ?>

								    </td>
								    <td>
									    <?php 
                    echo print_date($quote['date_create']);
コード例 #5
0
ファイル: job.php プロジェクト: sgh1986915/php-crm
 public static function get_job($job_id, $full = true, $skip_permissions = false)
 {
     $job_id = (int) $job_id;
     if ($job_id <= 0) {
         $job = array();
     } else {
         $cache_key = self::_job_cache_key($job_id, array($job_id, $full, $skip_permissions));
         if ($cached_item = module_cache::get('job', $cache_key)) {
             return $cached_item;
         }
         $cache_key_full = self::_job_cache_key($job_id, array($job_id, true, $skip_permissions));
         if ($cache_key_full != $cache_key && ($cached_item = module_cache::get('job', $cache_key_full))) {
             return $cached_item;
         }
         $cache_timeout = module_config::c('cache_objects', 60);
         $job = get_single("job", "job_id", $job_id);
     }
     // check permissions
     if ($job && isset($job['job_id']) && $job['job_id'] == $job_id) {
         switch (self::get_job_access_permissions()) {
             case _JOB_ACCESS_ALL:
                 break;
             case _JOB_ACCESS_ASSIGNED:
                 // only assigned jobs!
                 $has_job_access = false;
                 if ($job['user_id'] == module_security::get_loggedin_id()) {
                     $has_job_access = true;
                     break;
                 }
                 $tasks = module_job::get_tasks($job['job_id']);
                 foreach ($tasks as $task) {
                     if ($task['user_id'] == module_security::get_loggedin_id()) {
                         $has_job_access = true;
                         break;
                     }
                 }
                 unset($tasks);
                 if (!$has_job_access) {
                     if ($skip_permissions) {
                         $job['_no_access'] = true;
                         // set a flag for custom processing. we check for this when calling get_customer with the skip permissions argument. (eg: in the ticket file listing link)
                     } else {
                         $job = false;
                     }
                 }
                 break;
             case _JOB_ACCESS_CUSTOMER:
                 // tie in with customer permissions to only get jobs from customers we can access.
                 $customers = module_customer::get_customers();
                 $has_job_access = false;
                 if (isset($customers[$job['customer_id']])) {
                     $has_job_access = true;
                 }
                 /*foreach($customers as $customer){
                       // todo, if($job['customer_id'] == 0) // ignore this permission
                       if($customer['customer_id']==$job['customer_id']){
                           $has_job_access = true;
                           break;
                       }
                   }*/
                 unset($customers);
                 if (!$has_job_access) {
                     if ($skip_permissions) {
                         $job['_no_access'] = true;
                         // set a flag for custom processing. we check for this when calling get_customer with the skip permissions argument. (eg: in the ticket file listing link)
                     } else {
                         $job = false;
                     }
                 }
                 break;
         }
         if ($job) {
             $job['taxes'] = get_multiple('job_tax', array('job_id' => $job_id), 'job_tax_id', 'exact', 'order');
         }
     }
     if (!$full) {
         // unserialize our cached staff_total_grouped key (and other cache keys?)
         // this is used in finance.php line 1053
         $job['staff_total_grouped'] = array();
         if (isset($job['c_staff_total_grouped']) && strlen($job['c_staff_total_grouped'])) {
             $job['staff_total_grouped'] = @unserialize($job['c_staff_total_grouped']);
         }
         if (isset($cache_key)) {
             module_cache::put('job', $cache_key, $job, $cache_timeout);
         }
         return $job;
     }
     if (!$job) {
         $customer_id = 0;
         if (isset($_REQUEST['customer_id']) && $_REQUEST['customer_id']) {
             //
             $customer_id = (int) $_REQUEST['customer_id'];
             // find default website id to use.
             if (isset($_REQUEST['website_id'])) {
                 $website_id = (int) $_REQUEST['website_id'];
             } else {
             }
         }
         $default_job_name = module_config::c('job_default_new_name', '');
         if (module_config::c('job_name_incrementing', 0)) {
             $job_number = module_config::c('job_name_incrementing_next', 1);
             // see if there is an job number matching this one.
             $this_job_number = $job_number;
             do {
                 $jobs = get_multiple('job', array('name' => $this_job_number));
                 //'customer_id'=>$customer_id,
                 if (!count($jobs)) {
                     $job_number = $this_job_number;
                 } else {
                     $this_job_number++;
                 }
             } while (count($jobs));
             module_config::save_config('job_name_incrementing_next', $job_number);
             $default_job_name = $job_number . $default_job_name;
         }
         $job = array('job_id' => 'new', 'customer_id' => $customer_id, 'website_id' => isset($_REQUEST['website_id']) ? $_REQUEST['website_id'] : 0, 'hourly_rate' => module_config::c('hourly_rate', 60), 'name' => $default_job_name, 'date_quote' => date('Y-m-d'), 'date_start' => module_config::c('job_allow_quotes', 0) ? '' : date('Y-m-d'), 'date_due' => '', 'date_completed' => '', 'date_renew' => '', 'user_id' => module_security::get_loggedin_id(), 'renew_job_id' => '', 'status' => module_config::s('job_status_default', 'New'), 'type' => module_config::s('job_type_default', 'Website Design'), 'currency_id' => module_config::c('default_currency_id', 1), 'auto_task_numbers' => '0', 'default_task_type' => module_config::c('default_task_type', _TASK_TYPE_HOURS_AMOUNT), 'description' => '', 'quote_id' => 0, 'discount_description' => _l('Discount:'), 'discount_amount' => 0, 'discount_type' => module_config::c('invoice_discount_type', _DISCOUNT_TYPE_BEFORE_TAX));
         if (isset($_REQUEST['from_quote_id']) && (int) $_REQUEST['from_quote_id']) {
             $quote = module_quote::get_quote($_REQUEST['from_quote_id']);
             $job = array_merge($job, $quote);
             $job['date_quote'] = $quote['date_create'];
             $job['date_start'] = date('Y-m-d');
             $job['quote_id'] = (int) $_REQUEST['from_quote_id'];
         }
         // some defaults from the db.
         $job['total_tax_rate'] = module_config::c('tax_percent', 10);
         $job['total_tax_name'] = module_config::c('tax_name', 'TAX');
         if ($customer_id > 0) {
             $customer_data = module_customer::get_customer($customer_id, false, true);
             if ($customer_data && isset($customer_data['default_tax']) && $customer_data['default_tax'] >= 0) {
                 $job['total_tax_rate'] = $customer_data['default_tax'];
                 $job['total_tax_name'] = $customer_data['default_tax_name'];
             }
         }
     }
     // new support for multiple taxes
     if (!isset($job['taxes']) || !count($job['taxes']) && $job['total_tax_rate'] > 0) {
         $job['taxes'] = array();
         $tax_rates = explode(',', $job['total_tax_rate']);
         $tax_names = explode(',', $job['total_tax_name']);
         foreach ($tax_rates as $tax_rate_id => $tax_rate_amount) {
             if ($tax_rate_amount > 0) {
                 $job['taxes'][] = array('order' => 0, 'percent' => $tax_rate_amount, 'name' => isset($tax_names[$tax_rate_id]) ? $tax_names[$tax_rate_id] : $job['total_tax_name'], 'total' => 0, 'amount' => 0, 'discount' => 0, 'increment' => module_config::c('tax_multiple_increment', 0));
             }
         }
     }
     if ($job) {
         // work out total hours etc..
         $job['total_hours'] = 0;
         $job['total_hours_completed'] = 0;
         $job['total_hours_overworked'] = 0;
         $job['total_sub_amount'] = 0;
         $job['total_sub_amount_taxable'] = 0;
         $job['total_sub_amount_unbillable'] = 0;
         $job['total_sub_amount_invoicable'] = 0;
         $job['total_sub_amount_invoicable_taxable'] = 0;
         $job['total_amount_invoicable'] = 0;
         $job['total_tasks_remain'] = 0;
         $job['total_amount'] = 0;
         $job['total_amount_paid'] = 0;
         $job['total_amount_invoiced'] = 0;
         $job['total_amount_invoiced_deposit'] = 0;
         $job['total_amount_todo'] = 0;
         $job['total_amount_outstanding'] = 0;
         $job['total_amount_due'] = 0;
         $job['total_hours_remain'] = 0;
         $job['total_percent_complete'] = isset($job['total_percent_complete']) ? $job['total_percent_complete'] : 0;
         $job['total_tax'] = 0;
         $job['total_tax_invoicable'] = 0;
         $job['invoice_discount_amount'] = 0;
         $job['invoice_discount_amount_on_tax'] = 0;
         $job['total_amount_discounted'] = 0;
         // new feature to invoice incompleted tasks
         $job['uninvoiced_task_ids'] = array();
         // new staff expenses/totals
         $job['staff_hourly_rate'] = $job['hourly_rate'];
         $job['staff_total_hours'] = 0;
         $job['staff_total_hours_completed'] = 0;
         $job['staff_total_hours_overworked'] = 0;
         $job['staff_total_sub_amount'] = 0;
         $job['staff_total_sub_amount_unbillable'] = 0;
         $job['staff_total_amount'] = 0;
         $job['staff_total_grouped'] = array();
         // total staff expenses grouped by individual staff members.
         $job['total_net_amount'] = 0;
         // after the staff expense is taken away.
         if ($job_id > 0) {
             $non_hourly_job_count = $non_hourly_job_completed = 0;
             $tasks = self::get_tasks($job['job_id']);
             $job_percentage_complete_averages = array();
             foreach ($tasks as $task_id => $task) {
                 // new support for different task types
                 if (!isset($task['manual_task_type']) || $task['manual_task_type'] < 0) {
                     $task['manual_task_type'] = $job['default_task_type'];
                 }
                 if (module_config::c('job_task_log_all_hours', 1)) {
                     // jobs have to be marked fully_completd.
                     if (!$task['fully_completed']) {
                         $job['total_tasks_remain']++;
                     }
                 } else {
                     if ($task['amount'] != 0 && $task['completed'] <= 0) {
                         $job['total_tasks_remain']++;
                     } else {
                         if ($task['hours'] > 0 && $task['completed'] < $task['hours']) {
                             $job['total_tasks_remain']++;
                         }
                     }
                 }
                 $tasks[$task_id]['sum_amount'] = 0;
                 if ($task['amount'] != 0) {
                     // we have a custom amount for this task.
                     // do we multiply it by qty (stored in hours?)
                     if ($task['manual_task_type'] == _TASK_TYPE_QTY_AMOUNT) {
                         $tasks[$task_id]['sum_amount'] = $task['amount'] * $task['hours'];
                     } else {
                         $tasks[$task_id]['sum_amount'] = $task['amount'];
                     }
                 }
                 if ($task['manual_task_type'] == _TASK_TYPE_QTY_AMOUNT && $task['hours'] > 0 && $task['amount'] == 0) {
                     $tasks[$task_id]['sum_amount'] = $task['hours'] * $job['hourly_rate'];
                 }
                 if ($task['manual_task_type'] == _TASK_TYPE_HOURS_AMOUNT && $task['hours'] > 0) {
                     $job['total_hours'] += $task['hours'];
                     $task_completed_hours = min($task['hours'], $task['completed']);
                     if ($task['fully_completed']) {
                         // hack to record that we have worked 100% of this task.
                         $task_completed_hours = $task['hours'];
                     }
                     $job['total_hours_completed'] += $task_completed_hours;
                     if ($task['completed'] > $task['hours']) {
                         $job['total_hours_overworked'] += $task['completed'] - $task['hours'];
                     } else {
                         if ($task['completed'] > 0) {
                             // underworked hours
                             $job['total_hours_overworked'] += $task['completed'] - $task['hours'];
                         }
                     }
                     if ($task['amount'] <= 0) {
                         $tasks[$task_id]['sum_amount'] = $task['hours'] * $job['hourly_rate'];
                     }
                 } else {
                     // it's a non-hourly task.
                     // work out if it's completed or not.
                     $non_hourly_job_count++;
                     if ($task['fully_completed']) {
                         $non_hourly_job_completed++;
                     }
                 }
                 if (!$task['invoiced'] && $task['billable']) {
                     $job['uninvoiced_task_ids'][] = $task_id;
                 }
                 if (!$task['invoiced'] && $task['billable'] && (module_config::c('job_task_log_all_hours', 1) || $task['hours'] > 0 && $task['completed'] > 0 && $task['completed'] >= $task['hours'] || $task['hours'] <= 0 && $task['fully_completed'])) {
                     /*if(module_config::c('job_task_log_all_hours',1)){*/
                     // a task has to be marked "fully_completeD" before it will be invoiced.
                     if ($task['fully_completed']) {
                         $job['total_sub_amount_invoicable'] += $tasks[$task_id]['sum_amount'];
                         if ($task['taxable']) {
                             if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                                 foreach ($job['taxes'] as $job_tax_id => $job_tax) {
                                     $job['total_tax_invoicable'] += round($tasks[$task_id]['sum_amount'] * ($job_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                                 }
                             } else {
                                 $job['total_sub_amount_invoicable_taxable'] += $tasks[$task_id]['sum_amount'];
                             }
                         }
                     }
                     /*}else{
                           $job['total_sub_amount_invoicable'] += $tasks[$task_id]['sum_amount'];
                           if($task['taxable']){
                               if(module_config::c('tax_calculate_mode',_TAX_CALCULATE_AT_END)==_TAX_CALCULATE_INCREMENTAL){
                                   $job['total_tax_invoicable'] += round(($tasks[$task_id]['sum_amount'] * ($job['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
                               }else{
                                   $job['total_sub_amount_invoicable_taxable'] += $tasks[$task_id]['sum_amount'];
                               }
                           }
                           //(min($task['hours'],$task['completed']) * $job['hourly_rate']);
                       }*/
                 }
                 if ($task['taxable'] && $task['billable']) {
                     $job['total_sub_amount_taxable'] += $tasks[$task_id]['sum_amount'];
                     if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                         //$job['total_tax'] += round(($tasks[$task_id]['sum_amount'] * ($job['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
                         // todo - incremental multi-tax calculation
                         foreach ($job['taxes'] as $job_tax_id => $job_tax) {
                             if (!isset($job['taxes'][$job_tax_id]['total'])) {
                                 $job['taxes'][$job_tax_id]['total'] = 0;
                             }
                             $job['taxes'][$job_tax_id]['total'] += $tasks[$task_id]['sum_amount'];
                             $job['taxes'][$job_tax_id]['amount'] += round($tasks[$task_id]['sum_amount'] * ($job_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                         }
                     }
                 }
                 if ($task['billable']) {
                     $job['total_sub_amount'] += $tasks[$task_id]['sum_amount'];
                 } else {
                     $job['total_sub_amount_unbillable'] += $tasks[$task_id]['sum_amount'];
                 }
                 $job_percentage_complete_averages[] = self::get_percentage($tasks[$task_id]);
                 // new staff expenses calculations
                 if (self::job_task_has_split_hours($job_id, $job, $task_id, $task)) {
                     $tasks[$task_id]['staff_sum_amount'] = 0;
                     switch ($task['manual_task_type']) {
                         case _TASK_TYPE_QTY_AMOUNT:
                             $tasks[$task_id]['staff_sum_amount'] = $task['staff_amount'] * $task['staff_hours'];
                             break;
                         case _TASK_TYPE_AMOUNT_ONLY:
                             $tasks[$task_id]['staff_sum_amount'] = $task['staff_amount'];
                             break;
                         case _TASK_TYPE_HOURS_AMOUNT:
                             $tasks[$task_id]['staff_sum_amount'] = $task['staff_amount'] == 0 ? $task['staff_hours'] * $job['staff_hourly_rate'] : $task['staff_amount'] * $task['staff_hours'];
                             break;
                     }
                     if ($task['billable']) {
                         $job['staff_total_sub_amount'] += $tasks[$task_id]['staff_sum_amount'];
                         if (!isset($job['staff_total_grouped'][$task['user_id']])) {
                             $job['staff_total_grouped'][$task['user_id']] = 0;
                         }
                         $job['staff_total_grouped'][$task['user_id']] += $tasks[$task_id]['staff_sum_amount'];
                     } else {
                         $job['staff_total_sub_amount_unbillable'] += $tasks[$task_id]['staff_sum_amount'];
                     }
                 }
             }
             // end task loop
             $job['total_hours_remain'] = $job['total_hours'] - $job['total_hours_completed'];
             // add any discounts.
             if ($job['discount_amount'] != 0) {
                 if ($job['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
                     // after tax discount ::::::::::
                     // handled below.
                     //$job['final_modification'] = -$job['discount_amount'];
                 } else {
                     if ($job['discount_type'] == _DISCOUNT_TYPE_BEFORE_TAX) {
                         // before tax discount:::::
                         //$job['final_modification'] = -$job['discount_amount'];
                         // problem : this 'discount_amount_on_tax' calculation may not match the correct final discount calculation as per below
                         if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                             // tax calculated along the way.
                             // we have discounted the 'total amount taxable' so that means we need to reduce the tax amount by that much as well.
                             foreach ($job['taxes'] as $job_tax_id => $job_tax) {
                                 $this_tax_discount = round($job['discount_amount'] * ($job['taxes'][$job_tax_id]['percent'] / 100), module_config::c('currency_decimal_places', 2));
                                 $job['discount_amount_on_tax'] += $this_tax_discount;
                                 if (!isset($job['taxes'][$job_tax_id]['total'])) {
                                     $job['taxes'][$job_tax_id]['total'] = 0;
                                 }
                                 $job['taxes'][$job_tax_id]['total'] -= $job['discount_amount'];
                                 $job['taxes'][$job_tax_id]['amount'] -= $this_tax_discount;
                                 $job['taxes'][$job_tax_id]['discount'] = $this_tax_discount;
                             }
                         } else {
                             // we work out what the tax would have been if there was no applied discount
                             // this is used in job.php
                             $job['taxes_backup'] = $job['taxes'];
                             $job['total_sub_amount_taxable_backup'] = $job['total_sub_amount_taxable'];
                             $total_tax_before_discount = 0;
                             foreach ($job['taxes'] as $job_tax_id => $job_tax) {
                                 $job['taxes'][$job_tax_id]['total'] = $job['total_sub_amount_taxable'];
                                 $job['taxes'][$job_tax_id]['amount'] = round($job['total_sub_amount_taxable'] * ($job_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                                 // here we adjust the 'total_sub_amount_taxable' to include the value from the previous calculation.
                                 // this is for multiple taxes that addup as they go (eg: Canada)
                                 if (isset($job_tax['increment']) && $job_tax['increment']) {
                                     $job['total_sub_amount_taxable'] += $job['taxes'][$job_tax_id]['amount'];
                                 }
                                 $total_tax_before_discount += $job['taxes'][$job_tax_id]['amount'];
                             }
                             $job['taxes'] = $job['taxes_backup'];
                             $job['total_sub_amount_taxable'] = $job['total_sub_amount_taxable_backup'];
                         }
                         // remove the discount amount from the 'sub total' and the 'taxable total' but don't go negative on it.
                         // remove the discount from any non-taxable portion first.
                         $non_taxable_amount = $job['total_sub_amount'] - $job['total_sub_amount_taxable'];
                         $non_taxable_discount = min($job['discount_amount'], $non_taxable_amount);
                         $taxable_discount = $job['discount_amount'] - $non_taxable_discount;
                         //echo "non tax $non_taxable_amount \n nontax discount: $non_taxable_discount \n tax discount: $taxable_discount \n";print_r($job);exit;
                         $job['total_sub_amount'] -= $job['discount_amount'];
                         $job['total_sub_amount_taxable'] -= $taxable_discount;
                     }
                 }
             }
             if (count($job_percentage_complete_averages) > 0) {
                 if (!isset($job['total_percent_complete_manual']) || !$job['total_percent_complete_manual']) {
                     $job['total_percent_complete'] = round(array_sum($job_percentage_complete_averages) / count($job_percentage_complete_averages), 2);
                 } else {
                     $job['total_percent_complete_calculated'] = round(array_sum($job_percentage_complete_averages) / count($job_percentage_complete_averages), 2);
                 }
             }
             /*if($job['total_hours'] > 0){
                   // total hours completed. work out job task based on hours completed.
                   $job['total_percent_complete'] = round($job['total_hours_completed'] / $job['total_hours'],2);
               }else if($non_hourly_job_count>0){
                   // work out job completed rate based on $non_hourly_job_completed and $non_hourly_job_count
                   $job['total_percent_complete'] = round($non_hourly_job_completed/$non_hourly_job_count,2);
               }*/
             // find any invoices
             $invoices = module_invoice::get_invoices(array('job_id' => $job_id));
             foreach ($invoices as $invoice) {
                 $invoice = module_invoice::get_invoice($invoice['invoice_id']);
                 if (!$invoice) {
                     continue;
                 }
                 //print_r($invoice);
                 // we only ad up the invoiced tasks that are from this job
                 // an invoice could have added manually more items to it, so this would throw the price out.
                 $this_invoice = 0;
                 $this_invoice_taxable = 0;
                 $invoice_items = module_invoice::get_invoice_items($invoice['invoice_id']);
                 // first loop will find out of this is a merged invoice or not.
                 $merged_invoice = false;
                 foreach ($invoice_items as $invoice_item) {
                     if ($invoice_item['task_id'] && !isset($tasks[$invoice_item['task_id']])) {
                         $merged_invoice = true;
                     }
                 }
                 // if it's a merged invoice we don't add non-task-id items to the total.
                 // if its a normal non-merged invoice then we can add the non-task linked items to the total.
                 if (!$merged_invoice) {
                     $this_invoice = $invoice['total_amount'];
                 } else {
                     foreach ($invoice_items as $invoice_item) {
                         if ($invoice_item['task_id'] && isset($tasks[$invoice_item['task_id']]) && $tasks[$invoice_item['task_id']]['billable']) {
                             $this_invoice += $tasks[$invoice_item['task_id']]['sum_amount'];
                             if ($invoice_item['taxable']) {
                                 $this_invoice_taxable += $tasks[$invoice_item['task_id']]['sum_amount'];
                                 if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                                     foreach ($invoice_item['taxes'] as $invoice_item_tax) {
                                         $this_invoice += round($tasks[$invoice_item['task_id']]['sum_amount'] * ($invoice_item_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                                     }
                                 }
                             }
                         }
                     }
                 }
                 // any discounts ?
                 $job['invoice_discount_amount'] += $invoice['discount_amount'];
                 $job['invoice_discount_amount_on_tax'] += $invoice['discount_amount_on_tax'];
                 // todo - move all this tax calculation back to
                 if ($merged_invoice && module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_AT_END && $this_invoice_taxable > 0) {
                     $this_invoice_tax = 0;
                     foreach ($invoice['taxes'] as $invoice_tax) {
                         // todo - incremental or what not in here.
                         $this_invoice_tax = $this_invoice_tax + $this_invoice_taxable * ($invoice_tax['percent'] / 100);
                     }
                     $this_invoice += $this_invoice_tax;
                     //$this_invoice = ($this_invoice + ($this_invoice_taxable * ($invoice['total_tax_rate'] / 100)));
                 }
                 //print_r($invoice);
                 if ($invoice['deposit_job_id'] == $job_id) {
                     $job['total_amount_invoiced_deposit'] += $this_invoice;
                 } else {
                 }
                 $job['total_amount_invoiced'] += $this_invoice;
                 $job['total_amount_paid'] += min($invoice['total_amount_paid'], $this_invoice);
                 $job['total_amount_outstanding'] += min($invoice['total_amount_due'], $this_invoice);
             }
             // todo: save these two values in the database so that future changes do not affect them.
             if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_AT_END) {
                 $job['total_tax'] = 0;
                 $job['total_tax_invoicable'] = 0;
                 $previous_tax_id = false;
                 foreach ($job['taxes'] as $job_tax_id => $job_tax) {
                     if (!isset($job['taxes'][$job_tax_id]['total'])) {
                         $job['taxes'][$job_tax_id]['total'] = 0;
                     }
                     if (!isset($job['taxes'][$job_tax_id]['total_invoicable'])) {
                         $job['taxes'][$job_tax_id]['total_invoicable'] = 0;
                     }
                     if (!isset($job['taxes'][$job_tax_id]['amount_invoicable'])) {
                         $job['taxes'][$job_tax_id]['amount_invoicable'] = 0;
                     }
                     $job['taxes'][$job_tax_id]['total'] += $job['total_sub_amount_taxable'];
                     $job['taxes'][$job_tax_id]['total_invoicable'] += $job['total_sub_amount_invoicable_taxable'];
                     if (isset($job_tax['increment']) && $job_tax['increment'] && $previous_tax_id) {
                         $job['taxes'][$job_tax_id]['total'] += $job['taxes'][$previous_tax_id]['amount'];
                         $job['taxes'][$job_tax_id]['total_invoicable'] += $job['taxes'][$previous_tax_id]['amount_invoicable'];
                     }
                     $t = round($job['taxes'][$job_tax_id]['total'] * ($job_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                     $job['taxes'][$job_tax_id]['amount'] += $t;
                     $job['total_tax'] += $t;
                     $t = round($job['taxes'][$job_tax_id]['total_invoicable'] * ($job_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                     $job['taxes'][$job_tax_id]['amount_invoicable'] += $t;
                     $job['total_tax_invoicable'] += $t;
                     $previous_tax_id = $job_tax_id;
                 }
                 //$job['total_tax'] = ( ($job['total_sub_amount_taxable']) * ($job['total_tax_rate'] / 100));
                 //$job['total_tax_invoicable'] =$job['total_sub_amount_invoicable_taxable'] > 0 ? ($job['total_sub_amount_invoicable_taxable'] * ($job['total_tax_rate'] / 100)) : 0;
             }
             $job['total_amount'] = round($job['total_sub_amount'] + $job['total_tax'], module_config::c('currency_decimal_places', 2));
             if ($job['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
                 $job['total_amount'] -= $job['discount_amount'];
                 $job['total_sub_amount_invoicable'] -= $job['discount_amount'];
             }
             $job['total_amount_invoicable'] = $job['total_sub_amount_invoicable'] + $job['total_tax_invoicable'];
             // + ($job['total_sub_amount_invoicable'] * ($job['total_tax_rate'] / 100));
             $job['total_amount_due'] = $job['total_amount'] - $job['total_amount_paid'];
             //todo: chekc if this is wrong with non-invoicable tasks.
             //$job['total_amount_outstanding'] = $job['total_amount_invoiced'] - $job['total_amount_paid'];
             $job['total_amount_discounted'] = $job['total_amount'] - $job['invoice_discount_amount'] - $job['invoice_discount_amount_on_tax'];
             //$job['total_amount_invoicable'] = $job['total_amount_invoicable'] - $job['invoice_discounts']-$job['invoice_discounts_tax'];
             $job['total_amount_todo'] = $job['total_amount_discounted'] - $job['total_amount_invoiced'] - $job['total_amount_invoicable'];
             //$job['total_amount_paid'] -
             // staff calculations
             if ($job['staff_total_sub_amount'] > 0) {
                 // tax for staff??
                 $job['staff_total_amount'] = $job['staff_total_sub_amount'];
             }
             $job['total_net_amount'] = $job['total_amount'] - $job['staff_total_amount'];
         }
     }
     if (isset($cache_key)) {
         module_cache::put('job', $cache_key, $job, $cache_timeout);
     }
     self::save_job_cache($job_id, $job);
     return $job;
 }
コード例 #6
0
ファイル: quote.php プロジェクト: sgh1986915/php-crm
 public static function quote_approved($quote_id)
 {
     module_cache::clear('quote');
     $quote_data = module_quote::get_quote($quote_id);
     hook_handle_callback('quote_approved', $quote_id);
     self::add_history($quote_id, 'Quote approved by ' . $quote_data['approved_by']);
     if (module_config::c('quote_approval_auto_email', 1) && $quote_data['user_id']) {
         // send an email to the assigned staff member letting them know the quote was approved.
         $template = module_template::get_template_by_key('quote_approved_email');
         $replace = module_quote::get_replace_fields($quote_id, $quote_data);
         if (defined('_BLOCK_EMAILS') && _BLOCK_EMAILS) {
             $pdf = false;
         } else {
             $pdf = module_quote::generate_pdf($quote_id);
         }
         $template->assign_values($replace);
         $html = $template->render('html');
         // send an email to this user.
         $email = module_email::new_email();
         $email->replace_values = $replace;
         $email->set_to('user', $quote_data['user_id']);
         $email->set_bcc_manual(module_config::c('admin_email_address', ''), '');
         //$email->set_from('user',); // nfi
         $email->set_subject($template->description);
         // do we send images inline?
         $email->set_html($html);
         if ($pdf) {
             $email->add_attachment($pdf);
         }
         $email->quote_id = $quote_id;
         $email->customer_id = $quote_data['customer_id'];
         $email->prevent_duplicates = true;
         if ($email->send()) {
             // it worked successfully!!
             // record a log on the quote when it's done.
             self::add_history($quote_id, _l('Quote approval emailed to staff member'));
         } else {
             /// log err?
         }
     }
     module_cache::clear('quote');
 }
コード例 #7
0
    $fieldset_data['elements'][] = array('title' => 'Job', 'fields' => array(array('type' => 'select', 'name' => 'job_id', 'value' => $file['job_id'], 'options' => $c), function () use(&$file) {
        if ($file['job_id']) {
            echo ' ';
            echo '<a href="' . module_job::link_open($file['job_id'], false) . '">' . _l('Open Job &raquo;') . '</a>';
        }
    }));
}
if (class_exists('module_quote', false) && module_quote::is_plugin_enabled()) {
    $c = array();
    $res = module_quote::get_quotes(array('customer_id' => $file['customer_id']));
    foreach ($res as $row) {
        $c[$row['quote_id']] = $row['name'];
    }
    if ($file['quote_id'] && !isset($c[$file['quote_id']])) {
        // this file is related to another quote. from another customer.
        $related_quote = module_quote::get_quote($file['quote_id'], false, true);
        if ($related_quote && $related_quote['quote_id'] == $file['quote_id']) {
            $related_customer = module_customer::get_customer($related_quote['customer_id'], true);
            if ($related_customer && $related_customer['customer_id'] == $related_quote['customer_id']) {
                $c[$file['quote_id']] = _l('%s (from %s)', $related_quote['name'], $related_customer['customer_name']);
            } else {
                $file['quote_id'] = false;
            }
        } else {
            $file['quote_id'] = false;
        }
    }
    $fieldset_data['elements'][] = array('title' => 'Quote', 'fields' => array(array('type' => 'select', 'name' => 'quote_id', 'value' => $file['quote_id'], 'options' => $c), function () use(&$file) {
        if ($file['quote_id']) {
            echo ' ';
            echo '<a href="' . module_quote::link_open($file['quote_id'], false) . '">' . _l('Open Quote &raquo;') . '</a>';
コード例 #8
0
ファイル: ticket.php プロジェクト: sgh1986915/php-crm
 public static function hook_filter_generate_fieldset_options($callback_name, $fieldset_options)
 {
     if (is_array($fieldset_options) && isset($fieldset_options['id']) && $fieldset_options['id'] == 'quote_advanced') {
         $ticket_quote_rel_data = array();
         $customer_id = 0;
         // which customer to bring related quotes in from.
         if (isset($_REQUEST['ticket_id']) && (int) $_REQUEST['ticket_id'] > 0) {
             $ticket_data = module_ticket::get_ticket($_REQUEST['ticket_id'], false);
             if ($ticket_data && $ticket_data['ticket_id'] == $_REQUEST['ticket_id']) {
                 // we're creating a new quote linked to this particular ticket
                 $ticket_quote_rel_data[] = $ticket_data['ticket_id'];
                 $customer_id = $ticket_data['customer_id'];
             }
         }
         if (isset($_REQUEST['quote_id']) && (int) $_REQUEST['quote_id'] > 0) {
             // we're opening an existing quote, find any matching linked tickets.
             $quote_data = module_quote::get_quote($_REQUEST['quote_id']);
             if ($quote_data && $quote_data['quote_id'] == $_REQUEST['quote_id']) {
                 if ($quote_data['customer_id']) {
                     $customer_id = $quote_data['customer_id'];
                 }
                 // any existing ones from within the database?
                 $existing = get_multiple('ticket_quote_rel', array('quote_id' => $quote_data['quote_id']));
                 foreach ($existing as $e) {
                     if ($e['ticket_id']) {
                         $ticket_quote_rel_data[] = $e['ticket_id'];
                     }
                 }
             }
         }
         $select_values = array();
         if ($customer_id > 0) {
             $tickets = module_ticket::get_tickets(array('customer_id' => $customer_id));
             while ($row = mysql_fetch_assoc($tickets)) {
                 $select_values[$row['ticket_id']] = module_ticket::ticket_number($row['ticket_id']) . ' ' . substr($row['subject'], 0, 20) . '...';
             }
         }
         if (!count($ticket_quote_rel_data)) {
             $ticket_quote_rel_data = array(false);
         }
         $ticket_links = array();
         foreach ($ticket_quote_rel_data as $ticket_id) {
             if ($ticket_id > 0) {
                 $ticket_links[] = module_ticket::link_open($ticket_id, true);
             }
         }
         $fieldset_options['elements']['ticket_rel_ids'] = array('title' => 'Linked Tickets', 'fields' => array('<div id="ticket_rel_ids_holder">', array('type' => 'select', 'name' => 'ticket_rel_ids[]', 'options' => $select_values, 'multiple' => 'ticket_rel_ids_holder', 'values' => $ticket_quote_rel_data), '</div>', '<div>' . implode(' ', $ticket_links) . '</div>'));
     }
     return $fieldset_options;
 }