public function fill_in_additional_detail_fields() { parent::fill_in_additional_detail_fields(); if (empty($this->amount_usdollar) && !empty($this->amount)) { $this->amount_usdollar = SugarCurrency::convertWithRate($this->amount, $this->base_rate); } }
/** * Returns the entire enumeration bare. */ function evaluate() { $params = $this->getParameters(); //This should be of relate type, which means an array of SugarBean objects $linkField = $params[0]->evaluate(); $relfield = $params[1]->evaluate(); if (empty($linkField)) { return ""; } foreach ($linkField as $id => $bean) { if (!empty($bean->field_defs[$relfield]) && isset($bean->{$relfield})) { if (!empty($bean->field_defs[$relfield]['type'])) { global $timedate; if ($bean->field_defs[$relfield]['type'] == "date") { $ret = $timedate->fromDbDate($bean->{$relfield}); if (!$ret) { $ret = $timedate->fromUserDate($bean->{$relfield}); } if ($ret) { $ret->isDate = true; } return $ret; } if ($bean->field_defs[$relfield]['type'] == "datetime" || $bean->field_defs[$relfield]['type'] == "datetimecombo") { $ret = $timedate->fromDb($bean->{$relfield}); if (!$ret) { $ret = $timedate->fromUser($bean->{$relfield}); } return $ret; } if ($bean->field_defs[$relfield]['type'] == "bool") { require_once "include/Expressions/Expression/Boolean/BooleanExpression.php"; if ($bean->{$relfield}) { return BooleanExpression::$TRUE; } else { return BooleanExpression::$FALSE; } } //Currency values need to be converted to the current currency when the related value //doesn't match this records currency if ($bean->field_defs[$relfield]['type'] == "currency") { if (!isset($this->context)) { $this->setContext(); } if (isset($this->context->base_rate) && isset($bean->base_rate) && $this->context->base_rate != $bean->base_rate) { return SugarCurrency::convertWithRate($bean->{$relfield}, $bean->base_rate, $this->context->base_rate); } } } return $bean->{$relfield}; } } return ""; }
/** * Ability only rollup specific values from related records when a field on the related record is equal to * something. * * @return string */ public function evaluate() { $params = $this->getParameters(); // This should be of relate type, which means an array of SugarBean objects $linkField = $params[0]->evaluate(); $relfield = $params[1]->evaluate(); $conditionalField = $params[2]->evaluate(); $conditionalValues = $params[3]->evaluate(); if (!is_array($conditionalValues)) { $conditionalValues = array($conditionalValues); } $ret = '0'; if (!is_array($linkField) || empty($linkField)) { return $ret; } if (!isset($this->context)) { //If we don't have a context provided, we have to guess. This can be a large performance hit. $this->setContext(); } $toRate = isset($this->context->base_rate) ? $this->context->base_rate : null; $checkedTypeForCurrency = false; $relFieldIsCurrency = false; foreach ($linkField as $bean) { if (!in_array($bean->{$conditionalField}, $conditionalValues)) { continue; } // only check the target field once to see if it's a currency field. if ($checkedTypeForCurrency === false) { $checkedTypeForCurrency = true; $relFieldIsCurrency = $this->isCurrencyField($bean, $relfield); } if (!empty($bean->{$relfield})) { $value = $bean->{$relfield}; // if we have a currency field, it needs to convert the value into the rate of the row it's // being returned to. if ($relFieldIsCurrency) { $value = SugarCurrency::convertWithRate($value, $bean->base_rate, $toRate); } $ret = SugarMath::init($ret)->add($value)->result(); } } return $ret; }
/** * @param Opportunity $focus The Current Opportunity we are working with */ function perform_save($focus) { global $app_list_strings, $timedate, $current_language; $app_list_strings = return_app_list_strings_language($current_language); /* @var $admin Administration */ $admin = BeanFactory::getBean('Administration'); $settings = $admin->getConfigForModule('Forecasts'); // if any of the case fields are NULL or an empty string set it to the amount from the main opportunity if (is_null($focus->best_case) || strval($focus->best_case) === "") { $focus->best_case = $focus->amount; } if (is_null($focus->worst_case) || strval($focus->worst_case) === "") { $focus->worst_case = $focus->amount; } // Bug49495: amount may be a calculated field $focus->updateCalculatedFields(); //Store the base currency value if (isset($focus->amount) && !number_empty($focus->amount)) { $focus->amount_usdollar = SugarCurrency::convertWithRate($focus->amount, $focus->base_rate); } }
protected function generateChartJson() { global $app_list_strings, $app_strings; $arrData = array(); $arrProbabilities = array(); $forecast_strings = $this->getModuleLanguage('Forecasts'); $config = $this->getForecastConfig(); $acl = new SugarACLForecastWorksheets(); $bestAccess = $acl->checkAccess('ForecastWorksheets', 'field', array('field' => 'best_case', 'action' => 'view')); $worstAccess = $acl->checkAccess('ForecastWorksheets', 'field', array('field' => 'worst_case', 'action' => 'view')); if (!empty($this->dataArray)) { foreach ($this->dataArray as $data) { // If users have made likely/best/worst not required, // set the value to 0 for upcoming currency math if (empty($data['likely_case'])) { $data['likely_case'] = 0; } $v = array('id' => $data['id'], 'record_id' => $data['parent_id'], 'forecast' => $data['commit_stage'], 'probability' => $data['probability'], 'sales_stage' => $data['sales_stage'], 'likely' => SugarCurrency::convertWithRate($data['likely_case'], $data['base_rate']), 'date_closed_timestamp' => intval($data['date_closed_timestamp'])); if ($config['show_worksheet_best'] && $bestAccess) { if (empty($data['best_case'])) { $data['best_case'] = 0; } $v['best'] = SugarCurrency::convertWithRate($data['best_case'], $data['base_rate']); } if ($config['show_worksheet_worst'] && $worstAccess) { if (empty($data['worst_case'])) { $data['worst_case'] = 0; } $v['worst'] = SugarCurrency::convertWithRate($data['worst_case'], $data['base_rate']); } $arrData[] = $v; $arrProbabilities[$data['probability']] = $data['probability']; } asort($arrProbabilities); } $tp = $this->getTimeperiod(); $chart_info = array('title' => string_format($forecast_strings['LBL_CHART_FORECAST_FOR'], array($tp->name)), 'quota' => $this->getUserQuota(), 'x-axis' => $tp->getChartLabels(array()), 'labels' => array('forecast' => $app_list_strings[$config['buckets_dom']], 'sales_stage' => $app_list_strings['sales_stage_dom'], 'probability' => $arrProbabilities, 'dataset' => array('likely' => $app_strings['LBL_LIKELY'], 'best' => $app_strings['LBL_BEST'], 'worst' => $app_strings['LBL_WORST'])), 'data' => $arrData); return $chart_info; }
public function generateChartJson() { $config = $this->getForecastConfig(); // sort the data so it's in the correct order usort($this->dataArray, array($this, 'sortChartColumns')); // loop variables $values = array(); foreach ($this->dataArray as $data) { $value = array('id' => $data['id'], 'user_id' => $data['user_id'], 'name' => html_entity_decode($data['name'], ENT_QUOTES), 'likely' => SugarCurrency::convertWithRate($data['likely_case'], $data['base_rate']), 'likely_adjusted' => SugarCurrency::convertWithRate($data['likely_case_adjusted'], $data['base_rate'])); if ($config['show_worksheet_best']) { $value['best'] = SugarCurrency::convertWithRate($data['best_case'], $data['base_rate']); $value['best_adjusted'] = SugarCurrency::convertWithRate($data['best_case_adjusted'], $data['base_rate']); } if ($config['show_worksheet_worst']) { $value['worst'] = SugarCurrency::convertWithRate($data['worst_case'], $data['base_rate']); $value['worst_adjusted'] = SugarCurrency::convertWithRate($data['worst_case_adjusted'], $data['base_rate']); } $values[] = $value; } $forecast_strings = $this->getModuleLanguage('Forecasts'); global $app_strings; $tp = $this->getTimeperiod(); return array('title' => string_format($forecast_strings['LBL_CHART_FORECAST_FOR'], array($tp->name)), 'quota' => $this->getRollupQuota(), 'labels' => array('dataset' => array('likely' => $app_strings['LBL_LIKELY'], 'best' => $app_strings['LBL_BEST'], 'worst' => $app_strings['LBL_WORST'], 'likely_adjusted' => $app_strings['LBL_LIKELY_ADJUSTED'], 'best_adjusted' => $app_strings['LBL_BEST_ADJUSTED'], 'worst_adjusted' => $app_strings['LBL_WORST_ADJUSTED'])), 'data' => $values); }
/** * This method emulates the Forecast Rep Worksheet calculateTotals method. * * @param string $timeperiod_id * @param string $user_id * @param string|null $forecast_by * @param boolean $useDraftRecords * @return array|bool */ public function worksheetTotals($timeperiod_id, $user_id, $forecast_by = null, $useDraftRecords = false) { /* @var $tp TimePeriod */ $tp = BeanFactory::getBean('TimePeriods', $timeperiod_id); if (empty($tp->id)) { // timeperiod not found return false; } /* @var $admin Administration */ $admin = BeanFactory::getBean('Administration'); $settings = $admin->getConfigForModule('Forecasts'); if (is_null($forecast_by)) { $forecast_by = $settings['forecast_by']; } // setup the return array $return = array('amount' => '0', 'best_case' => '0', 'worst_case' => '0', 'overall_amount' => '0', 'overall_best' => '0', 'overall_worst' => '0', 'timeperiod_id' => $tp->id, 'lost_count' => '0', 'lost_amount' => '0', 'lost_best' => '0', 'lost_worst' => '0', 'won_count' => '0', 'won_amount' => '0', 'won_best' => '0', 'won_worst' => '0', 'included_opp_count' => 0, 'total_opp_count' => 0, 'includedClosedCount' => 0, 'includedClosedAmount' => '0', 'includedClosedBest' => '0', 'includedClosedWorst' => '0', 'pipeline_amount' => '0', 'pipeline_opp_count' => 0, 'closed_amount' => '0', 'includedIdsInLikelyTotal' => array()); global $current_user; $sq = new SugarQuery(); $bean_obj = BeanFactory::getBean($this->module_name); $sq->select(array($bean_obj->getTableName() . '.*')); $sq->from($bean_obj)->where()->equals('assigned_user_id', $user_id)->equals('parent_type', $forecast_by)->equals('deleted', 0)->equals('draft', $current_user->id == $user_id || $useDraftRecords === true ? 1 : 0)->queryAnd()->gte('date_closed_timestamp', $tp->start_date_timestamp)->lte('date_closed_timestamp', $tp->end_date_timestamp); $results = $sq->execute(); foreach ($results as $row) { // if customers have made likely_case, best_case, or worst_case not required, // it saves to the DB as NULL, make sure we set it to 0 for the math ahead if (empty($row['likely_case'])) { $row['likely_case'] = 0; } if (empty($row['best_case'])) { $row['best_case'] = 0; } if (empty($row['worst_case'])) { $row['worst_case'] = 0; } $worst_base = SugarCurrency::convertWithRate($row['worst_case'], $row['base_rate']); $amount_base = SugarCurrency::convertWithRate($row['likely_case'], $row['base_rate']); $best_base = SugarCurrency::convertWithRate($row['best_case'], $row['base_rate']); $closed = false; if (in_array($row['sales_stage'], $settings['sales_stage_won']) && in_array($row['commit_stage'], $settings['commit_stages_included'])) { $return['won_amount'] = SugarMath::init($return['won_amount'], 6)->add($amount_base)->result(); $return['won_best'] = SugarMath::init($return['won_best'], 6)->add($best_base)->result(); $return['won_worst'] = SugarMath::init($return['won_worst'], 6)->add($worst_base)->result(); $return['won_count']++; $return['includedClosedCount']++; $return['includedClosedAmount'] = SugarMath::init($return['includedClosedAmount'], 6)->add($amount_base)->result(); $closed = true; } elseif (in_array($row['sales_stage'], $settings['sales_stage_lost'])) { $return['lost_amount'] = SugarMath::init($return['lost_amount'], 6)->add($amount_base)->result(); $return['lost_best'] = SugarMath::init($return['lost_best'], 6)->add($best_base)->result(); $return['lost_worst'] = SugarMath::init($return['lost_worst'], 6)->add($worst_base)->result(); $return['lost_count']++; $closed = true; } if (in_array($row['commit_stage'], $settings['commit_stages_included'])) { if (!$closed) { $return['amount'] = SugarMath::init($return['amount'], 6)->add($amount_base)->result(); $return['best_case'] = SugarMath::init($return['best_case'], 6)->add($best_base)->result(); $return['worst_case'] = SugarMath::init($return['worst_case'], 6)->add($worst_base)->result(); // add RLI/Opp id to includedIds array array_push($return['includedIdsInLikelyTotal'], $row['parent_id']); } $return['included_opp_count']++; if ($closed) { $return['includedClosedBest'] = SugarMath::init($return['includedClosedBest'], 6)->add($best_base)->result(); $return['includedClosedWorst'] = SugarMath::init($return['includedClosedWorst'], 6)->add($worst_base)->result(); } } $return['total_opp_count']++; $return['overall_amount'] = SugarMath::init($return['overall_amount'], 6)->add($amount_base)->result(); $return['overall_best'] = SugarMath::init($return['overall_best'], 6)->add($best_base)->result(); $return['overall_worst'] = SugarMath::init($return['overall_worst'], 6)->add($worst_base)->result(); } // send back the totals return $return; }
/** * Handles export field sanitizing for field type * * @param $value string value to be sanitized * @param $vardef array representing the vardef definition * @param $focus SugarBean object * @param $row Array of a row of data to be exported * * @return string sanitized value */ public function exportSanitize($value, $vardef, $focus, $row = array()) { // If $value is null, default to zero to prevent conversion errors. $value = is_null($value) ? 0 : $value; require_once 'include/SugarCurrency/SugarCurrency.php'; if (isset($vardef['convertToBase']) && $vardef['convertToBase']) { // convert amount to base $baseRate = isset($row['base_rate']) ? $row['base_rate'] : $focus->base_rate; $value = SugarCurrency::convertWithRate($value, $baseRate); $currency_id = '-99'; } elseif (isset($vardef['is_base_currency']) && $vardef['is_base_currency']) { $currency_id = '-99'; } else { //If the row has a currency_id set, use that instead of the $focus->currency_id value $currency_id = isset($row['currency_id']) ? $row['currency_id'] : $focus->currency_id; } return SugarCurrency::formatAmountUserLocale($value, $currency_id); }
/** * convert amount from base currency * * @param float $amount currency amount in US Dollars * @param int $precision rounding precision scale * @return float currency value from US Dollar conversion */ function convertFromBase($amount, $precision = 6) { $amount = $amount == null ? 0 : $amount; return SugarCurrency::convertWithRate(str_replace($this->symbol, '', $amount), 1.0, $this->conversion_rate, $precision); }
/** * Used by the dependency manager to pre-load all the related fields required * to load an entire view. */ public function getRelatedValues($api, $args) { if (empty($args['module']) || empty($args['fields'])) { return; } $fields = json_decode(html_entity_decode($args['fields']), true); $focus = $this->loadBean($api, $args); $ret = array(); foreach ($fields as $rfDef) { if (!isset($rfDef['link']) || !isset($rfDef['type'])) { continue; } $link = $rfDef['link']; $type = $rfDef['type']; $rField = ''; if (!isset($ret[$link])) { $ret[$link] = array(); } if (empty($ret[$link][$type])) { $ret[$link][$type] = array(); } // count formulas don't have a relate attribute if (isset($rfDef['relate'])) { $rField = $rfDef['relate']; } switch ($type) { //The Related function is used for pulling a sing field from a related record case "related": //Default it to a blank value $ret[$link]['related'][$rfDef['relate']] = ""; //If we have neither a focus id nor a related record id, we can't retrieve anything $relBean = null; if (empty($rfDef['relId']) || empty($rfDef['relModule'])) { //If the relationship is invalid, just move onto another field if (!$focus->load_relationship($link)) { break; } $beans = $focus->{$link}->getBeans(array("enforce_teams" => true)); //No related beans means no value if (empty($beans)) { break; } //Grab the first bean on the list reset($beans); $relBean = current($beans); } else { $relBean = BeanFactory::getBean($rfDef['relModule'], $rfDef['relId']); } //If we found a bean and the current user has access to the related field, grab a value from it if (!empty($relBean) && ACLField::hasAccess($rfDef['relate'], $relBean->module_dir, $GLOBALS['current_user']->id, true)) { $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (isset($validFields[$rfDef['relate']])) { $ret[$link]['relId'] = $relBean->id; $ret[$link]['related'][$rfDef['relate']] = FormulaHelper::getFieldValue($relBean, $rfDef['relate']); } } break; case "count": if ($focus->load_relationship($link)) { $ret[$link][$type] = count($focus->{$link}->get()); } else { $ret[$link][$type] = 0; } break; case "rollupSum": case "rollupAve": case "rollupMin": case "rollupMax": //If we are going to calculate one rollup, calculate all the rollups since there is so little cost if ($focus->load_relationship($link)) { $relBeans = $focus->{$link}->getBeans(array("enforce_teams" => true)); $sum = 0; $count = 0; $min = false; $max = false; if (!empty($relBeans)) { //Check if the related record vardef has banned this field from formulas $relBean = reset($relBeans); $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (!isset($validFields[$rField])) { $ret[$link][$type][$rField] = 0; break; } } foreach ($relBeans as $bean) { if (isset($bean->{$rField}) && is_numeric($bean->{$rField}) && ACLField::hasAccess($rField, $bean->module_dir, $GLOBALS['current_user']->id, true)) { $count++; $sum += floatval($bean->{$rField}); if ($min === false || $bean->{$rField} < $min) { $min = floatval($bean->{$rField}); } if ($max === false || $bean->{$rField} > $max) { $max = floatval($bean->{$rField}); } } } if ($type == "rollupSum") { $ret[$link][$type][$rField] = $sum; } if ($type == "rollupAve") { $ret[$link][$type][$rField] = $count == 0 ? 0 : $sum / $count; } if ($type == "rollupMin") { $ret[$link][$type][$rField] = $min; } if ($type == "rollupMax") { $ret[$link][$type][$rField] = $max; } } else { $ret[$link][$type][$rField] = 0; } break; case "rollupCurrencySum": $ret[$link][$type][$rField] = 0; if ($focus->load_relationship($link)) { $toRate = isset($focus->base_rate) ? $focus->base_rate : null; $relBeans = $focus->{$link}->getBeans(array("enforce_teams" => true)); $sum = 0; foreach ($relBeans as $bean) { if (!empty($bean->{$rField}) && is_numeric($bean->{$rField}) && ACLField::hasAccess($rField, $bean->module_dir, $GLOBALS['current_user']->id, true)) { $sum = SugarMath::init($sum)->add(SugarCurrency::convertWithRate($bean->{$rField}, $bean->base_rate, $toRate))->result(); } } $ret[$link][$type][$rField] = $sum; } break; } } return $ret; }
/** * @see SugarView::display() */ public function display() { require_once 'modules/Quotes/Layouts.php'; require_once 'include/EditView/EditView2.php'; global $beanFiles; require_once $beanFiles['Quote']; require_once $beanFiles['TaxRate']; require_once $beanFiles['Shipper']; global $mod_strings; global $app_strings; global $app_list_strings; global $current_user; global $timedate; global $locale; $original_quote = BeanFactory::getBean('Quotes'); if ($this->ev->isDuplicate) { $this->bean->id = ""; $this->bean->quote_num = ""; $original_quote->retrieve($_REQUEST['record']); } //needed when creating a new quote only with a default account value passed in if (empty($this->bean->id) && !$this->ev->isDuplicate) { $this->bean->quote_num = ''; $this->bean->total = '0.00'; $this->bean->shipping = '0.00'; $this->bean->tax = '0.00'; $this->bean->subtotal = '0.00'; if (isset($_REQUEST['opportunity_name'])) { $this->bean->opportunity_name = $_REQUEST['opportunity_name']; } if (isset($_REQUEST['opportunity_id'])) { $this->bean->opportunity_id = $_REQUEST['opportunity_id']; } if (isset($_REQUEST['account_name'])) { $this->bean->billing_account_name = $_REQUEST['account_name']; $this->bean->shipping_account_name = $_REQUEST['account_name']; } if (isset($_REQUEST['account_id'])) { $this->bean->billing_account_id = $_REQUEST['account_id']; $this->bean->shipping_account_id = $_REQUEST['account_id']; require_once $beanFiles['Account']; $account = BeanFactory::getBean('Accounts', $this->bean->shipping_account_id); $this->bean->shipping_address_street = $account->shipping_address_street; $this->bean->shipping_address_city = $account->shipping_address_city; $this->bean->shipping_address_state = $account->shipping_address_state; $this->bean->shipping_address_country = $account->shipping_address_country; $this->bean->shipping_address_postalcode = $account->shipping_address_postalcode; $this->bean->billing_address_street = $account->billing_address_street; $this->bean->billing_address_city = $account->billing_address_city; $this->bean->billing_address_state = $account->billing_address_state; $this->bean->billing_address_country = $account->billing_address_country; $this->bean->billing_address_postalcode = $account->billing_address_postalcode; } if (isset($_REQUEST['contact_id'])) { $this->bean->contact_id = $_REQUEST['contact_id']; require_once $beanFiles['Contact']; $contact = BeanFactory::getBean('Contacts', $this->bean->contact_id); $this->bean->billing_contact_name = $locale->formatName($contact); $this->bean->billing_contact_id = $contact->id; $this->bean->shipping_contact_name = $locale->formatName($contact); $this->bean->shipping_contact_id = $contact->id; $this->bean->shipping_address_street = $contact->primary_address_street; $this->bean->shipping_address_city = $contact->primary_address_city; $this->bean->shipping_address_state = $contact->primary_address_state; $this->bean->shipping_address_country = $contact->primary_address_country; $this->bean->shipping_address_postalcode = $contact->primary_address_postalcode; } if (isset($_REQUEST['date_quote_expected_closed'])) { $this->bean->date_quote_expected_closed = $_REQUEST['date_quote_expected_closed']; } if (isset($_REQUEST['currency_id'])) { $this->bean->currency_id = $_REQUEST['currency_id']; } } $currency = BeanFactory::getBean('Currencies', $this->bean->currency_id); // Set the number grouping and decimal separators $seps = get_number_seperators(); $dec_sep = $seps[1]; $num_grp_sep = $seps[0]; $this->ss->assign('NUM_GRP_SEP', $num_grp_sep); $this->ss->assign('DEC_SEP', $dec_sep); $significantDigits = $locale->getPrecedentPreference('default_currency_significant_digits', $current_user); $this->ss->assign('PRECISION', $significantDigits); if ((is_admin($current_user) || is_admin_for_module($GLOBALS['current_user'], 'Quotes')) && $_REQUEST['module'] != 'DynamicLayout' && !empty($_SESSION['editinplace'])) { $record = ''; if (!empty($_REQUEST['record'])) { $record = $_REQUEST['record']; } $this->ss->assign('ADMIN_EDIT', "<a href='index.php?action=index&module=DynamicLayout&from_action=" . $_REQUEST['action'] . "&from_module=" . $_REQUEST['module'] . "&record=" . $record . "'>" . SugarThemeRegistry::current()->getImage("EditLayout", "border='0' align='bottom'", null, null, '.gif', $mod_strings['LBL_EDITLAYOUT']) . "</a>"); } $this->ss->assign('QUOTE_STAGE_OPTIONS', get_select_options_with_id($app_list_strings['quote_stage_dom'], $this->bean->quote_stage)); $this->ss->assign('DEFAULT_PRODUCT_STATUS', $app_list_strings['product_status_quote_key']); if (isset($this->bean->subtotal)) { $this->ss->assign('SUBTOTAL', $this->bean->subtotal); } else { $this->ss->assign('SUBTOTAL', "0.00"); } if (isset($this->bean->tax)) { $this->ss->assign('TAX', $this->bean->tax); } else { $this->ss->assign('TAX', "0.00"); } if (isset($this->bean->shipping)) { $this->ss->assign("SHIPPING", $this->bean->shipping); } else { $this->ss->assign('SHIPPING', "0.00"); } if (isset($this->bean->deal_tot)) { $this->ss->assign('DEAL_TOT', $this->bean->deal_tot); } else { $this->ss->assign('DEAL_TOT', "0.00"); } if (isset($this->bean->new_sub)) { $this->ss->assign('NEW_SUB', $this->bean->new_sub); } else { $this->ss->assign('NEW_SUB', "0.00"); } if (isset($this->bean->total)) { $this->ss->assign('TOTAL', $this->bean->total); } else { $this->ss->assign('TOTAL', "0.00"); } if (isset($this->bean->subtotal_usdollar)) { $this->ss->assign('SUBTOTAL_USDOLLAR', $this->bean->subtotal_usdollar); } else { $this->ss->assign('SUBTOTAL_USDOLLAR', "0.00"); } if (isset($this->bean->tax_usdollar)) { $this->ss->assign('TAX_USDOLLAR', $this->bean->tax_usdollar); } else { $this->ss->assign('TAX_USDOLLAR', "0.00"); } if (isset($this->bean->shipping_usdollar)) { $this->ss->assign('SHIPPING_USDOLLAR', $this->bean->shipping_usdollar); } else { $this->ss->assign('SHIPPING_USDOLLAR', "0.00"); } if (isset($this->bean->total_usdollar)) { $this->ss->assign('TOTAL_USDOLLAR', $this->bean->total_usdollar); } else { $this->ss->assign('TOTAL_USDOLLAR', "0.00"); } $this->ss->assign('USER_DATEFORMAT', '(' . $timedate->get_user_date_format() . ')'); $this->ss->assign('CALENDAR_DATEFORMAT', $timedate->get_cal_date_format()); $taxrate = BeanFactory::getBean('TaxRates'); $this->ss->assign('TAXRATE_OPTIONS', get_select_options_with_id($taxrate->get_taxrates(false), $this->bean->taxrate_id)); if (empty($this->bean->taxrate_value)) { $this->ss->assign('TAXRATE_VALUE', $taxrate->get_default_taxrate_value() / 100); } else { $this->ss->assign('TAXRATE_VALUE', $this->bean->taxrate_value / 100); } $shipper = BeanFactory::getBean('Shippers'); $this->ss->assign('SHIPPER_OPTIONS', get_select_options_with_id($shipper->get_shippers(true), $this->bean->shipper_id)); if (empty($this->bean->assigned_user_id) && empty($this->bean->id)) { $this->bean->assigned_user_id = $current_user->id; } if (empty($this->bean->assigned_name) && empty($this->bean->id)) { $this->bean->assigned_user_name = $current_user->user_name; } $this->ss->assign('ASSIGNED_USER_OPTIONS', get_select_options_with_id(get_user_array(TRUE, 'Active', $this->bean->assigned_user_id), $this->bean->assigned_user_id)); $this->ss->assign('ASSIGNED_USER_NAME', $this->bean->assigned_user_name); $this->ss->assign('ASSIGNED_USER_ID', $this->bean->assigned_user_id); if (!empty($this->bean->calc_grand_total) && $this->bean->calc_grand_total == 1) { $this->ss->assign('CALC_GRAND_TOTAL_CHECKED', 'checked'); } if (!empty($this->bean->show_line_nums) && $this->bean->show_line_nums == 1) { $this->ss->assign('SHOW_LINE_NUMS_CHECKED', 'checked'); } // Set Currency values and currency javascript require_once 'modules/Currencies/ListCurrency.php'; $currency = new ListCurrency(); $base_rate = '1.00'; if (isset($this->bean->currency_id) && !empty($this->bean->currency_id)) { $curid = $this->bean->currency_id; } elseif (isset($_REQUEST['currency_id']) && !empty($_REQUEST['currency_id'])) { $curid = $_REQUEST['currency_id']; } elseif (empty($this->bean->id)) { $curid = $current_user->getPreference('currency'); if (empty($curid)) { $curid = -99; } } else { $curid = -99; } if ($this->bean->isClosed()) { $base_rate = $this->bean->base_rate; } else { $base_rate = null; } $selectCurrency = $currency->getSelectOptions($curid, $base_rate); $this->ss->assign("CURRENCY", $selectCurrency); $this->ss->assign('CURRENCY_JAVASCRIPT', $currency->getJavascript()); if ($this->bean->fetched_row['date_quote_expected_closed'] == '1970-01-01' || $this->bean->fetched_row['date_quote_expected_closed'] == '0001-01-01') { $this->bean->date_quote_expected_closed = ''; } $add_row = array(); if (!empty($this->bean->id)) { $this->bean->load_relationship('product_bundles'); $product_bundle_list = $this->bean->product_bundles->getBeans(); usort($product_bundle_list, array('ProductBundle', 'compareProductBundlesByIndex')); $quote_currency_id = $this->bean->currency_id; $quote_base_rate = $this->bean->base_rate; $convert_format = function ($value, $prod_currency, $prod_base_rate) use($quote_currency_id, $quote_base_rate) { if ($prod_currency !== $quote_currency_id) { $value = SugarCurrency::convertWithRate($value, $prod_base_rate, $quote_base_rate); } return SugarCurrency::formatAmountUserLocale($value, $quote_currency_id, false); }; if (is_array($product_bundle_list)) { foreach ($product_bundle_list as $product_bundle) { $bundle_list = $product_bundle->get_product_bundle_line_items(); $add_row[] = "quotesManager.addTable('{$product_bundle->id}','{$product_bundle->bundle_stage}', '{$product_bundle->name}', '" . format_money($product_bundle->shipping, FALSE) . "' );\n"; if (is_array($bundle_list)) { while (list($key, $line_item) = each($bundle_list)) { if ($line_item->object_name == "Product") { /* @var $line_item Product */ $tax_class_name = isset($line_item->tax_class) ? $line_item->tax_class : ""; $encoded_name = js_escape(br2nl($line_item->name)); $add_row[] = "quotesManager.addRow('{$line_item->id}','" . format_number($line_item->quantity, $significantDigits, $significantDigits) . "','{$line_item->product_template_id}','{$encoded_name}'" . ", '" . $convert_format($line_item->cost_price, $line_item->currency_id, $line_item->base_rate) . "'" . ", '" . $convert_format($line_item->list_price, $line_item->currency_id, $line_item->base_rate) . "'" . ", '" . $convert_format($line_item->discount_price, $line_item->currency_id, $line_item->base_rate) . "'" . ", '', '', '{$line_item->pricing_factor}', '{$line_item->tax_class}', '{$tax_class_name}', '{$line_item->mft_part_num}', '{$product_bundle->id}', '{$product_bundle->bundle_stage}', '{$product_bundle->name}', '" . format_number($product_bundle->shipping) . "', '" . js_escape(br2nl($line_item->description)) . "', '" . $line_item->type_id . "'" . ", '" . format_number($line_item->discount_amount, $significantDigits, $significantDigits) . "'" . ", " . ($line_item->discount_select ? 1 : 0) . ", " . ($line_item->deal_calc ? 1 : 0) . ", '" . $line_item->status . "');\n"; } else { if ($line_item->object_name == "ProductBundleNote") { /* @var $line_item ProductBundleNote */ $encoded_description = js_escape(br2nl($line_item->description)); //$encoded_description = html_entity_decode($encoded_description); $add_row[] = "quotesManager.addCommentRow('{$line_item->id}', '{$product_bundle->id}', '{$encoded_description}');\n"; } } } //while } //if } //foreach } } else { // this else part is to create a new product_bundle for the duplicate quote $original_quote->load_relationship('product_bundles'); $product_bundle_list = $original_quote->product_bundles->getBeans(); usort($product_bundle_list, array('ProductBundle', 'compareProductBundlesByIndex')); if (is_array($product_bundle_list)) { foreach ($product_bundle_list as $product_bundle) { $product_list = $product_bundle->get_products(); if (is_array($product_list)) { foreach ($product_list as $line_item) { $tax_class_name = isset($line_item->tax_class) ? $line_item->tax_class : ""; $add_row[] = "quotesManager.addRow('','{$line_item->quantity}','{$line_item->product_template_id}','{$line_item->name}'" . ", '" . format_number($line_item->cost_usdollar, $significantDigits, $significantDigits, array('convert' => true, 'currency_id' => $curid)) . "'" . ", '" . format_number($line_item->list_usdollar, $significantDigits, $significantDigits, array('convert' => true, 'currency_id' => $curid)) . "'" . ", '" . format_number($line_item->discount_usdollar, $significantDigits, $significantDigits, array('convert' => true, 'currency_id' => $curid)) . "'" . ", '', '', '{$line_item->pricing_factor}', '{$line_item->tax_class}', '{$tax_class_name}',\n\t\t\t\t\t\t\t\t'{$line_item->mft_part_num}', 'group_{$product_bundle->id}', '{$product_bundle->bundle_stage}', '{$product_bundle->name}', '" . format_money($product_bundle->shipping, FALSE) . "', '" . js_escape(br2nl($line_item->description)) . "', '" . $line_item->type_id . "','" . format_number($line_item->discount_amount_usdollar, $significantDigits, $significantDigits, array('convert' => !$line_item->discount_select, 'currency_id' => $curid)) . "'," . ($line_item->discount_select ? 1 : 0) . ",0, '" . $line_item->status . "');\n"; } //foreach if (empty($product_list)) { $add_row[] = "quotesManager.addTable('group_{$product_bundle->id}','{$product_bundle->bundle_stage}', '{$product_bundle->name}' , ' " . format_money($product_bundle->shipping, FALSE) . "');\n"; } //if //bug 39573 - Comments are not duplicated in quotes $bundle_list = $product_bundle->get_product_bundle_line_items(); if (is_array($bundle_list)) { while (list($key, $line_item) = each($bundle_list)) { if ($line_item->object_name == "ProductBundleNote") { $encoded_description = js_escape(br2nl($line_item->description)); $add_row[] = "quotesManager.addCommentRow('{$line_item->id}', 'group_{$product_bundle->id}', '{$encoded_description}');\n"; } } } //end bug 39573 } //if } } } //if-else for !empty($this->bean->id) //Bug#53607: Create the javascript code to store the rendering function in a queue $add_row_js = 'var add_row_stack = [];'; foreach ($add_row as $script_command) { $add_row_js .= "add_row_stack.push(function(){\n {$script_command}\n });"; } //Bug#53607: Rather than executing all rendering row script once, it will keep in a queue. // And it will render the specified number of rows every interval. $add_row_js .= "function add_rows_on_load() {\n if(typeof add_row_stack != 'undefined' && add_row_stack.length > 0) {\n //interval is in msec,\n //size is the number of rows rendering every time\n asyncLoading = true; // to indicate that the content is still loading\n var _interval = 100,\n _size = 3,\n _exec = add_row_stack.splice(0, _size),\n _header_button = document.getElementById('SAVE_HEADER'),\n _footer_button = document.getElementById('SAVE_FOOTER');\n if(_header_button) {\n _header_button.disabled = true;\n }\n if(_footer_button) {\n _footer_button.disabled = true;\n }\n for(idx in _exec) {\n _exec[idx]();\n }\n window.setTimeout(add_rows_on_load, _interval);\n } else {\n asyncLoading = false; // content is loaded\n var _header_button = document.getElementById('SAVE_HEADER'),\n _footer_button = document.getElementById('SAVE_FOOTER');\n if(_header_button) {\n _header_button.disabled = false;\n }\n if(_footer_button) {\n _footer_button.disabled = false;\n }\n }\n }"; $this->ss->assign("ADD_ROWS", $add_row_js); $setup_script = ''; $taxclass = translate('tax_class_dom'); foreach ($taxclass as $value => $name) { $setup_script .= "quotesManager.add_tax_class('{$name}', '{$value}');\n"; } $this->ss->assign("SETUP_SCRIPT", $setup_script); $this->ss->assign('TAXRATE_JAVASCRIPT', $taxrate->get_taxrate_js()); $this->ss->assign('CALCULATE_FUNCTION', '<script type="text/javascript">YAHOO.util.Event.onDOMReady(function(){quotesManager.calculate(document);});</script>'); $this->ss->assign('NO_MATCH_VARIABLE', '<script type="text/javascript">sqs_no_match_text = "' . $app_strings['ERR_SQS_NO_MATCH'] . '";</script>'); $str = "<script language=\"javascript\">\n\t\tYAHOO.util.Event.onAvailable('add_tables', add_rows_on_load);\n\t\t</script>"; $this->ss->assign('SAVED_SEARCH_SELECTS', $str); parent::display(); echo '<script>sqs_must_match = false;</script>'; }
/** * @param ServiceBase $api * @param array $args * @return array * @throws SugarApiExceptionInvalidParameter * @throws SugarApiExceptionNotAuthorized * @throws SugarApiExceptionNotFound */ public function pipeline(ServiceBase $api, $args) { // if not in the allowed module list, then we throw a 404 not found if (!in_array($args['module'], $this->allowedModules)) { throw new SugarApiExceptionNotFound(); } // make sure we can view the module first // since we don't have a proper record just make an empty one $args['record'] = ''; /* @var $seed Opportunity|Product|RevenueLineItem */ $seed = $this->loadBean($api, $args, 'view'); if (!$seed->ACLAccess('view')) { throw new SugarApiExceptionNotAuthorized(); } $tp = $this->getTimeperiod($args['timeperiod_id']); // check the type param if (!isset($args['type']) || $args['type'] != 'user' && $args['type'] != 'group') { $args['type'] = 'user'; } $settings = $this->getForecastSettings(); // get sales_stages to ignore $ignore_stages = array_merge($settings['sales_stage_won'], $settings['sales_stage_lost']); // get the amount field here $amount_field = $this->moduleAmountField[$seed->module_name]; $sq = $this->buildQuery($api, $seed, $tp, $amount_field, $args['type']); // run the query $rows = $sq->execute(); // data storage $data = array(); // keep track of the total for later user $total = SugarMath::init('0', 0); foreach ($rows as $row) { // if the sales stage is one we need to ignore, the just continue to the next record if (in_array($row['sales_stage'], $ignore_stages)) { continue; } // if we have not seen this sales stage before, set the value to zero (0) if (!isset($data[$row['sales_stage']])) { $data[$row['sales_stage']] = array('count' => 0, 'total' => '0'); } // if customers have made amount not required, it saves to the DB as NULL // make sure we set it to 0 for the math ahead if (empty($row['amount'])) { $row['amount'] = 0; } // convert to the base currency $base_amount = SugarCurrency::convertWithRate($row[$amount_field], $row['base_rate']); // add the new value into what was already there $data[$row['sales_stage']]['total'] = SugarMath::init($data[$row['sales_stage']]['total'], 0)->add($base_amount)->result(); $data[$row['sales_stage']]['count']++; // add to the total $total->add($base_amount); } // get the default currency /* @var $currency Currency */ $currency = SugarCurrency::getBaseCurrency(); // setup for return format $return_data = array(); $series = 0; $previous_value = SugarMath::init('0', 0); foreach ($data as $key => $item) { $value = $item['total']; // set up each return key $return_data[] = array('key' => $key, 'count' => $item['count'], 'values' => array(array('series' => $series++, 'label' => SugarCurrency::formatAmount($value, $currency->id, 0), 'value' => intval($value), 'x' => 0, 'y' => intval($value), 'y0' => intval($previous_value->result())))); // save the previous value for use in the next item in the series $previous_value->add($value); } // actually return the formatted data $mod_strings = return_module_language($GLOBALS['current_language'], $seed->module_name); //return the total from the SugarMath Object. $total = $total->result(); return array('properties' => array('title' => $mod_strings['LBL_PIPELINE_TOTAL_IS'] . SugarCurrency::formatAmount($total, $currency->id), 'total' => $total, 'scale' => 1000, 'units' => $currency->symbol), 'data' => $return_data); }
/** * This method emulates the Forecast Manager Worksheet calculateTotals method. * * @param string $userId * @param string $timeperiodId * @param boolean $useDraftRecords * @return array|bool Return calculated totals or boolean false if timeperiod is not valid */ public function worksheetTotals($userId, $timeperiodId, $useDraftRecords = false) { /* @var $tp TimePeriod */ $tp = BeanFactory::getBean('TimePeriods', $timeperiodId); if (empty($tp->id)) { // timeperiod not found return false; } $return = array("quota" => '0', "best_case" => '0', "best_adjusted" => '0', "likely_case" => '0', "likely_adjusted" => '0', "worst_case" => '0', "worst_adjusted" => '0', "included_opp_count" => 0, "pipeline_opp_count" => 0, "pipeline_amount" => '0', "closed_amount" => '0'); global $current_user; require_once 'include/SugarQuery/SugarQuery.php'; $sq = new SugarQuery(); $bean_obj = BeanFactory::getBean($this->module_name); $sq->select(array($bean_obj->getTableName() . '.*')); $sq->from($bean_obj)->where()->equals('timeperiod_id', $tp->id)->equals('assigned_user_id', $userId)->equals('draft', $current_user->id == $userId || $useDraftRecords === true ? 1 : 0)->equals('deleted', 0); $results = $sq->execute(); foreach ($results as $row) { $return['quota'] = SugarMath::init($return['quota'], 6)->add(SugarCurrency::convertWithRate($row['quota'], $row['base_rate']))->result(); $return['best_case'] = SugarMath::init($return['best_case'], 6)->add(SugarCurrency::convertWithRate($row['best_case'], $row['base_rate']))->result(); $return['best_adjusted'] = SugarMath::init($return['best_adjusted'], 6)->add(SugarCurrency::convertWithRate($row['best_case_adjusted'], $row['base_rate']))->result(); $return['likely_case'] = SugarMath::init($return['likely_case'], 6)->add(SugarCurrency::convertWithRate($row['likely_case'], $row['base_rate']))->result(); $return['likely_adjusted'] = SugarMath::init($return['likely_adjusted'], 6)->add(SugarCurrency::convertWithRate($row['likely_case_adjusted'], $row['base_rate']))->result(); $return['worst_case'] = SugarMath::init($return['worst_case'], 6)->add(SugarCurrency::convertWithRate($row['worst_case'], $row['base_rate']))->result(); $return['worst_adjusted'] = SugarMath::init($return['worst_adjusted'], 6)->add(SugarCurrency::convertWithRate($row['worst_case_adjusted'], $row['base_rate']))->result(); $return['closed_amount'] = SugarMath::init($return['closed_amount'], 6)->add(SugarCurrency::convertWithRate($row['closed_amount'], $row['base_rate']))->result(); $return['included_opp_count'] += $row['opp_count']; $return['pipeline_opp_count'] += $row['pipeline_opp_count']; $return['pipeline_amount'] = SugarMath::init($return['pipeline_amount'], 6)->add($row['pipeline_amount'])->result(); } return $return; }
function get_next_row($result_field_name = 'result', $column_field_name = 'display_columns', $skip_non_summary_columns = false, $exporting = false) { global $current_user; $chart_cells = array(); if ($this->do_export) { $db_row = $this->db->fetchByAssoc($this->{$result_field_name}, false); } else { $db_row = $this->db->fetchByAssoc($this->{$result_field_name}); } if ($db_row == 0 || sizeof($db_row) == 0) { return 0; } // Call custom hooks if (isset($this->full_bean_list) && is_array($this->full_bean_list) && array_key_exists('self', $this->full_bean_list) && is_object($this->full_bean_list['self']) && method_exists($this->full_bean_list['self'], 'call_custom_logic')) { $this->full_bean_list['self']->call_custom_logic('process_report_row', array('row' => &$db_row, 'reporter' => $this)); } if ($result_field_name == 'summary_result') { if (!empty($this->child_filter) && !empty($db_row[$this->child_filter_name])) { $this->child_filter_by = $db_row[$this->child_filter_name]; } else { $this->child_filter = ''; $this->child_filter_by = ''; $this->child_filter_name = ''; } } $row = array(); $cells = array(); $fields = array(); foreach ($db_row as $key => $value) { //if value is null or not set, then change to empty string. This prevents array index errors while processing $fields[strtoupper($key)] = is_null($value) ? '' : $value; } // here we want to make copies, so use foreach foreach ($this->report_def[$column_field_name] as $display_column) { $display_column['table_alias'] = $this->getTableFromField($display_column); $this->register_field_for_query($display_column); if ($skip_non_summary_columns && empty($display_column['group_function'])) { if ($exporting || $this->plain_text_output) { array_push($cells, ' '); } else { array_push($cells, ' '); } continue; } $display_column['fields'] = $fields; if ($this->plain_text_output == true) { /*nsingh: bug 13554- date and time fields must be displayed using user's locale settings. * Since to_pdf uses plain_text_output=true, we handle the date and time case here by using the 'List' context of the layout_manager */ if ($display_column['type'] == 'date' || $display_column['type'] == 'time' || $display_column['type'] == 'datetimecombo') { $this->layout_manager->setAttribute('context', 'List'); } else { $this->layout_manager->setAttribute('context', 'ListPlain'); } } else { $this->layout_manager->setAttribute('context', 'List'); } // Make sure 'AVG' aggregate is shown as float, regardless of the original field type if (!empty($display_column['group_function']) && strtolower($display_column['group_function']) === 'avg' && $display_column['type'] != 'currency') { $display_column['type'] = 'float'; } if ($display_column['type'] != 'currency' || substr_count($display_column['name'], '_usdoll') == 0 && (isset($display_column['group_function']) ? $display_column['group_function'] != 'weighted_amount' && $display_column['group_function'] != 'weighted_sum' : true)) { $pos = $display_column['table_key']; $module_name = ''; if ($pos) { $module_name = substr($pos, strrpos($pos, ':') + 1); } $field_name = $this->getColumnFieldName($display_column); if ($module_name == 'currencies' && empty($display_column['fields'][$field_name])) { switch ($display_column['name']) { case 'iso4217': $display = $this->currency_obj->getDefaultISO4217(); break; case 'symbol': $display = $this->currency_obj->getDefaultCurrencySymbol(); break; case 'name': $display = $this->currency_obj->getDefaultCurrencyName(); break; default: $display = $this->layout_manager->widgetDisplay($display_column); } $display_column['fields'][$field_name] = $display; } else { if (!empty($field_name) && isset($display_column['fields'][$field_name])) { $display_column['fields'][$field_name] = $this->db->fromConvert($display_column['fields'][$field_name], $display_column['type']); } $display = $this->layout_manager->widgetDisplay($display_column); } } else { if (isset($display_column['group_function'])) { $field_name = $this->getTruncatedColumnAlias(strtoupper($display_column['table_alias']) . "_" . strtoupper($display_column['group_function']) . "_" . strtoupper($display_column['name'])); } else { unset($field_name); } if (!isset($field_name) || !isset($display_column['fields'][$field_name])) { $field_name = $this->getTruncatedColumnAlias(strtoupper($display_column['table_alias']) . "_" . strtoupper($display_column['name'])); } if (isset($display_column['fields'][$field_name])) { $display = $display_column['fields'][$field_name]; } } if ($display_column['type'] == 'currency' && (strpos($display_column['name'], '_usdoll') !== false || !empty($display_column['group_function']))) { // convert base to user preferred if set in user prefs if ($current_user->getPreference('currency_show_preferred')) { $userCurrency = SugarCurrency::getUserLocaleCurrency(); $raw_display = SugarCurrency::convertWithRate($display_column['fields'][$field_name], 1.0, $userCurrency->conversion_rate); $display = SugarCurrency::formatAmountUserLocale($raw_display, $userCurrency->id); } else { $raw_display = $display_column['fields'][$field_name]; $display = SugarCurrency::formatAmountUserLocale($raw_display, SugarCurrency::getBaseCurrency()->id); } } else { $raw_display = $display; } if (isset($display_column['type']) && $display_column['type'] == 'float') { $display = $this->layout_manager->widgetDisplay($display_column); } if (isset($display_column['type'])) { $alias = $this->alias_lookup[$display_column['table_key']]; $array_key = strtoupper($alias . '__count'); if (array_key_exists($array_key, $display_column['fields'])) { $displayData = $display_column['fields'][$array_key]; if (empty($displayData) && $display_column['type'] != 'bool' && ($display_column['type'] != 'enum' || $display_column['type'] == 'enum' && $displayData != '0')) { $display = ""; } } // if $module_bean = BeanFactory::getBean($this->module); if (is_array($module_bean->field_defs)) { if (isset($module_bean->field_defs[$display_column['type']])) { if (isset($module_bean->field_defs[$display_column['type']]['options'])) { $trans_options = translate($module_bean->field_defs[$display_column['type']]['options']); if (isset($trans_options[$display_column['fields'][$field_name]])) { $display = $trans_options[$display_column['fields'][$field_name]]; } } } } } // if // for charts if ($column_field_name == 'summary_columns' && $this->do_chart) { //_pp($display); $raw_value = ""; $keys = array_keys($fields); foreach ($this->report_def['summary_columns'] as $index => $column) { if ($column['name'] == $display_column['name'] && isset($keys[$index]) && isset($fields[$keys[$index]])) { $raw_value = $fields[$keys[$index]]; break; } } $cell_arr = array('val' => $raw_display, 'key' => $display_column['column_key'], 'raw_value' => $raw_value); //_pp($cell_arr); array_push($chart_cells, $cell_arr); } if ($exporting) { global $app_list_strings; // parse out checkboxes // TODO: wp this should be done in the widget if (preg_match('/type.*=.*checkbox/Uis', $display)) { if (preg_match('/checked/i', $display)) { $display = $app_list_strings['dom_switch_bool']['on']; } else { $display = $app_list_strings['dom_switch_bool']['off']; } } } array_push($cells, $display); } // END foreach $row['cells'] = $cells; // calculate summary rows count as the product of all count fields in summary $count = 1; $count_exists = false; foreach ($db_row as $count_column => $count_value) { if (substr($count_column, -10) == "__allcount" || $count_column == 'count') { $count *= max($count_value, 1); $count_exists = true; } } if ($count_exists) { $row['count'] = $count; } // for charts if ($column_field_name == 'summary_columns' && $this->do_chart) { $chart_row = 0; if (!empty($db_row['count'])) { $chart_row = array('cells' => $chart_cells, 'count' => $db_row['count']); } else { $chart_row = array('cells' => $chart_cells); } array_push($this->chart_rows, $chart_row); } if ($column_field_name == 'summary_columns' && isset($this->chart_group_position) && isset($this->group_header)) { $row['group_pos'] = $this->chart_group_position; $row['group_header'] = $this->group_header; $row['group_column_is_invisible'] = $this->group_column_is_invisible; } return $row; }