Esempio n. 1
0
    public function pre_menu()
    {
        if ($this->can_i('view', 'Members')) {
            // how many members are there?
            $link_name = _l('Members');
            if (module_config::c('member_show_summary', 1)) {
                $member_count = module_cache::get('member', 'member_menu_count');
                if ($member_count === false) {
                    $sql = "SELECT COUNT(member_id) AS c FROM `" . _DB_PREFIX . "member` m";
                    $res = qa1($sql);
                    $member_count = $res['c'];
                    module_cache::put('member', 'member_menu_count', $member_count);
                }
                if ($member_count > 0) {
                    $link_name .= " <span class='menu_label'>" . $member_count . "</span> ";
                }
            }
            $this->links['members'] = array("name" => $link_name, "p" => "member_admin", "args" => array('member_id' => false));
            if (class_exists('module_newsletter', false) && module_config::c('member_menu_under_newsletter', 1)) {
                $this->links['members']['holder_module'] = 'newsletter';
                $this->links['members']['holder_module_page'] = 'newsletter_admin';
                $this->links['members']['menu_include_parent'] = 0;
                $this->links['members']['allow_nesting'] = 1;
            }
        }
        if (class_exists('module_template', false)) {
            module_template::init_template('member_subscription_form', '<h2>Subscribe</h2>
<form action="" method="post">
    <p>Please Enter Your Email Address: <input type="text" name="member[email]" value="{EMAIL}"> </p>
    <p>Please Enter Your First Name: <input type="text" name="member[first_name]" value="{FIRST_NAME}"> </p>
    <p>Please Enter Your Last Name: <input type="text" name="member[last_name]" value="{LAST_NAME}"> </p>
    <p>Please Enter Your Business Name: <input type="text" name="member[business]" value="{BUSINESS}"> </p>
    <p>Please Enter Your Phone Number: <input type="text" name="member[phone]" value="{PHONE}"> </p>
    <p>
    Please choose your newsletter subscription options: <br/>
    {NEWSLETTER_OPTIONS}
    </p>
    <p><input type="submit" name="confirm" value="Subscribe"></p>
</form>
    ', 'Used when a user wishes to subscribe.', 'code', array());
            module_template::init_template('member_subscription_error', '<h2>Subscription Error</h2>
    <p>Sorry there was an error when processing your request:</p>
    <p>{MESSAGE}</p>
    ', 'Displayed when subscription fails (eg: missing email address).', 'code', array('MESSAGE' => 'Message to the user'));
            module_template::init_template('member_subscription_success', '<h2>Subscription Success</h2>
    <p>Thank you, subscription successful.</p>
    <p>A message has been sent to your email address ({EMAIL}) to confirm your newsletter subscription.</p>
    ', 'Displayed when subscription is successful.', 'code', array('EMAIL' => 'Users email address'));
            module_template::init_template('member_update_details_success', '<h2>Subscription Success</h2>
    <p>Thank you, subscription details updated.</p>
    <p>Your email address: ({EMAIL})</p>
    ', 'Displayed when updating details is successful.', 'code', array('EMAIL' => 'Users email address'));
        }
    }
Esempio n. 2
0
 public static function get_finance_summary($week_start, $week_end, $multiplyer = 1, $row_limit = 7)
 {
     $cache_key = 'finance_sum_' . md5(module_security::get_loggedin_id() . '_' . serialize(func_get_args()));
     $cache_timeout = module_config::c('cache_objects', 60);
     if ($cached_item = module_cache::get('finance', $cache_key)) {
         return $cached_item;
     }
     $base_href = module_finance::link_generate(false, array('full' => false, 'page' => 'dashboard_popup', 'arguments' => array('display_mode' => 'ajax')), array('foo'));
     $base_href .= '&';
     /*$base_href .= (strpos($base_href,'?')!==false) ? '&' : '?';
       $base_href .= 'display_mode=ajax&';
       $base_href .= 'home_page_stats=true&';*/
     // init structure:
     if ($multiplyer > 1) {
         $row_limit++;
     }
     for ($x = 0; $x < $row_limit; $x++) {
         //$time = strtotime("+$x days",strtotime($week_start));
         $time = strtotime("+" . $x * $multiplyer . " days", strtotime($week_start));
         $data[date("Ymd", $time)] = array("day" => $time, "hours" => 0, "amount" => 0, "amount_invoiced" => 0, "amount_paid" => 0, "amount_spent" => 0);
         if (class_exists('module_envato', false)) {
             $data[date("Ymd", $time)]['envato_earnings'] = 0;
         }
     }
     $data['total'] = array('day' => _l('Totals:'), 'week' => _l('Totals:'), 'hours' => 0, 'amount' => 0, 'amount_invoiced' => 0, 'amount_paid' => 0, 'amount_spent' => 0);
     if (class_exists('module_envato', false)) {
         $data['total']['envato_earnings'] = 0;
     }
     if (class_exists('module_job', false)) {
         module_debug::log(array('title' => 'Finance Dashboard Job', 'data' => ''));
         // find all task LOGS completed within these dayes
         $sql = "SELECT t.task_id, tl.date_created, t.hours AS task_hours, t.amount, tl.hours AS hours_logged, p.job_id, p.hourly_rate, t.date_done ";
         //            $sql .= " FROM `"._DB_PREFIX."task_log` tl ";
         //            $sql .= " LEFT JOIN `"._DB_PREFIX."task` t ON tl.task_id = t.task_id ";
         $sql .= " FROM `" . _DB_PREFIX . "task` t";
         $sql .= " LEFT JOIN `" . _DB_PREFIX . "task_log` tl ON t.task_id = tl.task_id ";
         $sql .= " LEFT JOIN `" . _DB_PREFIX . "job` p ON t.job_id = p.job_id";
         $sql .= " WHERE ( (tl.date_created >= '{$week_start}' AND tl.date_created < '{$week_end}') OR (t.fully_completed = 1 AND t.date_done >= '{$week_start}' AND t.date_done < '{$week_end}') )";
         $sql .= " AND t.job_id IN ( ";
         $valid_job_ids = module_job::get_valid_job_ids();
         if (count($valid_job_ids)) {
             foreach ($valid_job_ids as $valid_job_id) {
                 $sql .= (int) $valid_job_id['job_id'] . ", ";
             }
             $sql = rtrim($sql, ', ');
         } else {
             $sql .= ' NULL ';
         }
         $sql .= " ) ";
         //            echo $sql;
         $tasks = query($sql);
         $logged_tasks = array();
         while ($r = mysql_fetch_assoc($tasks)) {
             if (!$r['date_created']) {
                 $r['date_created'] = $r['date_done'];
             }
             if ($multiplyer > 1) {
                 $week_day = date('w', strtotime($r['date_created'])) - 1;
                 $r['date_created'] = date('Y-m-d', strtotime('-' . $week_day . ' days', strtotime($r['date_created'])));
             }
             $key = date("Ymd", strtotime($r['date_created']));
             if (!isset($data[$key])) {
                 // for some reason we're getting results here that shouldn't be in the list
                 // for now we just skip these results until I figure out why (only had 1 guy report this error, maybe misconfig)
                 continue;
             }
             // copied from dashboard_popup_hours_logged.php
             // needed get_tasks call to do the _JOB_TASK_ACCESS_ASSIGNED_ONLY permission check
             $jobtasks = module_job::get_tasks($r['job_id']);
             $task = isset($jobtasks[$r['task_id']]) ? $jobtasks[$r['task_id']] : false;
             if (!$task) {
                 continue;
             }
             if (!isset($task['manual_task_type']) || $task['manual_task_type'] < 0) {
                 $task['manual_task_type'] = $task['default_task_type'];
             }
             if (isset($r['hours_logged']) && $r['hours_logged'] > 0) {
                 if ($r['hours_logged'] == $task['completed']) {
                     // this listing is the only logged hours for this task.
                     if ($task['fully_completed']) {
                         // task complete, we show the final amount and hours.
                         if ($task['amount'] > 0) {
                             if ($task['manual_task_type'] == _TASK_TYPE_QTY_AMOUNT) {
                                 $display_amount = $task['amount'] * $task['hours'];
                             } else {
                                 $display_amount = $task['amount'];
                             }
                         } else {
                             $display_amount = $r['task_hours'] * $r['hourly_rate'];
                         }
                     } else {
                         // task isn't fully completed yet, just use hourly rate for now.
                         $display_amount = $r['hours_logged'] * $r['hourly_rate'];
                     }
                 } else {
                     // this is part of a bigger log of hours for this single task.
                     $display_amount = $r['hours_logged'] * $r['hourly_rate'];
                 }
                 $hours_logged = $r['task_hours'] > 0 ? $r['hours_logged'] : 0;
             } else {
                 // there are no logged hours for this particular task, but it is set to completed.
                 // we just assume it is completed on this day.
                 if ($task['amount'] > 0) {
                     if ($task['manual_task_type'] == _TASK_TYPE_QTY_AMOUNT) {
                         $display_amount = $task['amount'] * $task['hours'];
                     } else {
                         $display_amount = $task['amount'];
                     }
                 } else {
                     $display_amount = $r['task_hours'] * $r['hourly_rate'];
                 }
                 $hours_logged = $task['hours'];
             }
             $data[$key]['amount'] += $display_amount;
             $data['total']['amount'] += $display_amount;
             $data[$key]['hours'] += $hours_logged;
             $data['total']['hours'] += $hours_logged;
             /*$hourly_rate = $r['hourly_rate'];
               if($hours_logged > 0 && $r['amount'] > 0 && $hourly_rate > 0){
                   // there is a custom amount assigned to thsi task.
                   // only calculate this amount if the full hours is complete.
                   $hourly_rate = $r['amount'] / $r['task_hours'];
               }
               if($hours_logged > 0 && $hourly_rate > 0){
                   $data[$key]['amount'] += ($hours_logged * $hourly_rate);
                   $data['total']['amount'] += ($hours_logged * $hourly_rate);
               }*/
         }
     }
     module_debug::log(array('title' => 'Finance Dashboard Invoices', 'data' => ''));
     // find invoices sent this week.
     $sql = "SELECT i.* ";
     $sql .= " FROM `" . _DB_PREFIX . "invoice` i ";
     $sql .= " LEFT JOIN `" . _DB_PREFIX . "invoice_item` ii ON i.invoice_id = ii.invoice_id ";
     if (class_exists('module_job', false)) {
         $sql .= " LEFT JOIN `" . _DB_PREFIX . "task` t ON ii.task_id = t.task_id ";
         $sql .= " LEFT JOIN `" . _DB_PREFIX . "job` p ON t.job_id = p.job_id ";
     }
     $sql .= " WHERE (i.date_create >= '{$week_start}' AND i.date_create <= '{$week_end}')";
     $sql .= " GROUP BY i.invoice_id";
     // todo - sql in here to limit what they can see.
     $invoices = query($sql);
     // group invoices into days of the week.
     while ($invoice_data = mysql_fetch_assoc($invoices)) {
         //$invoice_data = module_invoice::get_invoice($i['invoice_id']);
         if ($invoice_data) {
             if ($multiplyer > 1) {
                 $week_day = date('w', strtotime($invoice_data['date_create'])) - 1;
                 $invoice_data['date_create'] = date('Y-m-d', strtotime('-' . $week_day . ' days', strtotime($invoice_data['date_create'])));
             }
             $key = date("Ymd", strtotime($invoice_data['date_create']));
             if (!isset($data[$key])) {
                 // for some reason we're getting results here that shouldn't be in the list
                 // for now we just skip these results until I figure out why (only had 1 guy report this error, maybe misconfig)
                 continue;
             }
             if (isset($data[$key])) {
                 $data[$key]['amount_invoiced'] += $invoice_data['c_total_amount'];
                 $data['total']['amount_invoiced'] += $invoice_data['c_total_amount'];
             }
         }
     }
     module_debug::log(array('title' => 'Finance Dashboard Finances', 'data' => ''));
     // find all payments made this week.
     // we also have to search for entries in the new "finance" table and make sure we dont double up here.
     $finance_records = module_finance::get_finances(array('date_from' => $week_start, 'date_to' => $week_end));
     foreach ($finance_records as $finance_record) {
         if (isset($finance_record['payment_type']) && ($finance_record['payment_type'] == _INVOICE_PAYMENT_TYPE_OVERPAYMENT_CREDIT || $finance_record['payment_type'] == _INVOICE_PAYMENT_TYPE_CREDIT)) {
             // CODE COPIED FROM FINANCE_LIST.PHP
             // dont add these ones to the totals on the dashboard
             continue;
         }
         if ($finance_record['credit'] > 0) {
             if ($multiplyer > 1) {
                 $week_day = date('w', strtotime($finance_record['transaction_date'])) - 1;
                 $finance_record['transaction_date'] = date('Y-m-d', strtotime('-' . $week_day . ' days', strtotime($finance_record['transaction_date'])));
             }
             $key = date("Ymd", strtotime($finance_record['transaction_date']));
             if (isset($data[$key])) {
                 $data[$key]['amount_paid'] += $finance_record['amount'];
                 $data['total']['amount_paid'] += $finance_record['amount'];
             }
         }
         if ($finance_record['debit'] > 0) {
             if ($multiplyer > 1) {
                 $week_day = date('w', strtotime($finance_record['transaction_date'])) - 1;
                 $finance_record['transaction_date'] = date('Y-m-d', strtotime('-' . $week_day . ' days', strtotime($finance_record['transaction_date'])));
             }
             $key = date("Ymd", strtotime($finance_record['transaction_date']));
             if (isset($data[$key])) {
                 $data[$key]['amount_spent'] += $finance_record['amount'];
                 $data['total']['amount_spent'] += $finance_record['amount'];
             }
         }
     }
     module_debug::log(array('title' => 'Finance Dashboard DONE!', 'data' => ''));
     /*$sql = "SELECT p.* ";
       $sql .= " FROM `"._DB_PREFIX."invoice_payment` p ";
       $sql .= " WHERE (p.date_paid >= '$week_start' AND p.date_paid <= '$week_end')";
       // todo - sql in here to limit what they can see.
       $payments = query($sql);
       // group invoices into days of the week.
       while($payment = mysql_fetch_assoc($payments)){
           //$invoice_data = module_invoice::get_invoice($i['invoice_id']);
           if($multiplyer > 1){
               $week_day = date('w',strtotime($payment['date_paid'])) - 1;
               $payment['date_paid'] = date('Y-m-d',strtotime('-'.$week_day.' days',strtotime($payment['date_paid'])));
           }
           $key = date("Ymd",strtotime($payment['date_paid']));
           if(isset($data[$key])){
               $data[$key]['amount_paid'] += $payment['amount'];
               $data['total']['amount_paid'] += $payment['amount'];
           }
       }*/
     if (class_exists('module_envato', false)) {
         $envato_currency = "USD";
         $envato = new envato_api();
         $local_currency = $envato->read_setting("local_currency", "AUD");
         $currency_convert_multiplier = $envato->currency_convert($envato_currency, $local_currency);
         // find summary of earnings between these dates in the envato statement.
         $week_start_time = strtotime($week_start);
         $week_end_time = strtotime($week_end);
         $sql = "SELECT * FROM `" . _DB_PREFIX . "envato_statement` s WHERE `time` >= '{$week_start_time}' AND `time` <= {$week_end_time}";
         $sql .= " AND ( `type` = 'sale' OR `type` = 'referral_cut' )";
         foreach (qa($sql) as $sale) {
             $sale_time = $sale['time'];
             if ($multiplyer > 1) {
                 $week_day = date('w', $sale_time) - 1;
                 $sale_time = strtotime('-' . $week_day . ' days', $sale_time);
             }
             $key = date("Ymd", $sale_time);
             if (!isset($data[$key])) {
                 continue;
             }
             $data[$key]['envato_earnings'] += round($currency_convert_multiplier * $sale['earnt'], 2);
             $data['total']['envato_earnings'] += round($currency_convert_multiplier * $sale['earnt'], 2);
             /*if($sale['type']=='sale'){
                   $sales_count++;
               }
               $sales_amount+= $sale['earnt'];*/
         }
     }
     if ($multiplyer > 1) {
         // dont want totals on previous weeks listing
         unset($data['total']);
     }
     foreach ($data as $data_id => $row) {
         //$row['amount'] = dollar($row['amount']);
         $row['chart_amount'] = $row['amount'];
         $row['amount'] = currency((int) $row['amount']);
         $row['chart_amount_invoiced'] = $row['amount_invoiced'];
         $row['amount_invoiced'] = currency((int) $row['amount_invoiced']);
         $row['chart_amount_paid'] = $row['amount_paid'];
         $row['amount_paid'] = currency((int) $row['amount_paid']);
         $row['chart_amount_spent'] = $row['amount_spent'];
         $row['amount_spent'] = currency((int) $row['amount_spent']);
         if (class_exists('module_envato', false)) {
             $row['chart_envato_earnings'] = $row['envato_earnings'];
             $row['envato_earnings'] = currency((int) $row['envato_earnings']);
         }
         // combine together
         $row['chart_hours'] = $row['hours'];
         $row['hours'] = sprintf('%s (%s)', $row['hours'], $row['amount']);
         if (is_numeric($row['day'])) {
             $time = $row['day'];
             $date = date('Y-m-d', $time);
             $row['date'] = $date;
             if ($multiplyer > 1) {
                 $date .= '|' . date('Y-m-d', strtotime('+' . $multiplyer . ' days', $time));
             }
             //$row['hours'] = '<a href="'.$base_href.'w=hours&date='.$date.'" class="summary_popup">'. _l('%s hours',$row['hours']) . '</a>';
             $row['hours_link'] = '<a href="' . $base_href . 'w=hours&date=' . $date . '" class="summary_popup">' . $row['hours'] . '</a>';
             $row['amount_link'] = '<a href="' . $base_href . 'w=hours&date=' . $date . '" class="summary_popup">' . $row['amount'] . '</a>';
             $row['amount_invoiced_link'] = '<a href="' . $base_href . 'w=amount_invoiced&date=' . $date . '" class="summary_popup">' . $row['amount_invoiced'] . '</a>';
             $row['amount_paid_link'] = '<a href="' . $base_href . 'w=amount_paid&date=' . $date . '" class="summary_popup">' . $row['amount_paid'] . '</a>';
             $row['amount_spent_link'] = '<a href="' . $base_href . 'w=amount_spent&date=' . $date . '" class="summary_popup">' . $row['amount_spent'] . '</a>';
             $row['day'] = _l(date('D', $time)) . ' ' . date('j', $time) . _l(date('S', $time));
             $row['week'] = _l(date('M', $time)) . ' ' . date('j', $time) . _l(date('S', $time));
             // if it's today.
             if ($time == strtotime(date("Y-m-d"))) {
                 $row['highlight'] = true;
             }
         } else {
         }
         $data[$data_id] = $row;
     }
     module_cache::put('finance', $cache_key, $data, $cache_timeout);
     return $data;
 }
Esempio n. 3
0
 public static function get_invoice($invoice_id, $basic = false, $skip_permissions = false)
 {
     $invoice = array();
     $invoice_id = (int) $invoice_id;
     if ((int) $invoice_id > 0) {
         // we check the cache to see if the 'full' copy of this invoice exists anywhere yet.
         // if it does
         $cache_key = self::_invoice_cache_key($invoice_id, array($invoice_id, $basic, $skip_permissions, isset($_REQUEST['customer_id']) ? $_REQUEST['customer_id'] : 0, isset($_REQUEST['job_id']) ? $_REQUEST['job_id'] : 0));
         if ($cached_item = module_cache::get('invoice', $cache_key)) {
             return $cached_item;
         }
         $cache_key_full = self::_invoice_cache_key($invoice_id, array($invoice_id, false, $skip_permissions, isset($_REQUEST['customer_id']) ? $_REQUEST['customer_id'] : 0, isset($_REQUEST['job_id']) ? $_REQUEST['job_id'] : 0));
         if ($cache_key_full != $cache_key && ($cached_item = module_cache::get('invoice', $cache_key_full))) {
             return $cached_item;
         }
         $cache_timeout = module_config::c('cache_objects', 60);
         if ($basic === 2) {
             // used in links. just want the invoice name really.
             // todo - cache. meh
             return get_single('invoice', 'invoice_id', $invoice_id);
         } else {
             $sql = "SELECT i.*";
             $sql .= ", c.primary_user_id  ";
             // AS user_id // DONE - change this to the invoice table. drop down to select invoice contact. auto select based on contacts role?
             $sql .= ", c.customer_name AS customer_name ";
             $sql .= ", GROUP_CONCAT(DISTINCT j.`website_id` SEPARATOR ',') AS website_ids";
             // the website id(s)
             $sql .= ", GROUP_CONCAT(DISTINCT j.`job_id` SEPARATOR ',') AS job_ids";
             // the job id(s)
             $sql .= ", j.customer_id AS new_customer_id ";
             $sql .= " FROM `" . _DB_PREFIX . "invoice` i ";
             $sql .= " LEFT JOIN `" . _DB_PREFIX . "invoice_item` ii USING (invoice_id) ";
             $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 .= " LEFT JOIN `" . _DB_PREFIX . "customer` c ON i.customer_id = c.customer_id ";
             //$sql .= " LEFT JOIN `"._DB_PREFIX."user` u ON c.primary_user_id = u.user_id ";
             $sql .= " WHERE i.invoice_id = " . (int) $invoice_id;
             $sql .= " GROUP BY i.invoice_id";
             $invoice = qa1($sql);
             if (isset($invoice['website_id']) && $invoice['website_id']) {
                 $website_ids = explode(',', $invoice['website_ids']);
                 if (!in_array($invoice['website_id'], $website_ids)) {
                     $website_ids[] = $invoice['website_id'];
                     $invoice['website_ids'] = implode(',', $website_ids);
                 }
             }
         }
         if (isset($invoice['job_ids']) && strlen(trim($invoice['job_ids'])) > 0) {
             $invoice['job_ids'] = explode(',', $invoice['job_ids']);
         } else {
             $invoice['job_ids'] = array();
         }
         // check permissions
         if ($invoice && isset($invoice['invoice_id']) && $invoice['invoice_id'] == $invoice_id) {
             switch (self::get_invoice_access_permissions()) {
                 case _INVOICE_ACCESS_ALL:
                     break;
                 case _INVOICE_ACCESS_STAFF:
                     if ($invoice['vendor_user_id'] != module_security::get_loggedin_id()) {
                         if ($skip_permissions) {
                             $invoice['_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 {
                             $invoice = false;
                         }
                     }
                     break;
                 case _INVOICE_ACCESS_JOB:
                     // only invoices from jobs!
                     $has_invoice_access = false;
                     $jobs = module_job::get_jobs();
                     foreach ($invoice['job_ids'] as $invoice_job_id) {
                         if (isset($jobs[$invoice_job_id])) {
                             $has_invoice_access = true;
                         }
                     }
                     unset($jobs);
                     if (!$has_invoice_access) {
                         if ($skip_permissions) {
                             $invoice['_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 {
                             $invoice = false;
                         }
                     }
                     break;
                 case _INVOICE_ACCESS_CUSTOMER:
                     // tie in with customer permissions to only get invoices from customers we can access.
                     $customers = module_customer::get_customers();
                     $has_invoice_access = false;
                     if (isset($customers[$invoice['customer_id']])) {
                         $has_invoice_access = true;
                     }
                     unset($customers);
                     /*foreach($customers as $customer){
                           // todo, if($invoice['customer_id'] == 0) // ignore this permission
                           if($customer['customer_id']==$invoice['customer_id']){
                               $has_invoice_access = true;
                               break;
                           }
                       }*/
                     if (!$has_invoice_access) {
                         if ($skip_permissions) {
                             $invoice['_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 {
                             $invoice = false;
                         }
                     }
                     break;
             }
             //            print_r($invoice);exit;
             if (!$invoice) {
                 return array();
             }
             $original_invoice = $invoice;
             $invoice['taxes'] = get_multiple('invoice_tax', array('invoice_id' => $invoice_id), 'invoice_tax_id', 'exact', 'order');
             // set the job id of the first job just for kicks
             if (isset($invoice['deposit_job_id']) && (int) $invoice['deposit_job_id'] > 0) {
                 $invoice['job_ids'][] = $invoice['deposit_job_id'];
             }
             if (isset($invoice['website_ids'])) {
                 $invoice['website_ids'] = explode(',', $invoice['website_ids']);
             } else {
                 $invoice['website_ids'] = array();
             }
             // incase teh customer id on this invoice changes:
             if (isset($invoice['new_customer_id']) && $invoice['new_customer_id'] > 0 && $invoice['new_customer_id'] != $invoice['customer_id']) {
                 $invoice['customer_id'] = $invoice['new_customer_id'];
                 update_insert('invoice_id', $invoice_id, 'invoice', array('customer_id' => $invoice['new_customer_id']));
             }
             if ($invoice['customer_id'] > 0) {
                 $customer_data = module_customer::get_customer($invoice['customer_id']);
                 if ($customer_data && class_exists('module_company', false) && isset($invoice['company_id']) && !$invoice['company_id'] && isset($customer_data['company_ids']) && count($customer_data['company_ids']) == 1) {
                     // check if this customer has a company.
                     $invoice['company_id'] = key($customer_data['company_ids']);
                 }
             }
             if ($basic === true) {
                 module_cache::put('invoice', $cache_key, $invoice, $cache_timeout);
                 return $invoice;
             }
         }
     }
     // not sure why this code was here, commenting it out for now until we need it.
     /*if(isset($invoice['customer_id']) && isset($invoice['job_id']) && $invoice['customer_id'] <= 0 && $invoice['job_id'] > 0){
           $job_data = module_job::get_job($invoice['job_id'],false);
           $invoice['customer_id'] = $job_data['customer_id'];
       }*/
     if (!$invoice || !is_array($invoice) || !isset($invoice['invoice_id']) || !$invoice['invoice_id']) {
         $customer_id = isset($_REQUEST['customer_id']) ? $_REQUEST['customer_id'] : 0;
         $job_id = isset($_REQUEST['job_id']) ? $_REQUEST['job_id'] : 0;
         $currency_id = module_config::c('default_currency_id', 1);
         if ($customer_id > 0) {
             // find a default website to use ?
         } else {
             if ($job_id > 0) {
                 // only a job, no customer. set the customer id.
                 $job_data = module_job::get_job($job_id, false);
                 $customer_id = $job_data['customer_id'];
                 $currency_id = $job_data['currency_id'];
             }
         }
         // work out an invoice number
         $invoice_number = self::new_invoice_number($customer_id);
         $invoice = array('invoice_id' => 'new', 'customer_id' => $customer_id, 'job_id' => $job_id, 'job_ids' => $job_id > 0 ? array($job_id) : array(), 'currency_id' => $currency_id, 'name' => $invoice_number, 'cached_total' => 0, 'discount_description' => $job_id > 0 && isset($job_data['discount_description']) ? $job_data['discount_description'] : _l('Discount:'), 'discount_amount' => $job_id > 0 && isset($job_data['discount_amount']) ? $job_data['discount_amount'] : 0, 'discount_type' => $job_id > 0 && isset($job_data['discount_type']) ? $job_data['discount_type'] : module_config::c('invoice_discount_type', _DISCOUNT_TYPE_BEFORE_TAX), 'tax_type' => module_config::c('invoice_tax_type', 0), 'date_create' => date('Y-m-d'), 'date_sent' => '', 'date_due' => date('Y-m-d', strtotime('+' . module_config::c('invoice_due_days', 30) . ' days')), 'date_paid' => '', 'hourly_rate' => module_config::c('hourly_rate', 60), 'status' => module_config::s('invoice_status_default', 'New'), 'user_id' => '', 'date_renew' => '', 'renew_invoice_id' => '', 'deposit_job_id' => 0, 'date_cancel' => '0000-00-00', 'total_amount_deposits' => 0, 'total_amount_deposits_tax' => 0, 'default_task_type' => module_config::c('default_task_type', _TASK_TYPE_HOURS_AMOUNT), 'overdue_email_auto' => module_config::c('overdue_email_auto', 0), 'renew_auto' => 0, 'renew_email' => 0, 'overdue' => false, 'invoice_template_print' => '', 'website_id' => '0', 'website_ids' => '');
         $invoice['total_tax_rate'] = module_config::c('tax_percent', 10);
         $invoice['total_tax_name'] = module_config::c('tax_name', 'TAX');
         $customer_data = false;
         if ($customer_id > 0) {
             $customer_data = module_customer::get_customer($customer_id);
         }
         if ($customer_data && $customer_data['customer_id'] && $customer_data['customer_id'] == $customer_id) {
             // is there a default invoice template for this customer?
             if (class_exists('module_extra', false)) {
                 $extras = module_extra::get_extras(array('owner_table' => 'customer', 'owner_id' => $customer_id));
                 foreach ($extras as $e) {
                     if ($e['extra_key'] == 'invoice_template_print') {
                         $invoice['invoice_template_print'] = $e['extra'];
                     }
                 }
             }
             if ($customer_data['primary_user_id']) {
                 $invoice['primary_user_id'] = $customer_data['primary_user_id'];
             }
             if (isset($customer_data['default_tax']) && $customer_data['default_tax'] >= 0) {
                 $invoice['total_tax_rate'] = $customer_data['default_tax'];
                 $invoice['total_tax_name'] = $customer_data['default_tax_name'];
             }
         }
     }
     // drag some details from the related job
     $first_job_id = 0;
     if (!(int) $invoice_id) {
         if (isset($invoice['job_ids']) && $invoice['job_ids']) {
             $first_job_id = current($invoice['job_ids']);
         } else {
             if (isset($invoice['job_id']) && $invoice['job_id']) {
                 $first_job_id = $invoice['job_id'];
                 // abckwards compatibility
             } else {
                 $first_job_id = 0;
             }
         }
         if ($first_job_id > 0) {
             $job_data = module_job::get_job($first_job_id, false);
             $invoice['hourly_rate'] = $job_data['hourly_rate'];
             $invoice['taxes'] = $job_data['taxes'];
             //$invoice['total_tax_rate'] = $job_data['total_tax_rate'];
             //$invoice['total_tax_name'] = $job_data['total_tax_name'];
         }
     }
     // new support for multiple taxes
     if (!isset($invoice['taxes']) || !count($invoice['taxes']) && $invoice['total_tax_rate'] > 0) {
         $invoice['taxes'] = array();
         if ($first_job_id > 0 && !(int) $invoice_id) {
             // taxes set above from job
         } else {
             $tax_rates = explode(',', $invoice['total_tax_rate']);
             $tax_names = explode(',', $invoice['total_tax_name']);
             foreach ($tax_rates as $tax_rate_id => $tax_rate_amount) {
                 if ($tax_rate_amount > 0) {
                     $invoice['taxes'][] = array('order' => 0, 'percent' => $tax_rate_amount, 'name' => isset($tax_names[$tax_rate_id]) ? $tax_names[$tax_rate_id] : $invoice['total_tax_name'], 'total' => 0, 'amount' => 0, 'discount' => 0, 'increment' => module_config::c('tax_multiple_increment', 0));
                 }
             }
         }
     }
     // work out total hours etc..
     //$invoice['total_hours'] = 0;
     //$invoice['total_hours_completed'] = 0;
     //$invoice['total_hours_overworked'] = 0;
     $invoice['discount_amount_on_tax'] = 0;
     // used in job.php
     $invoice['total_sub_amount'] = 0;
     $invoice['total_sub_amount_taxable'] = 0;
     $invoice_items = self::get_invoice_items((int) $invoice['invoice_id'], $invoice);
     foreach ($invoice_items as $invoice_item) {
         if ($invoice_item['invoice_item_amount'] != 0) {
             // we have a custom amount for this invoice_item
             $invoice['total_sub_amount'] += $invoice_item['invoice_item_amount'];
             if ($invoice_item['taxable']) {
                 $invoice['total_sub_amount_taxable'] += $invoice_item['invoice_item_amount'];
                 if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                     // tax calculated along the way (this isn't the recommended way, but was included as a feature request)
                     // we add tax to each of the tax array items
                     //$invoice['total_tax'] += round(($invoice_item['invoice_item_amount'] * ($invoice['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
                     foreach ($invoice['taxes'] as $invoice_tax_id => $invoice_tax) {
                         if (!isset($invoice['taxes'][$invoice_tax_id]['total'])) {
                             $invoice['taxes'][$invoice_tax_id]['total'] = 0;
                         }
                         $invoice['taxes'][$invoice_tax_id]['total'] += $invoice_item['invoice_item_amount'];
                         $invoice['taxes'][$invoice_tax_id]['amount'] += round($invoice_item['invoice_item_amount'] * ($invoice_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                     }
                 }
             }
         }
     }
     //$invoice['final_modification'] = 0; // hack for discount modes - change this to just 'discount_amount' cos that is all that uses this variable. HERE
     // add any discounts.
     if ($invoice['discount_amount'] != 0) {
         if ($invoice['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
             // after tax discount ::::::::::
             // handled below.
             //$invoice['final_modification'] = -$invoice['discount_amount'];
         } else {
             if ($invoice['discount_type'] == _DISCOUNT_TYPE_BEFORE_TAX) {
                 // before tax discount:::::
                 //$invoice['final_modification'] = -$invoice['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 ($invoice['taxes'] as $invoice_tax_id => $invoice_tax) {
                         $this_tax_discount = round($invoice['discount_amount'] * ($invoice['taxes'][$invoice_tax_id]['percent'] / 100), module_config::c('currency_decimal_places', 2));
                         $invoice['discount_amount_on_tax'] += $this_tax_discount;
                         if (!isset($invoice['taxes'][$invoice_tax_id]['total'])) {
                             $invoice['taxes'][$invoice_tax_id]['total'] = 0;
                         }
                         $invoice['taxes'][$invoice_tax_id]['total'] -= $invoice['discount_amount'];
                         $invoice['taxes'][$invoice_tax_id]['amount'] -= $this_tax_discount;
                         $invoice['taxes'][$invoice_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
                     $invoice['taxes_backup'] = $invoice['taxes'];
                     $invoice['total_sub_amount_taxable_backup'] = $invoice['total_sub_amount_taxable'];
                     $total_tax_before_discount = 0;
                     foreach ($invoice['taxes'] as $invoice_tax_id => $invoice_tax) {
                         $invoice['taxes'][$invoice_tax_id]['total'] = $invoice['total_sub_amount_taxable'];
                         $invoice['taxes'][$invoice_tax_id]['amount'] = round($invoice['total_sub_amount_taxable'] * ($invoice_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($invoice_tax['increment']) && $invoice_tax['increment']) {
                             $invoice['total_sub_amount_taxable'] += $invoice['taxes'][$invoice_tax_id]['amount'];
                         }
                         $total_tax_before_discount += $invoice['taxes'][$invoice_tax_id]['amount'];
                     }
                     $invoice['taxes'] = $invoice['taxes_backup'];
                     $invoice['total_sub_amount_taxable'] = $invoice['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 = $invoice['total_sub_amount'] - $invoice['total_sub_amount_taxable'];
                 $non_taxable_discount = min($invoice['discount_amount'], $non_taxable_amount);
                 $taxable_discount = $invoice['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($invoice);exit;
                 $invoice['total_sub_amount'] -= $invoice['discount_amount'];
                 $invoice['total_sub_amount_taxable'] -= $taxable_discount;
                 //                $invoice['total_sub_amount']-=$invoice['discount_amount'];
                 //                $invoice['total_sub_amount_taxable']-=$invoice['discount_amount'];
             }
         }
     }
     //$invoice['total_hours_remain'] = $invoice['total_hours'] - $invoice['total_hours_completed'];
     //$invoice['total_percent_complete'] = $invoice['total_hours'] > 0 ? round($invoice['total_hours_remain'] / $invoice['total_hours'],2) : 0;
     //if(isset($invoice['total_tax_rate'])){
     if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL && isset($invoice['total_tax']) && $invoice['total_tax'] > 0) {
         // tax already calculated above.
     } else {
         if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_AT_END) {
             // tax needs to be calculated based on the total_sub_amount_taxable
             $previous_invoice_tax_id = false;
             foreach ($invoice['taxes'] as $invoice_tax_id => $invoice_tax) {
                 $invoice['taxes'][$invoice_tax_id]['total'] = $invoice['total_sub_amount_taxable'];
                 if (isset($invoice_tax['increment']) && $invoice_tax['increment'] && $previous_invoice_tax_id) {
                     $invoice['taxes'][$invoice_tax_id]['total'] += $invoice['taxes'][$previous_invoice_tax_id]['amount'];
                 }
                 $invoice['taxes'][$invoice_tax_id]['amount'] = round($invoice['taxes'][$invoice_tax_id]['total'] * ($invoice_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)
                 $previous_invoice_tax_id = $invoice_tax_id;
             }
             //$invoice['total_tax'] = round(($invoice['total_sub_amount_taxable'] * ($invoice['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
         } else {
             //$invoice['total_tax'] = 0;
         }
     }
     if (isset($invoice['tax_type']) && $invoice['tax_type'] == 1) {
         // hack! not completely correct, oh well.
         // todo - make this work with more than 1 tax rate.
         // $amount / 1.05  ( this is 1 + tax %)
         // this will only work if a single tax has been included.
         if (is_array($invoice['taxes']) && count($invoice['taxes']) > 1) {
             set_error('Included tax calculation only works with 1 tax rate');
         } else {
             if (is_array($invoice['taxes']) && count($invoice['taxes'])) {
                 reset($invoice['taxes']);
                 $invoice_tax_id = key($invoice['taxes']);
                 if (isset($invoice['taxes'][$invoice_tax_id])) {
                     $taxable_amount = $invoice['total_sub_amount_taxable'] / (1 + $invoice['taxes'][$invoice_tax_id]['percent'] / 100);
                     $invoice['taxes'][$invoice_tax_id]['amount'] = $invoice['total_sub_amount_taxable'] - $taxable_amount;
                     $invoice['total_sub_amount'] = $invoice['total_sub_amount'] - $invoice['taxes'][$invoice_tax_id]['amount'];
                 }
             }
         }
     }
     $invoice['total_tax'] = 0;
     foreach ($invoice['taxes'] as $invoice_tax_id => $invoice_tax) {
         $invoice['total_tax'] += $invoice_tax['amount'];
     }
     if (isset($total_tax_before_discount)) {
         $invoice['discount_amount_on_tax'] += $total_tax_before_discount - $invoice['total_tax'];
     }
     $invoice['total_amount'] = $invoice['total_sub_amount'] + $invoice['total_tax'];
     if ($invoice['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
         $invoice['total_amount'] -= $invoice['discount_amount'];
     }
     $invoice['total_amount'] = round($invoice['total_amount'], module_config::c('currency_decimal_places', 2));
     $invoice['overdue'] = $invoice['date_due'] && $invoice['date_due'] != '0000-00-00' && (!$invoice['date_paid'] || $invoice['date_paid'] == '0000-00-00') && strtotime($invoice['date_due']) < strtotime(date('Y-m-d'));
     if ($basic === 1) {
         // so we don't go clearning cache and working out how much has been paid.
         // used in the finance module while displaying dashboard summary.
         return $invoice;
     }
     // find the user id if none exists.
     /*if($invoice['customer_id'] && !$invoice['user_id']){
           $customer_data = module_customer::get_customer($invoice['customer_id']);
           if($customer_data && $customer_data['customer_id'] == $invoice['customer_id']){
               if($customer_data['primary_user_id']){
                   $invoice['user_id'] = $customer_data['primary_user_id'];
               }else{
                   $customer_contacts = module_user::get_contacts(array('customer_id'=>$invoice['customer_id']));
                   foreach($customer_contacts as $contact){
                       // todo - search roles or something to find the accountant.
                       $invoice['user_id'] = $contact['user_id'];
                       break;
                   }
               }
           }
       }*/
     $paid = 0;
     /* START DEPOSITS */
     $invoice['total_amount_deposits'] = 0;
     // calculate deposits separately.
     $invoice['total_amount_deposits_tax'] = 0;
     // calculate deposits separately.
     //module_cache::clear_cache(); // no longer clearnig cache, it does it in get_invoice_payments.
     //module_cache::clear('invoice');
     foreach (self::get_invoice_payments($invoice_id) as $payment) {
         if ($payment['date_paid'] && $payment['date_paid'] != '0000-00-00') {
             if ($payment['payment_type'] == _INVOICE_PAYMENT_TYPE_DEPOSIT) {
                 // what invoice did this payment come from?
                 $deposit_invoice = module_invoice::get_invoice($payment['other_id']);
                 if ($deposit_invoice && $deposit_invoice['invoice_id'] == $payment['other_id']) {
                     $invoice['total_amount_deposits'] += min($deposit_invoice['total_amount'] - $deposit_invoice['total_tax'], $payment['amount'] - $deposit_invoice['total_tax']);
                     $invoice['total_amount_deposits_tax'] += $deposit_invoice['total_tax'];
                 }
             } else {
                 $paid += $payment['amount'];
             }
         }
     }
     if ($invoice['total_amount_deposits'] > 0) {
         // we need to reduce the 'total_amount' of this invoice so it doesn't double up with the other paid deposit invoice
         $invoice['total_amount'] -= $invoice['total_amount_deposits'];
     }
     if ($invoice['total_amount_deposits_tax'] > 0) {
         //$invoice['total_tax'] -= $invoice['total_amount_deposits_tax'];
         // we need to reduce the 'total_amount' of this invoice so it doesn't double up with the other paid deposit invoice
         $invoice['total_amount'] -= $invoice['total_amount_deposits_tax'];
     }
     /* END DEPOSITS */
     // any extra fees (eG: paypap fee?)
     $invoice['fees'] = self::get_fees($invoice_id, $invoice);
     foreach ($invoice['fees'] as $fee) {
         $invoice['total_amount'] += $fee['total'];
     }
     // dont go negative on payments:
     $invoice['total_amount_paid'] = max(0, min($invoice['total_amount'], $paid));
     $invoice['total_amount_credit'] = 0;
     if ($invoice['total_amount'] > 0 && $paid > $invoice['total_amount']) {
         // raise a credit against this customer for the difference.
         $invoice['total_amount_credit'] = round($paid - $invoice['total_amount'], 2);
         //echo $invoice['total_amount_overpaid'];exit;
     }
     if ($invoice['total_amount'] != $invoice['cached_total']) {
         if ((int) $invoice_id > 0) {
             update_insert('invoice_id', $invoice_id, 'invoice', array('cached_total' => $invoice['total_amount']));
         }
         $invoice['cached_total'] = $invoice['total_amount'];
     }
     $invoice['total_amount_due'] = round($invoice['total_amount'] - $invoice['total_amount_paid'], module_config::c('currency_decimal_places', 2));
     if ($invoice['date_cancel'] != '0000-00-00') {
         $invoice['total_amount_due'] = 0;
     }
     // a special addition for deposit invoices.
     if (isset($invoice['deposit_job_id']) && $invoice['deposit_job_id']) {
         // we find out how much deposit has actually been paid
         // and how much is remaining that hasn't been allocated to any other invoices
         $invoice['deposit_remaining'] = 0;
         if ($invoice['total_amount_paid'] > 0) {
             $invoice['deposit_remaining'] = $invoice['total_amount_paid'];
             $payments = get_multiple('invoice_payment', array('payment_type' => _INVOICE_PAYMENT_TYPE_DEPOSIT, 'other_id' => $invoice['invoice_id']));
             foreach ($payments as $payment) {
                 $invoice['deposit_remaining'] = $invoice['deposit_remaining'] - $payment['amount'];
             }
         }
     }
     // save our database cache values:
     if ((int) $invoice_id > 0) {
         foreach (array('total_amount', 'total_amount_due') as $cacheable_item) {
             if (isset($invoice[$cacheable_item]) && (!isset($original_invoice) || !isset($original_invoice['c_' . $cacheable_item]) || $original_invoice['c_' . $cacheable_item] != $invoice[$cacheable_item])) {
                 // cacheable items can be the same name or prefixed with c_
                 update_insert('invoice_id', $invoice_id, 'invoice', array("c_{$cacheable_item}" => $invoice[$cacheable_item]));
                 $invoice["c_{$cacheable_item}"] = $invoice[$cacheable_item];
             }
         }
     }
     if (isset($cache_key)) {
         module_cache::put('invoice', $cache_key, $invoice, $cache_timeout);
     }
     return $invoice;
 }
Esempio n. 4
0
 public static function get_fields($table, $ignore = array(), $hidden = array(), $from_cache = false)
 {
     if (is_array($table) || !trim($table)) {
         return array();
     }
     if (isset(self::$fieldscache[$table])) {
         return self::$fieldscache[$table];
     }
     $res = $db_cache = array();
     if ($from_cache) {
         $db_cache = module_cache::get('db', 'db_fields_' . $table);
         if (!is_array($db_cache)) {
             $db_cache = array();
         }
         if (isset($db_cache[$table])) {
             $res = $db_cache[$table];
         }
     }
     if (!count($res)) {
         $sql = "SHOW FIELDS FROM `" . _DB_PREFIX . "{$table}`";
         $res = qa($sql);
         if (!is_array($db_cache)) {
             $db_cache = array();
         }
         $db_cache[$table] = $res;
         module_cache::put('db', 'db_fields_' . $table, $db_cache, 172800);
     }
     $fields = array();
     foreach ($res as $r) {
         $format = "";
         $type = 'text';
         if (count($ignore) && in_array($r['Field'], $ignore)) {
             continue;
         }
         if (count($hidden) && in_array($r['Field'], $hidden)) {
             $type = "hidden";
             // new field for file.
         } else {
             if (preg_match("/^file_/", $r['Field']) && preg_match("/varchar\\((\\d+)\\)/", $r['Type'], $matches)) {
                 $type = "file";
                 $size = 50;
                 $maxlength = 255;
             } else {
                 if (preg_match("/varchar\\((\\d+)\\)/", $r['Type'], $matches)) {
                     $type = "text";
                     $size = max("10", min("30", $matches[1]));
                     $maxlength = $matches[1];
                 } else {
                     if (preg_match("/int/i", $r['Type']) || preg_match("/float/i", $r['Type'])) {
                         $format = array("/^\\d+\$/", "Integer");
                         $type = "number";
                         $maxlength = $size = 20;
                     } else {
                         if ($r['Type'] == "text") {
                             $type = "textarea";
                             $size = 0;
                         } else {
                             if ($r['Type'] == "date" || $r['Type'] == "datetime") {
                                 $format = array("/^\\d\\d\\d\\d-\\d\\d-\\d\\d\$/", "YYYY-MM-DD");
                                 $type = "date";
                                 $maxlength = $size = 20;
                             } else {
                                 if (preg_match("/decimal/", $r['Type']) || preg_match("/double/", $r['Type'])) {
                                     $format = array("/^\\d+\\.?[\\d+]?\$/", "Decimal");
                                     $type = "decimal";
                                     $maxlength = $size = 20;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         $required = false;
         if ($r['Null'] == "NO") {
             $required = true;
         }
         $fields[$r['Field']] = array("name" => $r['Field'], "type" => $type, "dbtype" => $r['Type'], "size" => $size, "maxlength" => $maxlength, "required" => $required, "format" => $format);
     }
     self::$fieldscache[$table] = $fields;
     return $fields;
 }
Esempio n. 5
0
 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;
 }
Esempio n. 6
0
 public static function get_quote($quote_id, $full = true, $skip_permissions = false)
 {
     $quote_id = (int) $quote_id;
     if ($quote_id <= 0) {
         $quote = array();
     } else {
         $cache_key = self::_quote_cache_key($quote_id, array($quote_id, $full, $skip_permissions));
         if ($cached_item = module_cache::get('quote', $cache_key)) {
             if (function_exists('hook_filter_var')) {
                 $cached_item = hook_filter_var('get_quote', $cached_item, $quote_id);
             }
             return $cached_item;
         }
         $cache_key_full = self::_quote_cache_key($quote_id, array($quote_id, true, $skip_permissions));
         if ($cache_key_full != $cache_key && ($cached_item = module_cache::get('quote', $cache_key_full))) {
             if (function_exists('hook_filter_var')) {
                 $cached_item = hook_filter_var('get_quote', $cached_item, $quote_id);
             }
             return $cached_item;
         }
         $cache_timeout = module_config::c('cache_objects', 60);
         $quote = get_single("quote", "quote_id", $quote_id);
     }
     // check permissions
     if ($quote && isset($quote['quote_id']) && $quote['quote_id'] == $quote_id) {
         switch (self::get_quote_access_permissions()) {
             case _QUOTE_ACCESS_ALL:
                 break;
             case _QUOTE_ACCESS_ASSIGNED:
                 // only assigned quotes!
                 $has_quote_access = false;
                 if ($quote['user_id'] == module_security::get_loggedin_id()) {
                     $has_quote_access = true;
                     break;
                 }
                 $tasks = module_quote::get_tasks($quote['quote_id']);
                 foreach ($tasks as $task) {
                     if ($task['user_id'] == module_security::get_loggedin_id()) {
                         $has_quote_access = true;
                         break;
                     }
                 }
                 unset($tasks);
                 if (!$has_quote_access) {
                     if ($skip_permissions) {
                         $quote['_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 {
                         $quote = false;
                     }
                 }
                 break;
             case _QUOTE_ACCESS_CUSTOMER:
                 // tie in with customer permissions to only get quotes from customers we can access.
                 $customers = module_customer::get_customers();
                 $has_quote_access = false;
                 if (isset($customers[$quote['customer_id']])) {
                     $has_quote_access = true;
                 }
                 /*foreach($customers as $customer){
                       // todo, if($quote['customer_id'] == 0) // ignore this permission
                       if($customer['customer_id']==$quote['customer_id']){
                           $has_quote_access = true;
                           break;
                       }
                   }*/
                 unset($customers);
                 if (!$has_quote_access) {
                     if ($skip_permissions) {
                         $quote['_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 {
                         $quote = false;
                     }
                 }
                 break;
         }
         if (!$quote) {
             $quote = array();
             if (function_exists('hook_filter_var')) {
                 $quote = hook_filter_var('get_quote', $quote, $quote_id);
             }
             return $quote;
         }
         $quote['taxes'] = get_multiple('quote_tax', array('quote_id' => $quote_id), 'quote_tax_id', 'exact', 'order');
     }
     if (!$full) {
         if (isset($cache_key)) {
             module_cache::put('quote', $cache_key, $quote, $cache_timeout);
         }
         if (function_exists('hook_filter_var')) {
             $quote = hook_filter_var('get_quote', $quote, $quote_id);
         }
         return $quote;
     }
     if (!$quote) {
         $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_quote_name = module_config::c('quote_default_new_name', '');
         if (module_config::c('quote_name_incrementing', 0)) {
             $quote_number = module_config::c('quote_name_incrementing_next', 1);
             // see if there is an quote number matching this one.
             $this_quote_number = $quote_number;
             do {
                 $quotes = get_multiple('quote', array('name' => $this_quote_number));
                 //'customer_id'=>$customer_id,
                 if (!count($quotes)) {
                     $quote_number = $this_quote_number;
                 } else {
                     $this_quote_number++;
                 }
             } while (count($quotes));
             module_config::save_config('quote_name_incrementing_next', $quote_number);
             $default_quote_name = $quote_number . $default_quote_name;
         }
         $quote = array('quote_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_quote_name, 'date_create' => date('Y-m-d'), 'date_approved' => '0000-00-00', 'approved_by' => '', 'user_id' => module_security::get_loggedin_id(), 'contact_user_id' => -1, 'status' => module_config::s('quote_status_default', 'New'), 'tax_type' => module_config::c('invoice_tax_type', 0), 'type' => module_config::s('quote_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' => '', 'discount_description' => _l('Discount:'), 'discount_amount' => 0, 'discount_type' => module_config::c('invoice_discount_type', _DISCOUNT_TYPE_BEFORE_TAX));
         // some defaults from the db.
         $quote['total_tax_rate'] = module_config::c('tax_percent', 10);
         $quote['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) {
                 $quote['total_tax_rate'] = $customer_data['default_tax'];
                 $quote['total_tax_name'] = $customer_data['default_tax_name'];
             }
         }
     }
     // new support for multiple taxes
     if (!isset($quote['taxes']) || !count($quote['taxes']) && $quote['total_tax_rate'] > 0) {
         $quote['taxes'] = array();
         $tax_rates = explode(',', $quote['total_tax_rate']);
         $tax_names = explode(',', $quote['total_tax_name']);
         foreach ($tax_rates as $tax_rate_id => $tax_rate_amount) {
             if ($tax_rate_amount > 0) {
                 $quote['taxes'][] = array('order' => 0, 'percent' => $tax_rate_amount, 'name' => isset($tax_names[$tax_rate_id]) ? $tax_names[$tax_rate_id] : $quote['total_tax_name'], 'total' => 0, 'amount' => 0, 'discount' => 0, 'increment' => module_config::c('tax_multiple_increment', 0));
             }
         }
     }
     if ($quote) {
         // work out total hours etc..
         $quote['total_hours'] = 0;
         $quote['total_hours_completed'] = 0;
         $quote['total_hours_overworked'] = 0;
         $quote['total_sub_amount'] = 0;
         $quote['total_sub_amount_taxable'] = 0;
         $quote['total_sub_amount_unbillable'] = 0;
         $quote['total_sub_amount_invoicable'] = 0;
         $quote['total_sub_amount_invoicable_taxable'] = 0;
         $quote['total_amount_invoicable'] = 0;
         $quote['total_tasks_remain'] = 0;
         $quote['total_amount'] = 0;
         $quote['total_amount_paid'] = 0;
         $quote['total_amount_invoiced'] = 0;
         $quote['total_amount_invoiced_deposit'] = 0;
         $quote['total_amount_todo'] = 0;
         $quote['total_amount_outstanding'] = 0;
         $quote['total_amount_due'] = 0;
         $quote['total_hours_remain'] = 0;
         $quote['total_percent_complete'] = 0;
         $quote['total_tax'] = 0;
         $quote['total_tax_invoicable'] = 0;
         //            $quote['invoice_discount_amount'] = 0;
         //            $quote['invoice_discount_amount_on_tax'] = 0;
         //            $quote['total_amount_discounted'] = 0;
         // new feature to invoice incompleted tasks
         $quote['uninvoiced_quote_task_ids'] = array();
         $quote_items = self::get_quote_items((int) $quote['quote_id'], $quote);
         foreach ($quote_items as $quote_item) {
             if ($quote_item['quote_item_amount'] != 0) {
                 // we have a custom amount for this quote_item
                 if ($quote_item['billable']) {
                     $quote['total_sub_amount'] += $quote_item['quote_item_amount'];
                     if ($quote_item['taxable']) {
                         $quote['total_sub_amount_taxable'] += $quote_item['quote_item_amount'];
                         if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_INCREMENTAL) {
                             // tax calculated along the way (this isn't the recommended way, but was included as a feature request)
                             // we add tax to each of the tax array items
                             //$quote['total_tax'] += round(($quote_item['quote_item_amount'] * ($quote['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
                             foreach ($quote['taxes'] as $quote_tax_id => $quote_tax) {
                                 if (!isset($quote['taxes'][$quote_tax_id]['total'])) {
                                     $quote['taxes'][$quote_tax_id]['total'] = 0;
                                 }
                                 $quote['taxes'][$quote_tax_id]['total'] += $quote_item['quote_item_amount'];
                                 $quote['taxes'][$quote_tax_id]['amount'] += round($quote_item['quote_item_amount'] * ($quote_tax['percent'] / 100), module_config::c('currency_decimal_places', 2));
                             }
                         }
                     }
                 } else {
                     $quote['total_sub_amount_unbillable'] += $quote_item['quote_item_amount'];
                 }
             }
         }
         // add any discounts.
         if ($quote['discount_amount'] != 0) {
             if ($quote['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
                 // after tax discount ::::::::::
                 // handled below.
                 //$quote['final_modification'] = -$quote['discount_amount'];
             } else {
                 if ($quote['discount_type'] == _DISCOUNT_TYPE_BEFORE_TAX) {
                     // before tax discount:::::
                     //$quote['final_modification'] = -$quote['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 ($quote['taxes'] as $quote_tax_id => $quote_tax) {
                             $this_tax_discount = round($quote['discount_amount'] * ($quote['taxes'][$quote_tax_id]['percent'] / 100), module_config::c('currency_decimal_places', 2));
                             $quote['discount_amount_on_tax'] += $this_tax_discount;
                             if (!isset($quote['taxes'][$quote_tax_id]['total'])) {
                                 $quote['taxes'][$quote_tax_id]['total'] = 0;
                             }
                             $quote['taxes'][$quote_tax_id]['total'] -= $quote['discount_amount'];
                             $quote['taxes'][$quote_tax_id]['amount'] -= $this_tax_discount;
                             $quote['taxes'][$quote_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
                         $quote['taxes_backup'] = $quote['taxes'];
                         $quote['total_sub_amount_taxable_backup'] = $quote['total_sub_amount_taxable'];
                         $total_tax_before_discount = 0;
                         foreach ($quote['taxes'] as $quote_tax_id => $quote_tax) {
                             $quote['taxes'][$quote_tax_id]['total'] = $quote['total_sub_amount_taxable'];
                             $quote['taxes'][$quote_tax_id]['amount'] = round($quote['total_sub_amount_taxable'] * ($quote_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($quote_tax['increment']) && $quote_tax['increment']) {
                                 $quote['total_sub_amount_taxable'] += $quote['taxes'][$quote_tax_id]['amount'];
                             }
                             $total_tax_before_discount += $quote['taxes'][$quote_tax_id]['amount'];
                         }
                         $quote['taxes'] = $quote['taxes_backup'];
                         $quote['total_sub_amount_taxable'] = $quote['total_sub_amount_taxable_backup'];
                     }
                     $quote['total_sub_amount'] -= $quote['discount_amount'];
                     $quote['total_sub_amount_taxable'] -= $quote['discount_amount'];
                 }
             }
         }
         if (module_config::c('tax_calculate_mode', _TAX_CALCULATE_AT_END) == _TAX_CALCULATE_AT_END) {
             // tax needs to be calculated based on the total_sub_amount_taxable
             $previous_quote_tax_id = false;
             foreach ($quote['taxes'] as $quote_tax_id => $quote_tax) {
                 $quote['taxes'][$quote_tax_id]['total'] = $quote['total_sub_amount_taxable'];
                 if (isset($quote_tax['increment']) && $quote_tax['increment'] && $previous_quote_tax_id) {
                     $quote['taxes'][$quote_tax_id]['total'] += $quote['taxes'][$previous_quote_tax_id]['amount'];
                 }
                 $quote['taxes'][$quote_tax_id]['amount'] = round($quote['taxes'][$quote_tax_id]['total'] * ($quote_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)
                 $previous_quote_tax_id = $quote_tax_id;
             }
             //$quote['total_tax'] = round(($quote['total_sub_amount_taxable'] * ($quote['total_tax_rate'] / 100)),module_config::c('currency_decimal_places',2));
         } else {
             //$quote['total_tax'] = 0;
         }
         if (isset($quote['tax_type']) && $quote['tax_type'] == 1) {
             // hack! not completely correct, oh well.
             // todo - make this work with more than 1 tax rate.
             // $amount / 1.05  ( this is 1 + tax %)
             // this will only work if a single tax has been included.
             if (is_array($quote['taxes']) && count($quote['taxes']) > 1) {
                 set_error('Included tax calculation only works with 1 tax rate');
             } else {
                 if (is_array($quote['taxes']) && count($quote['taxes'])) {
                     reset($quote['taxes']);
                     $quote_tax_id = key($quote['taxes']);
                     if (isset($quote['taxes'][$quote_tax_id])) {
                         $taxable_amount = $quote['total_sub_amount_taxable'] / (1 + $quote['taxes'][$quote_tax_id]['percent'] / 100);
                         $quote['taxes'][$quote_tax_id]['amount'] = $quote['total_sub_amount_taxable'] - $taxable_amount;
                         $quote['total_sub_amount'] = $quote['total_sub_amount'] - $quote['taxes'][$quote_tax_id]['amount'];
                     }
                 }
             }
         }
         $quote['total_tax'] = 0;
         foreach ($quote['taxes'] as $quote_tax_id => $quote_tax) {
             $quote['total_tax'] += $quote_tax['amount'];
         }
         $quote['total_amount'] = $quote['total_sub_amount'] + $quote['total_tax'];
         if ($quote['discount_type'] == _DISCOUNT_TYPE_AFTER_TAX) {
             $quote['total_amount'] -= $quote['discount_amount'];
         }
         $quote['total_amount'] = round($quote['total_amount'], module_config::c('currency_decimal_places', 2));
     }
     if (isset($cache_key)) {
         module_cache::put('quote', $cache_key, $quote, $cache_timeout);
     }
     if (function_exists('hook_filter_var')) {
         $quote = hook_filter_var('get_quote', $quote, $quote_id);
     }
     return $quote;
 }
Esempio n. 7
0
 public function handle_hook($hook, &$calling_module = false)
 {
     switch ($hook) {
         case "home_alerts":
             $alerts = array();
             if (module_config::c('change_request_alerts', 1) && class_exists('module_website', false)) {
                 $cache_key = "home_alerts_" . module_security::get_loggedin_id();
                 $cache_timeout = module_config::c('cache_objects', 60);
                 if ($alerts = module_cache::get('change_request', $cache_key)) {
                     return $alerts;
                 }
                 // find any open change requests for all customers.
                 $websites = module_website::get_websites(array(), array('columns' => 'u.website_id'));
                 // this gets websites we have permission to view.
                 if (count($websites) > 0) {
                     $website_ids = array();
                     foreach ($websites as $website) {
                         $website_ids[] = $website['website_id'];
                     }
                     // build a query to find all new change requests for websitse we have access to
                     $sql = "SELECT * FROM `" . _DB_PREFIX . "change_request` cr WHERE `website_id` IN (" . implode(', ', $website_ids) . ") AND `status` = " . _CHANGE_REQUEST_STATUS_NEW;
                     $website_requests = qa($sql);
                     foreach ($website_requests as $website_request) {
                         $alert_res = process_alert($website_request['date_created'], _l('Change Request'));
                         if ($alert_res) {
                             $alert_res['link'] = module_website::link_open($website_request['website_id'], false);
                             $alert_res['name'] = $website_request['url'];
                             $alerts[] = $alert_res;
                         }
                     }
                     /*$website_requests = self::get_change_requests(array(
                                                 'website_id'=>$website['website_id'],
                                                 'status'=>_CHANGE_REQUEST_STATUS_NEW,
                                             ));
                                             foreach($website_requests as $website_request){
                     
                                                 $alert_res = process_alert($website_request['date_created'], _l('Change Request'));
                                                 if($alert_res){
                                                     $alert_res['link'] = module_website::link_open($website['website_id'],false);
                                                     $alert_res['name'] = $website_request['url'];
                                                     $alerts[] = $alert_res;
                                                 }
                     
                                             }*/
                 }
                 module_cache::put('change_request', $cache_key, $alerts, $cache_timeout);
             }
             return $alerts;
     }
 }
Esempio n. 8
0
                }
                $item_ticket_count[$item_id]['count']++;
                $envato_count += $item['cost'];
            }
        } else {
            $item_id = '-1';
            if (!isset($item_ticket_count[$item_id])) {
                $item_ticket_count[$item_id] = array('envato_id' => $item_id, 'name' => 'No product', 'count' => 0, 'cost' => 0);
            }
            $item_ticket_count[$item_id]['count']++;
        }
    }
    if (mysql_num_rows($tickets) > 0) {
        mysql_data_seek($tickets, 0);
    }
    module_cache::put('ticket', 'envato_ticket_earning', $envato_count);
    //}
    function sort_envato_ticket_count($a, $b)
    {
        //return ($a['count']*$a['cost'])<=($b['count']*$b['cost']);
        return $a['count'] <= $b['count'];
    }
    uasort($item_ticket_count, 'sort_envato_ticket_count');
    foreach ($item_ticket_count as $i) {
        ?>
 <a href="?search[envato_item_id][]=<?php 
        echo $i['envato_id'];
        ?>
"><?php 
        echo htmlspecialchars($i['name']);
        ?>
Esempio n. 9
0
											    <li class="footer">
												    <a href="<?php 
                                echo module_job::link_open(false);
                                ?>
"><?php 
                                _e('View All Jobs');
                                ?>
</a>
											    </li>
										    </ul>
									    </li>
								    <?php 
                            }
                            $job_todo_cache = ob_get_clean();
                            echo $job_todo_cache;
                            module_cache::put('job', 'job_todo_header_cache', $job_todo_cache);
                        }
                    }
                    ?>


						    <!-- User Account: style can be found in dropdown.less -->
						    <li class="dropdown user user-menu">
							    <?php 
                    $user = module_user::get_user(module_security::get_loggedin_id());
                    ?>

							    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
								    <i class="glyphicon glyphicon-user"></i>
								    <span><?php 
                    echo htmlspecialchars($user['name']);
Esempio n. 10
0
 public static function get_customer($customer_id, $skip_permissions = false, $basic_for_link = false)
 {
     $customer_id = (int) $customer_id;
     $customer = false;
     if ($customer_id > 0) {
         $cache_key_args = func_get_args();
         $cache_key = self::_customer_cache_key($customer_id, $cache_key_args);
         $cache_timeout = module_config::c('cache_objects', 60);
         if ($cached_item = module_cache::get('customer', $cache_key)) {
             return $cached_item;
         }
         $customer = get_single("customer", "customer_id", $customer_id);
         // get their address.
         if ($customer && isset($customer['customer_id']) && $customer['customer_id'] == $customer_id) {
             if (!$basic_for_link) {
                 $customer['staff_ids'] = array();
                 foreach (get_multiple('customer_user_rel', array('customer_id' => $customer_id), 'user_id') as $val) {
                     $customer['staff_ids'][] = $val['user_id'];
                 }
                 $customer['customer_address'] = module_address::get_address($customer_id, 'customer', 'physical', true);
             }
             switch (self::get_customer_data_access()) {
                 case _CUSTOMER_ACCESS_ALL:
                     break;
                 case _CUSTOMER_ACCESS_ALL_COMPANY:
                 case _CUSTOMER_ACCESS_CONTACTS:
                 case _CUSTOMER_ACCESS_TASKS:
                 case _CUSTOMER_ACCESS_STAFF:
                     $valid_customer_ids = module_security::get_customer_restrictions();
                     $is_valid_customer = isset($valid_customer_ids[$customer['customer_id']]);
                     if (!$is_valid_customer) {
                         if ($skip_permissions) {
                             $customer['_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 {
                             $customer = false;
                         }
                     }
                     break;
             }
         }
     }
     if (!$customer) {
         $customer = array('customer_id' => 'new', 'customer_name' => '', 'customer_status' => _CUSTOMER_STATUS_PAID, 'primary_user_id' => '', 'credit' => '0', 'customer_address' => array(), 'staff_ids' => array(), 'customer_type_id' => self::get_current_customer_type_id());
     }
     if (class_exists('module_company', false) && module_company::is_enabled() && !$basic_for_link) {
         $customer['company_ids'] = array();
         if (isset($customer['customer_id']) && (int) $customer['customer_id'] > 0) {
             foreach (module_company::get_companys_by_customer($customer['customer_id']) as $company) {
                 $customer['company_ids'][$company['company_id']] = $company['name'];
             }
         }
     }
     //$customer['customer_industry_id'] = get_multiple('customer_industry_rel',array('customer_id'=>$customer_id),'customer_industry_id');
     //echo $customer_id;print_r($customer);exit;
     if (isset($cache_key) && isset($cache_timeout)) {
         module_cache::put('customer', $cache_key, $customer, $cache_timeout);
     }
     return $customer;
 }
Esempio n. 11
0
 public static function get_user($user_id, $perms = true, $do_link = true, $basic_for_link = false)
 {
     //,$basic=false
     $cache_key_args = func_get_args();
     $cache_key = self::_user_cache_key($user_id, $cache_key_args);
     $cache_timeout = module_config::c('cache_objects', 60);
     if ($cached_item = module_cache::get('user', $cache_key)) {
         return $cached_item;
     }
     $user = get_single("user", "user_id", $user_id);
     if ($do_link && $user && isset($user['linked_parent_user_id']) && $user['linked_parent_user_id'] && $user['linked_parent_user_id'] != $user['user_id']) {
         $user = self::get_user($user['linked_parent_user_id']);
         module_cache::put('user', $cache_key, $user, $cache_timeout);
         return $user;
     }
     if ($user) {
         if ($basic_for_link) {
             module_cache::put('user', $cache_key, $user, $cache_timeout);
             return $user;
         }
         // if this user is a linked contact to the current contact then we allow access.
         if (isset($user['linked_parent_user_id']) && $user['linked_parent_user_id'] == module_security::get_loggedin_id()) {
             // allow all access.
         } else {
             if (class_exists('module_customer', false)) {
                 if ($user) {
                     switch (module_user::get_user_data_access()) {
                         case _USER_ACCESS_ME:
                             if ($user['user_id'] != module_security::get_loggedin_id()) {
                                 if ($perms) {
                                     $user = false;
                                 } else {
                                     // eg for linking.
                                     $user['_perms'] = false;
                                 }
                             }
                             break;
                         case _USER_ACCESS_CONTACTS:
                             if (!$user['customer_id'] && !$user['vendor_id'] && $user['user_id'] != module_security::get_loggedin_id()) {
                                 // this user is not a customer contact, don't let them access it.
                                 if ($perms) {
                                     $user = false;
                                 } else {
                                     // eg for linking.
                                     $user['_perms'] = false;
                                 }
                             }
                             break;
                         case _USER_ACCESS_ALL:
                         default:
                             // all user accounts.
                             break;
                     }
                 }
                 if ($user && $user['customer_id'] > 0) {
                     switch (module_customer::get_customer_data_access()) {
                         case _CUSTOMER_ACCESS_ALL:
                             // all customers! so this means all jobs!
                             break;
                         case _CUSTOMER_ACCESS_ALL_COMPANY:
                         case _CUSTOMER_ACCESS_CONTACTS:
                         case _CUSTOMER_ACCESS_TASKS:
                         case _CUSTOMER_ACCESS_STAFF:
                             $valid_customer_ids = module_security::get_customer_restrictions();
                             $is_valid_user = isset($valid_customer_ids[$user['customer_id']]);
                             if (!$is_valid_user) {
                                 if ($perms) {
                                     $user = false;
                                 } else {
                                     // eg for linking.
                                     $user['_perms'] = false;
                                 }
                             }
                     }
                 }
             }
             if ($user && $user['vendor_id'] > 0) {
                 switch (module_vendor::get_vendor_data_access()) {
                     case _VENDOR_ACCESS_ALL:
                         // all vendors! so this means all jobs!
                         break;
                     case _VENDOR_ACCESS_ALL_COMPANY:
                     case _VENDOR_ACCESS_CONTACTS:
                         $valid_vendor_check = module_vendor::get_vendor($user['vendor_id']);
                         $is_valid_user = $valid_vendor_check && isset($valid_vendor_check['vendor_id']) && $valid_vendor_check['vendor_id'] == $user['vendor_id'];
                         if (!$is_valid_user) {
                             if ($perms) {
                                 $user = false;
                             } else {
                                 // eg for linking.
                                 $user['_perms'] = false;
                             }
                         }
                 }
             }
         }
     }
     if (!$user) {
         $user = array('user_id' => 'new', 'customer_id' => 0, 'vendor_id' => 0, 'name' => '', 'last_name' => '', 'email' => '', 'password' => '', 'phone' => '', 'mobile' => '', 'fax' => '', 'roles' => array(), 'language' => module_config::c('default_language', 'en'), 'company_ids' => array());
         $use_master_key = self::get_contact_master_key();
         if (isset($_REQUEST[$use_master_key])) {
             $user[$use_master_key] = $_REQUEST[$use_master_key];
         }
     } else {
         $user['roles'] = get_multiple('user_role', array('user_id' => $user_id));
         if (class_exists('module_company', false) && module_company::is_enabled()) {
             $user['company_ids'] = array();
             foreach (module_company::get_companys_by_user($user['user_id']) as $company) {
                 $user['company_ids'][$company['company_id']] = $company['name'];
             }
         }
         module_cache::put('user', $cache_key, $user, $cache_timeout);
     }
     return $user;
 }
Esempio n. 12
0
 public static function get_reply_rate()
 {
     // cached?
     $rate = module_cache::get('ticket', 'ticket_count_rate');
     if ($rate === false) {
         $rate = array('daily' => 0, 'weekly' => 0);
         // how many messages were replied to by the admin in the last week?
         $admins_rel = module_ticket::get_ticket_staff_rel();
         if (count($admins_rel)) {
             $sql = "SELECT COUNT(*) AS c FROM `" . _DB_PREFIX . "ticket_message` WHERE from_user_id IN (" . implode(', ', array_keys($admins_rel)) . ") AND message_time >= " . (int) strtotime('-7 days');
             $res = qa1($sql);
             $rate['weekly'] = $res['c'];
             $rate['daily'] = ceil($res['c'] / 7);
             module_cache::put('ticket', 'ticket_count_rate', $rate);
         }
     }
     return $rate;
 }