예제 #1
0
 /**
  * Check tax amount.
  *
  * @param array $params
  * @param bool $isLineItem
  *
  * @return mixed
  */
 public static function checkTaxAmount($params, $isLineItem = FALSE)
 {
     $taxRates = CRM_Core_PseudoConstant::getTaxRates();
     // Update contribution.
     if (!empty($params['id'])) {
         $id = $params['id'];
         $values = $ids = array();
         $contrbutionParams = array('id' => $id);
         $prevContributionValue = CRM_Contribute_BAO_Contribution::getValues($contrbutionParams, $values, $ids);
         // To assign pervious finantial type on update of contribution
         if (!isset($params['financial_type_id'])) {
             $params['financial_type_id'] = $prevContributionValue->financial_type_id;
         } elseif (isset($params['financial_type_id']) && !array_key_exists($params['financial_type_id'], $taxRates)) {
             // Assisn tax Amount on update of contrbution
             if (!empty($prevContributionValue->tax_amount)) {
                 $params['tax_amount'] = 'null';
                 CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
                 foreach ($params['line_item'] as $setID => $priceField) {
                     foreach ($priceField as $priceFieldID => $priceFieldValue) {
                         $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
                     }
                 }
             }
         }
     }
     // New Contrbution and update of contribution with tax rate financial type
     if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && empty($params['skipLineItem']) && !$isLineItem) {
         $taxRateParams = $taxRates[$params['financial_type_id']];
         $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['total_amount'], $taxRateParams);
         $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
         // Get Line Item on update of contribution
         if (isset($params['id'])) {
             CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
         } else {
             CRM_Price_BAO_LineItem::getLineItemArray($params);
         }
         foreach ($params['line_item'] as $setID => $priceField) {
             foreach ($priceField as $priceFieldID => $priceFieldValue) {
                 $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
             }
         }
         $params['total_amount'] = $params['total_amount'] + $params['tax_amount'];
     } elseif (isset($params['api.line_item.create'])) {
         // Update total amount of contribution using lineItem
         $taxAmountArray = array();
         foreach ($params['api.line_item.create'] as $key => $value) {
             if (isset($value['financial_type_id']) && array_key_exists($value['financial_type_id'], $taxRates)) {
                 $taxRate = $taxRates[$value['financial_type_id']];
                 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($value['line_total'], $taxRate);
                 $taxAmountArray[] = round($taxAmount['tax_amount'], 2);
             }
         }
         $params['tax_amount'] = array_sum($taxAmountArray);
         $params['total_amount'] = $params['total_amount'] + $params['tax_amount'];
     } else {
         // update line item of contrbution
         if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && $isLineItem) {
             $taxRate = $taxRates[$params['financial_type_id']];
             $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['line_total'], $taxRate);
             $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
         }
     }
     return $params;
 }
예제 #2
0
 /**
  * Browse all price fields.
  *
  * @return void
  */
 public function browse()
 {
     $customOption = array();
     CRM_Price_BAO_PriceFieldValue::getValues($this->_fid, $customOption);
     // CRM-15378 - check if these price options are in an Event price set
     $isEvent = FALSE;
     $extendComponentId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_sid, 'extends', 'id');
     $allComponents = explode(CRM_Core_DAO::VALUE_SEPARATOR, $extendComponentId);
     $eventComponentId = CRM_Core_Component::getComponentID('CiviEvent');
     if (in_array($eventComponentId, $allComponents)) {
         $isEvent = TRUE;
     }
     $config = CRM_Core_Config::singleton();
     $financialType = CRM_Contribute_PseudoConstant::financialType();
     $taxRate = CRM_Core_PseudoConstant::getTaxRates();
     // display taxTerm for priceFields
     $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
     $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
     $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
     $getTaxDetails = FALSE;
     foreach ($customOption as $id => $values) {
         $action = array_sum(array_keys($this->actionLinks()));
         // Adding the required fields in the array
         if (isset($taxRate[$values['financial_type_id']])) {
             $customOption[$id]['tax_rate'] = $taxRate[$values['financial_type_id']];
             if ($invoicing && isset($customOption[$id]['tax_rate'])) {
                 $getTaxDetails = TRUE;
             }
             $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($customOption[$id]['amount'], $customOption[$id]['tax_rate']);
             $customOption[$id]['tax_amount'] = $taxAmount['tax_amount'];
         }
         if (!empty($values['financial_type_id'])) {
             $customOption[$id]['financial_type_id'] = $financialType[$values['financial_type_id']];
         }
         // update enable/disable links depending on price_field properties.
         if ($this->_isSetReserved) {
             $action -= CRM_Core_Action::UPDATE + CRM_Core_Action::DELETE + CRM_Core_Action::DISABLE + CRM_Core_Action::ENABLE;
         } else {
             if ($values['is_active']) {
                 $action -= CRM_Core_Action::ENABLE;
             } else {
                 $action -= CRM_Core_Action::DISABLE;
             }
         }
         if (!empty($customOption[$id]['is_default'])) {
             $customOption[$id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
         } else {
             $customOption[$id]['is_default'] = '';
         }
         $customOption[$id]['order'] = $customOption[$id]['weight'];
         $customOption[$id]['action'] = CRM_Core_Action::formLink(self::actionLinks(), $action, array('oid' => $id, 'fid' => $this->_fid, 'sid' => $this->_sid), ts('more'), FALSE, 'priceFieldValue.row.actions', 'PriceFieldValue', $id);
     }
     // Add order changing widget to selector
     $returnURL = CRM_Utils_System::url('civicrm/admin/price/field/option', "action=browse&reset=1&fid={$this->_fid}&sid={$this->_sid}");
     $filter = "price_field_id = {$this->_fid}";
     CRM_Utils_Weight::addOrder($customOption, 'CRM_Price_DAO_PriceFieldValue', 'id', $returnURL, $filter);
     $this->assign('taxTerm', $taxTerm);
     $this->assign('getTaxDetails', $getTaxDetails);
     $this->assign('customOption', $customOption);
     $this->assign('sid', $this->_sid);
     $this->assign('isEvent', $isEvent);
 }
예제 #3
0
 /**
  * Retrieve a list of options for the specified field.
  *
  * @param int $fieldId
  *   Price field ID.
  * @param bool $inactiveNeeded
  *   Include inactive options.
  * @param bool $reset
  *   Ignore stored values\.
  *
  * @return array
  *   array of options
  */
 public static function getOptions($fieldId, $inactiveNeeded = FALSE, $reset = FALSE)
 {
     static $options = array();
     if ($reset || empty($options[$fieldId])) {
         $values = array();
         CRM_Price_BAO_PriceFieldValue::getValues($fieldId, $values, 'weight', !$inactiveNeeded);
         $options[$fieldId] = $values;
         $taxRates = CRM_Core_PseudoConstant::getTaxRates();
         // ToDo - Code for Hook Invoke
         foreach ($options[$fieldId] as $priceFieldId => $priceFieldValues) {
             if (isset($priceFieldValues['financial_type_id']) && array_key_exists($priceFieldValues['financial_type_id'], $taxRates)) {
                 $options[$fieldId][$priceFieldId]['tax_rate'] = $taxRates[$priceFieldValues['financial_type_id']];
                 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($priceFieldValues['amount'], $options[$fieldId][$priceFieldId]['tax_rate']);
                 $options[$fieldId][$priceFieldId]['tax_amount'] = round($taxAmount['tax_amount'], 2);
             }
         }
     }
     return $options[$fieldId];
 }
