Beispiel #1
0
        infowindow = new google.maps.InfoWindow({});
    }
    google.maps.event.addListener(item, 'click', function(event) {
        infowindow.close();
        infowindow = new google.maps.InfoWindow({
            content: content,
            position: event.latLng
        });
        infowindow.open(map, item);
    });
}

var customer_address = [];
<?php 
$customer_addresses = array();
$customers = module_customer::get_customers(array('customer_id' => isset($_REQUEST['customer_id']) && (int) $_REQUEST['customer_id'] > 0 ? (int) $_REQUEST['customer_id'] : false), array('columns' => 'c.customer_id, c.customer_name'));
foreach ($customers as $customer) {
    $address = module_address::get_address($customer['customer_id'], 'customer', 'physical');
    if (!empty($address)) {
        $address_count = 0;
        $customer['full_address'] = '';
        foreach (array('line_1', 'line_2', 'suburb', 'state', 'region', 'country', 'post_code') as $key) {
            if (!empty($address[$key])) {
                $address_count++;
                $customer['full_address'] .= $address[$key] . ', ';
            }
            $customer[$key] = $address[$key];
        }
        if ($address_count > 1) {
            $customer['address_id'] = $address['address_id'];
            $customer['full_address'] = rtrim($customer['full_address'], ', ');
Beispiel #2
0
    function process()
    {
        if ('plupload' == $_REQUEST['_process']) {
            if (!self::can_i('edit', 'Files') && !self::can_i('create', 'Files')) {
                die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Permission error."}, "id" : "id"}');
            }
            @ob_end_clean();
            // HTTP headers for no cache etc
            header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
            header("Cache-Control: no-store, no-cache, must-revalidate");
            header("Cache-Control: post-check=0, pre-check=0", false);
            header("Pragma: no-cache");
            // Settings
            $targetDir = _FILE_UPLOAD_PATH . "plupload";
            //$targetDir = 'uploads';
            $cleanupTargetDir = true;
            // Remove old files
            $maxFileAge = 5 * 3600;
            // Temp file age in seconds
            // 5 minutes execution time
            @set_time_limit(5 * 60);
            // Uncomment this one to fake upload time
            // usleep(5000);
            // Get parameters
            $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
            $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
            $fileName = isset($_REQUEST["plupload_key"]) ? $_REQUEST["plupload_key"] : '';
            $fileName .= isset($_REQUEST["fileid"]) ? '-' . $_REQUEST["fileid"] : '';
            $fileName = preg_replace('/[^a-zA-Z0-9-_]+/', '', $fileName);
            if (!$fileName) {
                die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "No plupload_key defined."}, "id" : "id"}');
            }
            // Make sure the fileName is unique but only if chunking is disabled
            if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
                $ext = strrpos($fileName, '.');
                $fileName_a = substr($fileName, 0, $ext);
                $fileName_b = substr($fileName, $ext);
                $count = 1;
                while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b)) {
                    $count++;
                }
                $fileName = $fileName_a . '_' . $count . $fileName_b;
            }
            $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
            // Create target dir
            if (!file_exists($targetDir)) {
                @mkdir($targetDir);
            }
            // Remove old temp files
            if ($cleanupTargetDir) {
                if (!is_dir($targetDir) || !($dir = opendir($targetDir))) {
                    die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
                }
                while (($file = readdir($dir)) !== false) {
                    $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
                    // If temp file is current file proceed to the next
                    if ($tmpfilePath == "{$filePath}.part") {
                        continue;
                    }
                    // Remove temp file if it is older than the max age and is not the current file
                    if (preg_match('/\\.part$/', $file) && filemtime($tmpfilePath) < time() - $maxFileAge) {
                        @unlink($tmpfilePath);
                    }
                }
                closedir($dir);
            }
            /// Open temp file
            if (!($out = @fopen("{$filePath}.part", $chunks ? "ab" : "wb"))) {
                die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
            }
            if (!empty($_FILES)) {
                if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
                    die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
                }
                // Read binary input stream and append it to temp file
                if (!($in = @fopen($_FILES["file"]["tmp_name"], "rb"))) {
                    die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
                }
            } else {
                if (!($in = @fopen("php://input", "rb"))) {
                    die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
                }
            }
            while ($buff = fread($in, 4096)) {
                fwrite($out, $buff);
            }
            @fclose($out);
            @fclose($in);
            // Check if file has been uploaded
            if (!$chunks || $chunk == $chunks - 1) {
                // Strip the temp .part suffix off
                rename("{$filePath}.part", $filePath);
            }
            die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
        } else {
            if ('download' == $_REQUEST['_process']) {
                @ob_end_clean();
                $file_id = (int) $_REQUEST['file_id'];
                $file_data = $this->get_file($file_id);
                if (isset($file_data['file_url']) && strlen($file_data['file_url'])) {
                    redirect_browser($file_data['file_url']);
                } else {
                    if (is_file($file_data['file_path'])) {
                        header("Pragma: public");
                        header("Expires: 0");
                        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                        header("Cache-Control: private", false);
                        //header("Content-Type: application/pdf");
                        header("Content-type: " . dtbaker_mime_type($file_data['file_name'], $file_data['file_path']));
                        header("Content-Disposition: attachment; filename=\"" . $file_data['file_name'] . "\";");
                        header("Content-Transfer-Encoding: binary");
                        header("Content-Length: " . filesize($file_data['file_path']));
                        //readfile($file_data['file_path']);
                        $size = @readfile($file_data['file_path']);
                        if (!$size) {
                            echo file_get_contents($file_data['file_path']);
                        }
                    } else {
                        echo 'Not found';
                    }
                }
                exit;
            } else {
                if ('save_file_popup' == $_REQUEST['_process']) {
                    $file_id = $_REQUEST['file_id'];
                    $file_path = false;
                    $file_name = false;
                    $options = unserialize(base64_decode($_REQUEST['options']));
                    // have we uploaded anything
                    if (isset($_FILES['file_upload']) && is_uploaded_file($_FILES['file_upload']['tmp_name'])) {
                        // copy to file area.
                        $file_name = basename($_FILES['file_upload']['name']);
                        if ($file_name) {
                            $file_path = _FILE_UPLOAD_PATH . md5(time() . $file_name);
                            if (move_uploaded_file($_FILES['file_upload']['tmp_name'], $file_path)) {
                                // it worked. umm.. do something.
                            } else {
                                ?>

                    <script type="text/javascript">
                        alert('Unable to save file. Please check permissions.');
                    </script>
                    <?php 
                                // it didnt work. todo: display error.
                                $file_path = false;
                                $file_name = false;
                                //set_error('Unable to save file');
                            }
                        }
                    }
                    if (isset($_REQUEST['file_name']) && $_REQUEST['file_name']) {
                        $file_name = $_REQUEST['file_name'];
                    }
                    if (!$file_path && !$file_name) {
                        return false;
                    }
                    if (!$file_id || $file_id == 'new') {
                        $file_data = array('file_id' => $file_id, 'owner_id' => (int) $_REQUEST['owner_id'], 'owner_table' => $_REQUEST['owner_table'], 'file_time' => time(), 'file_name' => $file_name, 'file_path' => $file_path);
                    } else {
                        // some fields we dont want to overwrite on existing files:
                        $file_data = array('file_id' => $file_id, 'file_path' => $file_path, 'file_name' => $file_name);
                    }
                    // make sure we're saving a file we have access too.
                    module_security::sanatise_data('file', $file_data);
                    $file_id = update_insert('file_id', $file_id, 'file', $file_data);
                    $file_data = $this->get_file($file_id);
                    // we've updated from a popup.
                    // this means we have to replace an existing file id with the updated output.
                    // or if none exists on the page, we add a new one to the holder.
                    $layout_type = isset($_REQUEST['layout']) && $_REQUEST['layout'] ? $_REQUEST['layout'] : 'gallery';
                    ?>

			<script type="text/javascript">
				// check if it exists in parent window
				var new_html = '<?php 
                    echo addcslashes(preg_replace('/\\s+/', ' ', $this->print_file($file_id, $layout_type, true, $options)), "'");
                    ?>
';
				parent.new_file_added<?php 
                    echo $file_data['owner_table'];
                    ?>
_<?php 
                    echo $file_data['owner_id'];
                    ?>
(<?php 
                    echo $file_id;
                    ?>
,'<?php 
                    echo $file_data['owner_table'];
                    ?>
',<?php 
                    echo $file_data['owner_id'];
                    ?>
,new_html);
			</script>
			<?php 
                    exit;
                } else {
                    if ('save_file' == $_REQUEST['_process']) {
                        $file_id = (int) $_REQUEST['file_id'];
                        $file_path = false;
                        $file_name = false;
                        $file_url = '';
                        if (isset($_REQUEST['butt_del']) && self::can_i('delete', 'Files')) {
                            if (module_form::confirm_delete('file_id', 'Really delete this file?')) {
                                $ucm_file = new ucm_file($file_id);
                                $ucm_file->delete();
                                set_message('File removed successfully');
                            }
                            redirect_browser(module_file::link_open(false));
                        } else {
                            $files_to_save = array();
                            // pump data in to here for multiple file uploads.
                            // todo: stop people changing the "file_id" to another file they don't own.
                            if (self::can_i('edit', 'Files') || self::can_i('create', 'Files')) {
                                // have we uploaded anything
                                $file_changed = false;
                                if (isset($_REQUEST['plupload_key']) && isset($_REQUEST['plupload_file_name']) && is_array($_REQUEST['plupload_file_name']) && strlen(preg_replace('/[^a-zA-Z0-9-_]+/', '', basename($_REQUEST['plupload_key'])))) {
                                    $plupload_key = preg_replace('/[^a-zA-Z0-9-_]+/', '', basename($_REQUEST['plupload_key']));
                                    foreach ($_REQUEST['plupload_file_name'] as $plupload_file_name_key => $file_name) {
                                        $plupload_file_name_key = preg_replace('/[^a-zA-Z0-9-_]+/', '', basename($plupload_file_name_key));
                                        if ($plupload_key && $plupload_file_name_key && $file_name && is_file(_FILE_UPLOAD_PATH . 'plupload' . DIRECTORY_SEPARATOR . $plupload_key . '-' . $plupload_file_name_key)) {
                                            $file_path = _FILE_UPLOAD_PATH . time() . '-' . md5(time() . $file_name);
                                            if (rename(_FILE_UPLOAD_PATH . 'plupload' . DIRECTORY_SEPARATOR . $plupload_key . '-' . $plupload_file_name_key, $file_path)) {
                                                // it worked. umm.. do something.
                                                $file_changed = true;
                                                $files_to_save[] = array('file_path' => $file_path, 'file_name' => $file_name);
                                            } else {
                                                // it didnt work. todo: display error.
                                                $file_path = false;
                                                $file_name = false;
                                                set_error('Unable to save file via plupload.');
                                            }
                                        }
                                    }
                                }
                                // the old file upload method, no plupload:
                                if (!$file_changed && isset($_FILES['file_upload']) && is_uploaded_file($_FILES['file_upload']['tmp_name'])) {
                                    // copy to file area.
                                    $file_name = basename($_FILES['file_upload']['name']);
                                    if ($file_name) {
                                        $file_path = _FILE_UPLOAD_PATH . time() . '-' . md5(time() . $file_name);
                                        if (move_uploaded_file($_FILES['file_upload']['tmp_name'], $file_path)) {
                                            // it worked. umm.. do something.
                                            $file_changed = true;
                                            $files_to_save[] = array('file_path' => $file_path, 'file_name' => $file_name);
                                        } else {
                                            // it didnt work. todo: display error.
                                            $file_path = false;
                                            $file_name = false;
                                            set_error('Unable to save file');
                                        }
                                    }
                                }
                                if (!$file_path && isset($_REQUEST['file_url']) && isset($_REQUEST['file_name'])) {
                                    $files_to_save[] = array('file_path' => '', 'file_url' => $_REQUEST['file_url'], 'file_name' => $_REQUEST['file_name']);
                                }
                                if (!$file_path && isset($_REQUEST['bucket'])) {
                                    $files_to_save[] = array('file_name' => $_REQUEST['file_name'], 'bucket' => 1);
                                }
                                // make sure we have a valid customer_id and job_id selected.
                                $possible_customers = $possible_jobs = array();
                                if (class_exists('module_customer', false)) {
                                    $possible_customers = module_customer::get_customers();
                                }
                                if (class_exists('module_job', false)) {
                                    $possible_jobs = module_job::get_jobs();
                                }
                                $original_file_data = array();
                                if ($file_id > 0) {
                                    $original_file_data = self::get_file($file_id);
                                    if (!$original_file_data || $original_file_data['file_id'] != $file_id) {
                                        die('No permissions to update this file');
                                    }
                                }
                                $new_file = false;
                                if (!$file_id) {
                                    $file_data = array('file_id' => $file_id, 'bucket_parent_file_id' => isset($_REQUEST['bucket_parent_file_id']) ? (int) $_REQUEST['bucket_parent_file_id'] : false, 'customer_id' => isset($_REQUEST['customer_id']) ? (int) $_REQUEST['customer_id'] : false, 'job_id' => isset($_REQUEST['job_id']) ? (int) $_REQUEST['job_id'] : false, 'quote_id' => isset($_REQUEST['quote_id']) ? (int) $_REQUEST['quote_id'] : false, 'website_id' => isset($_REQUEST['website_id']) ? (int) $_REQUEST['website_id'] : false, 'status' => isset($_REQUEST['status']) ? $_REQUEST['status'] : false, 'pointers' => isset($_REQUEST['pointers']) ? $_REQUEST['pointers'] : false, 'description' => isset($_REQUEST['description']) ? $_REQUEST['description'] : false, 'file_time' => time());
                                    if (!isset($possible_customers[$file_data['customer_id']])) {
                                        $file_data['customer_id'] = 0;
                                    }
                                    if (!isset($possible_jobs[$file_data['job_id']])) {
                                        $file_data['job_id'] = 0;
                                    }
                                    $new_file = true;
                                } else {
                                    // some fields we dont want to overwrite on existing files:
                                    $file_data = array('file_id' => $file_id, 'bucket_parent_file_id' => isset($_REQUEST['bucket_parent_file_id']) ? (int) $_REQUEST['bucket_parent_file_id'] : false, 'pointers' => isset($_REQUEST['pointers']) ? $_REQUEST['pointers'] : false, 'customer_id' => isset($_REQUEST['customer_id']) ? (int) $_REQUEST['customer_id'] : false, 'job_id' => isset($_REQUEST['job_id']) ? (int) $_REQUEST['job_id'] : false, 'quote_id' => isset($_REQUEST['quote_id']) ? (int) $_REQUEST['quote_id'] : false, 'website_id' => isset($_REQUEST['website_id']) ? (int) $_REQUEST['website_id'] : false, 'status' => isset($_REQUEST['status']) ? $_REQUEST['status'] : false, 'description' => isset($_REQUEST['description']) ? $_REQUEST['description'] : false);
                                    if (!isset($possible_customers[$file_data['customer_id']]) && $file_data['customer_id'] != $original_file_data['customer_id']) {
                                        $file_data['customer_id'] = $original_file_data['customer_id'];
                                    }
                                    if ($file_data['job_id'] && !isset($possible_jobs[$file_data['job_id']]) && $file_data['job_id'] != $original_file_data['job_id']) {
                                        $file_data['job_id'] = $original_file_data['job_id'];
                                    }
                                }
                                $sub_bucket_fields = array('customer_id', 'job_id', 'quote_id', 'website_id');
                                if ($file_data['bucket_parent_file_id']) {
                                    // we're saving a sub bucket file, pull in the file data from the parent file.
                                    $parent_file = new ucm_file($file_data['bucket_parent_file_id']);
                                    $parent_file_data = $parent_file->get_data();
                                    foreach ($sub_bucket_fields as $sub_bucket_field) {
                                        $file_data[$sub_bucket_field] = $parent_file_data[$sub_bucket_field];
                                    }
                                }
                                if (!count($files_to_save)) {
                                    $files_to_save[] = array();
                                }
                                foreach ($files_to_save as $id => $file_to_save) {
                                    $file_data_to_save = array_merge($file_data, $file_to_save);
                                    $files_to_save[$id]['file_id'] = update_insert('file_id', $file_data['file_id'], 'file', $file_data_to_save);
                                    $file_data['file_id'] = 0;
                                    // incease we're uploading multiple files
                                    if (isset($_POST['staff_ids_save']) && (int) $files_to_save[$id]['file_id'] > 0) {
                                        delete_from_db('file_user_rel', array('file_id'), array($files_to_save[$id]['file_id']));
                                        if (isset($_POST['staff_ids']) && is_array($_POST['staff_ids'])) {
                                            foreach ($_POST['staff_ids'] as $staff_id) {
                                                $sql = "REPLACE INTO `" . _DB_PREFIX . "file_user_rel` SET ";
                                                $sql .= " `user_id` = " . (int) $staff_id;
                                                $sql .= ", `file_id` = " . (int) $files_to_save[$id]['file_id'];
                                                query($sql);
                                            }
                                        }
                                    }
                                    if ($files_to_save[$id]['file_id'] > 0 && isset($file_data_to_save['bucket']) && $file_data_to_save['bucket']) {
                                        // update certain fields of all the child files to match the parent bucket.
                                        $search = array('bucket_parent_file_id' => $files_to_save[$id]['file_id']);
                                        $sub_files = module_file::get_files($search);
                                        $vals = array();
                                        foreach ($sub_bucket_fields as $field) {
                                            $vals[$field] = isset($file_data_to_save[$field]) ? $file_data_to_save[$field] : false;
                                        }
                                        foreach ($sub_files as $sub_file) {
                                            update_insert('file_id', $sub_file['file_id'], 'file', $vals);
                                            // and save the staff assignment manually too
                                            if (isset($_POST['staff_ids_save']) && (int) $sub_file['file_id'] > 0) {
                                                delete_from_db('file_user_rel', array('file_id'), array($sub_file['file_id']));
                                                if (isset($_POST['staff_ids']) && is_array($_POST['staff_ids'])) {
                                                    foreach ($_POST['staff_ids'] as $staff_id) {
                                                        $sql = "REPLACE INTO `" . _DB_PREFIX . "file_user_rel` SET ";
                                                        $sql .= " `user_id` = " . (int) $staff_id;
                                                        $sql .= ", `file_id` = " . (int) $sub_file['file_id'];
                                                        query($sql);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    module_extra::save_extras('file', 'file_id', $files_to_save[$id]['file_id']);
                                    if ($file_changed) {
                                        $this->send_file_changed_notice($files_to_save[$id]['file_id'], $new_file);
                                    }
                                    // file changed
                                }
                            }
                            if (module_file::can_i('create', 'File Comments')) {
                                $this->save_file_comments($file_id);
                            }
                            if (isset($_REQUEST['delete_file_comment_id']) && $_REQUEST['delete_file_comment_id']) {
                                $file_comment_id = (int) $_REQUEST['delete_file_comment_id'];
                                $comment = get_single('file_comment', 'file_comment_id', $file_comment_id);
                                if ($comment['create_user_id'] == module_security::get_loggedin_id() || module_file::can_i('delete', 'File Comments')) {
                                    $sql = "DELETE FROM `" . _DB_PREFIX . "file_comment` WHERE file_id = '" . (int) $file_id . "' AND file_comment_id = '{$file_comment_id}' ";
                                    $sql .= " LIMIT 1";
                                    query($sql);
                                }
                            }
                            if (isset($_REQUEST['butt_email']) && $_REQUEST['butt_email'] && module_file::can_i('edit', 'File Approval')) {
                                redirect_browser($this->link_open_email($file_id));
                            }
                            if (count($files_to_save)) {
                                if (count($files_to_save) > 1) {
                                    $file_id = false;
                                    set_message(_l('%s Files saved successfully', count($files_to_save)));
                                } else {
                                    set_message(_l('File saved successfully'));
                                    $file_id = $files_to_save[0]['file_id'];
                                }
                            }
                            redirect_browser($this->link_open($file_id));
                        }
                    } else {
                        if ('delete_file_popup' == $_REQUEST['_process']) {
                            $file_id = (int) $_REQUEST['file_id'];
                            if (!$file_id || $file_id == 'new') {
                                // cant delete a new file.. do nothing.
                            } else {
                                $file_data = $this->get_file($file_id);
                                if (true) {
                                    //module_security::can_access_data('file',$file_data,$file_id)){
                                    // delete the physical file.
                                    if (is_file($file_data['file_path'])) {
                                        unlink($file_data['file_path']);
                                    }
                                    // delete the db entry.
                                    delete_from_db('file', 'file_id', $file_id);
                                    // update ui with changes.
                                    ?>

					<script type="text/javascript">
						var new_html = '';
						parent.new_file_added<?php 
                                    echo $file_data['owner_table'];
                                    ?>
_<?php 
                                    echo $file_data['owner_id'];
                                    ?>
(<?php 
                                    echo $file_id;
                                    ?>
,'<?php 
                                    echo $file_data['owner_table'];
                                    ?>
',<?php 
                                    echo $file_data['owner_id'];
                                    ?>
,new_html);
					</script>
					<?php 
                                }
                            }
                            exit;
                        }
                    }
                }
            }
        }
    }
}));
if (count($invoice['job_ids'])) {
    $fieldset_data['elements'][] = array('title' => 'Linked Job', 'fields' => array(function () use(&$invoice) {
        foreach ($invoice['job_ids'] as $job_id) {
            if ((int) $job_id > 0) {
                echo module_job::link_open($job_id, true);
                echo "<br/>\n";
            }
        }
    }));
}
$fieldset_data['elements'][] = array('title' => 'Customer', 'fields' => array(function () use(&$invoice) {
    if (!$invoice['customer_id'] || isset($_REQUEST['change_customer'])) {
        // allow them to pick customer.
        $c = array();
        $customers = module_customer::get_customers();
        foreach ($customers as $customer) {
            $c[$customer['customer_id']] = $customer['customer_name'];
        }
        echo print_select_box($c, 'customer_id', $invoice['customer_id']);
        if ($invoice['customer_id'] && module_customer::can_i('view', 'Customers')) {
            ?>

                        <a href="<?php 
            echo module_customer::link_open($invoice['customer_id'], false);
            ?>
"><?php 
            _e('Open');
            ?>
</a>
                        <?php 
    $customer_type = module_customer::get_customer_type($current_customer_type_id);
    if ($customer_type && !empty($customer_type['type_name'])) {
        $page_type = $customer_type['type_name_plural'];
        $page_type_single = $customer_type['type_name'];
    }
}
if (!module_customer::can_i('view', $page_type)) {
    redirect_browser(_BASE_HREF);
}
$module->page_title = _l($page_type);
$staff_members = module_user::get_staff_members();
$staff_member_rel = array();
foreach ($staff_members as $staff_member) {
    $staff_member_rel[$staff_member['user_id']] = $staff_member['name'];
}
$customers = module_customer::get_customers($search, array('as_resource' => true));
$header_buttons = array();
if (module_customer::can_i('create', $page_type)) {
    $header_buttons[] = array('url' => module_customer::link_open('new', false), 'title' => 'Create New ' . $page_type_single, 'type' => 'add');
}
if (class_exists('module_import_export', false) && module_customer::can_i('view', 'Import ' . $page_type)) {
    $header_buttons[] = array('url' => module_import_export::import_link(array('callback' => 'module_customer::handle_import' . ($current_customer_type_id ? '_leads' : ''), 'name' => $page_type, 'return_url' => $_SERVER['REQUEST_URI'], 'group' => 'customer', 'fields' => array($page_type_single . ' ID' => 'customer_id', $page_type_single . ' Name' => 'customer_name', 'Credit' => 'credit', 'Address Line 1' => 'line_1', 'Address Line 2' => 'line_2', 'Address Suburb' => 'suburb', 'Address Country' => 'country', 'Address State' => 'state', 'Address Region' => 'region', 'Address Post Code' => 'post_code', 'Primary Contact First Name' => 'primary_user_name', 'Primary Contact Last Name' => 'primary_user_last_name', 'Primary Phone' => 'primary_user_phone', 'Primary Email' => 'primary_user_email', 'Primary Fax' => 'primary_user_fax', 'Primary Mobile' => 'primary_user_mobile', 'Primary Language' => 'primary_user_language', 'Invoice Prefix' => 'default_invoice_prefix', 'Tax Name' => 'default_tax_name', 'Tax Rate' => 'default_tax', 'Password' => 'password', 'User Role Name' => 'role', 'Notes' => 'notes', 'Staff' => 'customer_staff'), 'extra' => array(array('owner_table' => 'customer', 'owner_id' => 'customer_id'), array('owner_table' => 'user', 'owner_id' => 'primary_user_id')))), 'title' => 'Import ' . $page_type, 'type' => 'add');
}
if (file_exists('includes/plugin_user/pages/contact_admin_list.php') && module_user::can_i('view', 'All ' . $page_type_single . ' Contacts', 'Customer', 'customer')) {
    $header_buttons[] = array('url' => module_user::link_open_contact(false), 'title' => 'View All Contacts');
}
print_heading(array('main' => true, 'type' => 'h2', 'title' => $page_type, 'button' => $header_buttons));
?>


<form action="" method="post">
Beispiel #5
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;
 }
Beispiel #6
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;
 }
Beispiel #7
0
 public static function get_customer_restrictions()
 {
     if (!self::is_logged_in()) {
         return array(-1 => -1);
     }
     /*
     new feature: we use this function instead of our hardcoded:
     switch($customer_access){
         case _CUSTOMER_ACCESS_ALL:
         case _CUSTOMER_ACCESS_CONTACTS:
         case _CUSTOMER_ACCESS_TASKS:
         case _CUSTOMER_ACCESS_STAFF:
     }
     through out the system.
     */
     /*$res = (isset($_SESSION['_restrict_customer_id'])) ? $_SESSION['_restrict_customer_id'] : false;
       if(!is_array($res) && $res > 0){
           $res = array($res);
       }*/
     if (isset(self::$customer_restrictions[module_security::get_loggedin_id()])) {
         return self::$customer_restrictions[module_security::get_loggedin_id()];
     }
     self::$customer_restrictions[module_security::get_loggedin_id()] = array();
     $customers = module_customer::get_customers(array(), array('columns' => 'c.customer_id', 'as_resource' => false));
     if (count($customers) > 0) {
         foreach ($customers as $customer) {
             self::$customer_restrictions[module_security::get_loggedin_id()][$customer['customer_id']] = $customer['customer_id'];
         }
     } else {
         self::$customer_restrictions[module_security::get_loggedin_id()] = array(-1 => -1);
     }
     return self::$customer_restrictions[module_security::get_loggedin_id()];
 }
Beispiel #8
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;
 }
Beispiel #9
0
 * Licence: Please check CodeCanyon.net for licence details. 
 * More licence clarification available here:  http://codecanyon.net/wiki/support/legal-terms/licensing-terms/ 
 * Deploy: 9809 f200f46c2a19bb98d112f2d32a8de0c4
 * Envato: 4ffca17e-861e-4921-86c3-8931978c40ca, 0a3014a3-2b8f-460b-8850-d6025aa845f8
 * Package Date: 2015-11-25 03:08:08 
 * IP Address: 67.79.165.254
 */
if (class_exists('module_customer', false) && module_security::can_user(module_security::get_loggedin_id(), 'Show Dashboard Widgets')) {
    $customer_types = module_customer::get_customer_types();
    foreach ($customer_types as $customer_type) {
        // if(!empty($customer_type['type_name_plural']) && $customer_type['customer_type_id']) { // dtbaker
        if (!empty($customer_type['type_name_plural'])) {
            // dtbaker
            if (module_customer::can_i('view', $customer_type['type_name_plural'])) {
                // find out how many open customers are left..
                $customers = module_customer::get_customers(array('customer_type_id' => $customer_type['customer_type_id']), true);
                ob_start();
                // icons from http://ionicons.com/
                ?>

				<div class="small-box bg-yellow">
					<div class="inner">
						<h3>
							<?php 
                echo mysql_num_rows($customers);
                ?>
						</h3>
						<p>
							<?php 
                _e('Current %s', htmlspecialchars($customer_type['type_name_plural']));
                ?>
Beispiel #10
0
 public static function hook_filter_var_customer_list($call, $customer_attributes)
 {
     if (!is_array($customer_attributes)) {
         $customer_attributes = array();
     }
     foreach (module_customer::get_customers(array(), array('columns' => 'c.customer_id, c.customer_name')) as $customer) {
         $customer_attributes[$customer['customer_id']] = $customer['customer_name'];
     }
     return $customer_attributes;
 }
<?php

/** 
 * Copyright: dtbaker 2012
 * Licence: Please check CodeCanyon.net for licence details. 
 * More licence clarification available here:  http://codecanyon.net/wiki/support/legal-terms/licensing-terms/ 
 * Deploy: 9809 f200f46c2a19bb98d112f2d32a8de0c4
 * Envato: 4ffca17e-861e-4921-86c3-8931978c40ca
 * Package Date: 2015-11-25 02:55:20 
 * IP Address: 67.79.165.254
 */
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : array();
$customers = module_customer::get_customers($search);
$pagination = process_pagination($customers);
?>


<h2>
    <?php 
if (module_customer::can_i('create', 'Customers')) {
    ?>

	<span class="button">
		<?php 
    echo create_link("Create New Customer", "add", module_customer::link_open('new'));
    ?>

	</span>
    <?php 
}
?>
Beispiel #12
0
                <input type="checkbox" name="finance_category_new_checked" value="new">
                <input type="text" name="finance_category_new" value="">
                <?php 
}));
if (class_exists('module_company', false) && module_company::can_i('view', 'Company') && module_company::is_enabled()) {
    $companys = module_company::get_companys();
    $companys_rel = array();
    foreach ($companys as $company) {
        $companys_rel[$company['company_id']] = $company['name'];
    }
    $fieldset_data['elements'][] = array('title' => 'Company', 'field' => array('type' => 'select', 'name' => 'company_id', 'value' => isset($finance['company_id']) ? $finance['company_id'] : '', 'options' => $companys_rel, 'blank' => _l(' - Default - '), 'help' => 'Link this finance item with an individual company. It is better to select a Customer below and assign the Customer to a Company.'));
}
if (module_config::c('finance_link_to_jobs', 1) && module_job::can_i('view', 'Jobs')) {
    $fieldset_data['elements'][] = array('title' => 'Linked Customer', 'fields' => array(function () use(&$finance, $locked) {
        echo print_select_box(module_customer::get_customers(), 'customer_id', $finance['customer_id'], '', _l(' - None - '), 'customer_name');
        ?>

                        <script type="text/javascript">
                        $(function(){
                            $('#customer_id').change(function(){
                                // change our customer id.
                                var new_customer_id = $(this).val();
                                $.ajax({
                                    type: 'POST',
                                    url: '<?php 
        echo module_job::link_open(false);
        ?>
',
                                    data: {
                                        '_process': 'ajax_job_list',