/** * Get the options required by WsShippingEstimator.js. * * @param array $arrCartScenario An array of cart scenarios @see * Shipping::getCartScenarios. * @param integer $selectedShippingProviderId The ID (xlsws_modules.id) of * the selected shipping provider. * @param string $selectedShippingPriorityLabel The label for the shipping * priority. This value in combination with $selectedShippingProviderId * describes which shipping option is selected. * @param string $shippingCity The city that the cart is shipping to. * @param string $shippingStateCode The code for the state that the cart is shipping to. * @param string $shippingCountryCode The code the country that the cart is shipping to. * @param bool $updateOnLoad Whether the shipping estimator should get updated estimates right away. * * @return array $shippingEstimatorOptions */ public static function getShippingEstimatorOptions($arrCartScenario, $selectedShippingProviderId, $selectedShippingPriorityLabel, $shippingCity, $shippingStateCode, $shippingCountryCode, $updateOnLoad = false) { // Build up an associative array of the options required for the shipping estimator. $shippingEstimatorOptions = array('class' => self::CSS_CLASS, 'getShippingRatesEndpoint' => Yii::app()->createUrl('cart/getshippingrates'), 'setShippingOptionEndpoint' => Yii::app()->createUrl('cart/chooseshippingoption'), 'updateOnLoad' => CPropertyValue::ensureBoolean($updateOnLoad), 'shippingCity' => $shippingCity, 'shippingState' => $shippingStateCode, 'messages' => array()); // If a shipping country code is provided, then use it to get the // shipping country name. if ($shippingCountryCode !== null) { $shippingCountryName = Country::CountryByCode($shippingCountryCode); } else { // Otherwise, just use the first option from the list of countries. $countries = CHtml::listData(Country::getShippingCountries(), 'code', 'country'); $shippingCountryName = reset($countries); $shippingCountryCode = key($countries); } $shippingEstimatorOptions['shippingCountryName'] = $shippingCountryName; $shippingEstimatorOptions['shippingCountryCode'] = $shippingCountryCode; $shippingEstimatorOptions['selectedShippingOption'] = null; // With a set of shipping scenarios available and a previously selected // option, we can try to find a match. if ($arrCartScenario !== null) { if ($selectedShippingProviderId !== null && $selectedShippingPriorityLabel !== null) { // Try to find the previously selected option in the cart scenario array. $selectedCartScenario = findWhere($arrCartScenario, array('providerId' => $selectedShippingProviderId, 'priorityLabel' => $selectedShippingPriorityLabel)); if ($selectedCartScenario !== null) { // The selected scenario is available. $shippingEstimatorOptions['selectedProviderId'] = $selectedShippingProviderId; $shippingEstimatorOptions['selectedPriorityLabel'] = $selectedShippingPriorityLabel; // Currently if we get back too many shipping options, the selected one might // not be part of the returned options on the view since we limit our results to 8 // For now, a selected shipping option will be added as a key to the $shippingEstimatorOptions $shippingEstimatorOptions['selectedShippingOption'] = static::formartCartScenarioAsShippingOption($selectedCartScenario); } else { // The selected shipping option is not available. array_push($shippingEstimatorOptions['messages'], array('code' => 'WARN', 'message' => Yii::t('cart', 'Shipping option unavailable. Please choose another shipping option.'))); } } // Find store pickup and remove from array if found. // We must do this after we check to see if store // pickup was previously selected foreach ($arrCartScenario as $key => $cartScenario) { if ($cartScenario['module'] === 'storepickup') { // Setup message to show end user $strMessage = sprintf('We also offer %s. Proceed to checkout for complete details', $cartScenario['providerLabel']); array_push($shippingEstimatorOptions['messages'], array('code' => 'INFOTOP', 'message' => Yii::t('cart', $strMessage))); // remove store pickup from options unset($arrCartScenario[$key]); // there can be only one storepickup scenario // so no need to continue the loop break; } } // Apply the maximum shipping options limit to the cart scenarios. if (sizeof($arrCartScenario) > self::MAX_SHIPPING_OPTIONS) { $totalNumberOfOptions = sizeof($arrCartScenario); // In order to prevent writing "1 more shipping options" // (because it's not grammatically correct) we actually show 1 // less than the limit. $arrCartScenario = array_slice($arrCartScenario, 0, self::MAX_SHIPPING_OPTIONS - 1); array_push($shippingEstimatorOptions['messages'], array('code' => 'INFO', 'message' => Yii::t('cart', '{number} more shipping options. Proceed to checkout for complete options.', array('{number}' => $totalNumberOfOptions - sizeof($arrCartScenario))))); } // Format the cart scenarios into an array of shipping options. $shippingEstimatorOptions['shippingOptions'] = self::formatCartScenariosAsShippingOptions($arrCartScenario); } return $shippingEstimatorOptions; }
/** * Returns the cartScenario (element of array returned by * Shipping::getCartScenarios) that has been selected, from the session. * @return array|null A cart scenario associative array. * @see Shipping::getCartScenarios. */ public static function getSelectedCartScenarioFromSession() { $arrCartScenario = self::loadCartScenariosFromSession(); if ($arrCartScenario === null) { return null; } $checkoutForm = MultiCheckoutForm::loadFromSession(); if ($checkoutForm === null) { return null; } return findWhere($arrCartScenario, array('providerId' => $checkoutForm->shippingProvider, 'priorityLabel' => $checkoutForm->shippingPriority)); }
/** * 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'); }