/** * Test to see if Promo Code is valid, used by Model validation. Note this doesn't mean that all products will use it, * just that at least item in the cart (or free shipping) will accept the code. If this function returns true, * we still have to Apply the code to the cart which will determine which items actually get the discount. * @param $attribute * @param $param */ public function validatePromocode($attribute, $param) { $strCode = $this->{$attribute}; if ($strCode == '') { return; } $objPromoCode = PromoCode::LoadByCode($strCode); if (!$objPromoCode) { $this->addError($attribute, Yii::t('global', 'Promo Code is invalid.')); return; } if (!$objPromoCode->enabled) { $this->addError($attribute, Yii::t('global', 'Promo Code is invalid')); return; } $strLabel = Yii::t('global', 'Promo Code'); if ($objPromoCode->Shipping) { $strLabel = Yii::t('global', 'Free Shipping'); } //If start date is defined, have we reached it yet if (!$objPromoCode->Started) { $this->addError($attribute, Yii::t('global', '{label} is not active yet.', array('{label}' => $strLabel))); return; } //If end date is defined or remaining uses if ($objPromoCode->Expired || !$objPromoCode->HasRemaining) { $this->addError($attribute, Yii::t('global', '{label} has expired or has been used up.', array('{label}' => $strLabel))); return; } //Minimum price threshold if (!is_null($objPromoCode->threshold)) { if ($objPromoCode->Threshold > Yii::app()->shoppingcart->originalSubTotal) { $this->addError($attribute, Yii::t('global', '{label} only valid when your purchases total at least {amount}.', array('{label}' => $strLabel, '{amount}' => _xls_currency($objPromoCode->threshold)))); return; } } //If this is for shipping, we need to make sure all items in the cart qualify if ($objPromoCode->Shipping) { //Test our two extremes -- all items or no items. The IsProductAffected() takes care of the reverse logic for No Items if ($objPromoCode->exception == PromoCode::QUALIFY_ALL_ITEMS || $objPromoCode == PromoCode::QUALIFY_NO_ITEMS) { $bolApplied = true; //We start with true because we want to make sure we don't have a disqualifying item in our cart foreach (Yii::app()->shoppingcart->cartItems as $objItem) { if (!$objPromoCode->IsProductAffected($objItem)) { $bolApplied = false; } } } //Test for just one qualifying item if ($objPromoCode->exception == PromoCode::QUALIFY_MIN_ONE_ITEM) { $bolApplied = false; foreach (Yii::app()->shoppingcart->cartItems as $objItem) { if ($objPromoCode->IsProductAffected($objItem)) { $bolApplied = true; } } } if ($bolApplied == false) { $this->addError($attribute, Yii::t('yii', 'We are sorry, but one or more of the items in your cart cannot be used with {label}.', array('{label}' => $strLabel))); return; } } else { //else for regular promo codes, see if any items in the cart match qualify for this promo code $bolApplied = false; foreach (Yii::app()->shoppingcart->cartItems as $objItem) { if ($objPromoCode->IsProductAffected($objItem)) { $bolApplied = true; } } //If we have reached this point and $bolApplied is still false, none of our items qualify if (!$bolApplied) { $this->addError($attribute, Yii::t('yii', 'We are sorry, but one or more of the items in your cart cannot be used with {label}.', array('{label}' => $strLabel))); return; } } }
public function applyPromoCode($mixCode) { if ($mixCode instanceof PromoCode) { $objPromoCode = $mixCode; } else { $objPromoCode = PromoCode::LoadByCode($mixCode); } if ($objPromoCode instanceof PromoCode) { $this->model->fk_promo_id = $objPromoCode->id; $this->recalculateAndSave(); } }
/** * Apply a promo code to the cart and return an array indicating what happened. * @param string $strPromoCode The promocode. * @return array An array indicating what happened. * ['success'] boolean Whether the promo code was applied. * ['action'] string Recommended action: alert|error|triggerCalc|success. * ['message'] string A message to display. */ protected function applyPromoCodeModal($strPromoCode) { if (Yii::app()->shoppingcart->PromoCode !== null) { return array('success' => false, 'action' => 'alert', 'message' => Yii::t('global', 'Only one promo code can be applied')); } $objPromoCode = new PromoCode(); $objPromoCode->code = $strPromoCode; $objPromoCode->setScenario('checkout'); if ($objPromoCode->validate() === false) { $arrErrors = $objPromoCode->getErrors(); return array('success' => false, 'action' => 'error', 'message' => $arrErrors['code'][0]); } $objPromoCode = PromoCode::LoadByCode($strPromoCode); Yii::app()->shoppingcart->applyPromoCode($objPromoCode); // See if this promo code is supposed to turn on free shipping. // This runs AFTER validate() so if we get here, it means that any // criteria have passed. So just apply and refresh the shipping list. if ($objPromoCode->Shipping) { // Update the shipping selection to use the free shipping module. $objFreeShipping = Modules::model()->freeshipping()->find(); if ($objFreeShipping !== null) { $checkoutForm = MultiCheckoutForm::loadFromSession(); if ($checkoutForm !== null) { try { $arrCartScenario = Shipping::getCartScenarios($checkoutForm); } catch (Exception $e) { $arrCartScenario = null; } if ($arrCartScenario !== null) { $freeShippingScenario = findWhere($arrCartScenario, array('providerId' => $objFreeShipping->id)); $checkoutForm = MultiCheckoutForm::loadFromSessionOrNew(); $checkoutForm->shippingProvider = $freeShippingScenario['providerId']; $checkoutForm->shippingPriority = $freeShippingScenario['priorityLabel']; MultiCheckoutForm::saveToSession($checkoutForm); } } } return array('success' => true, 'action' => 'triggerCalc', 'message' => Yii::t('global', 'Congratulations! This order qualifies for Free Shipping!')); } return array('success' => true, 'action' => 'success'); }