예제 #4
0
 /**
  * Browse all price set fields.
  *
  * @return void
  */
 public function browse()
 {
     $resourceManager = CRM_Core_Resources::singleton();
     if (!empty($_GET['new']) && $resourceManager->ajaxPopupsEnabled) {
         $resourceManager->addScriptFile('civicrm', 'js/crm.addNew.js', 999, 'html-header');
     }
     $priceField = array();
     $priceFieldBAO = new CRM_Price_BAO_PriceField();
     // fkey is sid
     $priceFieldBAO->price_set_id = $this->_sid;
     $priceFieldBAO->orderBy('weight, label');
     $priceFieldBAO->find();
     // display taxTerm for priceFields
     $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
     $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
     $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
     $getTaxDetails = FALSE;
     $taxRate = CRM_Core_PseudoConstant::getTaxRates();
     CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes);
     while ($priceFieldBAO->fetch()) {
         $priceField[$priceFieldBAO->id] = array();
         CRM_Core_DAO::storeValues($priceFieldBAO, $priceField[$priceFieldBAO->id]);
         // get price if it's a text field
         if ($priceFieldBAO->html_type == 'Text') {
             $optionValues = array();
             $params = array('price_field_id' => $priceFieldBAO->id);
             CRM_Price_BAO_PriceFieldValue::retrieve($params, $optionValues);
             $financialTypeId = $optionValues['financial_type_id'];
             if (!array_key_exists($financialTypeId, $financialTypes)) {
                 unset($priceField[$priceFieldBAO->id]);
                 continue;
             }
             $priceField[$priceFieldBAO->id]['price'] = CRM_Utils_Array::value('amount', $optionValues);
             if ($invoicing && isset($taxRate[$financialTypeId])) {
                 $priceField[$priceFieldBAO->id]['tax_rate'] = $taxRate[$financialTypeId];
                 $getTaxDetails = TRUE;
             }
             if (isset($priceField[$priceFieldBAO->id]['tax_rate'])) {
                 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($priceField[$priceFieldBAO->id]['price'], $priceField[$priceFieldBAO->id]['tax_rate']);
                 $priceField[$priceFieldBAO->id]['tax_amount'] = $taxAmount['tax_amount'];
             }
         }
         $action = array_sum(array_keys(self::actionLinks()));
         if ($this->_isSetReserved) {
             $action -= CRM_Core_Action::UPDATE + CRM_Core_Action::DELETE + CRM_Core_Action::ENABLE + CRM_Core_Action::DISABLE;
         } else {
             if ($priceFieldBAO->is_active) {
                 $action -= CRM_Core_Action::ENABLE;
             } else {
                 $action -= CRM_Core_Action::DISABLE;
             }
         }
         if ($priceFieldBAO->active_on == '0000-00-00 00:00:00') {
             $priceField[$priceFieldBAO->id]['active_on'] = '';
         }
         if ($priceFieldBAO->expire_on == '0000-00-00 00:00:00') {
             $priceField[$priceFieldBAO->id]['expire_on'] = '';
         }
         // need to translate html types from the db
         $htmlTypes = CRM_Price_BAO_PriceField::htmlTypes();
         $priceField[$priceFieldBAO->id]['html_type_display'] = $htmlTypes[$priceField[$priceFieldBAO->id]['html_type']];
         $priceField[$priceFieldBAO->id]['order'] = $priceField[$priceFieldBAO->id]['weight'];
         $priceField[$priceFieldBAO->id]['action'] = CRM_Core_Action::formLink(self::actionLinks(), $action, array('fid' => $priceFieldBAO->id, 'sid' => $this->_sid), ts('more'), FALSE, 'priceField.row.actions', 'PriceField', $priceFieldBAO->id);
         $this->assign('taxTerm', $taxTerm);
         $this->assign('getTaxDetails', $getTaxDetails);
     }
     $returnURL = CRM_Utils_System::url('civicrm/admin/price/field', "reset=1&action=browse&sid={$this->_sid}");
     $filter = "price_set_id = {$this->_sid}";
     CRM_Utils_Weight::addOrder($priceField, 'CRM_Price_DAO_PriceField', 'id', $returnURL, $filter);
     $this->assign('priceField', $priceField);
 }
