Version: current

      1 <?php
      2 /**
      3  * Декоратор заказа для оформления доставки
      4  *
      5  * @package cart_shipping
      6  * @author menedem
      7  */
      8 class ShippingOrderDecorator extends DataObjectDecorator{
      9
     10     protected $cachedEstimates = false;
     11
     12     function extraStatics(){
     13         return array(
     14             'db' => array(
     15                 'ShippingTotal' => 'CatalogPrice',
     16                 'Country' => 'ShopCountry',
     17                 'PostalCode' => 'Varchar(20)',
     18                 'State' => 'Varchar(100)',
     19                 'City' => 'Varchar(100)',
     20                 'Address' => 'Varchar(255)',
     21             ),
     22             'has_one' => array(
     23                 'ShippingMethod' => 'ShippingMethod',
     24             )
     25         );
     26     }
     27
     28     function updateCMSFields(& $fields) {
     29         $fields->insertBefore($fields->dataFieldByName('ShippingTotal')->performReadonlyTransformation(), 'Discount');
     30
     31         $fields->FindOrMakeTab('Root.Shipping', _t('Order.tabShipping', 'Address'));
     32         $fields->addFieldToTab('Root.Shipping', $fields->dataFieldByName('ShippingMethodID')->performReadonlyTransformation());
     33         $fields->addFieldToTab('Root.Shipping', new ReadonlyField('ShippingCost', _t('Order.db_ShippingTotal', 'Shipping Cost'), $this->owner->ShippingTotal));
     34         foreach (array('Country', 'PostalCode', 'State', 'City', 'Address') as $field) {
     35             if ($field != 'Country')
     36                 $fields->addFieldToTab('Root.Shipping', $fields->dataFieldByName($field));
     37             else
     38                 $fields->addFieldToTab('Root.Shipping', new RestrictionRegionCountryDropdownField($field, $this->owner->fieldLabel($field), null, $this->owner->{$field}));
     39         }
     40     }
     41
     42     /**
     43      * ???
     44      *
     45      * @return ShippingPackage
     46      */
     47     function createShippingPackage(){
     48         //create package, with total weight, dimensions, value, etc
     49         $weight = $quantity = 0;
     50         $weight = $this->Sum('Weight'); //Sum is found on OrdItemList (Component Extension)
     51         $dimensions = array();
     52         if (is_array(ShippingPackage::get_default_dimensions()) && count(ShippingPackage::get_default_dimensions())) {
     53             foreach(ShippingPackage::get_default_dimensions() as $dimension) {
     54                 $dimensions[$dimension] = $this->Sum($dimension);
     55             }
     56         }
     57         $cost = $this->owner->getTotalPrice();
     58         $quantity = $this->owner->getTotalQuantity();
     59         $order = $this->owner;
     60         $package = new ShippingPackage(
     61             $weight,
     62             array(
     63                 'Cost' => $cost,
     64                 'currency' => $this->owner->Currency(),
     65                 'quantity' => $quantity,
     66                 'Order' => $order,
     67             ),
     68             $dimensions
     69         );
     70         return $package;
     71     }
     72
     73     /**
     74      * ???
     75      *
     76      * @return Address|null
     77      */
     78     function getShippingAddress(){
     79         // если у заказа есть все обязательные поля, то собираем объект адрес
     80         $hasAddress = true;
     81         foreach (singleton('Address')->getRequiredfields() as $field) {
     82             if (!$this->owner->{$field}) {
     83                 $hasAddress = false;
     84             }
     85         }
     86         if ($hasAddress){
     87             //Собираем адрес из полей Заказа
     88             $address = new Address();
     89             $address->Country = $this->owner->Country;
     90             $address->State = $this->owner->State;
     91             $address->City = $this->owner->City;
     92             $address->Address = $this->owner->Address;
     93             $address->PostalCode = $this->owner->PostalCode;
     94             $address->ID = 1; // иначе в шаблонах определяется как false
     95             return $address;
     96         }elseif ($this->owner->Member() && $address = $this->owner->Member()->DefaultShippingAddress()){
     97             return $address;
     98         }
     99         return null;
    100     }
    101
    102     /**
    103      * ???
    104      *
    105      * @return DataObjectSet
    106      */
    107     function getShippingEstimates(){
    108         if (!$this->cachedEstimates) {
    109             $package = $this->createShippingPackage();
    110             $address = $this->getShippingAddress();
    111             $estimator = new ShippingEstimator($package, $address);
    112             $estimates = $estimator->getEstimates();
    113             $this->cachedEstimates = $estimates;
    114         }
    115         return $this->cachedEstimates;
    116     }
    117
    118     /**
    119      * Пробегается по всем позициям заказа и суммирует по ним указанное поле
    120      *
    121      * @param string $field - имя поля для суммирования
    122      *
    123      * @return float - сумма значений поля $field с учетом кол-ва позиций в заказе
    124      */
    125     function Sum($field){
    126         $total = 0;
    127         if($this->owner->Items()){
    128             foreach ($this->owner->Items() as $item){
    129                 if (($product = $item->getProduct()) && ($product->hasValue($field))){ //&& $product->hasValue($field)
    130                     $total += $product->RAW_val($field) * $item->Quantity;
    131                 }
    132             }
    133         }
    134         return $total;
    135     }
    136
    137     function updateGrandTotal(& $grandTotal) {
    138         if ($this->owner->ShippingTotal)
    139             $grandTotal += $this->owner->ShippingTotal;
    140     }
    141
    142     function onBeforeWrite() {
    143         // пересчитаем стоимость доставки
    144         if ($this->owner->ShippingMethodID && $this->owner->ShippingMethod()->ID) {
    145             $package = $this->createShippingPackage();
    146             $address = $this->getShippingAddress();
    147             $rate = $this->owner->ShippingMethod()->calculateRate($package, $address);
    148             if ($rate !== false) {
    149                 $this->owner->ShippingTotal = $rate;
    150             }
    151
    152             // пересчитаем общую стоимость заказа
    153             if ($this->owner->isChanged('ShippingTotal'))
    154                 $this->owner->GrandTotal += $this->owner->ShippingTotal;
    155         }
    156     }
    157 }

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -