/**
  * Function to process the form
  *
  * @access public
  * @return None
  */
 public function postProcess()
 {
     if ($this->_action & CRM_Core_Action::DELETE) {
         CRM_CiviDiscount_BAO_Item::del($this->_id);
         CRM_Core_Session::setStatus(ts('Selected Discount has been deleted.'), ts('Deleted'), 'success');
         return;
     }
     if ($this->_action & CRM_Core_Action::COPY) {
         $params = $this->exportValues();
         $newCode = CRM_CiviDiscount_Utils::randomString('abcdefghjklmnpqrstwxyz23456789', 8);
         CRM_CiviDiscount_BAO_Item::copy($this->_cloneID, $params, $newCode);
         CRM_Core_Session::setStatus(ts('Selected Discount has been duplicated.'), ts('Copied'), 'success');
         return;
     }
     $params = $this->exportValues();
     $params['count_max'] = (int) $params['count_max'];
     if ($this->_action & CRM_Core_Action::UPDATE) {
         $params['id'] = $this->_id;
     }
     $params['multi_valued'] = $this->_multiValued;
     if (isset($params['events']) && in_array(0, $params['events']) && count($params['events']) > 1) {
         CRM_Core_Session::setStatus(ts('You selected `any event` and specific events, specific events have been unset'));
         $params['events'] = array(0);
     }
     if (!empty($params['autodiscount_membership_type_id']) && count($params['autodiscount_membership_status_id']) == 0) {
         $params['autodiscount_membership_status_id'] = array('');
     }
     $params['filters'] = $this->getFiltersFromParams($params);
     $params['autodiscount'] = $this->getAutoDiscountFromParams($params);
     if (!empty($params['advanced_autodiscount_filter_entity'])) {
         $this->addAdvancedFilterToAutodiscount($params, $params['advanced_autodiscount_filter_entity'], CRM_Utils_Array::value('advanced_autodiscount_filter_string', $params));
     }
     $item = CRM_CiviDiscount_BAO_Item::add($params);
     CRM_Core_Session::setStatus(ts('The discount \'%1\' has been saved.', array(1 => $item->description ? $item->description : $item->code)), ts('Saved'), 'success');
 }
 static function getUsage($id = NULL, $cid = NULL, $orgid = NULL)
 {
     require_once 'CRM/CiviDiscount/Utils.php';
     require_once 'CRM/Member/BAO/Membership.php';
     require_once 'CRM/Contact/BAO/Contact.php';
     $where = '';
     $sql = "\nSELECT    t.item_id as item_id,\n      t.contact_id as contact_id,\n      t.used_date as used_date,\n      t.contribution_id as contribution_id,\n      t.entity_table as entity_table,\n      t.entity_id as entity_id,\n      t.description as description ";
     $from = " FROM cividiscount_track AS t ";
     if ($orgid) {
         $sql .= ", i.code ";
         $where = " LEFT JOIN cividiscount_item AS i ON (i.id = t.item_id) ";
         $where .= " WHERE i.organization_id = " . CRM_Utils_Type::escape($orgid, 'Integer');
     } else {
         if ($cid) {
             $where = " WHERE t.contact_id = " . CRM_Utils_Type::escape($cid, 'Integer');
         } else {
             $where = " WHERE t.item_id = " . CRM_Utils_Type::escape($id, 'Integer');
         }
     }
     $orderby = " ORDER BY t.item_id, t.used_date ";
     $sql = $sql . $from . $where . $orderby;
     $dao = new CRM_Core_DAO();
     $dao->query($sql);
     $rows = array();
     while ($dao->fetch()) {
         $row = array();
         $row['contact_id'] = $dao->contact_id;
         $row['display_name'] = CRM_Contact_BAO_Contact::displayName($dao->contact_id);
         $row['used_date'] = $dao->used_date;
         $row['contribution_id'] = $dao->contribution_id;
         $row['entity_table'] = $dao->entity_table;
         $row['entity_id'] = $dao->entity_id;
         $row['description'] = $dao->description;
         if (isset($dao->code)) {
             $row['code'] = $dao->code;
         }
         if ($row['entity_table'] == 'civicrm_participant') {
             $event_id = self::_get_participant_event($dao->entity_id);
             $events = CRM_CiviDiscount_Utils::getEvents();
             if (array_key_exists($event_id, $events)) {
                 $row['event_title'] = $events[$event_id];
             }
         } else {
             if ($row['entity_table'] == 'civicrm_membership') {
                 $result = CRM_Member_BAO_Membership::getStatusANDTypeValues($dao->entity_id);
                 if (array_key_exists($dao->entity_id, $result)) {
                     if (array_key_exists('membership_type', $result[$dao->entity_id])) {
                         $row['membership_title'] = $result[$dao->entity_id]['membership_type'];
                     }
                 }
             }
         }
         $rows[] = $row;
     }
     return $rows;
 }