예제 #5
0
 /**
  * Get line item purchase information.
  *
  * This function takes the input parameters and interprets out of it what has been purchased.
  *
  * @param $fields
  *   This is the output of the function CRM_Price_BAO_PriceSet::getSetDetail($priceSetID, FALSE, FALSE);
  *   And, it would make sense to introduce caching into that function and call it from here rather than
  *   require the $fields array which is passed from pillar to post around the form in order to pass it in here.
  * @param array $params
  *   Params reflecting form input e.g with fields 'price_5' => 7, 'price_8' => array(7, 8)
  * @param $lineItem
  *   Line item array to be altered.
  * @param string $component
  *   This parameter appears to only be relevant to determining whether memberships should be auto-renewed.
  *   (and is effectively a boolean for 'is_membership' which could be calculated from the line items.)
  */
 public static function processAmount($fields, &$params, &$lineItem, $component = '')
 {
     // using price set
     $totalPrice = $totalTax = 0;
     $radioLevel = $checkboxLevel = $selectLevel = $textLevel = array();
     if ($component) {
         $autoRenew = array();
         $autoRenew[0] = $autoRenew[1] = $autoRenew[2] = 0;
     }
     foreach ($fields as $id => $field) {
         if (empty($params["price_{$id}"]) || empty($params["price_{$id}"]) && $params["price_{$id}"] == NULL) {
             // skip if nothing was submitted for this field
             continue;
         }
         switch ($field['html_type']) {
             case 'Text':
                 $firstOption = reset($field['options']);
                 $params["price_{$id}"] = array($firstOption['id'] => $params["price_{$id}"]);
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][key($field['options'])])) {
                     $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
                     $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
                 }
                 if (CRM_Utils_Array::value('name', $field['options'][key($field['options'])]) == 'contribution_amount') {
                     $taxRates = CRM_Core_PseudoConstant::getTaxRates();
                     if (array_key_exists($params['financial_type_id'], $taxRates)) {
                         $field['options'][key($field['options'])]['tax_rate'] = $taxRates[$params['financial_type_id']];
                         $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($field['options'][key($field['options'])]['amount'], $field['options'][key($field['options'])]['tax_rate']);
                         $field['options'][key($field['options'])]['tax_amount'] = round($taxAmount['tax_amount'], 2);
                         $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
                         $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
                     }
                 }
                 $totalPrice += $lineItem[$firstOption['id']]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[key($field['options'])]);
                 break;
             case 'Radio':
                 //special case if user select -none-
                 if ($params["price_{$id}"] <= 0) {
                     continue;
                 }
                 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
                 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
                 $optionLabel = CRM_Utils_Array::value('label', $field['options'][$optionValueId]);
                 $params['amount_priceset_level_radio'] = array();
                 $params['amount_priceset_level_radio'][$optionValueId] = $optionLabel;
                 if (isset($radioLevel)) {
                     $radioLevel = array_merge($radioLevel, array_keys($params['amount_priceset_level_radio']));
                 } else {
                     $radioLevel = array_keys($params['amount_priceset_level_radio']);
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
                     $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
                     $totalTax += $field['options'][$optionValueId]['tax_amount'];
                     if (CRM_Utils_Array::value('field_title', $lineItem[$optionValueId]) == 'Membership Amount') {
                         $lineItem[$optionValueId]['line_total'] = $lineItem[$optionValueId]['unit_price'] = CRM_Utils_Rule::cleanMoney($lineItem[$optionValueId]['line_total'] - $lineItem[$optionValueId]['tax_amount']);
                     }
                 }
                 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
                 if ($component && isset($lineItem[$optionValueId]['auto_renew']) && is_numeric($lineItem[$optionValueId]['auto_renew'])) {
                     $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
                 }
                 break;
             case 'Select':
                 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
                 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
                 $optionLabel = $field['options'][$optionValueId]['label'];
                 $params['amount_priceset_level_select'] = array();
                 $params['amount_priceset_level_select'][CRM_Utils_Array::key(1, $params["price_{$id}"])] = $optionLabel;
                 if (isset($selectLevel)) {
                     $selectLevel = array_merge($selectLevel, array_keys($params['amount_priceset_level_select']));
                 } else {
                     $selectLevel = array_keys($params['amount_priceset_level_select']);
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
                     $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
                     $totalTax += $field['options'][$optionValueId]['tax_amount'];
                 }
                 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
                 if ($component && isset($lineItem[$optionValueId]['auto_renew']) && is_numeric($lineItem[$optionValueId]['auto_renew'])) {
                     $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
                 }
                 break;
             case 'CheckBox':
                 $params['amount_priceset_level_checkbox'] = $optionIds = array();
                 foreach ($params["price_{$id}"] as $optionId => $option) {
                     $optionIds[] = $optionId;
                     $optionLabel = $field['options'][$optionId]['label'];
                     $params['amount_priceset_level_checkbox']["{$field['options'][$optionId]['id']}"] = $optionLabel;
                     if (isset($checkboxLevel)) {
                         $checkboxLevel = array_unique(array_merge($checkboxLevel, array_keys($params['amount_priceset_level_checkbox'])));
                     } else {
                         $checkboxLevel = array_keys($params['amount_priceset_level_checkbox']);
                     }
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 foreach ($optionIds as $optionId) {
                     if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionId])) {
                         $lineItem = self::setLineItem($field, $lineItem, $optionId);
                         $totalTax += $field['options'][$optionId]['tax_amount'];
                     }
                     $totalPrice += $lineItem[$optionId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionId]);
                     if ($component && isset($lineItem[$optionId]['auto_renew']) && is_numeric($lineItem[$optionId]['auto_renew'])) {
                         $autoRenew[$lineItem[$optionId]['auto_renew']] += $lineItem[$optionId]['line_total'];
                     }
                 }
                 break;
         }
     }
     $amount_level = array();
     $totalParticipant = 0;
     if (is_array($lineItem)) {
         foreach ($lineItem as $values) {
             $totalParticipant += $values['participant_count'];
             $amount_level[] = $values['label'] . ' - ' . (double) $values['qty'];
         }
     }
     $displayParticipantCount = '';
     if ($totalParticipant > 0) {
         $displayParticipantCount = ' Participant Count -' . $totalParticipant;
     }
     $params['amount_level'] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $amount_level) . $displayParticipantCount . CRM_Core_DAO::VALUE_SEPARATOR;
     $params['amount'] = CRM_Utils_Money::format($totalPrice, NULL, NULL, TRUE);
     $params['tax_amount'] = $totalTax;
     if ($component) {
         foreach ($autoRenew as $dontCare => $eachAmount) {
             if (!$eachAmount) {
                 unset($autoRenew[$dontCare]);
             }
         }
         if (count($autoRenew) > 1) {
             $params['autoRenew'] = $autoRenew;
         }
     }
 }
/**
 * Implementation of hook_civicrm_buildAmount()
 *
 * If the event id of the form being loaded has a discount code, calculate the
 * the discount and update the price and label. Apply the initial autodiscount
 * based on a users membership.
 *
 * Check all priceset items and only apply the discount to the discounted items.
 *
 * @param string $pageType
 * @param CRM_Core_Form $form
 * @param $amounts
 */
function cividiscount_civicrm_buildAmount($pagetype, &$form, &$amounts)
{
    if ((!$form->getVar('_action') || $form->getVar('_action') & CRM_Core_Action::PREVIEW || $form->getVar('_action') & CRM_Core_Action::ADD || $form->getVar('_action') & CRM_Core_Action::UPDATE) && !empty($amounts) && is_array($amounts) && ($pagetype == 'event' || $pagetype == 'membership')) {
        if (!$pagetype == 'membership' && in_array(get_class($form), array('CRM_Contribute_Form_Contribution', 'CRM_Contribute_Form_Contribution_Main'))) {
            return;
        }
        $contact_id = _cividiscount_get_form_contact_id($form);
        $autodiscount = FALSE;
        $eid = $form->getVar('_eventId');
        $psid = $form->get('priceSetId');
        $ps = $form->get('priceSet');
        $v = $form->getVar('_values');
        $code = trim(CRM_Utils_Request::retrieve('discountcode', 'String', $form, false, null, 'REQUEST'));
        if (!array_key_exists('discountcode', $form->_submitValues) && ($pid = $form->getVar('_participantId')) && $form->getVar('_action') & CRM_Core_Action::UPDATE) {
            $code = _cividiscount_get_item_by_track('civicrm_participant', $pid, $contact_id, TRUE);
        }
        if (!empty($v['currency'])) {
            $currency = $v['currency'];
        } elseif (!empty($v['event']['currency'])) {
            $currency = $v['event']['currency'];
        } else {
            $currency = CRM_Core_Config::singleton()->defaultCurrency;
        }
        // If additional participants are not allowed to receive a discount we need
        // to interrupt the form processing on build and POST.
        // This is a potential landmine if the form processing ever changes in Civi.
        if (!_cividiscount_allow_multiple()) {
            // POST from participant form to confirm page
            if ($form->getVar('_lastParticipant') == 1) {
                return;
            }
            // On build participant form
            $keys = array_keys($_GET);
            foreach ($keys as $key) {
                if (substr($key, 0, 16) == "_qf_Participant_") {
                    // We can somewhat safely assume we're in the additional participant
                    // registration form.
                    // @todo what is the effect of this?
                    if ($_GET[$key] == 'true') {
                        return;
                    }
                }
            }
        }
        $form->set('_discountInfo', NULL);
        $discountCalculator = new CRM_CiviDiscount_DiscountCalculator($pagetype, $eid, $contact_id, $code, FALSE);
        $discounts = $discountCalculator->getDiscounts();
        if (!empty($code) && empty($discounts)) {
            $form->set('discountCodeErrorMsg', ts('The discount code you entered is invalid.'));
        }
        // here we check if discount is configured for events or for membership types.
        // There are two scenarios:
        // 1. Discount is configure for the event or membership type, in that case we should apply discount only
        //    if default fee / membership type is configured. ( i.e price set with quick config true )
        // 2. Discount is configure at price field level, in this case discount should be applied only for
        //    that particular price set field.
        $keys = array_keys($discounts);
        $key = array_shift($keys);
        // in this case discount is specified for event id or membership type id, so we need to get info of
        // associated price set fields. For events discount we already have the list, but for memberships we
        // need to filter at membership type level
        //retrieve price set field associated with this priceset
        $priceSetInfo = CRM_CiviDiscount_Utils::getPriceSetsInfo($psid);
        $originalAmounts = $amounts;
        //$discount = array_shift($discounts);
        foreach ($discounts as $done_care => $discount) {
            if (!empty($discountCalculator->autoDiscounts) && array_key_exists($done_care, $discountCalculator->autoDiscounts)) {
                $autodiscount = TRUE;
            } else {
                $autodiscount = FALSE;
            }
            $priceFields = isset($discount['pricesets']) ? $discount['pricesets'] : array();
            if (empty($priceFields) && (!empty($code) || $autodiscount)) {
                // apply discount to all the price fields if no price set set
                if ($pagetype == 'event') {
                    $applyToAllLineItems = TRUE;
                    if (!empty($key)) {
                        $discounts[$key]['pricesets'] = array_keys($priceSetInfo);
                    }
                } else {
                    // filter only valid membership types that have discount
                    foreach ($priceSetInfo as $pfID => $priceFieldValues) {
                        if (!empty($priceFieldValues['membership_type_id']) && in_array($priceFieldValues['membership_type_id'], CRM_Utils_Array::value('memberships', $discount, array()))) {
                            $priceFields[$pfID] = $pfID;
                        }
                    }
                }
            }
            // we should check for MultParticipant AND set Error Messages only if
            // this $discount is autodiscount or used discount
            if ($autodiscount || !empty($code) && $code == $discount['code']) {
                $apcount = _cividiscount_checkEventDiscountMultipleParticipants($pagetype, $form, $discount);
            } else {
                // silently set FALSE
                $apcount = FALSE;
            }
            if (empty($apcount)) {
                //this was set to return but that doesn't make sense as there might be another discount
                continue;
            }
            $discountApplied = FALSE;
            if (!empty($autodiscount) || !empty($code)) {
                foreach ($amounts as $fee_id => &$fee) {
                    if (!is_array($fee['options'])) {
                        continue;
                    }
                    foreach ($fee['options'] as $option_id => &$option) {
                        if (!empty($applyToAllLineItems) || CRM_Utils_Array::value($option['id'], $priceFields)) {
                            $originalLabel = $originalAmounts[$fee_id]['options'][$option_id]['label'];
                            $originalAmount = CRM_Utils_Rule::cleanMoney($originalAmounts[$fee_id]['options'][$option_id]['amount']);
                            list($amount, $label) = _cividiscount_calc_discount($originalAmount, $originalLabel, $discount, $autodiscount, $currency);
                            $discountAmount = $originalAmounts[$fee_id]['options'][$option_id]['amount'] - $amount;
                            if ($discountAmount > CRM_Utils_Array::value('discount_applied', $option)) {
                                $option['amount'] = $amount;
                                $option['label'] = $label;
                                $option['discount_applied'] = $discountAmount;
                                /*
                                 * Priyanka Karan @ Veda NFP Consulting Ltd
                                 * Re-calculate VAT/Sales TAX on discounted amount.
                                 */
                                $recalculateTaxAmount = array();
                                if (array_key_exists('tax_amount', $originalAmounts[$fee_id]['options'][$option_id]) && array_key_exists('tax_rate', $originalAmounts[$fee_id]['options'][$option_id])) {
                                    $recalculateTaxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($amount, $originalAmounts[$fee_id]['options'][$option_id]['tax_rate']);
                                    if (!empty($recalculateTaxAmount)) {
                                        $option['tax_amount'] = round($recalculateTaxAmount['tax_amount'], 2);
                                    }
                                }
                            }
                            $discountApplied = TRUE;
                        }
                    }
                }
            }
        }
        // Display discount message if one is available
        if ($pagetype == 'event') {
            foreach ($discounts as $code => $discount) {
                if (isset($discount['events']) && array_key_exists($eid, $discount['events']) && $discount['discount_msg_enabled'] && (!isset($discountApplied) || !$discountApplied) && !empty($discount['autodiscount'])) {
                    CRM_Core_Session::setStatus(html_entity_decode($discount['discount_msg']), '', 'no-popup');
                }
            }
        }
        // this seems to incorrectly set to only the last discount but it seems not to matter in the way it is used
        if (isset($discountApplied) && $discountApplied) {
            if (!empty($ps['fields'])) {
                $ps['fields'] = $amounts;
                $form->setVar('_priceSet', $ps);
            }
            $form->set('_discountInfo', array('discount' => $discount, 'autodiscount' => $autodiscount, 'contact_id' => $contact_id));
        }
    }
}
예제 #7
0
 /**
  * Get the tax amount (misnamed function).
  *
  * @param array $params
  * @param bool $isLineItem
  *
  * @return array
  */
 public static function checkTaxAmount($params, $isLineItem = FALSE)
 {
     $taxRates = CRM_Core_PseudoConstant::getTaxRates();
     // Update contribution.
     if (!empty($params['id'])) {
         // CRM-19126 and CRM-19152 If neither total or financial_type_id are set on an update
         // there are no tax implications - early return.
         if (!isset($params['total_amount']) && !isset($params['financial_type_id'])) {
             return $params;
         }
         if (empty($params['prevContribution'])) {
             $params['prevContribution'] = self::getOriginalContribution($params['id']);
         }
         foreach (array('total_amount', 'financial_type_id', 'fee_amount') as $field) {
             if (!isset($params[$field])) {
                 if ($field == 'total_amount' && $params['prevContribution']->tax_amount) {
                     // Tax amount gets added back on later....
                     $params['total_amount'] = $params['prevContribution']->total_amount - $params['prevContribution']->tax_amount;
                 } else {
                     $params[$field] = $params['prevContribution']->{$field};
                     if ($params[$field] != $params['prevContribution']->{$field}) {
                     }
                 }
             }
         }
         self::calculateMissingAmountParams($params, $params['id']);
         if (!array_key_exists($params['financial_type_id'], $taxRates)) {
             // Assign tax Amount on update of contribution
             if (!empty($params['prevContribution']->tax_amount)) {
                 $params['tax_amount'] = 'null';
                 CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
                 foreach ($params['line_item'] as $setID => $priceField) {
                     foreach ($priceField as $priceFieldID => $priceFieldValue) {
                         $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
                     }
                 }
             }
         }
     }
     // New Contribution and update of contribution with tax rate financial type
     if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && empty($params['skipLineItem']) && !$isLineItem) {
         $taxRateParams = $taxRates[$params['financial_type_id']];
         $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount(CRM_Utils_Array::value('total_amount', $params), $taxRateParams);
         $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
         // Get Line Item on update of contribution
         if (isset($params['id'])) {
             CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
         } else {
             CRM_Price_BAO_LineItem::getLineItemArray($params);
         }
         foreach ($params['line_item'] as $setID => $priceField) {
             foreach ($priceField as $priceFieldID => $priceFieldValue) {
                 $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
             }
         }
         $params['total_amount'] = CRM_Utils_Array::value('total_amount', $params) + $params['tax_amount'];
     } elseif (isset($params['api.line_item.create'])) {
         // Update total amount of contribution using lineItem
         $taxAmountArray = array();
         foreach ($params['api.line_item.create'] as $key => $value) {
             if (isset($value['financial_type_id']) && array_key_exists($value['financial_type_id'], $taxRates)) {
                 $taxRate = $taxRates[$value['financial_type_id']];
                 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($value['line_total'], $taxRate);
                 $taxAmountArray[] = round($taxAmount['tax_amount'], 2);
             }
         }
         $params['tax_amount'] = array_sum($taxAmountArray);
         $params['total_amount'] = $params['total_amount'] + $params['tax_amount'];
     } else {
         // update line item of contrbution
         if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && $isLineItem) {
             $taxRate = $taxRates[$params['financial_type_id']];
             $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['line_total'], $taxRate);
             $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
         }
     }
     return $params;
 }
