|
|
- <?php
- if(!defined('QUINTACMS') ) die("No quinta.");
-
- if (!defined("SHIPPINGMODULE.CLASS.PHP")){
- define("SHIPPINGMODULE.CLASS.PHP",1);
-
- /**
- * Class ShippingModule - a module to display a selection of ShippingMethods
- *
- * This class obtains any shipping methods flagged as active in the database and
- * adds them to a radiobutton list which is the only display object. For each method
- * a new ShippingCalculator is instantiated and GetEstimate is called to obtain a price
- * for the order based on information in the OrderItems and the addresses (ie. weight,
- * size and destination).
- *
- * @todo
- * - check availability more gracefully
- * - handle errors
- *
- *@author Erik Winn <sidewalksoftware@gmail.com>
- *
- *@version 0.3
- *
- *@package Quinta
- * @subpackage Modules
- */
- class ShippingModule extends QPanel{
- public $blnDebug = false;
- /**
- * This is the main control block for this module - it is designed to be the CheckOutModule,
- * but it may be used with other controllers as long as you pass an Order object as we obtain
- * address information, weight, etc from the order ..
- *@var QPanel objControlBlock - the main control block for this module, usually CheckOutModule
- */
- protected $objControlBlock;
- /**
- *@var Order objOrder - a local reference to the Order
- */
- protected $objOrder;
- /**
- *@var Address objAddress - a local reference to the Address
- */
- protected $objAddress;
- /**
- *@var ShippingMethod objSelectedMethod - the selected method for this module
- */
- protected $objSelectedMethod;
- /**
- *@var array aryShippingMethods - the active methods available for this module
- */
- protected $aryShippingMethods;
-
- protected $strDefaultCarrier;
- protected $strDefaultServiceType;
-
- protected $fltShippingTotal;
- protected $blnHasActiveMethods=true;
- protected $blnIsInternational=false;
- protected $intPreviousAddressId;
- /**
- * This is a mapping of shipping provider to method. Each ShippingMethod has a title
- * field, this is displayed at the top of a block showing each method active for a provider.
- * The title field is used as the title of the block, so the map is in the form title => objShippingMethodController
- * the view containing a radiobutton for the selection of that method.
- *@var array aryShippingProviders - an array/map of Carriers to methods
- */
- public $aryShippingProviders;
-
- /**
- *@var AddressSelectionModule objAddressSelectionModule - handles selecting the shipping address
- */
- public $objAddressSelectionModule;
- /**
- *@var QTextBox txtNotes - customer comments added to order ..
- */
- public $txtNotes;
- /**
- * Module constructor
- *@param QPanel objControlBlock - the main control block for this module, usually CheckOutModule
- *@param Order objOrder - the order to be shipped ...
- */
- public function __construct($pnlParentObject, $objControlBlock, Order $objOrder, $blnDebug = false ){
-
- try {
- parent::__construct($pnlParentObject );
- } catch (QCallerException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
-
- if($blnDebug)
- $this->blnDebug = $blnDebug;
- $this->strDefaultCarrier = DEFAULT_SHIPPING_CARRIER;
- $this->strDefaultServiceType = DEFAULT_SHIPPING_SERVICE;
-
- //normally refers to the CheckOutModule ..
- $this->objControlBlock =& $objControlBlock;
-
- $this->objOrder =& $objOrder;
-
- $this->AutoRenderChildren = true;
- $this->strTemplate = __QUINTA_CORE_VIEWS__ . '/ShippingModule.tpl.php';
-
- $this->initMethodViews();
- if( !empty($this->aryShippingMethods)){
- $this->objAddressSelectionModule = new AddressSelectionModule($this,
- 'SelectAddress',
- $this->objOrder->ShippingAddressId
- );
- $this->objAddress = $this->objAddressSelectionModule->Address;
- }else
- $this->blnHasActiveMethods = false;
-
- $this->txtNotes = new QTextBox($this);
- $this->txtNotes->TextMode = QTextMode::MultiLine;
- $this->txtNotes->Columns = 30;
- }
-
- /**
- * This function initializes the array of potential shipping methods
- *@todo make the local pickup option configurable, currently you have to change the check here ..
- */
- protected function initShippingMethods(){
- if( $this->objOrder->IsInternational)
- $this->aryShippingMethods = ShippingMethod::QueryArray( QQ::AndCondition(
- QQ::Equal(QQN::ShippingMethod()->Active, true),
- QQ::Equal(QQN::ShippingMethod()->IsInternational,true)
- ));
- else
- $this->aryShippingMethods = ShippingMethod::QueryArray(
- QQ::Equal(QQN::ShippingMethod()->Active, true)
- );
-
- if(ZoneType::Colorado == $this->objOrder->ShippingZoneId )
- $this->aryShippingMethods[] = ShippingMethod::Load(1);
- }
- /**
- * This function creates a radio button to display for each active shipping method as
- * appropriate - if the method is not international no button will be created for an international
- * order and if a method is not available or returns a 0 rate charge it will also not be created.
- * @todo
- * - check availability
- * - implement try/catch to handle errors, log them when not debugging.
- */
- protected function initMethodViews(){
- $this->initShippingMethods();
-
- if( empty($this->aryShippingMethods))
- return;
-
- if( is_array($this->aryShippingProviders) ){
- foreach( $this->aryShippingProviders as $strName => &$aryMethodViews ){
- foreach($aryMethodViews as $it => $objMethodView){
- $strControlId = $objMethodView->ControlId;
- $this->RemoveChildControl($strControlId, true);
- unset($aryMethodViews[$it]);
- }
- unset($this->aryShippingProviders[$strName]);
- }
- $this->aryShippingProviders = array();
- }
-
- foreach($this->aryShippingMethods as $objShippingMethod){
- //Fedex Ground international only goes for Canada
- if($this->objOrder->IsInternational && CountryType::Canada != $this->objOrder->ShippingCountryId
- && false !== stripos( $objShippingMethod->ServiceType, 'FEDEX_GROUND' ) )
- continue;
- //Skip the Fedex international methods for domestic orders ..
- if( !$this->objOrder->IsInternational
- && ( false !== stripos( $objShippingMethod->ServiceType, 'GLOBAL' )
- || false !== stripos( $objShippingMethod->ServiceType, 'INTERNATIONAL' )) )
- continue;
-
- $objShippingMethod->Init($this->objOrder);
- ///@todo check availability ..
- /* if( ! $objShippingMethod->MethodAvailable() ) continue;*/
- $objShippingMethod->GetRate();
- /**
- *@todo figure this out - USPS, eg. provides no clear way to determine availability (in fact i can't even
- * find their !@#$ing error codes ..) so for now if there is no charge we assume it is not available ..
- */
- if( ! $objShippingMethod->IsAvailable || $objShippingMethod->HasErrors || 0 == $objShippingMethod->Rate ){
- // if($this->blnDebug && 'FEDEX_2_DAY' != $objShippingMethod->ServiceType)
- if($this->blnDebug)
- // exit(var_dump($objShippingMethod));
- die($objShippingMethod->Title . ', '
- . $objShippingMethod->ServiceType . '<br /> '
- . $objShippingMethod->Errors );
- else
- continue;
- }
- //eh, could be a server error .. skip it. todo: make me smarter ..
- if( ! is_numeric($objShippingMethod->Rate) )
- continue;
-
- $objShippingMethodController = new ShippingMethodController($this, $objShippingMethod);
-
- //set the defaults here - note that if the default method is not active this leaves everything
- //null until/unless the user selects a method; hence default should be properly configured.
- if( $objShippingMethod->Carrier == $this->strDefaultCarrier
- && $objShippingMethod->ServiceType == $this->strDefaultServiceType )
- {
- $objShippingMethodController->Checked = true;
- $this->objSelectedMethod = $objShippingMethod;
- $this->objOrder->ShippingMethodId = $objShippingMethod->Id;
- $this->objOrder->ShippingCharged = $objShippingMethod->Rate;
- }
- //store by title for the method display ..
- $this->aryShippingProviders[$objShippingMethod->Title][] = $objShippingMethodController;
- }
- }
-
- /**
- * This Function is called when the user selects a method - it sets objSelectedMethod
- * and updates ShippingMethodId and ShippingCharged in the Order ..
- *@param integer intShippingMethodId - the id of the selected method
- */
- public function SelectMethod($intShippingMethodId){
- foreach($this->aryShippingMethods as $objMethod )
- if($intShippingMethodId == $objMethod->Id){
- //this is redundant .. todo: pick one way or the other?
- $this->objSelectedMethod = $objMethod;
- $this->objOrder->ShippingMethodId = $objMethod->Id;
- $this->objOrder->ShippingCharged = $objMethod->Rate;
- if($this->objControlBlock instanceof CheckOutModule)
- $this->objControlBlock->RefreshOrderTotalsController();
- break;
- }
- }
-
- public function SelectAddress($intAddressId, $strParameter=null){
- if( is_numeric($intAddressId) ){
- $this->intPreviousAddressId = $intAddressId;
- $this->objOrder->SetShippingAddress($this->objAddressSelectionModule->Address);
- $this->objAddress = $this->objAddressSelectionModule->Address;
- }
-
- $this->objAddressSelectionModule->RemoveChildControls(true);
- $this->RemoveChildControl($this->objAddressSelectionModule->ControlId, false);
-
- if( 'Edit' == $strParameter )
- $this->objAddressSelectionModule = new AddressSelectionModule($this, 'SelectAddress', $intAddressId, true);
- elseif( 'New' == $strParameter )
- $this->objAddressSelectionModule = new AddressSelectionModule($this, 'SelectAddress', null, true);
- else{//Note: includes Save and Cancel .
- if($intAddressId)
- $this->objAddressSelectionModule = new AddressSelectionModule($this, 'SelectAddress', $intAddressId);
- else
- $this->objAddressSelectionModule = new AddressSelectionModule($this, 'SelectAddress', $this->intPreviousAddressId);
- //Refresh the options listing ..
- $this->initMethodViews();
- }
-
- $this->objAddressSelectionModule->Visible = true;
- $this->AddChildControl($this->objAddressSelectionModule);
- }
- /**
- * This Function is called when any input is sent - on failure the
- * fields are redrawn with optional error messages.
- */
- public function Validate(){
- $blnToReturn = true;
- // validate input here
- return $blnToReturn;
- }
-
- public function __get($strName){
- switch ($strName){
- case 'Notes':
- return $this->txtNotes->Text ;
- case 'SelectedMethod':
- return $this->objSelectedMethod ;
- case 'Address':
- return $this->objAddress ;
- case 'HasActiveMethods':
- return $this->blnHasActiveMethods ;
- case 'IsInternational':
- return $this->blnIsInternational ;
- case 'DefaultCarrier':
- return $this->strDefaultCarrier ;
- case 'DefaultServiceType':
- return $this->strDefaultServiceType ;
- default:
- try {
- return parent::__get($strName);
- } catch (QCallerException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
- }
- }
- public function __set($strName, $mixValue){
- switch ($strName){
- case 'IsInternational':
- try {
- return ($this->blnIsInternational = QType::Cast($mixValue, Qtype::Boolean ));
- } catch (QInvalidCastException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
- case 'DefaultCarrier':
- try {
- return ($this->strDefaultCarrier = QType::Cast($mixValue, Qtype::String ));
- } catch (QInvalidCastException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
- case 'DefaultServiceType':
- try {
- return ($this->strDefaultServiceType = QType::Cast($mixValue, Qtype::String ));
- } catch (QInvalidCastException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
-
- default:
- try {
- return (parent::__set($strName, $mixValue));
- } catch (QCallerException $objExc) {
- $objExc->IncrementOffset();
- throw $objExc;
- }
- }
- }
-
- }//end class
- }//end define
- ?>
|