/** * Run the widget. Renders the shipping estimator lines on the page. */ public function run() { // Required assets. $assets = Yii::app()->getAssetManager()->publish(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets', false, -1, true); Yii::app()->clientScript->registerScriptFile($assets . '/js/WsShippingEstimator.js'); $pathToZippo = Yii::getPathOfAlias('ext') . DIRECTORY_SEPARATOR . 'wsadvcheckout' . DIRECTORY_SEPARATOR . 'assets'; $assets = Yii::app()->getAssetManager()->publish($pathToZippo, false, -1, true); Yii::app()->clientScript->registerScriptFile($assets . '/zippo.js'); $checkoutForm = MultiCheckoutForm::loadFromSessionOrNew(); // We may wish to update the shipping options right away if we know the // cart has changed. $updateOnLoad = false; if ($this->updateShippingOptions) { // This check for shippingCountry being null is a workaround to fix // WS-3180. When shippingCountry is null, we need to update the // shipping estimates *now* because they will not be updated by the // JavaScript (since the JavaScript in WsShippingEstimator requires // country to be set). The reason we need to do this is because // shippingCountry may be null when in-store pickup has been // chosen. // TODO: Fix this in WsShippingEstimator and remove this workaround. if (empty($checkoutForm->shippingCountry) || empty($checkoutForm->shippingPostal)) { Shipping::updateCartScenariosInSession(); } else { $updateOnLoad = true; } } // Use the shipping scenarios and shipping address in the session. $arrCartScenario = Shipping::loadCartScenariosFromSession(); $wsShippingEstimatorOptions = self::getShippingEstimatorOptions($arrCartScenario, $checkoutForm->shippingProvider, $checkoutForm->shippingPriority, $checkoutForm->shippingCity, $checkoutForm->shippingStateCode, $checkoutForm->shippingCountryCode, $updateOnLoad); $selectedCartScenario = Shipping::getSelectedCartScenarioFromSession(); if ($selectedCartScenario !== null) { $formattedShippingPrice = $selectedCartScenario['formattedShippingPrice']; $formattedCartTax = $selectedCartScenario['formattedCartTax']; } else { $formattedShippingPrice = null; $formattedCartTax = null; } $this->render('_shippingestimator', array('countries' => CHtml::listData(Country::getShippingCountries(), 'code', 'country'), 'formattedShippingPrice' => $formattedShippingPrice, 'formattedCartTax' => $formattedCartTax, 'shippingCountryCode' => $wsShippingEstimatorOptions['shippingCountryCode'], 'shippingCountryName' => $wsShippingEstimatorOptions['shippingCountryName'], 'shippingPostal' => $checkoutForm->shippingPostal, 'wsShippingEstimatorOptions' => CJSON::encode($wsShippingEstimatorOptions), 'cssClass' => self::CSS_CLASS)); }
/** * Display a radio button list of shipping options * to the end user and process the chosen option * * @return void */ public function actionShippingOptions() { $this->publishJS('shipping'); $this->publishJS('zippo'); $this->layout = '/layouts/checkout'; $this->checkoutForm = MultiCheckoutForm::loadFromSessionOrNew(); // Check whether the user has selected a shipping option. if (isset($_POST['MultiCheckoutForm'])) { $this->checkoutForm->attributes = $_POST['MultiCheckoutForm']; $this->checkoutForm->hasTaxModeChanged = false; $this->checkoutForm->setScenario('ShippingOptions'); if ($this->checkoutForm->validate() === true) { $this->checkoutForm->saveFormToSession(); // Update the cart shipping in the database. // Update shipping. If in-store pickup was chosen then we need to // ensure the cart shipping values are updated. $objShipping = CartShipping::getOrCreateCartShipping(); if ($objShipping->hasErrors() === false) { $objShipping->updateShipping(); $this->checkoutForm->addErrors($objShipping->getErrors()); } else { $this->checkoutForm->addErrors($objShipping->getErrors()); } $this->checkoutForm->passedScenario = $this->checkoutForm->getScenario(); $this->redirect($this->createUrl('/checkout/final')); } else { Yii::log(sprintf('Validation of the checkout form failed: %s', print_r($this->checkoutForm->getErrors(), true)), 'error', 'application.' . __CLASS__ . '.' . __FUNCTION__); } } // In the case where the destination does not have a defined tax code, // return to the shipping page with an error message. if (Checkout::verifyUserShippingDestination($this->checkoutForm) === false) { Yii::log(sprintf('Shipping destination is invalid: country=%s state=%s postal=%s', $this->checkoutForm->shippingCountryCode, $this->checkoutForm->shippingStateCode, $this->checkoutForm->shippingPostal), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__); $this->redirect(array('/checkout/shipping', 'error-destination' => true)); return; } // Update the cart taxes prior to updating the cart scenarios. Yii::app()->shoppingcart->setTaxCodeByCheckoutForm($this->checkoutForm); $arrCartScenario = Shipping::loadCartScenariosFromSession(); // In the case where no shipping options are available, return to the // shipping page with an error message. // TODO: This isn't quite right. If store pickup is the only option, we // also want to display this error because store pickup is not shown // shown on the shipping options screen. See WS-3267. if ($arrCartScenario === null || count($arrCartScenario) === 0) { Yii::log(sprintf('No shipping options available: country=%s state=%s postal=%s', $this->checkoutForm->shippingCountryCode, $this->checkoutForm->shippingStateCode, $this->checkoutForm->shippingPostal), 'info', 'application.' . __CLASS__ . "." . __FUNCTION__); $this->redirect(array('/checkout/shipping', 'error-destination' => true)); return; } // Render the shipping options. // The options themselves are loaded from the session. // The implication here is that before redirecting to this page, ensure // that the shipping options stored in the session are up to date. $this->render('shippingoptions', array('model' => $this->checkoutForm, 'arrCartScenario' => $arrCartScenario, 'error' => $this->formatErrors())); }