/**
 * 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;
        }
        // // Don't provide Discount if the logged in user already subscribed to any membership types in the form
        $currentMemberships = $form->_currentMemberships;
        //if logged in
        if (!empty($currentMemberships)) {
            $new_member = FALSE;
        } else {
            // if not logged in
            $new_member = validate_email_for_discount($form);
        }
        /*
        Check if a payment type is set for discounts
        */
        $payids = array();
        $payids = _cividiscount_get_discounted_paymentProcessor_type_ids();
        $selectedProcessorValue = $form->_paymentProcessor['payment_processor_type_id'];
        $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;
                    }
                }
            }
        }
        if (!$new_member && !empty($code)) {
            echo "Sorry! Discount is not applicable for renewal!";
            return;
        }
        if (!empty($payids) && !empty($code)) {
            if (!in_array($selectedProcessorValue, $payids)) {
                echo "Sorry! Discount is only applicable for Direct Debit!";
                return;
            }
        }
        $form->set('_discountInfo', NULL);
        $dicountCalculater = new CRM_CiviDiscount_DiscountCalculator($pagetype, $eid, $contact_id, $code, FALSE);
        $discounts = $dicountCalculater->getDiscounts();
        if (!empty($code)) {
            if (empty($discounts)) {
                $form->set('discountCodeErrorMsg', ts('The discount code you entered is invalid.'));
            } else {
                /*gets discounts info, even if a discount code is not applicable 
                  for the membership types in the current form */
                // Check if a discount code is applicable to any of the membership types in the form
                $membership_ids_in_form = membership_type_ids_in_form($form);
                $membership_ids_in_dicount_info = array();
                foreach ($discounts as $code => $discount) {
                    $membership_ids_in_dicount_info = $discount['memberships'];
                }
                if (count(array_intersect($membership_ids_in_dicount_info, $membership_ids_in_form)) == 0) {
                    $form->set('discountCodeErrorMsg', ts('The discount code you entered is invalid.'));
                }
            }
        }
        if (empty($discounts)) {
            // Check if a discount is available
            if ($pagetype == 'event') {
                $discounts = _cividiscount_get_discounts();
                foreach ($discounts as $code => $discount) {
                    if (isset($discount['events']) && array_key_exists($eid, $discount['events']) && $discount['discount_msg_enabled']) {
                        // Display discount available message
                        CRM_Core_Session::setStatus(html_entity_decode($discount['discount_msg']), '', 'no-popup');
                    }
                }
            }
            return;
        }
        // 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.
        // here we need to check if selected price set is quick config
        $isQuickConfigPriceSet = CRM_CiviDiscount_Utils::checkForQuickConfigPriceSet($psid);
        $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($dicountCalculater->autoDiscounts) && array_key_exists($done_care, $dicountCalculater->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 for quickconfig pricesets
                if ($pagetype == 'event' && $isQuickConfigPriceSet) {
                    $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;
                        }
                    }
                }
            }
            $apcount = _cividiscount_checkEventDiscountMultipleParticipants($pagetype, $form, $discount);
            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;
                            }
                            $discountApplied = TRUE;
                        }
                    }
                }
            }
        }
        // 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));
        }
    }
}
 function preProcess()
 {
     $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE);
     require_once 'CRM/Utils/Rule.php';
     if (!CRM_Utils_Rule::positiveInteger($this->_id)) {
         CRM_Core_Error::fatal(ts('We need a valid discount ID for view'));
     }
     $this->assign('id', $this->_id);
     $defaults = array();
     $params = array('id' => $this->_id);
     require_once 'CRM/CiviDiscount/BAO/Item.php';
     CRM_CiviDiscount_BAO_Item::retrieve($params, $defaults);
     $this->assign('code_id', $defaults['id']);
     $this->assign('code', $defaults['code']);
     $this->assign('description', $defaults['description']);
     $this->assign('amount', $defaults['amount']);
     $this->assign('amount_type', $defaults['amount_type']);
     $this->assign('count_use', $defaults['count_use']);
     $this->assign('count_max', $defaults['count_max']);
     $this->assign('is_active', $defaults['is_active']);
     $this->assign('discount_term', $defaults['discount_term']);
     if (array_key_exists('expire_on', $defaults)) {
         $this->assign('expire_on', $defaults['expire_on']);
     }
     if (array_key_exists('active_on', $defaults)) {
         $this->assign('active_on', $defaults['active_on']);
     }
     if (array_key_exists('organization_id', $defaults)) {
         $this->assign('organization_id', $defaults['organization_id']);
         require_once 'CRM/Contact/BAO/Contact.php';
         $orgname = CRM_Contact_BAO_Contact::displayName($defaults['organization_id']);
         $this->assign('organization', $orgname);
     }
     $this->_multiValued = array('autodiscount' => NULL, 'memberships' => NULL, 'events' => NULL, 'pricesets' => NULL, 'pp_types' => NULL);
     foreach ($this->_multiValued as $mv => $info) {
         if (!empty($defaults[$mv])) {
             $v = substr($defaults[$mv], 1, -1);
             $values = explode(CRM_Core_DAO::VALUE_SEPARATOR, $v);
             $defaults[$mv] = array();
             if (!empty($values)) {
                 foreach ($values as $val) {
                     $defaults[$mv][] = $val;
                 }
             }
         }
     }
     require_once 'CRM/CiviDiscount/Utils.php';
     require_once 'CRM/Member/BAO/MembershipType.php';
     if (array_key_exists('pp_types', $defaults)) {
         $pp_types = CRM_CiviDiscount_Utils::getPaymentProcessorTypes();
         $defaults['pp_types'] = CRM_CiviDiscount_Utils::getIdsTitles($defaults['pp_types'], $pp_types);
         $this->assign('pp_types', $defaults['pp_types']);
     }
     if (array_key_exists('events', $defaults)) {
         $events = CRM_CiviDiscount_Utils::getEvents();
         $defaults['events'] = CRM_CiviDiscount_Utils::getIdsTitles($defaults['events'], $events);
         $this->assign('events', $defaults['events']);
     }
     $membershipTypes = CRM_Member_BAO_MembershipType::getMembershipTypes(FALSE);
     if (array_key_exists('memberships', $defaults)) {
         $defaults['memberships'] = CRM_CiviDiscount_Utils::getIdsTitles($defaults['memberships'], $membershipTypes);
         $this->assign('memberships', $defaults['memberships']);
     }
     if (array_key_exists('autodiscount', $defaults)) {
         $defaults['autodiscount'] = CRM_CiviDiscount_Utils::getIdsTitles($defaults['autodiscount'], $membershipTypes);
         $this->assign('autodiscount', $defaults['autodiscount']);
     }
     if (array_key_exists('pricesets', $defaults)) {
         $priceSets = CRM_CiviDiscount_Utils::getPriceSets();
         $defaults['pricesets'] = CRM_CiviDiscount_Utils::getIdsTitles($defaults['pricesets'], $priceSets);
         $this->assign('pricesets', $defaults['pricesets']);
     }
     CRM_Utils_System::setTitle($defaults['code']);
 }