예제 #8
0
 /**
  * Get line item purchase information.
  *
  * This function takes the input parameters and interprets out of it what has been purchased.
  *
  * @param $fields
  *   This is the output of the function CRM_Price_BAO_PriceSet::getSetDetail($priceSetID, FALSE, FALSE);
  *   And, it would make sense to introduce caching into that function and call it from here rather than
  *   require the $fields array which is passed from pillar to post around the form in order to pass it in here.
  * @param array $params
  *   Params reflecting form input e.g with fields 'price_5' => 7, 'price_8' => array(7, 8)
  * @param $lineItem
  *   Line item array to be altered.
  * @param string $component
  *   This parameter appears to only be relevant to determining whether memberships should be auto-renewed.
  *   (and is effectively a boolean for 'is_membership' which could be calculated from the line items.)
  */
 public static function processAmount($fields, &$params, &$lineItem, $component = '')
 {
     // using price set
     $totalPrice = $totalTax = 0;
     $radioLevel = $checkboxLevel = $selectLevel = $textLevel = array();
     if ($component) {
         $autoRenew = array();
         $autoRenew[0] = $autoRenew[1] = $autoRenew[2] = 0;
     }
     foreach ($fields as $id => $field) {
         if (empty($params["price_{$id}"]) || empty($params["price_{$id}"]) && $params["price_{$id}"] == NULL) {
             // skip if nothing was submitted for this field
             continue;
         }
         switch ($field['html_type']) {
             case 'Text':
                 $firstOption = reset($field['options']);
                 $params["price_{$id}"] = array($firstOption['id'] => $params["price_{$id}"]);
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][key($field['options'])])) {
                     $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
                     $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
                 }
                 if (CRM_Utils_Array::value('name', $field['options'][key($field['options'])]) == 'contribution_amount') {
                     $taxRates = CRM_Core_PseudoConstant::getTaxRates();
                     if (array_key_exists($params['financial_type_id'], $taxRates)) {
                         $field['options'][key($field['options'])]['tax_rate'] = $taxRates[$params['financial_type_id']];
                         $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($field['options'][key($field['options'])]['amount'], $field['options'][key($field['options'])]['tax_rate']);
                         $field['options'][key($field['options'])]['tax_amount'] = round($taxAmount['tax_amount'], 2);
                         $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
                         $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
                     }
                 }
                 $totalPrice += $lineItem[$firstOption['id']]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[key($field['options'])]);
                 break;
             case 'Radio':
                 //special case if user select -none-
                 if ($params["price_{$id}"] <= 0) {
                     continue;
                 }
                 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
                 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
                 $optionLabel = CRM_Utils_Array::value('label', $field['options'][$optionValueId]);
                 $params['amount_priceset_level_radio'] = array();
                 $params['amount_priceset_level_radio'][$optionValueId] = $optionLabel;
                 if (isset($radioLevel)) {
                     $radioLevel = array_merge($radioLevel, array_keys($params['amount_priceset_level_radio']));
                 } else {
                     $radioLevel = array_keys($params['amount_priceset_level_radio']);
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
                     $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
                     $totalTax += $field['options'][$optionValueId]['tax_amount'];
                     if (CRM_Utils_Array::value('field_title', $lineItem[$optionValueId]) == 'Membership Amount') {
                         $lineItem[$optionValueId]['line_total'] = $lineItem[$optionValueId]['unit_price'] = CRM_Utils_Rule::cleanMoney($lineItem[$optionValueId]['line_total'] - $lineItem[$optionValueId]['tax_amount']);
                     }
                 }
                 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
                 if ($component && isset($lineItem[$optionValueId]['auto_renew']) && is_numeric($lineItem[$optionValueId]['auto_renew'])) {
                     $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
                 }
                 break;
             case 'Select':
                 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
                 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
                 $optionLabel = $field['options'][$optionValueId]['label'];
                 $params['amount_priceset_level_select'] = array();
                 $params['amount_priceset_level_select'][CRM_Utils_Array::key(1, $params["price_{$id}"])] = $optionLabel;
                 if (isset($selectLevel)) {
                     $selectLevel = array_merge($selectLevel, array_keys($params['amount_priceset_level_select']));
                 } else {
                     $selectLevel = array_keys($params['amount_priceset_level_select']);
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
                     $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
                     $totalTax += $field['options'][$optionValueId]['tax_amount'];
                 }
                 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
                 if ($component && isset($lineItem[$optionValueId]['auto_renew']) && is_numeric($lineItem[$optionValueId]['auto_renew'])) {
                     $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
                 }
                 break;
             case 'CheckBox':
                 $params['amount_priceset_level_checkbox'] = $optionIds = array();
                 foreach ($params["price_{$id}"] as $optionId => $option) {
                     $optionIds[] = $optionId;
                     $optionLabel = $field['options'][$optionId]['label'];
                     $params['amount_priceset_level_checkbox']["{$field['options'][$optionId]['id']}"] = $optionLabel;
                     if (isset($checkboxLevel)) {
                         $checkboxLevel = array_unique(array_merge($checkboxLevel, array_keys($params['amount_priceset_level_checkbox'])));
                     } else {
                         $checkboxLevel = array_keys($params['amount_priceset_level_checkbox']);
                     }
                 }
                 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
                 foreach ($optionIds as $optionId) {
                     if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionId])) {
                         $lineItem = self::setLineItem($field, $lineItem, $optionId);
                         $totalTax += $field['options'][$optionId]['tax_amount'];
                     }
                     $totalPrice += $lineItem[$optionId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionId]);
                     if ($component && isset($lineItem[$optionId]['auto_renew']) && is_numeric($lineItem[$optionId]['auto_renew'])) {
                         $autoRenew[$lineItem[$optionId]['auto_renew']] += $lineItem[$optionId]['line_total'];
                     }
                 }
                 break;
         }
     }
     $amount_level = array();
     $totalParticipant = 0;
     if (is_array($lineItem)) {
         foreach ($lineItem as $values) {
             $totalParticipant += $values['participant_count'];
             // This is a bit nasty. The logic of 'quick config' was because price set configuration was
             // (and still is) too difficult to replace the 'quick config' price set configuration on the contribution
             // page.
             //
             // However, because the quick config concept existed all sorts of logic was hung off it
             // and function behaviour sometimes depends on whether 'price set' is set - although actually it
             // is always set at the functional level. In this case we are dealing with the default 'quick config'
             // price set having a label of 'Contribution Amount' which could wind up creating a 'funny looking' label.
             // The correct answer is probably for it to have an empty label in the DB - the label is never shown so it is a
             // place holder.
             //
             // But, in the interests of being careful when capacity is low - avoiding the known default value
             // will get us by.
             // Crucially a test has been added so a better solution can be implemented later with some comfort.
             // @todo - stop setting amount level in this function & call the getAmountLevel function to retrieve it.
             if ($values['label'] != ts('Contribution Amount')) {
                 $amount_level[] = $values['label'] . ' - ' . (double) $values['qty'];
             }
         }
     }
     $displayParticipantCount = '';
     if ($totalParticipant > 0) {
         $displayParticipantCount = ' Participant Count -' . $totalParticipant;
     }
     // @todo - stop setting amount level in this function & call the getAmountLevel function to retrieve it.
     if (!empty($amount_level)) {
         $params['amount_level'] = CRM_Utils_Array::implodePadded($amount_level);
         if (!empty($displayParticipantCount)) {
             $params['amount_level'] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $amount_level) . $displayParticipantCount . CRM_Core_DAO::VALUE_SEPARATOR;
         }
     }
     $params['amount'] = CRM_Utils_Money::format($totalPrice, NULL, NULL, TRUE);
     $params['tax_amount'] = $totalTax;
     if ($component) {
         foreach ($autoRenew as $dontCare => $eachAmount) {
             if (!$eachAmount) {
                 unset($autoRenew[$dontCare]);
             }
         }
         if (count($autoRenew) > 1) {
             $params['autoRenew'] = $autoRenew;
         }
     }
 }