public function run() { // process any search data that may be passed if (is_array($this->_data['Search']) && isset($this->_data['Search']['report_id'])) { $this->_data[$this->_templateobject->idField] = $this->_data['Search']['report_id']; unset($this->_data['Search']['report_id']); } if (!$this->loadData()) { $this->dataError(); sendBack(); } $flash = Flash::Instance(); // get the report model, lets not envoke it again... that's not cool $report = $this->_uses[$this->modeltype]; // there's no point in processing all the following data just to display the dialog... display it now if (isset($this->_data['printaction']) || isset($this->_data['printAction']) || isset($this->_data['ajax_print'])) { // build options array $defs = ReportDefinition::getDefinition('PrintCollection'); $dialog_options = array('type' => array('pdf' => '', 'xml' => '', 'csv' => ''), 'output' => array('print' => '', 'save' => '', 'email' => '', 'view' => ''), 'filename' => strtolower(str_replace(" ", "_", $report->description)) . '_' . date('d-m-Y')); // if ajax_print is not set we must be on the dialog if (!isset($this->_data['ajax_print'])) { return $dialog_options; } } // give smarty the title $this->view->set('title', $report->description); // unserialise the options from the db $options = unserialize($report->options); // overlay the defaults so we've got a full set of options $options = $this->expand_options($options, $report->tablename); // sort options by position $options = $this->sort_options($options); // vars $aggregate_fields = array(); $at_agg = FALSE; $fields = array(); $display_fields = array(); $measure_fields = array(); $search_fields = array(); $filter_fields = array(); $aggregate_methods = array(); // build arrays for use in the view foreach ($options as $field => $field_options) { // we need to check against legacy search options if ($field_options['field_type'] === 'search') { $flash->addError('Report has legacy search fields, please edit this report to update'); sendBack(); } // ignore the filter field... it really isn't a field if ($field == 'filter') { continue; } // iron out the field label if it exists if (isset($field_options['field_label']) && !empty($field_options['field_label'])) { $label = $field_options['field_label']; } else { $label = $field; } $position = $field_options['position']; // we're always dealing with normal fields now // no need for a switch statement // ignore fields that aren't meant to be displayed if ($field_options['normal_display_field'] !== 'false') { // build two arrays, the display fields array will include filter fields... for now $original_fields[$position] = $field; $display_fields[$position] = $field; if ($field_options['normal_break_on'] === "true") { $measure_fields[$position] = $field; } if (!empty($field_options['normal_method']) && $field_options['normal_method'] !== 'dont_total') { $aggregate_fields[$position] = $field; $aggregate_methods[$position] = $field_options['normal_method'] . '(' . $field . ') as ' . $field; // if we're setting an aggregate field... this must not be a display field unset($display_fields[$position]); } } // if the field is also a search field, add it to the search array if (isset($field_options['normal_enable_search']) && $field_options['normal_enable_search'] === 'true') { $search_fields[$field] = $field_options; } } // if the filters aren't empty, apply them one by one if (!empty($options['filter'])) { // loop through filter lines foreach (range(1, 3) as $number) { if (!isset($filter_cc)) { $filter_cc = new ConstraintChain(); } // filter line 1 will never have an operator if ($number === 1) { $operator = 'AND'; } else { $operator = $options['filter']['filter_' . $number . '_operator']; } $field = $options['filter']['filter_' . $number . '_field']; $condition = $options['filter']['filter_' . $number . '_condition']; $value = $options['filter']['filter_' . $number . '_value']; // if we're dealing with a valid filter line... if (($number === 1 or !empty($operator)) and !empty($value)) { // add the field to the display fields if (!array_search($field, $display_fields)) { $display_fields = array_merge($display_fields, array($field)); } // add the filter to the contraint chain $filter_cc->add(new Constraint($field, $condition, $value), $operator); } } } // NB: The follow idField is being passed by reference... it isn't passing a value, instead recieving one back $do = $report->createDataObject($display_fields, $idField, $this->getColumns($report->tablename)); $doc = new DataObjectCollection($do); $sh = new SearchHandler($doc, FALSE); $sh->setGroupby($display_fields); $sh->setOrderby($display_fields); if (!isset($this->_data['Search'])) { $this->_data['Search'] = array(); } // we don't need a condition here... always display the search box $this->search = $report->createSearch($search_fields, $this->_data['Search']); $cc = $this->search->toConstraintChain(); $cc->removeByField('report_id'); $sh->addConstraintChain($cc); // if the filter constraint chain has been set, use it if (isset($filter_cc)) { $sh->addConstraintChain($filter_cc); } $measure_fields = array_merge(array('' => 'report'), $measure_fields); /// merge the aggregate methods array in with the display fields array // the aggregate methods array is preset as an array to allow for empty values // we don't use the array_merge function as we want to maintain keys (representing position) $display_fields = (array) $display_fields + (array) $aggregate_methods; if (count($aggregate_fields) === 0) { $this->view->set('aggregate_count', 0); } // sort display fields by key (position) ksort($display_fields); // prepend the id field to the display fields... // at this stage the items are in order, so keys don't matter $display_fields = array_merge(array($idField), $display_fields); $sh->setFields($display_fields); $data = $doc->load($sh, null, RETURN_ROWS); $this->view->set('total_records', $doc->total_records); $headings = $doc->getHeadings(); // loop through headings... foreach ($headings as $key => $field) { if (!array_search($key, $original_fields)) { // if item isn't in original fields remove it from headings array unset($headings[$key]); } else { // if label exists, use that for heading if (!empty($options[$key]['normal_field_label'])) { $headings[$key] = $options[$key]['normal_field_label']; } } } $heading_keys = array_keys($headings); $this->view->set('headings', $headings); /* * Build the data array * * There is no point in processing everything just to output the * print dialog OR is we're CSVing the output. */ if (!isset($this->_data['printaction']) && !isset($this->_data['printAction']) || $this->_data['print']['printtype'] !== 'csv') { $response = $this->buildArray($data, $headings, $measure_fields, $aggregate_fields, $heading_keys, $options); $data_arr = $response['data_arr']; $sub_total_keys = $response['sub_total_keys']; } $this->view->set('options', $options); // are we being called from a print dialog or are we actually printing? if (isset($this->_data['printaction']) || isset($this->_data['printAction']) || isset($this->_data['ajax_print'])) { if ($this->_data['print']['printtype'] === 'csv') { $dialog_options['csv_source'] = $this->generate_csv($this->_data['print'], $data_arr, array_keys($headings)); } else { // build xml $xml = ''; $xml .= "<data>" . "\n"; if (!empty($data_arr)) { foreach ($data_arr as $key => $row) { // if row is a subtotal, construct an appropriate attribute $row_class = ''; if (isset($sub_total_keys[$key])) { $row_class = 'sub_total="true"'; } // build the xml // cannot utalise all of the output functions as we need to do some specific stuff $xml .= "\t" . "<record " . $row_class . ">" . "\n"; foreach ($row as $field => $value) { $cell_class = array(); if (isset($options[$field]['normal_red_negative_numbers']) && $options[$field]['normal_red_negative_numbers'] == "true" && $value < 0) { $cell_class[] = 'negative_number="true"'; } if ($options[$field]['normal_enable_formatting'] === 'true') { if (isset($options[$field]['normal_justify'])) { $cell_class[] = 'text-align="' . $options[$field]['normal_justify'] . '"'; } } $xml .= "\t\t" . "<" . $field . " " . implode(' ', $cell_class) . ">" . $value . "</" . $field . ">" . "\n"; } $xml .= "\t" . "</record>" . "\n"; } } $xml .= "</data>" . "\n"; // build xsl $col_widths = array(); if (isset($this->_data['col_widths'])) { $col_widths = $this->parse_column_widths($this->_data['col_widths']); } // Use the report defintion defined in DB, else use the standard list xsl if ($report->report_definition) { $def = new ReportDefinition(); $def->loadBy('id', $report->report_definition); $report_definition_name = $def->_data['name']; } else { $report_definition_name = 'PrintCollection'; } $xsl = $this->build_custom_xsl($doc, $report_definition_name, $report->description, $headings, $col_widths, $options); // set resources $dialog_options['xmlSource'] = $xml; $dialog_options['xslSource'] = $xsl; $search_options = $this->search->toString('fop'); if (!empty($search_options)) { $dialog_options['xslVars']['search_string'] = "Search options: " . $search_options; } else { $dialog_options['xslVars']['search_string'] = ''; } } $this->_data['print']['attributes']['orientation-requested'] = 'landscape'; // execute the print output function, echo the returned json for jquery echo $this->generate_output($this->_data['print'], $dialog_options); exit; } $this->view->set('report_array', $data_arr); $this->view->set('sub_total_keys', $sub_total_keys); }
public function select_products() { $s_data = array(); // so set context from calling module if (isset($this->_data['slmaster_id'])) { $s_data['slmaster_id'] = $this->_data['slmaster_id']; } if (isset($this->_data['parent_id'])) { $s_data['parent_id'] = $this->_data['parent_id']; } $this->setSearch('sordersSearch', 'selectProduct', $s_data); $slmaster_id = $this->search->getValue('slmaster_id'); $this->view->set('slmaster_id', $slmaster_id); $slcustomer = DataObjectFactory::Factory('SLCustomer'); if ($slmaster_id > 0) { $slcustomer->load($slmaster_id); } // Get the list of Product Headers for the selected item $product_ids = SelectorCollection::getTargets('sales_order', $this->search->getValue('parent_id')); $product = DataObjectFactory::Factory('SOProductLine'); $product->identifierField = 'productline_header_id'; $cc = new ConstraintChain(); $customer_lines = array(); if ($slcustomer->isLoaded()) { // Get any lines specific for this customer $this->view->set('slcustomer', $slcustomer->companydetail->name); $cc1 = new ConstraintChain(); $cc1->add(new Constraint('slmaster_id', '=', $slcustomer->id)); if (is_null($slcustomer->so_price_type_id)) { $cc1->add(new Constraint('so_price_type_id', 'is', 'NULL')); $cc->add(new Constraint('so_price_type_id', 'is', 'NULL')); } else { $cc1->add(new Constraint('so_price_type_id', '=', $slcustomer->so_price_type_id)); $cc->add(new Constraint('so_price_type_id', '=', $slcustomer->so_price_type_id)); } $cc1->add($product->currentConstraint()); if (!empty($product_ids)) { $cc1->add(new Constraint('productline_header_id', 'in', '(' . implode(',', array_keys($product_ids)) . ')')); } else { $cc1->add(new Constraint('productline_header_id', '=', '-1')); } $customer_lines = $product->getAll($cc1, true, true); // Now exclude any lines for a header where the line for the customer exists if (count($customer_lines) > 0) { $cc->add(new Constraint('productline_header_id', 'not in', '(' . implode(',', $customer_lines) . ')')); } } else { $this->view->set('slcustomer', 'Not Set'); } // Get the non-customer lines, excluding any lines for a header found above for a customer $cc->add(new Constraint('slmaster_id', 'is', 'NULL')); if (!empty($product_ids)) { $cc->add(new Constraint('productline_header_id', 'in', '(' . implode(',', array_keys($product_ids)) . ')')); } else { $cc->add(new Constraint('productline_header_id', '=', '-1')); } $cc->add($product->currentConstraint()); $lines = $product->getAll($cc, true, true); $lines += $customer_lines; $products = new SOProductLineCollection($product); if (!isset($this->_data['orderby']) && !isset($this->_data['page'])) { $sh = new SearchHandler($products, false); $cc2 = new ConstraintChain(); if (count($lines) > 0) { $cc2->add(new Constraint('id', 'in', '(' . implode(',', array_keys($lines)) . ')')); } else { // No lines found, so ensure no rows returned $cc2->add(new Constraint('id', '=', -1)); } $sh->addConstraint($cc2); } else { $sh = new SearchHandler($products); } $sh->extract(); $fields = array('id', 'description', 'price', 'currency', 'uom_name', 'so_price_type', 'stitem_id', 'slmaster_id', 'prod_group_id'); $sh->setFields($fields); $sh->setGroupby($fields); $sh->setOrderby(array('description', 'so_price_type')); parent::index($products, $sh); $this->view->set('stitem', DataObjectFactory::Factory('STItem')); if (empty($this->_data['sorders'])) { $this->_data['sorders'] = array(); } $this->view->set('selected', $this->_data['sorders']); foreach ($this->_modules as $key => $value) { $modules[] = $key . '=' . $value; } $link = implode('&', $modules) . '&controller=' . $this->name . '&action=showProducts'; $this->view->set('link', $link); $selectedproduct = empty($_SESSION['selectedproducts']) ? array() : $_SESSION['selectedproducts']; $selectedproducts = new SOProductLineCollection(DataObjectFactory::Factory('SOProductLine')); if (!empty($selectedproduct)) { $sh = new SearchHandler($selectedproducts, false); $sh->addConstraint(new Constraint('id', 'in', '(' . implode(',', array_keys($selectedproduct)) . ')')); $selectedproducts->load($sh); } $this->view->set('selected', $selectedproduct); $this->view->set('productlines', $selectedproducts); $this->view->set('page_title', $this->getPageName('', 'Select Products for')); }