/**
  * Create a new payment
  *
  * @param void
  * @return null
  */
 function add()
 {
     if ($this->active_invoice->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     $max_payment = $this->active_invoice->getMaxPayment();
     $invoice_payment_data = $this->request->post('invoice_payment');
     if (!is_array($invoice_payment_data)) {
         $invoice_payment_data = array('amount' => $max_payment, 'paid_on' => new DateValue());
     }
     // if
     js_assign('max_invoice_payment', $max_payment);
     $this->smarty->assign('invoice_payment_data', $invoice_payment_data);
     if ($this->request->isSubmitted()) {
         db_begin_work();
         $this->active_invoice_payment->setAttributes($invoice_payment_data);
         $this->active_invoice_payment->setInvoiceId($this->active_invoice->getId());
         $this->active_invoice_payment->setCreatedBy($this->logged_user);
         $this->active_invoice_payment->setCreatedOn(new DateTimeValue());
         $this->active_invoice_payment->setSendNotifications((bool) $this->request->post('notify_company'));
         $save = $this->active_invoice_payment->save();
         if ($save && !is_error($save)) {
             db_commit();
             flash_success('Payment #:id has been added', array('id' => $this->active_invoice_payment->getId()));
             $this->redirectToUrl($this->active_invoice->getViewUrl());
         } else {
             db_rollback();
             $this->smarty->assign('errors', $save);
         }
         // if
     }
     // if
 }
 /**
  * Settings form
  * 
  * @param void
  * @return null
  */
 function index()
 {
     js_assign('test_svn_url', assemble_url('admin_source_test_svn'));
     $source_data = $this->request->post('source');
     if (!is_foreachable($source_data)) {
         $source_data = array('svn_path' => ConfigOptions::getValue('source_svn_path'), 'svn_config_dir' => ConfigOptions::getValue('source_svn_config_dir'), 'source_svn_use_output_redirect' => ConfigOptions::getValue('source_svn_use_output_redirect'), 'source_svn_trust_server_cert' => ConfigOptions::getValue('source_svn_trust_server_cert'));
     }
     // if
     if ($this->request->isSubmitted()) {
         $svn_path = array_var($source_data, 'svn_path', null);
         $svn_path = $svn_path ? with_slash($svn_path) : null;
         ConfigOptions::setValue('source_svn_path', $svn_path);
         $svn_config_dir = array_var($source_data, 'svn_config_dir') == '' ? null : array_var($source_data, 'svn_config_dir');
         ConfigOptions::setValue('source_svn_config_dir', $svn_config_dir);
         $svn_use_output_redirection = array_var($source_data, 'source_svn_use_output_redirect') == "1";
         ConfigOptions::setValue('source_svn_use_output_redirect', $svn_use_output_redirection);
         $svn_trust_server_certificate = array_var($source_data, 'source_svn_trust_server_cert') == "1";
         ConfigOptions::setValue('source_svn_trust_server_cert', $svn_trust_server_certificate);
         flash_success("Source settings successfully saved");
         $this->redirectTo('admin_source');
     }
     // if
     if (!RepositoryEngine::executableExists()) {
         $this->wireframe->addPageMessage(lang("SVN executable not found. You won't be able to use this module"), 'error');
     }
     // if
     $this->smarty->assign(array('source_data' => $source_data));
 }
 /**
  * Construct company invoices controller
  *
  * @param Request $request
  * @return CompanyInvoicesController
  */
 function __construct($request)
 {
     parent::__construct($request);
     if (!Invoice::canAccessCompanyInvoices($this->logged_user, $this->active_company)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $this->wireframe->current_menu_item = 'invoicing';
     $this->wireframe->page_actions = array();
     $this->wireframe->addBreadCrumb(lang('Invoices'), assemble_url('people_company_invoices', array('company_id' => $this->active_company->getId())));
     $invoice_id = $this->request->getId('invoice_id');
     if ($invoice_id) {
         $this->active_invoice = Invoices::findById($invoice_id);
     }
     // if
     if (instance_of($this->active_invoice, 'Invoice')) {
         if ($this->active_invoice->getCompanyId() != $this->active_company->getId()) {
             $this->httpError(HTTP_ERR_CONFLICT);
         }
         // if
         $this->wireframe->addBreadCrumb($this->active_invoice->getName(), $this->active_invoice->getCompanyViewUrl());
     } else {
         $this->active_invoice = new Invoice();
     }
     // if
     $this->smarty->assign(array('active_invoice' => $this->active_invoice, 'page_tab' => 'invoices'));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
/**
 * Render object subscribers
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_subscriptions($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    js_assign('max_subscribers_count', MAX_SUBSCRIBERS_COUNT);
    require_once SYSTEM_MODULE_PATH . '/helpers/function.user_link.php';
    $subscribers = $object->getSubscribers();
    if (count($subscribers) > MAX_SUBSCRIBERS_COUNT) {
        $smarty->assign(array('_object_subscriptions_list_subscribers' => false, '_object_subscriptions_object' => $object, '_object_subscriptions_subscribers_count' => count($subscribers), '_object_subscription_brief' => array_var($params, 'brief', false), '_object_subscriptions_popup_url' => assemble_url('object_subscribers_widget', array('object_id' => $object->getId()))));
    } else {
        $links = null;
        if (is_foreachable($subscribers)) {
            $links = array();
            foreach ($subscribers as $subscriber) {
                $links[] = smarty_function_user_link(array('user' => $subscriber), $smarty);
            }
            // foreach
        }
        // if
        $smarty->assign(array('_object_subscriptions_list_subscribers' => true, '_object_subscriptions' => $subscribers, '_object_subscriptions_object' => $object, '_object_subscription_links' => $links, '_object_subscription_brief' => array_var($params, 'brief', false), '_object_subscriptions_popup_url' => assemble_url('object_subscribers_widget', array('object_id' => $object->getId()))));
    }
    // if
    return $smarty->fetch(get_template_path('_object_subscriptions', 'subscriptions', RESOURCES_MODULE));
}
 /**
  * Index page action
  * 
  * @param void
  * @return void
  */
 function index()
 {
     $page = (int) $this->request->get('page');
     if ($page < 1) {
         $page = 1;
     }
     // if
     $per_page = 10;
     list($documents, $pagination) = Documents::paginateDocuments($this->logged_user->getVisibility(), $page, $per_page);
     $this->smarty->assign(array('documents' => $documents, 'pagination' => $pagination));
     js_assign(array('pin_icon_url' => get_image_url('icons/pinned.16x16.gif'), 'unpin_icon_url' => get_image_url('icons/not-pinned.16x16.gif')));
 }
 /**
  * Contruct predefined invoice items admin controler
  *
  * @param Request $request
  * @return InvoiceItemTemplatesAdminController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $this->wireframe->addBreadCrumb(lang('Invoicing'), assemble_url('admin'));
     $this->wireframe->addBreadCrumb(lang('Invoice Item Templates'), assemble_url('admin_invoicing_items'));
     $this->active_item_template = InvoiceItemTemplates::findById($this->request->get('item_id'));
     if (!instance_of($this->active_item_template, 'InvoiceItemTemplate')) {
         $this->active_item_template = new InvoiceItemTemplate();
     }
     // if
     $this->smarty->assign(array('active_item_template' => $this->active_item_template, 'add_template_url' => assemble_url('admin_invoicing_item_add')));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
 /**
  * Contruct tax rates controller
  *
  * @param Request $request
  * @return TaxRatesAdminController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $tax_rate_id = $this->request->getId('tax_rate_id');
     if ($tax_rate_id) {
         $this->active_tax_rate = TaxRates::findById($tax_rate_id);
     }
     // if
     if (!instance_of($this->active_tax_rate, 'TaxRate')) {
         $this->active_tax_rate = new TaxRate();
     }
     // if
     $add_tax_rate_url = assemble_url('admin_tax_rate_add');
     $this->wireframe->addBreadCrumb(lang('Tax Rates'), assemble_url('admin_tax_rates'));
     $this->wireframe->addPageAction(lang('New Tax Rate'), $add_tax_rate_url);
     $this->smarty->assign(array('active_tax_rate' => $this->active_tax_rate, 'add_tax_rate_url' => $add_tax_rate_url));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
 /**
  * Construct payments controller
  *
  * @param Request $request
  * @return InvoicesController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $payment_id = $this->request->getId('payment_id');
     if ($payment_id) {
         $this->active_payment = Payments::findById($payment_id);
     }
     // if
     if (!instance_of($this->active_payment, 'Payment')) {
         $this->active_payment = new Payment();
     }
     // if
     $add_payment_url = assemble_url('payments_add');
     $this->wireframe->addPageAction(lang('New Payment'), $add_payment_url);
     $this->wireframe->addBreadCrumb(lang('Payments'), assemble_url('payments'));
     $this->smarty->assign(array('active_payment' => $this->active_payment, 'add_payment_url' => $add_payment_url));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
 /**
  * Construct currencies admin controller
  *
  * @param Request $request
  * @return CurrenciesAdminController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $currency_id = $this->request->getId('currency_id');
     if ($currency_id) {
         $this->active_currency = Currencies::findById($currency_id);
     }
     // if
     if (!instance_of($this->active_currency, 'Currency')) {
         $this->active_currency = new Currency();
     }
     // if
     $add_currency_url = assemble_url('admin_currencies_add');
     $this->wireframe->addBreadCrumb(lang('Currencies'), assemble_url('admin_currencies'));
     $this->wireframe->addPageAction(lang('New Currency'), $add_currency_url);
     $this->smarty->assign(array('active_currency' => $this->active_currency, 'add_currency_url' => $add_currency_url));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
 /**
  * Index page
  * 
  * @param void
  * @return null
  */
 function index()
 {
     js_assign('invoicing_precision', INVOICE_PRECISION);
     $this->wireframe->addBreadCrumb(lang('Invoicing'), assemble_url('admin'));
     $this->wireframe->addBreadCrumb(lang('Number Generator'), assemble_url('admin_invoicing_number'));
     // prepare javascript variables and counters for preview
     $pattern = Invoices::getInvoiceNumberGeneratorPattern();
     list($total_counter, $year_counter, $month_counter) = Invoices::getDateInvoiceCounters();
     $total_counter++;
     $year_counter++;
     $month_counter++;
     $variable_year = date('Y');
     $variable_month = date('n');
     $variable_month_short = date('M');
     $variable_month_long = date('F');
     js_assign('pattern_variables', array(INVOICE_VARIABLE_CURRENT_YEAR => $variable_year, INVOICE_VARIABLE_CURRENT_MONTH => $variable_month, INVOICE_VARIABLE_CURRENT_MONTH_SHORT => $variable_month_short, INVOICE_VARIABLE_CURRENT_MONTH_LONG => $variable_month_long, INVOICE_NUMBER_COUNTER_TOTAL => $total_counter, INVOICE_NUMBER_COUNTER_YEAR => $year_counter, INVOICE_NUMBER_COUNTER_MONTH => $month_counter));
     $generator_data = $this->request->post('generator');
     if (!is_foreachable($generator_data)) {
         $generator_data = array('pattern' => Invoices::getinvoiceNumberGeneratorPattern());
     }
     // if
     $this->smarty->assign(array('generator_data' => $generator_data));
     if ($this->request->isSubmitted()) {
         $errors = new ValidationErrors();
         $posted_pattern = array_var($generator_data, 'pattern', null);
         if (!trim($posted_pattern)) {
             $errors->addError(lang('Pattern is required'), 'pattern');
         }
         // if
         if (strpos($posted_pattern, INVOICE_NUMBER_COUNTER_TOTAL) === false && strpos($posted_pattern, INVOICE_NUMBER_COUNTER_YEAR) === false && strpos($posted_pattern, INVOICE_NUMBER_COUNTER_MONTH) === false) {
             $errors->addError(lang('One of invoice counters is required (:total, :year, :month)', array('total' => INVOICE_NUMBER_COUNTER_TOTAL, 'year' => INVOICE_NUMBER_COUNTER_YEAR, 'month' => INVOICE_NUMBER_COUNTER_MONTH)), 'pattern');
         }
         // if
         if ($errors->hasErrors()) {
             $this->smarty->assign(array('errors' => $errors));
         } else {
             Invoices::setInvoiceNumberGeneratorPattern($posted_pattern);
             flash_success('Pattern for invoice number generator is saved');
             $this->redirectTo('admin');
         }
         // if
     }
     // if
 }
 /**
  * Index - main page for project exporter
  *
  * @param void
  * @return null
  */
 function index()
 {
     $is_writable = folder_is_writable(PROJECT_EXPORT_PATH);
     if (!$is_writable) {
         $this->wireframe->addPageMessage(lang("Folder <strong>:folder</strong> is not writable", array("folder" => PROJECT_EXPORT_PATH)), PAGE_MESSAGE_ERROR);
         $this->smarty->assign(array('is_writable' => false));
     } else {
         $exportable_modules = array();
         event_trigger('on_project_export', array(&$exportable_modules, &$this->active_project));
         require_once PROJECT_EXPORTER_MODULE_PATH . '/models/ProjectExporterOutputBuilder.class.php';
         $output_builder = new ProjectExporterOutputBuilder($this->active_project, $this->smarty, null);
         if (is_file($output_builder->getOutputArchivePath())) {
             $this->wireframe->addPageMessage(lang('Previous project archive already exists. You can download it using following <a href=":link"><strong>link</strong></a>', array('link' => assemble_url('project_exporter_download_export', array('project_id' => $this->active_project->getId())))), PAGE_MESSAGE_INFO);
         }
         // if
         $this->smarty->assign(array('visibility_normal_caption' => lang('Only the data clients can'), 'visibility_private_caption' => lang('All project data, including data marked as private'), 'exportable_modules' => $exportable_modules, "project" => $this->active_project, 'export_project_url' => assemble_url('project_exporter', array('project_id' => $this->active_project->getId())), 'submitted' => false, 'is_writable' => true));
         js_assign('download_url', assemble_url('project_exporter_download_export', array('project_id' => $this->active_project->getId())));
         js_assign('download_ftp_url', PROJECT_EXPORT_PATH . '/project_' . $this->active_project->getId() . '/');
     }
 }
 /**
  * Construct project controller
  *
  * @param Request $request
  * @return ProjectController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $this->wireframe->page_actions = array();
     // Reset page actions
     $project_id = $this->request->get('project_id');
     if ($project_id) {
         $this->active_project = Projects::findById($project_id);
     }
     // if
     if (instance_of($this->active_project, 'Project')) {
         if (!$this->logged_user->isProjectMember($this->active_project)) {
             $this->httpError(HTTP_ERR_FORBIDDEN);
         }
         // if
         if ($this->active_project->getType() == PROJECT_TYPE_SYSTEM) {
             $this->httpError(HTTP_ERR_NOT_FOUND);
         }
         // if
         if ($this->active_project->isCompleted()) {
             $this->wireframe->addBreadCrumb(lang('Archive'), assemble_url('projects_archive'));
         }
         // if
         $this->wireframe->addBreadCrumb($this->active_project->getName(), $this->active_project->getOverviewUrl());
         $tabs = new NamedList();
         $tabs->add('overview', array('text' => str_excerpt($this->active_project->getName(), 25), 'url' => $this->active_project->getOverviewUrl()));
         event_trigger('on_project_tabs', array(&$tabs, &$this->logged_user, &$this->active_project));
         $tabs->add('people', array('text' => lang('People'), 'url' => $this->active_project->getPeopleUrl()));
         $tabs->add('recent_pages', array('text' => lang('Recent Pages'), 'url' => assemble_url('recent_pages') . '&project_id=' . $this->active_project->getId()));
         /*$tabs->add('recent_pages_1', array(
             'text' => lang('Recent Pages'),
             'url' => assemble_url('project_recent_pages_1'),
           ));*/
         //BOF:mod
         /*$tabs->add('attachments', array(
             'text' => lang('Attachments'),
             'url' => assemble_url('attachments_list', array('project_id' => $this->active_project->getId())) ,
           ));*/
         //EOF:mod
         $tabs->add('reminders', array('text' => lang('Notifications'), 'url' => assemble_url('reminders_list', array('project_id' => $this->active_project->getId()))));
         $tabs->add('calendar', array('text' => lang('Calendar'), 'url' => Calendar::getProjectCalendarUrl($this->active_project)));
         js_assign('image_picker_url', assemble_url('image_picker', array('project_id' => $this->active_project->getId())));
         js_assign('active_project_id', $this->active_project->getId());
         $this->smarty->assign('page_tabs', $tabs);
         // ---------------------------------------------------
         //  Set page company and page project
         // ---------------------------------------------------
         $page_company = $this->active_project->getCompany();
         if (instance_of($page_company, 'Company')) {
             $this->wireframe->page_company = $page_company;
         }
         // if
         $this->wireframe->page_project = $this->active_project;
         // New project
     } else {
         if ($this->controller_name == 'project') {
             $this->active_project = new Project();
         } else {
             $this->httpError(HTTP_ERR_NOT_FOUND);
         }
         // if
     }
     // if
     $this->smarty->assign(array('active_project' => $this->active_project, 'page_tab' => 'overview'));
     // -----------------------------------------------------------------------
     //  Do category related voodoo if categories are enabled. Categories are
     //  not initialized if we don't have a loaded project (no project ID)
     // -----------------------------------------------------------------------
     if ($this->active_project->isLoaded() && $this->enable_categories) {
         $category_id = $this->request->get('category_id');
         if ($category_id) {
             $this->active_category = Categories::findById($category_id);
         }
         // if
         if (instance_of($this->active_category, 'Category')) {
             if ($this->active_category->getProjectId() != $this->active_project->getId()) {
                 $this->active_category = new Category();
                 // this category is not part of selected project
             }
             // if
         } else {
             $this->active_category = new Category();
         }
         // if
         $this->smarty->assign(array('active_category' => $this->active_category, 'categories_url' => Category::getSectionUrl($this->active_project, $this->getControllerName(), $this->active_module), 'add_category_url' => Category::getAddUrl($this->active_project, $this->getControllerName(), $this->active_module)));
     }
     // if
 }
 /**
  * Show upload form
  *
  * @param void
  * @return null
  */
 function upload()
 {
     $this->wireframe->page_actions = array();
     // clear page actions
     if (!File::canAdd($this->logged_user, $this->active_project)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $file_data = array('milestone_id' => $this->request->get('milestone_id'), 'visibility' => $this->active_project->getDefaultVisibility());
     if (instance_of($this->active_category, 'Category')) {
         $file_data['parent_id'] = $this->active_category->getId();
     }
     // if
     js_assign('files_section_url', files_module_url($this->active_project));
     require_once SMARTY_PATH . '/plugins/modifier.filesize.php';
     $this->smarty->assign(array('file_data' => $file_data, 'max_upload_size' => smarty_modifier_filesize(get_max_upload_size()), 'upload_single_file_url' => assemble_url('project_files_upload_single', array('project_id' => $this->active_project->getId()))));
 }
 /**
  * View documents category page action
  *
  * @param void
  * @return null
  */
 function view()
 {
     if ($this->active_document_category->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     if (!$this->active_document_category->canView($this->logged_user)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $this->setTemplate(array('template' => 'index', 'controller' => 'documents', 'module' => DOCUMENTS_MODULE));
     $page = (int) $this->request->get('page');
     if ($page < 1) {
         $page = 1;
     }
     // if
     $per_page = 10;
     list($documents, $pagination) = Documents::paginateByCategory($this->active_document_category, $this->logged_user->getVisibility(), $page, $per_page);
     $this->smarty->assign(array('documents' => $documents, 'pagination' => $pagination));
     js_assign(array('pin_icon_url' => get_image_url('icons/pinned.16x16.gif'), 'unpin_icon_url' => get_image_url('icons/not-pinned.16x16.gif')));
 }
 /**
  * Page for editing mailbox
  *
  * @param void
  * @return void
  */
 function edit_mailbox()
 {
     if ($this->active_mailbox->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     $this->wireframe->addBreadCrumb(clean($this->active_mailbox->getDisplayName()), $this->active_mailbox->getViewUrl());
     $mailbox_data = $this->request->post('mailbox');
     if (!is_array($mailbox_data)) {
         $mailbox_data = array("from_email" => $this->active_mailbox->getFromEmail(), "from_name" => $this->active_mailbox->getFromName(), "object_type" => $this->active_mailbox->getObjectType(), "host" => $this->active_mailbox->getHost(), "username" => $this->active_mailbox->getUsername(), "password" => $this->active_mailbox->getPassword(), "type" => $this->active_mailbox->getType(), "security" => $this->active_mailbox->getSecurity(), "port" => $this->active_mailbox->getPort(), "mailbox" => $this->active_mailbox->getMailbox(), "project_id" => $this->active_mailbox->getProjectId(), "enabled" => $this->active_mailbox->getEnabled(), "accept_all_registered" => $this->active_mailbox->getAcceptAllRegistered(), "accept_anonymous" => $this->active_mailbox->getAcceptAnonymous());
     } else {
         $mailbox_data['accept_all_registered'] = array_var($mailbox_data, 'accept_all_registered', null) > 0;
         $mailbox_data['accept_anonymous'] = array_var($mailbox_data, 'accept_anonymous', null) > 0;
     }
     // if
     if ($this->request->isSubmitted()) {
         $this->active_mailbox->setAttributes($mailbox_data);
         $manager = $this->active_mailbox->getMailboxManager();
         $result = $manager->testConnection();
         if (is_error($result)) {
             $this->smarty->assign('errors', $result);
         } else {
             $save = $this->active_mailbox->save();
             if (!$save || is_error($save)) {
                 $this->smarty->assign('errors', $save);
             } else {
                 flash_success(lang('Mailbox for email address :mailbox is edited', array('mailbox' => $this->active_mailbox->getFromEmail())));
                 $this->redirectTo('incoming_mail_admin');
             }
             // if
         }
         // if
     }
     // if
     js_assign('test_mailbox_connection_url', assemble_url('incoming_mail_admin_test_mailbox_connection'));
     $this->smarty->assign(array("mailbox_data" => $mailbox_data));
 }
 function reminders_list()
 {
     $project_id = $_GET['project_id'];
     $flag = $_GET['flag'];
     $active_project = Projects::findById($project_id);
     $tabs = new NamedList();
     $tabs->add('overview', array('text' => str_excerpt($active_project->getName(), 25), 'url' => $active_project->getOverviewUrl()));
     event_trigger('on_project_tabs', array(&$tabs, &$this->logged_user, &$active_project));
     $tabs->add('people', array('text' => lang('People'), 'url' => $active_project->getPeopleUrl()));
     $tabs->add('recent_pages', array('text' => lang('Recent Pages'), 'url' => assemble_url('recent_pages') . '&project_id=' . $active_project->getId()));
     /*$tabs->add('attachments', array(
         'text' => lang('Attachments'),
         'url' => assemble_url('attachments_list', array('project_id' => $active_project->getId())) ,
       ));*/
     $tabs->add('reminders', array('text' => lang('Notifications'), 'url' => assemble_url('reminders_list', array('project_id' => $active_project->getId()))));
     $tabs->add('calendar', array('text' => lang('Calendar'), 'url' => Calendar::getProjectCalendarUrl($active_project)));
     js_assign('active_project_id', $active_project->getId());
     $this->smarty->assign('page_tabs', $tabs);
     $reminders = array();
     $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
     mysql_select_db(DB_NAME);
     if ($flag) {
         $query = "select a.user_id, a.object_id, a.comment, a.created_by_id, a.created_on from healingcrystals_reminders a inner join healingcrystals_project_objects b on a.object_id=b.id where b.project_id='" . $active_project->getId() . "' and a.user_id='" . $this->logged_user->getId() . "' order by a.created_on desc";
     } else {
         $query = "select a.user_id, a.object_id, a.comment, a.created_by_id, a.created_on from healingcrystals_reminders a inner join healingcrystals_project_objects b on a.object_id=b.id where b.project_id='" . $active_project->getId() . "' and (a.created_by_id='" . $this->logged_user->getId() . "' or a.user_id='" . $this->logged_user->getId() . "') order by a.created_on desc";
     }
     $result = mysql_query($query, $link);
     while ($entry = mysql_fetch_assoc($result)) {
         $object_ref = new ProjectObject($entry['object_id']);
         $cur_type = $object_ref->getType();
         $type_ref = new $cur_type($entry['object_id']);
         $reminders[] = array('sent_to' => new User($entry['user_id']), 'object' => $type_ref, 'comment' => $entry['comment'], 'sent_by' => new User($entry['created_by_id']), 'sent_on' => date('d-M-Y H:i', strtotime($entry['created_on'])));
     }
     mysql_close($link);
     $this->smarty->assign('reminders', $reminders);
     $this->smarty->assign('page_tab', 'reminders');
     $this->smarty->assign('flag', $flag);
 }
 /**
  * Show tickets index page
  *
  * @param void
  * @return null
  */
 function index()
 {
     /*
         	$selected_milestone_id = $_GET['milestone_id'];
     		$milestones = Milestones::findByProject($this->active_project, $this->logged_user);
     		//$milestones = Milestones::findActiveByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility());
     		
     		if (empty($selected_milestone_id)){
     			//$tickets = Tickets::findOpenByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility());
               	$tickets = Milestones::groupByMilestone(Tickets::findOpenByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility()), STATE_VISIBLE, $this->logged_user->getVisibility());
     		} else {
     			$milestone = new Milestone($selected_milestone_id);
     			$tickets_in_milestone = Tickets::findByMilestone($milestone, STATE_VISIBLE, $this->logged_user->getVisibility());
     			$tickets[$milestone->getId()] = array('milestone' => $milestone, 'objects' => $tickets_in_milestone);
     		}
     		
     		$this->smarty->assign(array('milestones' => $milestones, 
     								    'selected_milestone_id' => $selected_milestone_id, 
               							'can_add_ticket' => Ticket::canAdd($this->logged_user, $this->active_project),
               							'can_manage_categories' => $this->logged_user->isProjectLeader($this->active_project) || $this->logged_user->isProjectManager(),
               							'tickets' => $tickets,
     									'categories' => Categories::findByModuleSection($this->active_project, TICKETS_MODULE, 'tickets'),
     									'tickets_count' => (!empty($selected_milestone_id) ? count($tickets[$milestone->getId()]['objects']) : '-1')
     									));
     */
     if ($this->request->isApiCall()) {
         if ($this->active_category->isLoaded()) {
             $this->serveData(Tickets::findOpenByCategory($this->active_category, STATE_VISIBLE, $this->logged_user->getVisibility()), 'tickets');
         } else {
             $this->serveData(Tickets::findOpenByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility()), 'tickets');
         }
         // if
     } else {
         $tickets_url = tickets_module_url($this->active_project);
         $options_sort = new NamedList();
         $options_sort->add('category', array('url' => $tickets_url . '&sort=category', 'text' => lang('by Category')));
         $options_sort->add('star', array('url' => $tickets_url . '&sort=star', 'text' => lang('by Star')));
         $options_sort->add('priority', array('url' => $tickets_url . '&sort=priority', 'text' => lang('by Priority')));
         $options_sort->add('name', array('url' => $tickets_url . '&sort=name', 'text' => lang('by Name')));
         $options_sort->add('owner', array('url' => $tickets_url . '&sort=owner', 'text' => lang('by Owner')));
         //BOF:mod #59_266
         $options_sort->add('project', array('url' => $tickets_url . '&sort=milestone', 'text' => 'by Milestone'));
         //EOF:mod #59_266
         $this->wireframe->addPageAction(lang('Sort'), '#', $options_sort->data);
         $task_id = $_GET['task_id'];
         if (!empty($task_id)) {
             $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
             mysql_select_db(DB_NAME);
             $query = "select type, body from healingcrystals_project_objects where id='" . (int) $task_id . "'";
             $result = mysql_query($query);
             $info = mysql_fetch_assoc($result);
             if (strtolower($info['type']) == 'task') {
                 $body_wo_tags = strip_tags($info['body']);
                 $query = "select max(integer_field_1) as max_count from healingcrystals_project_objects where project_id='" . $this->active_project->getId() . "'";
                 $result = mysql_query($query);
                 $info = mysql_fetch_assoc($result);
                 $integer_field_1 = $info['max_count'] + 1;
                 $query = "update healingcrystals_project_objects set \n                                     type='Ticket', \n                                     module='tickets', \n                                     parent_id='0', \n                                     parent_type=null, \n                                     name='" . str_replace("'", "''", $body_wo_tags) . "', \n                                     body=null, \n                                     updated_on=now(), \n                                     updated_by_id='" . $this->logged_user->getId() . "', \n                                     integer_field_1='" . $integer_field_1 . "' where id='" . (int) $task_id . "'";
                 mysql_query($query);
                 $edit_url = assemble_url('project_ticket_edit', array('project_id' => $this->active_project->getId(), 'ticket_id' => $integer_field_1));
                 header('Location: ' . $edit_url);
             }
             mysql_close($link);
         }
         $cur_department = $_GET['department_id'];
         $mID = $_GET['mID'];
         $page = (int) $_GET['page'];
         $page = $page <= 0 ? 1 : $page;
         $limit = (int) $_GET['limit'];
         //$limit = $limit<=0 ? 50 : $limit;
         $limit = $limit <= 0 ? 1000 : $limit;
         $offset = ($page - 1) * $limit;
         $sort_by = trim(strtolower($_GET['sort']));
         $sort_by = empty($sort_by) ? 'category' : $sort_by;
         $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
         mysql_select_db(DB_NAME);
         $tickets = array();
         /*if($this->active_category->isLoaded()) {
             $tickets = Milestones::groupByMilestone(
               Tickets::findOpenByCategory($this->active_category, STATE_VISIBLE, $this->logged_user->getVisibility()), 
               STATE_VISIBLE, $this->logged_user->getVisibility()
             );
           } else {
             $tickets = Milestones::groupByMilestone(
               Tickets::findOpenByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility()), 
               STATE_VISIBLE, $this->logged_user->getVisibility()
             );*/
         if (empty($cur_department)) {
             //BOF:mod #59_266
             /*
             //EOF:mod #59_266
             $query = "select a.id as ticket_id, b.id as milestone_id, ifnull(a.priority, '0') from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id " ;
             //BOF:mod #59_266
             */
             $query = "select distinct a.id as ticket_id, b.id as milestone_id, cast(ifnull(a.priority, '0') as signed integer) as priority ::CONTENT_PLACE_HOLDER:: from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id ";
             //EOF:mod #59_266
             //BOF:mod 20120911
             /*
             //EOF:mod 20120911
                         $query_condition = " where a.project_id='" . $this->active_project->getId() . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility='" . VISIBILITY_NORMAL . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
             //BOF:mod 20120911
             */
             $query_condition = " where a.project_id='" . $this->active_project->getId() . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility>='" . $this->logged_user->getVisibility() . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
             //EOF:mod 20120911
         } else {
             if ($cur_department == '-1') {
                 //BOF:mod #59_266
                 /*
                 //EOF:mod #59_266
                 $query = "select a.id as ticket_id, b.id as milestone_id, ifnull(a.priority, '0') from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id " ;
                 //BOF:mod #59_266
                 */
                 $query = "select distinct a.id as ticket_id, b.id as milestone_id, cast(ifnull(a.priority, '0') as signed integer) as priority ::CONTENT_PLACE_HOLDER:: from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id ";
                 //EOF:mod #59_266
                 //BOF:mod 20120911
                 /*
                 //EOF:mod 20120911
                                 $query_condition = " where not exists(select * from healingcrystals_project_object_categories obj where obj.object_id=a.id) and a.project_id='" . $this->active_project->getId() . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility='" . VISIBILITY_NORMAL . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
                 //BOF:mod 20120911
                 */
                 $query_condition = " where not exists(select * from healingcrystals_project_object_categories obj where obj.object_id=a.id) and a.project_id='" . $this->active_project->getId() . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility>='" . $this->logged_user->getVisibility() . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
                 //EOF:mod 20120911
             } elseif ($cur_department == '-99') {
                 //BOF:mod #59_266
                 /*
                 //EOF:mod #59_266
                 $query = "select a.id as ticket_id, b.id as milestone_id, ifnull(a.priority, '0') from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id left join healingcrystals_project_milestone_categories dep on a.project_id=dep.project_id left join healingcrystals_project_object_categories obj on (dep.id=obj.category_id and a.id=obj.object_id) " ;
                 //BOF:mod #59_266
                 */
                 $query = "select distinct a.id as ticket_id, b.id as milestone_id, cast(ifnull(a.priority, '0') as signed integer) as priority ::CONTENT_PLACE_HOLDER:: from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id left join healingcrystals_project_milestone_categories dep on a.project_id=dep.project_id left join healingcrystals_project_object_categories obj on (dep.id=obj.category_id and a.id=obj.object_id) ";
                 //EOF:mod #59_266
                 $query_condition = " where a.project_id='" . $this->active_project->getId() . "' and a.type='Ticket' and a.completed_on is not null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
             } else {
                 //BOF:mod #59_266
                 /*
                 //EOF:mod #59_266
                 $query = "select a.id as ticket_id, b.id as milestone_id, ifnull(a.priority, '0') from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id inner join healingcrystals_project_milestone_categories dep on a.project_id=dep.project_id inner join healingcrystals_project_object_categories obj on (dep.id=obj.category_id and a.id=obj.object_id) " ;
                 //BOF:mod #59_266
                 */
                 $query = "select distinct a.id as ticket_id, b.id as milestone_id, cast(ifnull(a.priority, '0') as signed integer) as priority ::CONTENT_PLACE_HOLDER:: from healingcrystals_project_objects a left join healingcrystals_project_objects b on a.milestone_id=b.id inner join healingcrystals_project_milestone_categories dep on a.project_id=dep.project_id inner join healingcrystals_project_object_categories obj on (dep.id=obj.category_id and a.id=obj.object_id) ";
                 //EOF:mod #59_266
                 //BOF:mod 20120911
                 /*
                 //EOF:mod 20120911
                                 $query_condition = " where a.project_id='" . $this->active_project->getId() . "' and dep.id='" . $cur_department . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility='" . VISIBILITY_NORMAL . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
                 //BOF:mod 20120911
                 */
                 $query_condition = " where a.project_id='" . $this->active_project->getId() . "' and dep.id='" . $cur_department . "' and a.type='Ticket' and a.state='" . STATE_VISIBLE . "' and a.visibility>='" . $this->logged_user->getVisibility() . "' and a.completed_on is null " . ($this->active_category && $this->active_category->isLoaded() ? " and a.parent_id='" . $this->active_category->getId() . "' " : "") . (!empty($mID) ? " and b.id='" . $mID . "'" : "");
                 //EOF:mod 20120911
             }
         }
         //BOF:mod #59_266
         /*
         //EOF:mod #59_266
         $result = mysql_query($query . $query_condition);
         $total_tickets = mysql_num_rows($result);
         $total_pages = ceil($total_tickets / $limit);
         if ($sort_by=='category'){
         //BOF:mod #59_266
         */
         if ($sort_by == 'category' || $sort_by == 'milestone') {
             if ($sort_by == 'category') {
                 $query_1 = str_replace('::CONTENT_PLACE_HOLDER::', '', $query) . $query_condition;
             } else {
                 $query_1 = str_replace('::CONTENT_PLACE_HOLDER::', ", (select max(created_on) from healingcrystals_project_objects c where c.type='Comment' and c.parent_id=a.id) as comment_date", $query) . $query_condition;
             }
             $result_temp = mysql_query($query_1);
             $total_tickets = mysql_num_rows($result_temp);
             $total_pages = ceil($total_tickets / $limit);
             if ($sort_by == 'category') {
                 //$query_1 .= " order by isnull(b.id), b.name, a.position, priority desc limit " . $offset . ", " . $limit;
                 $query_1 .= " order by isnull(b.id), b.name, priority desc, a.position limit " . $offset . ", " . $limit;
             } else {
                 $query_1 .= " order by isnull(b.id), b.name, priority desc, comment_date desc limit " . $offset . ", " . $limit;
             }
             /*
             //EOF:mod #59_266
                 $query_1 = $query . $query_condition . " order by isnull(b.id), b.name, a.priority desc limit " . $offset . ", " . $limit;
             //BOF:mod #59_266
             */
             //EOF:mod #59_266
             $result = mysql_query($query_1, $link);
             $cur_milestone_id = -1;
             while ($ticket = mysql_fetch_assoc($result)) {
                 if ($cur_milestone_id == -1 || $cur_milestone_id != (int) $ticket['milestone_id']) {
                     $cur_milestone_id = (int) $ticket['milestone_id'];
                     if ($cur_milestone_id == 0) {
                         $cur_milestone_ref = null;
                     } else {
                         $cur_milestone_ref = new Milestone($ticket['milestone_id']);
                     }
                     $tickets[] = array('milestone' => $cur_milestone_ref, 'objects' => array());
                 }
                 $tickets[count($tickets) - 1]['objects'][] = new Ticket($ticket['ticket_id']);
             }
         } elseif ($sort_by == 'star' || $sort_by == 'priority' || $sort_by == 'name' || $sort_by == 'owner') {
             //BOF:mod #59_266
             $query = str_replace('::CONTENT_PLACE_HOLDER::', '', $query);
             $result_temp = mysql_query($query . $query_condition);
             $total_tickets = mysql_num_rows($result_temp);
             $total_pages = ceil($total_tickets / $limit);
             //EOF:mod #59_266
             switch ($sort_by) {
                 case 'star':
                     $query_1 = $query . " left join healingcrystals_starred_objects c on (a.id=c.object_id and c.user_id='" . $this->logged_user->getId() . "') left join healingcrystals_assignments d on (a.id=d.object_id and d.is_owner='1') left join healingcrystals_users e on d.user_id=e.id " . $query_condition . " order by isnull(c.object_id), 3 desc, isnull(e.first_name), e.first_name limit " . $offset . ", " . $limit;
                     break;
                 case 'priority':
                     $query_1 = $query . " left join healingcrystals_assignments d on (a.id=d.object_id and d.is_owner='1') left join healingcrystals_users e on d.user_id=e.id " . $query_condition . " order by 3 desc, isnull(e.first_name), e.first_name, a.name limit " . $offset . ", " . $limit;
                     break;
                 case 'name':
                     $query_1 = $query . $query_condition . " order by a.name limit " . $offset . ", " . $limit;
                     break;
                 case 'owner':
                     $query_1 = $query . " left join healingcrystals_assignments d on (a.id=d.object_id and d.is_owner='1') left join healingcrystals_users e on d.user_id=e.id " . $query_condition . " order by isnull(e.first_name), e.first_name, 3 desc, a.name limit " . $offset . ", " . $limit;
                     break;
             }
             $result = mysql_query($query_1, $link);
             while ($ticket = mysql_fetch_assoc($result)) {
                 $cur_milestone_id = (int) $ticket['milestone_id'];
                 if ($cur_milestone_id == 0) {
                     $cur_milestone_ref = null;
                 } else {
                     $cur_milestone_ref = new Milestone($ticket['milestone_id']);
                 }
                 $tickets[] = array('milestone' => $cur_milestone_ref, 'ticket' => new Ticket($ticket['ticket_id']));
             }
         }
         //} // if
         $all_milestones = array();
         //BOF:mod 20120911
         /*
         //EOF:mod 20120911
                 $query = "select id, name from healingcrystals_project_objects where project_id='" . $this->active_project->getId() . "' and type='Milestone' and state='" . STATE_VISIBLE . "' and visibility='" . VISIBILITY_NORMAL . "' and completed_on is null order by name";
         //BOF:mod 20120911
         */
         $query = "select id, name from healingcrystals_project_objects where project_id='" . $this->active_project->getId() . "' and type='Milestone' and state='" . STATE_VISIBLE . "' and visibility>='" . $this->logged_user->getVisibility() . "' and completed_on is null order by name";
         //EOF:mod 20120911
         $result = mysql_query($query, $link);
         while ($milestone = mysql_fetch_assoc($result)) {
             $all_milestones[] = array('id' => $milestone['id'], 'name' => $milestone['name']);
         }
         $departments = array();
         $query = "select id, category_name from healingcrystals_project_milestone_categories where project_id='" . $this->active_project->getId() . "' order by category_name";
         $result = mysql_query($query);
         while ($department = mysql_fetch_assoc($result)) {
             $departments[] = array('department_id' => $department['id'], 'department_name' => $department['category_name']);
         }
         $departments[] = array('department_id' => '-1', 'department_name' => 'Uncategorized');
         mysql_close($link);
         $this->smarty->assign(array('categories' => Categories::findByModuleSection($this->active_project, TICKETS_MODULE, 'tickets'), 'groupped_tickets' => $tickets, 'milestones' => Milestones::findActiveByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility()), 'can_add_ticket' => Ticket::canAdd($this->logged_user, $this->active_project), 'can_manage_categories' => $this->logged_user->isProjectLeader($this->active_project) || $this->logged_user->isProjectManager(), 'departments_url' => assemble_url('project_manage_milestone_categories', array('project_id' => $this->active_project->getId())), 'total_tickets' => $total_tickets, 'total_pages' => $total_pages, 'current_page' => $page, 'all_milestones' => $all_milestones, 'current_milestone' => $mID, 'sort_by' => $sort_by, 'departments' => $departments, 'current_department_id' => $cur_department));
         js_assign('can_manage_tickets', Ticket::canManage($this->logged_user, $this->active_project));
     }
     // if
 }
 /**
  * Show checklists page
  *
  * @param void
  * @return null
  */
 function index()
 {
     $checklists = Checklists::findActiveByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility());
     if ($this->request->isApiCall()) {
         $this->serveData($checklists, 'checklists');
     } else {
         $selected_category_id = $_GET['category_id'];
         $departments = Checklists::getItemsByDepartment($this->active_project->getId(), new Checklist());
         $this->smarty->assign('departments', $departments);
         $this->smarty->assign('selected_category_id', $selected_category_id);
         $this->smarty->assign('categories_url', assemble_url('project_manage_milestone_categories', array('project_id' => $this->active_project->getId())));
         //$this->smarty->assign('checklists', $checklists);
     }
     // if
     js_assign('can_manage_checklists', Checklist::canReorder($this->logged_user, $this->active_project));
     js_assign('reorder_checklists_url', assemble_url('project_checklists_reorder', array('project_id' => $this->active_project->getId())), null, array('id' => 'reorder_checklists'));
     js_assign('expander_collapsed', get_image_url('expand_collapsed.gif'));
     js_assign('expander_expanded', get_image_url('expand_expanded.gif'));
 }
 /**
  * Contruct tax Invoicing settings controller
  *
  * @param Request $request
  * @return InvoicingSettingsAdminController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $this->wireframe->addBreadCrumb(lang('Invoicing PDF Settings'), assemble_url('admin_invoicing_pdf'));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
 /**
  * Reorder pages
  * 
  * @param void
  * @return null
  */
 function reorder()
 {
     $this->skip_layout = $this->request->isAsyncCall();
     if (!$this->active_category->isLoaded()) {
         $this->httpError(HTTP_ERR_BAD_REQUEST);
     }
     // if
     $ordered_pages = $this->request->post('ordered_pages');
     $layout_pages = Pages::findByCategory($this->active_category, STATE_VISIBLE, $this->logged_user->getVisibility());
     js_assign('is_async_call', $this->request->isAsyncCall());
     $this->smarty->assign(array('pages' => $layout_pages, 'opened' => implode(',', $opened), 'reorder_pages_url' => assemble_url('project_pages_reorder', array('project_id' => $this->active_project->getId(), 'category_id' => $this->active_category->getId()))));
     if ($this->request->isSubmitted()) {
         if (is_foreachable($ordered_pages)) {
             $sorted_pages = array();
             $positions = array();
             foreach ($ordered_pages as $ordered_page_id => $ordered_page_parent_id) {
                 $ordered_page_parent_id = $ordered_page_parent_id ? $ordered_page_parent_id : $this->active_category->getId();
                 $position = array_var($positions, $ordered_page_parent_id, 1);
                 $sorted_pages[$ordered_page_id] = array('position' => $position, 'parent_id' => $ordered_page_parent_id);
                 $position++;
                 $positions[$ordered_page_parent_id] = $position;
             }
             // if
             $pages = Pages::findByIds(array_keys($ordered_pages), STATE_VISIBLE, $this->logged_user->getVisibility());
             if (is_foreachable($pages)) {
                 foreach ($pages as $page) {
                     if (isset($sorted_pages[$page->getId()])) {
                         $page->setPosition(array_var($sorted_pages[$page->getId()], 'position'));
                         $parent_id = array_var($sorted_pages[$page->getId()], 'parent_id');
                         if ($parent_id) {
                             $page->setParentId($parent_id);
                         }
                         // if
                         $page->save();
                     }
                     // if
                 }
                 // foreach
             }
             // if
         }
         // if
         if ($this->request->isAsyncCall()) {
             $per_page = 30;
             $page = (int) $this->request->get('page');
             if ($page < 1) {
                 $page = 1;
             }
             // if
             if ($this->active_category->isLoaded()) {
                 $this->setTemplate(array('module' => PAGES_MODULE, 'controller' => 'pages', 'template' => 'category'));
                 $this->smarty->assign(array('pages' => Pages::findByCategory($this->active_category, STATE_VISIBLE, $this->logged_user->getVisibility()), 'categories' => Categories::findByModuleSection($this->active_project, PAGES_MODULE, 'pages'), 'can_manage_categories' => $this->logged_user->isProjectLeader($this->active_project) || $this->logged_user->isProjectManager()));
             }
             // if
         }
         // if
     }
     // if submitted
 }
 /**
  * Repository history
  *
  * @return void
  * @author Chris Conover
  **/
 function history()
 {
     $page = intval(array_var($_GET, 'page')) > 0 ? array_var($_GET, 'page') : 1;
     $branch_tag = strval(array_var($_GET, 'branch_tag')) != '' ? array_var($_GET, 'branch_tag') : 'master';
     js_assign('commit_filepath_url', assemble_url('github_commit_filepaths', array('project_id' => $this->active_project->getId(), 'github_repository_id' => $this->active_repository->getID())));
     $commits = $this->active_repository->getBranchTagCommits($branch_tag, $page);
     // Group commits by days
     $grouped_commits = array();
     $date_format = 'F j. Y';
     foreach ($commits as $commit) {
         $commit->short_id = substr($commit->id, 0, 9) . '...' . substr($commit->id, -9);
         $commit->message = $this->analyzeCommitMessage($commit->message);
         $commit_formatted_date = date($date_format, strtotime($commit->committed_date));
         if (count($grouped_commits) == 0 || !isset($grouped_commits[$commit_formatted_date])) {
             $grouped_commits[$commit_formatted_date] = array($commit);
         } else {
             array_push($grouped_commits[$commit_formatted_date], $commit);
         }
     }
     $this->smarty->assign(array('path_info' => strval(array_var($_GET, 'path_info')), 'page' => $page, 'next_page' => $page + 1, 'prev_page' => $page > 1 ? $page - 1 : null, 'branches' => $this->active_repository->getBranches(), 'tags' => $this->active_repository->getTags(), 'commits' => $grouped_commits, 'user' => $this->active_repository->getUserName(), 'repo' => $this->active_repository->getRepoName(), 'branch_tag' => $branch_tag));
 }
 /**
  * Show timetracking module homepage
  *
  * @param void
  * @return null
  */
 function index()
 {
     if ($this->request->isApiCall()) {
         $this->serveData(TimeRecords::findByProject($this->active_project, STATE_VISIBLE, $this->logged_user->getVisibility()), 'time_records');
     } else {
         // Content for widget popup
         if ($this->request->get('for_popup_dialog')) {
             $this->_render_popup_content();
             // Classic page
         } else {
             if (instance_of($this->active_object, 'ProjectObject')) {
                 $this->wireframe->addPageMessage(lang('Time spent on <a href=":url">:name</a> :type', array('url' => $this->active_object->getViewUrl(), 'name' => $this->active_object->getName(), 'type' => $this->active_object->getVerboseType(true))), 'info');
             }
             // if
             $timetracking_data = array('record_date' => new DateValue(time() + get_user_gmt_offset($this->logged_user)), 'user_id' => $this->logged_user->getId());
             $per_page = 20;
             $page = (int) $this->request->get('page');
             if ($page < 1) {
                 $page = 1;
             }
             // if
             if (instance_of($this->active_object, 'ProjectObject')) {
                 list($timerecords, $pagination) = TimeRecords::paginateByObject($this->active_object, $page, $per_page, STATE_VISIBLE, $this->logged_user->getVisibility());
             } else {
                 list($timerecords, $pagination) = TimeRecords::paginateByProject($this->active_project, $page, $per_page, STATE_VISIBLE, $this->logged_user->getVisibility());
             }
             // if
             // Mark this objects as read
             if (is_foreachable($timerecords)) {
                 foreach ($timerecords as $timerecord) {
                     ProjectObjectViews::log($timerecord, $this->logged_user);
                 }
                 // foreach
             }
             // if
             $this->smarty->assign(array('timetracking_data' => $timetracking_data, 'timerecords' => $timerecords, 'pagination' => $pagination, 'can_add' => TimeRecord::canAdd($this->logged_user, $this->active_project)));
             js_assign('mass_update_url', assemble_url('project_time_mass_update', array('project_id' => $this->active_project->getId())));
         }
         // if
     }
     // if
 }
 /**
  * Edit repository
  *
  * @param null
  * @return void
  */
 function edit()
 {
     if (!$this->active_repository->canEdit($this->logged_user)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $repository_data = $this->request->post('repository');
     if (!is_array($repository_data)) {
         $repository_data = array('name' => $this->active_repository->getName(), 'url' => $this->active_repository->getUrl(), 'username' => $this->active_repository->getUsername(), 'password' => $this->active_repository->getPassword(), 'repositorytype' => $this->active_repository->getRepositoryType(), 'updatetype' => $this->active_repository->getUpdateType(), 'visibility' => $this->active_repository->getVisibility());
     }
     if ($this->request->isSubmitted()) {
         db_begin_work();
         $this->active_repository->setAttributes($repository_data);
         $this->active_repository->loadEngine($this->active_repository->getRepositoryType());
         $this->repository_engine = new RepositoryEngine($this->active_repository);
         $this->repository_engine->triggerred_by_handler = true;
         $result = $this->repository_engine->testRepositoryConnection();
         if ($result === true) {
             $save = $this->active_repository->save();
             if ($save && !is_error($save)) {
                 db_commit();
                 flash_success(lang('Repository has been successfully updated'));
                 $this->redirectToUrl($this->active_repository->getHistoryUrl());
             } else {
                 db_rollback();
                 $this->smarty->assign('errors', $save);
             }
             //if
         } else {
             db_rollback();
             $errors = new ValidationErrors();
             $errors->addError(lang('Failed to connect to repository: :message', array('message' => $result)));
             $this->smarty->assign('errors', $errors);
         }
         // if
     }
     // if
     js_assign('repository_test_connection_url', assemble_url('repository_test_connection', array('project_id' => $this->active_project->getId())));
     $this->smarty->assign(array('types' => $this->active_repository->types, 'update_types' => $this->active_repository->update_types, 'repository_data' => $repository_data, 'active_repository' => $this->active_repository, 'disable_url_and_type' => instance_of($this->active_repository->getLastCommit(), 'Commit'), 'aid_url' => lang('The path to the existing repository cannot be changed'), 'aid_engine' => lang('Repository type cannot be changed')));
 }
 /**
  * Show module details page
  *
  * @param void
  * @return null
  */
 function module()
 {
     js_assign('invoicing_precision', INVOICE_PRECISION);
     $this->smarty->assign('roles', Roles::findSystemRoles());
 }
 /**
  * Conflict incoming mail
  * 
  * @param void
  * @return void
  */
 function conflict()
 {
     if ($this->active_mail->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     require_once INCOMING_MAIL_MODULE_PATH . '/models/IncomingMailImporter.class.php';
     $mail_data = $this->request->post('mail');
     if (!is_foreachable($mail_data)) {
         flash_error(incoming_mail_module_get_status_description($this->active_mail->getState()));
         $mail_data = array('subject' => $this->active_mail->getSubject(), 'body' => $this->active_mail->getBody(), 'created_by_id' => $this->active_mail->getCreatedById(), 'project_id' => $this->active_mail->getProjectId());
     }
     // if
     if ($this->request->isSubmitted()) {
         $this->active_mail->setSubject(array_var($mail_data, 'subject'));
         $this->active_mail->setBody(array_var($mail_data, 'body'));
         $creator_id = array_var($mail_data, 'created_by_id');
         if ($creator_id && $creator_id != 'original_author') {
             $creator = Users::findById($creator_id);
             if (instance_of($creator, 'User')) {
                 $this->active_mail->setCreatedBy($creator);
             }
             // if
         }
         // if
         $this->active_mail->setCreatedById(array_var($mail_data, 'created_by_id'));
         $this->active_mail->setObjectType(array_var($mail_data, 'object_type'));
         if (array_var($mail_data, 'object_type') == 'comment') {
             $this->active_mail->setParentId(array_var($mail_data, 'parent_id'));
         }
         // if
         // import email
         if (instance_of($importing_result = IncomingMailImporter::importPendingEmail($this->active_mail, $creator_id == 'original_author'), 'ProjectObject')) {
             // we have successfully imported email
             $this->active_mail->delete();
             if ($this->request->isAsyncCall()) {
                 $this->renderText(lang('<p>Conflict Solved Successfully!</p><p>View created <a href=":url">:object</a>.</p>', array('object' => $this->active_mail->getObjectType(), 'url' => $importing_result->getViewUrl())));
             } else {
                 flash_success('Conflict Solved Successfully!');
                 $this->redirectTo('incoming_mail');
             }
             // if
         } else {
             if ($this->request->isAsyncCall()) {
                 $this->httpError(HTTP_ERR_INVALID_PROPERTIES, null, false, 2);
             } else {
                 flash_error($importing_result->getMessage());
             }
             // if
         }
         // if
     }
     // if
     $user = $this->active_mail->getCreatedBy();
     if (instance_of($user, 'User')) {
         $this->smarty->assign('object_user', $user);
     } else {
         $this->smarty->assign('object_user', $this->logged_user);
     }
     // if
     $this->smarty->assign(array('async' => $this->request->isAsyncCall(), 'form_url' => $this->active_mail->getImportUrl() . ($this->request->isAsyncCall() ? '?skip_layout=1&async=1' : ''), 'status_message' => incoming_mail_module_get_status_description($this->active_mail->getState()), 'mail_data' => $mail_data, 'project' => $this->active_mail->getProject()));
     $flash =& Flash::instance();
     $flash->init();
     js_assign('additional_fields_url', assemble_url('incoming_mail_additional_form_fields'));
 }
 /**
  * Update existing invoice
  *
  * @param void
  * @return null
  */
 function edit()
 {
     $this->wireframe->print_button = false;
     if ($this->active_invoice->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     if (!$this->active_invoice->canEdit($this->logged_user)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $invoice_data = $this->request->post('invoice');
     if (!is_array($invoice_data)) {
         $invoice_data = array('number' => $this->active_invoice->getNumber(), 'due_on' => $this->active_invoice->getDueOn(), 'issued_on' => $this->active_invoice->getIssuedOn(), 'currency_id' => $this->active_invoice->getCurrencyId(), 'comment' => $this->active_invoice->getComment(), 'company_id' => $this->active_invoice->getCompanyId(), 'company_address' => $this->active_invoice->getCompanyAddress(), 'project_id' => $this->active_invoice->getProjectId(), 'note' => $this->active_invoice->getNote(), 'language_id' => $this->active_invoice->getLanguageId());
         if (is_foreachable($this->active_invoice->getItems())) {
             $invoice_data['items'] = array();
             foreach ($this->active_invoice->getItems() as $item) {
                 $invoice_data['items'][] = array('description' => $item->getDescription(), 'unit_cost' => $item->getUnitCost(), 'quantity' => $item->getQuantity(), 'tax_rate_id' => $item->getTaxRateId(), 'total' => $item->getTotal(), 'subtotal' => $item->getSubtotal(), 'time_record_ids' => $item->getTimeRecordIds());
             }
             // foreach
         }
         // if
     }
     // if
     $invoice_notes = InvoiceNoteTemplates::findAll();
     $invoice_item_templates = InvoiceItemTemplates::findAll();
     $this->smarty->assign(array('invoice_data' => $invoice_data, 'invoice_item_templates' => $invoice_item_templates, 'tax_rates' => TaxRates::findAll(), 'invoice_notes' => $invoice_notes, 'original_note' => $this->active_invoice->getNote()));
     $cleaned_notes = array();
     if (is_foreachable($invoice_notes)) {
         foreach ($invoice_notes as $invoice_note) {
             $cleaned_notes[$invoice_note->getId()] = $invoice_note->getContent();
         }
         // foreach
     }
     // if
     js_assign('invoice_notes', $cleaned_notes);
     js_assign('original_note', $this->active_invoice->getNote());
     $cleaned_item_templates = array();
     if (is_foreachable($invoice_item_templates)) {
         foreach ($invoice_item_templates as $invoice_item_template) {
             $cleaned_item_templates[$invoice_item_template->getId()] = array('description' => $invoice_item_template->getDescription(), 'unit_cost' => $invoice_item_template->getUnitCost(), 'quantity' => $invoice_item_template->getQuantity(), 'tax_rate_id' => $invoice_item_template->getTaxRateId());
         }
         // foreach
     }
     // if
     js_assign('invoice_item_templates', $cleaned_item_templates);
     js_assign('company_details_url', assemble_url('invoice_company_details'));
     js_assign('move_icon_url', get_image_url('move.gif'));
     if ($this->request->isSubmitted()) {
         $this->active_invoice->setAttributes($invoice_data);
         $invoice_company = Companies::findById(array_var($invoice_data, 'company_id', null));
         $this->active_invoice->setCompanyName($invoice_company->getName());
         $save = $this->active_invoice->save();
         if ($save && !is_error($save)) {
             InvoiceItems::deleteByInvoice($this->active_invoice);
             $counter = 1;
             if (is_foreachable($invoice_data['items'])) {
                 foreach ($invoice_data['items'] as $invoice_item_data) {
                     $invoice_item = new InvoiceItem();
                     $invoice_item->setAttributes($invoice_item_data);
                     $invoice_item->setInvoiceId($this->active_invoice->getId());
                     $invoice_item->setPosition($counter);
                     $item_save = $invoice_item->save();
                     if ($item_save && !is_error($item_save)) {
                         $invoice_item->setTimeRecordIds(array_var($invoice_item_data, 'time_record_ids', null));
                         $counter++;
                     } else {
                         $this->smarty->assign('errors', new ValidationErrors(array('items' => lang('Invoice items data is not valid. All descriptions are required and there need to be at least one unit with cost set per item!'))));
                     }
                     // if
                 }
                 // foreach
                 flash_success('":number" has been updated', array('number' => $this->active_invoice->getName()));
                 if ($this->active_invoice->isIssued()) {
                     $invoice_company = $this->active_invoice->getCompany();
                     if (instance_of($invoice_company, 'Company') && $invoice_company->hasManagers()) {
                         $this->redirectTo('invoice_notify', array('invoice_id' => $this->active_invoice->getId()));
                     }
                     // if
                 }
                 // if
                 $this->redirectToUrl($this->active_invoice->getViewUrl());
             } else {
                 $this->smarty->assign('errors', $save);
             }
             // if
         }
         // if
     }
     // if
 }
 /**
  * Constructor
  *
  * @param Request $request
  * @return ApplicationController
  */
 function __construct($request)
 {
     parent::__construct($request);
     // Set detault layout for application pages
     $this->setLayout(array('module' => SYSTEM_MODULE, 'layout' => 'wireframe'));
     // Get Smarty instance... We need it
     $this->smarty =& Smarty::instance();
     // Load and init owner company
     $this->owner_company = get_owner_company();
     if (instance_of($this->owner_company, 'Company')) {
         cache_set('owner_company', $this->owner_company);
     } else {
         $this->httpError(HTTP_ERR_NOT_FOUND, 'Owner company is not defined');
     }
     // if
     $this->application =& application();
     $this->authentication =& Authentication::instance();
     $this->logged_user =& $this->authentication->provider->getUser();
     $this->wireframe =& Wireframe::instance();
     $this->wireframe->page_company = $this->owner_company;
     $this->theme_name = instance_of($this->logged_user, 'User') ? UserConfigOptions::getValue('theme', $this->logged_user) : ConfigOptions::getValue('theme');
     $this->smarty->assign(array('root_url' => ROOT_URL, 'assets_url' => ASSETS_URL));
     // Maintenance mode
     if (ConfigOptions::getValue('maintenance_enabled')) {
         if (instance_of($this->logged_user, 'User') && $this->logged_user->isAdministrator()) {
             $this->wireframe->addPageMessage(lang('System is in maintenance mode and can be used by administrators only. <a href=":url">Click here</a> to turn off maintenance mode', array('url' => assemble_url('admin_settings_maintenance'))), 'warning');
         } else {
             $additional_error_info = ConfigOptions::getValue('maintenance_message');
             if ($additional_error_info) {
                 $additional_error_info .= "\n\n";
             }
             // if
             $additional_error_info .= lang('When system is in maintenance mode, administrators can log in and access the system') . ": " . assemble_url('login');
             $this->smarty->assign('additional_error_info', $additional_error_info);
             if ($this->restrict_access_in_maintenance_mode) {
                 $this->httpError(503);
             }
             // if
         }
         // if
     }
     // if
     // Check permissions
     if ($this->login_required && !instance_of($this->logged_user, 'User')) {
         // If async don't redirect to loging, just server proper HTTP code
         if ($this->request->isAsyncCall()) {
             $this->httpError(HTTP_ERR_UNAUTHORIZED, null, true, true);
             // Not async? Redirect to login with extracted route data...
         } else {
             $params = array();
             if ($request->matched_route != 'login') {
                 $params['re_route'] = $request->matched_route;
                 foreach ($this->request->url_params as $k => $v) {
                     if ($k == 'module' || $k == 'controller' || $k == 'action') {
                         continue;
                     }
                     // if
                     $params["re_{$k}"] = $v;
                 }
                 // foreach
             }
             // if
             $this->redirectTo($this->login_route, $params);
         }
         // if
     }
     // if
     if (instance_of($this->logged_user, 'User') && !$this->logged_user->getSystemPermission('system_access')) {
         $this->authentication->provider->logUserOut();
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $loaded_modules = $this->application->getModules();
     $assets_query_string = 'v=' . $this->application->version . '&modules=';
     foreach ($loaded_modules as $loaded_module) {
         $assets_query_string .= $loaded_module->getName() . ',';
     }
     // foreach
     $this->smarty->assign(array('api_status' => API_STATUS, 'application' => $this->application, 'owner_company' => $this->owner_company, 'authentication' => $this->authentication, 'logged_user' => $this->logged_user, 'request' => $this->request, 'theme_name' => $this->theme_name, 'request_time' => $this->request_time, 'loaded_modules' => $this->application->getModules(), 'captcha_url' => ROOT_URL . '/captcha.php?id=' . md5(time()), 'assets_query_string' => $assets_query_string, 'js_disabled_url' => assemble_url('js_disabled')));
     $this->smarty->assign_by_ref('wireframe', $this->wireframe);
     js_assign(array('homepage_url' => ROOT_URL, 'assets_url' => ASSETS_URL, 'indicator_url' => get_image_url('indicator.gif'), 'big_indicator_url' => get_image_url('indicator_big.gif'), 'ok_indicator_url' => get_image_url('ok_indicator.gif'), 'warning_indicator_url' => get_image_url('warning_indicator.gif'), 'error_indicator_url' => get_image_url('error_indicator.gif'), 'pending_indicator_url' => get_image_url('pending_indicator.gif'), 'url_base' => URL_BASE, 'keep_alive_interval' => KEEP_ALIVE_INTERVAL, 'refresh_session_url' => assemble_url('refresh_session'), 'jump_to_project_url' => assemble_url('jump_to_project_widget'), 'quick_add_url' => assemble_url('quick_add'), 'path_info_through_query_string' => PATH_INFO_THROUGH_QUERY_STRING, 'image_picker_url' => assemble_url('image_picker'), 'copyright_removed' => LICENSE_COPYRIGHT_REMOVED, 'custom_tabs_manager' => assemble_url('custom_tabs_manager'), 'add_milestone_url' => assemble_url('project_milestones_add', array('project_id' => '--PROJECT_ID--')), 'add_checklist_url' => assemble_url('project_checklists_add', array('project_id' => '--PROJECT_ID--')), 'add_discussion_url' => assemble_url('project_discussions_add', array('project_id' => '--PROJECT_ID--')), 'add_file_url' => assemble_url('project_files_upload', array('project_id' => '--PROJECT_ID--')), 'add_page_url' => assemble_url('project_pages_add', array('project_id' => '--PROJECT_ID--')), 'add_ticket_url' => assemble_url('project_tickets_add', array('project_id' => '--PROJECT_ID--')), 'add_timerecord_url' => assemble_url('project_time_add', array('project_id' => '--PROJECT_ID--')), 'attachment_rename_url' => assemble_url('attachment_rename', array('project_id' => '--PROJECT_ID--', 'attachment_id' => '--ATTACHMENT_ID--')), 'attachment_copy_to_url' => assemble_url('attachment_copy_to', array('project_id' => '--PROJECT_ID--', 'attachment_id' => '--ATTACHMENT_ID--')), 'attachment_move_to_url' => assemble_url('attachment_move_to', array('project_id' => '--PROJECT_ID--', 'attachment_id' => '--ATTACHMENT_ID--')), 'image_uploader_url' => assemble_url('image_uploader'), 'render_comments_url' => assemble_url('render_comments'), 'move_task_url' => assemble_url('project_task_move', array('project_id' => '--PROJECT_ID--', 'task_id' => '--TASK_ID--')), 'get_collection_url' => assemble_url('collection'), 'quick_task_reminder_url' => assemble_url('project_task_quickreminder', array('project_id' => '--PROJECT_ID--', 'task_id' => '--TASK_ID--')), 'convert_to_ticket_url' => assemble_url('project_object_convert_to_ticket', array('project_id' => '--PROJECT_ID--', 'object_id' => '--OBJECT_ID--')), 'convert_to_milestone_url' => assemble_url('project_object_convert_to_milestone', array('project_id' => '--PROJECT_ID--', 'object_id' => '--OBJECT_ID--')), 'convert_to_page_url' => assemble_url('project_object_convert_to_page', array('project_id' => '--PROJECT_ID--', 'object_id' => '--OBJECT_ID--')), 'snooze_task_url' => assemble_url('project_task_snooze', array('project_id' => '--PROJECT_ID--', 'task_id' => '--TASK_ID--'))));
     if ($this->logged_user) {
         $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
         mysql_select_db(DB_NAME);
         if (!empty($_SESSION['pg_ttl'])) {
             mysql_query("update healingcrystals_user_visited_pages set title='" . mysql_real_escape_string($_SESSION['pg_ttl']) . "' where user_id='" . $this->logged_user->getId() . "' and access_time='" . date('Y-m-d H:i:s', $_SESSION['temp_time']) . "'");
         }
         $current_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
         $pos = strpos($_SERVER['QUERY_STRING'], '%2F');
         if ($pos !== false) {
             $max_pages_count_per_user = 50;
             //require_once SMARTY_PATH . '/plugins/function.page_title.php';
             //$current_page_title = smarty_function_page_title(array('default' => 'Projects'));
             //$current_page_title = PageConstruction::getPageTitle();
             $_SESSION['temp_time'] = time();
             mysql_query("insert into healingcrystals_user_visited_pages (user_id, page_url, title, access_time) values ('" . $this->logged_user->getId() . "', '" . $current_url . "', '', '" . date('Y-m-d H:i:s', $_SESSION['temp_time']) . "')");
             //mysql_query("insert into healingcrystals_user_visited_pages (user_id, page_url, title, access_time) values ('" . $this->logged_user->getId() . "', '" . $current_url . "', '', now())");
             $query = "select count(*) as count from healingcrystals_user_visited_pages where user_id='" . $this->logged_user->getId() . "'";
             $result = mysql_query($query);
             $info = mysql_fetch_assoc($result);
             $current_count = $info['count'];
             if ($current_count > $max_pages_count_per_user) {
                 $querries = array();
                 $query = "select * from healingcrystals_user_visited_pages where user_id='" . $this->logged_user->getId() . "' order by access_time limit 0, " . ($current_count - $max_pages_count_per_user);
                 $result = mysql_query($query);
                 while ($info = mysql_fetch_assoc($result)) {
                     $querries[] = "delete from healingcrystals_user_visited_pages where user_id='" . $this->logged_user->getId() . "' and page_url='" . $info['page_url'] . "' and access_time='" . $info['access_time'] . "'";
                 }
             }
             foreach ($querries as $query) {
                 mysql_query($query);
             }
         }
         $_SESSION['pg_ttl'] = '';
         mysql_close($link);
     }
 }
 /**
  * Construct invoices archive controller
  *
  * @param Request $request
  * @return InvoicesArchiveController
  */
 function __construct($request)
 {
     parent::__construct($request);
     $this->wireframe->addBreadCrumb(lang('Archive'), assemble_url('invoices_archive'));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }