| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228 | 
							- <?php
 
- /**
 
-  *
 
-  * PHP Pro Bid $Id$ 94C7KNN/BdTtx4IqxR5vsTzCIGduH+ERfjL0ZUax41U=
 
-  *
 
-  * @link        http://www.phpprobid.com
 
-  * @copyright   Copyright (c) 2017 Online Ventures Software & CodeCube SRL
 
-  * @license     http://www.phpprobid.com/license Commercial License
 
-  *
 
-  * @version     7.9 [rev.7.9.02]
 
-  */
 
- /**
 
-  * shipping model
 
-  *
 
-  * the model will require a user object in order to be initialized, and to be able
 
-  * to calculate postage, it will require either a listing owned by the user, or
 
-  * a sale made by the user
 
-  *
 
-  * Important: the calculation will always take the location of the item(s) as the source location,
 
-  * and not the location of the owner
 
-  */
 
- namespace Ppb\Model;
 
- use Cube\Controller\Front,
 
-     Cube\Translate,
 
-     Cube\Translate\Adapter\AbstractAdapter as TranslateAdapter,
 
-     Ppb\Db\Table\Row\User as UserModel,
 
-     Ppb\Db\Table\Row\Listing as ListingModel,
 
-     Ppb\Form\Element\FlatRatesLocationGroups,
 
-     Ppb\Service;
 
- class Shipping
 
- {
 
-     /**
 
-      * weight uom
 
-      */
 
-     const UOM_LBS = 'lbs';
 
-     const UOM_KG = 'kg';
 
-     /**
 
-      * dimensions uom
 
-      */
 
-     const UOM_INCHES = 'inches';
 
-     const UOM_CM = 'cm';
 
-     /**
 
-      * dimension coordinates
 
-      */
 
-     const DIMENSION_LENGTH = 'length';
 
-     const DIMENSION_WIDTH = 'width';
 
-     const DIMENSION_HEIGHT = 'height';
 
-     /**
 
-      * min weight value
 
-      */
 
-     const MIN_WEIGHT = 0.1;
 
-     /**
 
-      * pickup options
 
-      */
 
-     const NO_PICKUPS = 'no_pickups';
 
-     const CAN_PICKUP = 'can_pickup';
 
-     const MUST_PICKUP = 'must_pickup';
 
-     /**
 
-      * key and value for drop downs for the pick-up option
 
-      */
 
-     const KEY_PICK_UP = -1;
 
-     const VALUE_PICK_UP = 'Pick-up';
 
-     /**
 
-      * seller postage setup page fields
 
-      */
 
-     const SETUP_FREE_POSTAGE = 'free_postage';
 
-     const SETUP_FREE_POSTAGE_AMOUNT = 'free_postage_amount';
 
-     const SETUP_POSTAGE_TYPE = 'postage_type';
 
-     const SETUP_POSTAGE_FLAT_FIRST = 'postage_flat_first';
 
-     const SETUP_POSTAGE_FLAT_ADDL = 'postage_flat_addl';
 
-     const SETUP_SHIPPING_CARRIERS = 'shipping_carriers';
 
-     const SETUP_WEIGHT_UOM = 'weight_uom';
 
-     const SETUP_SHIPPING_LOCATIONS = 'shipping_locations';
 
-     const SETUP_LOCATION_GROUPS = 'location_groups';
 
-     const SETUP_DIMENSIONS_UOM = 'dimensions_uom';
 
-     /**
 
-      * postage calculation types
 
-      */
 
-     const POSTAGE_TYPE_ITEM = 'item';
 
-     const POSTAGE_TYPE_FLAT = 'flat';
 
-     const POSTAGE_TYPE_CARRIERS = 'carriers';
 
-     /**
 
-      * shipping locations options
 
-      */
 
-     const POSTAGE_LOCATION_DOMESTIC = 'domestic';
 
-     const POSTAGE_LOCATION_WORLDWIDE = 'worldwide';
 
-     const POSTAGE_LOCATION_CUSTOM = 'custom';
 
-     /**
 
-      * listing setup shipping related fields
 
-      */
 
-     const FLD_ACCEPT_RETURNS = 'accept_returns';
 
-     const FLD_RETURNS_POLICY = 'returns_policy';
 
-     const FLD_PICKUP_OPTIONS = 'pickup_options';
 
-     const FLD_SHIPPING_DETAILS = 'shipping_details';
 
-     const FLD_POSTAGE = 'postage';
 
-     const FLD_ITEM_WEIGHT = 'item_weight';
 
-     const FLD_DIMENSIONS = 'dimensions';
 
-     const FLD_INSURANCE = 'insurance';
 
-     /**
 
-      * listings data array keys
 
-      */
 
-     const DATA_LISTING = 'listing';
 
-     const DATA_QUANTITY = 'quantity';
 
-     /**
 
-      * standard shipping method desc.
 
-      */
 
-     const MSG_STANDARD_SHIPPING = 'Standard Shipping';
 
-     /**
 
-      *
 
-      * weight uom list
 
-      *
 
-      * @var array
 
-      */
 
-     public static $weightUom = array(
 
-         self::UOM_LBS => 'Lbs',
 
-         self::UOM_KG  => 'Kg'
 
-     );
 
-     /**
 
-      *
 
-      * dimensions uom list
 
-      *
 
-      * @var array
 
-      */
 
-     public static $dimensionsUom = array(
 
-         self::UOM_INCHES => 'inches',
 
-         self::UOM_CM     => 'cm',
 
-     );
 
-     public static $dimensionsCoordinates = array(
 
-         self::DIMENSION_LENGTH => 'Length',
 
-         self::DIMENSION_WIDTH  => 'Width',
 
-         self::DIMENSION_HEIGHT => 'Height',
 
-     );
 
-     /**
 
-      *
 
-      * pick-up options array
 
-      *
 
-      * @var array
 
-      */
 
-     public static $pickupOptions = array(
 
-         self::NO_PICKUPS  => 'No pick-ups',
 
-         self::CAN_PICKUP  => 'Buyer can pick-up',
 
-         self::MUST_PICKUP => 'Buyer must pick-up',
 
-     );
 
-     /**
 
-      *
 
-      * seller postage setup page fields
 
-      *
 
-      * @var array
 
-      */
 
-     public static $postageSetupFields = array(
 
-         self::SETUP_FREE_POSTAGE        => 'Offer Free Postage',
 
-         self::SETUP_FREE_POSTAGE_AMOUNT => 'If amount exceeds',
 
-         self::SETUP_POSTAGE_TYPE        => 'Postage Calculation Type',
 
-         self::SETUP_POSTAGE_FLAT_FIRST  => 'First Item',
 
-         self::SETUP_POSTAGE_FLAT_ADDL   => 'Additional Items',
 
-         self::SETUP_SHIPPING_CARRIERS   => 'Select Shipping Carriers',
 
-         self::SETUP_WEIGHT_UOM          => 'Weight UOM',
 
-         self::SETUP_SHIPPING_LOCATIONS  => 'Shipping Locations',
 
-         self::SETUP_LOCATION_GROUPS     => 'Location Groups',
 
-         self::SETUP_DIMENSIONS_UOM      => 'Dimensions UOM',
 
-     );
 
-     /**
 
-      *
 
-      * listing postage related fields array
 
-      *
 
-      * @var array
 
-      */
 
-     public static $postageFields = array(
 
-         self::FLD_ACCEPT_RETURNS   => 'Accept Returns',
 
-         self::FLD_RETURNS_POLICY   => 'Return Policy Details',
 
-         self::FLD_PICKUP_OPTIONS   => 'Pick-ups',
 
-         self::FLD_POSTAGE          => 'Postage',
 
-         self::FLD_ITEM_WEIGHT      => 'Item Weight',
 
-         self::FLD_DIMENSIONS       => 'Dimensions',
 
-         self::FLD_INSURANCE        => 'Insurance',
 
-         self::FLD_SHIPPING_DETAILS => 'Shipping Instructions',
 
-     );
 
-     /**
 
-      *
 
-      * default dimensions - standard rectangular box
 
-      *
 
-      * @var array
 
-      */
 
-     protected static $_defaultDimensions = array(
 
-         self::DIMENSION_LENGTH => 12,
 
-         self::DIMENSION_WIDTH  => 9,
 
-         self::DIMENSION_HEIGHT => 6,
 
-     );
 
-     /**
 
-      *
 
-      * seller user model
 
-      *
 
-      * @var \Ppb\Db\Table\Row\User
 
-      */
 
-     protected $_user;
 
-     /**
 
-      *
 
-      * the postage settings that the seller has set up
 
-      *
 
-      * @var array
 
-      */
 
-     protected $_postageSettings = array();
 
-     /**
 
-      *
 
-      * array of data of listing object - quantity combinations for which the postage is to be calculated
 
-      *
 
-      * @var array
 
-      */
 
-     protected $_data = array();
 
-     /**
 
-      *
 
-      * locations table service
 
-      *
 
-      * @var \Ppb\Service\Table\Relational\Locations
 
-      */
 
-     protected $_locations;
 
-     /**
 
-      *
 
-      * currencies table service
 
-      *
 
-      * @var \Ppb\Service\Table\Currencies
 
-      */
 
-     protected $_currencies;
 
-     /**
 
-      *
 
-      * translate adapter
 
-      *
 
-      * @var \Cube\Translate\Adapter\AbstractAdapter
 
-      */
 
-     protected $_translate;
 
-     /**
 
-      *
 
-      * the location id of the destination (from the locations table)
 
-      *
 
-      * @var int
 
-      */
 
-     protected $_locationId;
 
-     /**
 
-      *
 
-      * the zip/post code of the destination
 
-      *
 
-      * @var string
 
-      */
 
-     protected $_postCode;
 
-     /**
 
-      *
 
-      * the name of the shipping method that will be used to send the items.
 
-      * (valid for shipping carriers too)
 
-      *
 
-      * @var string
 
-      */
 
-     protected $_postageMethod;
 
-     /**
 
-      *
 
-      * this flag is set from the addData() method
 
-      *
 
-      * @var bool
 
-      */
 
-     protected $_canPickUp = false;
 
-     /**
 
-      *
 
-      * the currency of the listings inserted in the model
 
-      *
 
-      * @var string
 
-      */
 
-     protected $_currency;
 
-     /**
 
-      *
 
-      * class constructor
 
-      *
 
-      * @param \Ppb\Db\Table\Row\User $user
 
-      */
 
-     public function __construct(UserModel $user)
 
-     {
 
-         $this->_user = $user;
 
-         $this->setPostageSettings($user['postage_settings']);
 
-     }
 
-     /**
 
-      *
 
-      * get pick-up option description
 
-      *
 
-      * @param string $key pick-up option key
 
-      *
 
-      * @return string|null
 
-      */
 
-     public static function getPickupOptions($key)
 
-     {
 
-         if (isset(self::$pickupOptions[$key])) {
 
-             return self::$pickupOptions[$key];
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *
 
-      * get postage settings
 
-      *
 
-      * @param string|null $key
 
-      *
 
-      * @return mixed
 
-      */
 
-     public function getPostageSettings($key = null)
 
-     {
 
-         if ($key !== null) {
 
-             return (isset($this->_postageSettings[$key])) ? $this->_postageSettings[$key] : null;
 
-         }
 
-         return $this->_postageSettings;
 
-     }
 
-     /**
 
-      *
 
-      * set postage settings (accepted an array or a serialized string)
 
-      *
 
-      * @param array|string $postageSettings
 
-      *
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function setPostageSettings($postageSettings)
 
-     {
 
-         if (!is_array($postageSettings)) {
 
-             $postageSettings = \Ppb\Utility::unserialize($postageSettings, array());
 
-         }
 
-         $this->_postageSettings = $postageSettings;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get currencies table service
 
-      *
 
-      * @return \Ppb\Service\Table\Currencies
 
-      */
 
-     public function getCurrencies()
 
-     {
 
-         if (!$this->_currencies instanceof Service\Table\Currencies) {
 
-             $this->setCurrencies(
 
-                 new Service\Table\Currencies());
 
-         }
 
-         return $this->_currencies;
 
-     }
 
-     /**
 
-      *
 
-      * set currencies service
 
-      *
 
-      * @param \Ppb\Service\Table\Currencies $currencies
 
-      *
 
-      * @return $this
 
-      */
 
-     public function setCurrencies(Service\Table\Currencies $currencies)
 
-     {
 
-         $this->_currencies = $currencies;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * set translate adapter
 
-      *
 
-      * @param \Cube\Translate\Adapter\AbstractAdapter $translate
 
-      *
 
-      * @return $this
 
-      */
 
-     public function setTranslate(TranslateAdapter $translate)
 
-     {
 
-         $this->_translate = $translate;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get translate adapter
 
-      *
 
-      * @return \Cube\Translate\Adapter\AbstractAdapter
 
-      */
 
-     public function getTranslate()
 
-     {
 
-         if (!$this->_translate instanceof TranslateAdapter) {
 
-             $translate = Front::getInstance()->getBootstrap()->getResource('translate');
 
-             if ($translate instanceof Translate) {
 
-                 $this->setTranslate(
 
-                     $translate->getAdapter());
 
-             }
 
-         }
 
-         return $this->_translate;
 
-     }
 
-     /**
 
-      *
 
-      * get data array
 
-      *
 
-      * @return array
 
-      */
 
-     public function getData()
 
-     {
 
-         return $this->_data;
 
-     }
 
-     /**
 
-      *
 
-      * set data array
 
-      *
 
-      * @param array $data
 
-      *
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function setData(array $data)
 
-     {
 
-         $this->_data = array();
 
-         $this->_canPickUp = false;
 
-         foreach ($data as $row) {
 
-             $this->addData($row[self::DATA_LISTING], $row[self::DATA_QUANTITY]);
 
-         }
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * add a data row in the array
 
-      * all items that are added must have the same location
 
-      *  ** and currency (for now)
 
-      *  ** and pickup options as well
 
-      *
 
-      * @param \Ppb\Db\Table\Row\Listing $listing
 
-      * @param int                       $quantity
 
-      *
 
-      * @throws \RuntimeException
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function addData(ListingModel $listing, $quantity = 1)
 
-     {
 
-         foreach ($this->_data as $data) {
 
-             if (
 
-                 $data[self::DATA_LISTING]['country'] != $listing['country'] ||
 
-                 $data[self::DATA_LISTING]['state'] != $listing['state'] ||
 
-                 $data[self::DATA_LISTING]['address'] != $listing['address'] ||
 
-                 $data[self::DATA_LISTING]['currency'] != $listing['currency'] ||
 
-                 $data[self::DATA_LISTING][self::FLD_PICKUP_OPTIONS] != $listing[self::FLD_PICKUP_OPTIONS]
 
-             ) {
 
-                 $translate = $this->getTranslate();
 
-                 throw new \RuntimeException($translate->_("All the listings added in the shipping model must have the same location "
 
-                     . "(country, state, address), use the same currency and have the same pick-up options selected."));
 
-             }
 
-         }
 
-         if ($listing[self::FLD_PICKUP_OPTIONS] !== self::NO_PICKUPS) {
 
-             $this->_canPickUp = true;
 
-         }
 
-         $this->_data[] = array(
 
-             self::DATA_LISTING  => $listing,
 
-             self::DATA_QUANTITY => ($quantity > 0) ? (int)$quantity : 1
 
-         );
 
-         $this->_currency = $listing['currency'];
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get locations service
 
-      *
 
-      * @return \Ppb\Service\Table\Relational\Locations
 
-      */
 
-     public function getLocations()
 
-     {
 
-         if (!$this->_locations instanceof Service\Table\Relational\Locations) {
 
-             $this->setLocations(
 
-                 new Service\Table\Relational\Locations());
 
-         }
 
-         return $this->_locations;
 
-     }
 
-     /**
 
-      *
 
-      * set locations service
 
-      *
 
-      * @param \Ppb\Service\Table\Relational\Locations $locations
 
-      *
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function setLocations(Service\Table\Relational\Locations $locations)
 
-     {
 
-         $this->_locations = $locations;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get destination location id
 
-      *
 
-      * @return int
 
-      */
 
-     public function getLocationId()
 
-     {
 
-         return $this->_locationId;
 
-     }
 
-     /**
 
-      *
 
-      * set destination location id
 
-      *
 
-      * @param int $locationId
 
-      *
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function setLocationId($locationId)
 
-     {
 
-         $this->_locationId = (int)$locationId;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get destination location post code
 
-      *
 
-      * @return string
 
-      */
 
-     public function getPostCode()
 
-     {
 
-         return $this->_postCode;
 
-     }
 
-     /**
 
-      *
 
-      * set destination location post code
 
-      *
 
-      * @param string $postCode
 
-      *
 
-      * @return \Ppb\Model\Shipping
 
-      */
 
-     public function setPostCode($postCode)
 
-     {
 
-         $this->_postCode = (string)$postCode;
 
-         return $this;
 
-     }
 
-     public function getPostageMethod()
 
-     {
 
-         $translate = $this->getTranslate();
 
-         if (null !== $translate) {
 
-             return $translate->_($this->_postageMethod);
 
-         }
 
-         return $this->_postageMethod;
 
-     }
 
-     public function setPostageMethod($postageMethod)
 
-     {
 
-         $this->_postageMethod = (string)$postageMethod;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get weight uom set by the user
 
-      *
 
-      * @param bool $sentence
 
-      *
 
-      * @return string
 
-      */
 
-     public function getWeightUom($sentence = true)
 
-     {
 
-         $weightUom = $this->getPostageSettings(self::SETUP_WEIGHT_UOM);
 
-         if ($weightUom !== null) {
 
-             if ($sentence !== true) {
 
-                 return $weightUom;
 
-             }
 
-             $translate = $this->getTranslate();
 
-             $sentence = self::$weightUom[$weightUom];
 
-             if (null !== $translate) {
 
-                 return $translate->_($sentence);
 
-             }
 
-             return $sentence;
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *
 
-      * get dimensions uom set by the user
 
-      *
 
-      * @param bool $sentence
 
-      *
 
-      * @return string
 
-      */
 
-     public function getDimensionsUom($sentence = true)
 
-     {
 
-         $dimensionsUom = $this->getPostageSettings(self::SETUP_DIMENSIONS_UOM);
 
-         if ($dimensionsUom !== null) {
 
-             if ($sentence !== true) {
 
-                 return $dimensionsUom;
 
-             }
 
-             $translate = $this->getTranslate();
 
-             $sentence = self::$dimensionsUom[$dimensionsUom];
 
-             if (null !== $translate) {
 
-                 return $translate->_($sentence);
 
-             }
 
-             return $sentence;
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      *
 
-      * get location groups array
 
-      *
 
-      * @return array|bool    will return false if there are no locations or if the location based calculation is not set to custom
 
-      */
 
-     public function getLocationGroups()
 
-     {
 
-         if ($this->getPostageSettings(self::SETUP_SHIPPING_LOCATIONS) == self::POSTAGE_LOCATION_CUSTOM) {
 
-             return $this->_postageSettings[self::SETUP_LOCATION_GROUPS][FlatRatesLocationGroups::FIELD_NAME];
 
-         }
 
-         return false;
 
-     }
 
-     /**
 
-      *
 
-      * get the postage calculation type set by the user
 
-      *
 
-      * @return string
 
-      */
 
-     public function getPostageType()
 
-     {
 
-         return $this->getPostageSettings(self::SETUP_POSTAGE_TYPE);
 
-     }
 
-     /**
 
-      *
 
-      * return the postage options available based on a set of input values
 
-      *
 
-      * required values:
 
-      * - one or more listings from the same seller
 
-      * - a destination location (id from the locations table)
 
-      * - a destination zip/post code
 
-      *
 
-      * outputs:
 
-      * - an array of all available postage methods
 
-      * OR
 
-      * - a runtime error if any error has occurred
 
-      *
 
-      * [OBSOLETE]
 
-      * currencies output:
 
-      * - item based : item currency
 
-      * - flat rates : site's default currency
 
-      * - carriers : carrier currency
 
-      *
 
-      * [ACTUAL]
 
-      * currency output will always be in the item's currency
 
-      *
 
-      * @return array
 
-      * @throws \RuntimeException
 
-      */
 
-     public function calculatePostage()
 
-     {
 
-         $result = array();
 
-         $translate = $this->getTranslate();
 
-         if (!$this->_locationId) {
 
-             throw new \RuntimeException($translate->_("No destination location has been set."));
 
-         }
 
-         else if (!$this->_postCode) {
 
-             throw new \RuntimeException($translate->_("No destination zip/post code has been set."));
 
-         }
 
-         else if (empty($this->_data)) {
 
-             throw new \RuntimeException($translate->_("At least one item needs to be set in order to calculate the postage."));
 
-         }
 
-         $shippableLocations = $this->getShippableLocations();
 
-         $shippingLocations = $this->getPostageSettings(self::SETUP_SHIPPING_LOCATIONS);
 
-         if (in_array($this->_locationId, $shippableLocations)) {
 
-             if ($this->_isFreePostage()) {
 
-                 $result[] = array(
 
-                     'currency' => $this->_currency,
 
-                     'price'    => 0,
 
-                     'carrier'  => $translate->_('N/A'),
 
-                     'method'   => self::MSG_STANDARD_SHIPPING,
 
-                 );
 
-             }
 
-             else {
 
-                 switch ($this->getPostageType()) {
 
-                     case self::POSTAGE_TYPE_ITEM:
 
-                         $postageMethods = null;
 
-                         $postageData = array();
 
-                         foreach ($this->_data as $row) {
 
-                             $fldPostage = $row[self::DATA_LISTING][self::FLD_POSTAGE];
 
-                             if (isset($fldPostage['locations'])) {
 
-                                 if (in_array($shippingLocations,
 
-                                     array(self::POSTAGE_LOCATION_DOMESTIC, self::POSTAGE_LOCATION_WORLDWIDE))
 
-                                 ) {
 
-                                     // unset locations field if we have domestic or worldwide postage
 
-                                     unset($fldPostage['locations']);
 
-                                 }
 
-                                 else {
 
-                                     // set locations as countries
 
-                                     $fldPostage['locations'] = array_filter($fldPostage['locations']);
 
-                                     foreach ($fldPostage['locations'] as $key => $loc) {
 
-                                         foreach ($loc as $k => $v) {
 
-                                             $fldPostage['locations'][$key][$k] = $this->_postageSettings[self::SETUP_LOCATION_GROUPS][FlatRatesLocationGroups::FIELD_LOCATIONS][$v];
 
-                                         }
 
-                                         $fldPostage['locations'][$key] = call_user_func_array('array_merge',
 
-                                             $fldPostage['locations'][$key]);
 
-                                     }
 
-                                 }
 
-                             }
 
-                             // modify the price to be calculated on the quantity requested
 
-                             if (!empty($fldPostage['price'])) {
 
-                                 foreach ($fldPostage['price'] as $key => $value) {
 
-                                     $fldPostage['price'][$key] = $fldPostage['price'][$key] * $row[self::DATA_QUANTITY];
 
-                                 }
 
-                                 // flip postage array
 
-                                 $postageData[] = $this->_flipArray($fldPostage);
 
-                             }
 
-                             // unset price field to compare data
 
-                             if (isset($fldPostage['price'])) {
 
-                                 unset($fldPostage['price']);
 
-                             }
 
-                             // the locations and postage methods must be the same for the postage to be calculated (for multiple items)
 
-                             if ($postageMethods !== null && $postageMethods != $fldPostage) {
 
-                                 throw new \RuntimeException($translate->_("All listings included must have the same postage methods."));
 
-                             }
 
-                             $postageMethods = $fldPostage;
 
-                         }
 
-                         $listing = $this->_data[0][self::DATA_LISTING];
 
-                         switch ($shippingLocations) {
 
-                             case self::POSTAGE_LOCATION_DOMESTIC:
 
-                             case self::POSTAGE_LOCATION_WORLDWIDE:
 
-                                 if (!empty($postageMethods['method'])) {
 
-                                     foreach ($postageMethods['method'] as $key => $method) {
 
-                                         if (!empty($method)) {
 
-                                             foreach ($postageData as $data) {
 
-                                                 $price = (!empty($result[$key]['price'])) ? $result[$key]['price'] : 0;
 
-                                                 $result[$key] = array(
 
-                                                     'currency' => $listing['currency'],
 
-                                                     'price'    => ($price + $data[$key]['price']),
 
-                                                     'method'   => $method,
 
-                                                 );
 
-                                             }
 
-                                         }
 
-                                     }
 
-                                 }
 
-                                 break;
 
-                             case self::POSTAGE_LOCATION_CUSTOM:
 
-                                 foreach ($postageMethods['method'] as $key => $method) {
 
-                                     if (!empty($method)) {
 
-                                         foreach ($postageData as $data) {
 
-                                             if (in_array($this->_locationId, (array)$data[$key]['locations'])) {
 
-                                                 $price = (!empty($result[$key]['price'])) ? $result[$key]['price'] : 0;
 
-                                                 $result[$key] = array(
 
-                                                     'currency' => $listing['currency'],
 
-                                                     'price'    => ($price + $data[$key]['price']),
 
-                                                     'method'   => $method,
 
-                                                 );
 
-                                             }
 
-                                         }
 
-                                     }
 
-                                 }
 
-                                 break;
 
-                         }
 
-                         break;
 
-                     case self::POSTAGE_TYPE_FLAT:
 
-                         $quantity = 0;
 
-                         foreach ($this->_data as $row) {
 
-                             $quantity += $row[self::DATA_QUANTITY];
 
-                         }
 
-                         $settings = Front::getInstance()->getBootstrap()->getResource('settings');
 
-                         switch ($shippingLocations) {
 
-                             case self::POSTAGE_LOCATION_DOMESTIC:
 
-                             case self::POSTAGE_LOCATION_WORLDWIDE:
 
-                                 $price = $this->getPostageSettings(self::SETUP_POSTAGE_FLAT_FIRST) +
 
-                                     ($this->getPostageSettings(self::SETUP_POSTAGE_FLAT_ADDL) * ($quantity - 1));
 
-                                 $result[] = array(
 
-                                     'currency' => $settings['currency'],
 
-                                     'price'    => doubleval($price),
 
-                                     'method'   => self::MSG_STANDARD_SHIPPING,
 
-                                 );
 
-                                 break;
 
-                             case self::POSTAGE_LOCATION_CUSTOM:
 
-                                 $locationGroups = $this->getPostageSettings(self::SETUP_LOCATION_GROUPS);
 
-                                 foreach ($locationGroups[FlatRatesLocationGroups::FIELD_LOCATIONS] as $key => $val) {
 
-                                     if (in_array($this->_locationId, array_values((array)$val))) {
 
-                                         $price = $locationGroups[FlatRatesLocationGroups::FIELD_FIRST][$key] +
 
-                                             ($locationGroups[FlatRatesLocationGroups::FIELD_ADDL][$key] * ($quantity - 1));
 
-                                         $result[] = array(
 
-                                             'currency' => $settings['currency'],
 
-                                             'price'    => doubleval($price),
 
-                                             'method'   => $locationGroups[FlatRatesLocationGroups::FIELD_NAME][$key],
 
-                                         );
 
-                                     }
 
-                                 }
 
-                                 break;
 
-                         }
 
-                         break;
 
-                     case self::POSTAGE_TYPE_CARRIERS:
 
-                         $shippingCarriers = (array)$this->getPostageSettings(self::SETUP_SHIPPING_CARRIERS);
 
-                         foreach ($shippingCarriers as $rowCarrier) {
 
-                             $className = '\\Ppb\\Model\\Shipping\\Carrier\\' . $rowCarrier;
 
-                             if (class_exists($className)) {
 
-                                 /** @var \Ppb\Model\Shipping\Carrier\AbstractCarrier $carrier */
 
-                                 $carrier = new $className();
 
-                                 if (!empty($this->_data[0][self::DATA_LISTING]['country'])) {
 
-                                     $sourceCountry = $this->getLocations()->findBy('id',
 
-                                         $this->_data[0][self::DATA_LISTING]['country']);
 
-                                     $carrier->setSourceCountry($sourceCountry['iso_code']);
 
-                                 }
 
-                                 $destCountry = $this->getLocations()->findBy('id', $this->getLocationId());
 
-                                 $carrier->setSourceZip($this->_data[0][self::DATA_LISTING]['address'])
 
-                                     ->setDestCountry($destCountry['iso_code'])
 
-                                     ->setDestZip($this->_postCode)
 
-                                     ->setWeightUom(
 
-                                         $this->getPostageSettings(self::SETUP_WEIGHT_UOM))
 
-                                     ->setWeight(
 
-                                         $this->_calculateTotalWeight())
 
-                                     ->setDimensionsUom(
 
-                                         $this->getPostageSettings(self::SETUP_DIMENSIONS_UOM))
 
-                                     ->setDimensions(
 
-                                         $this->_calculateTotalDimensions());
 
-                                 if (($carrierResult = $carrier->getPrice()) !== false) {
 
-                                     foreach ($carrierResult as $val) {
 
-                                         $result[] = array(
 
-                                             'currency' => $val['currency'],
 
-                                             'price'    => $val['price'],
 
-                                             'method'   => $translate->_($rowCarrier) . ' ' . $val['name'],
 
-                                             'code'     => $val['code'],
 
-                                             'carrier'  => $rowCarrier,
 
-                                             'class'    => $className,
 
-                                         );
 
-                                     }
 
-                                 }
 
-                             }
 
-                         }
 
-                         break;
 
-                 }
 
-             }
 
-         }
 
-         if ($this->_canPickUp === true) {
 
-             $result[self::KEY_PICK_UP] = array(
 
-                 'currency' => $this->_currency,
 
-                 'price'    => 0,
 
-                 'method'   => $translate->_(self::VALUE_PICK_UP),
 
-                 'carrier'  => '-',
 
-             );
 
-         }
 
-         if (empty($result)) {
 
-             throw new \RuntimeException($translate->_("The item(s) cannot be shipped to your selected destination."));
 
-         }
 
-         // convert currencies
 
-         $result = $this->_convertCurrency($result);
 
-         return $result;
 
-     }
 
-     /**
 
-      *
 
-      * calculate insurance amount for the items in a sale
 
-      *
 
-      * @return float
 
-      */
 
-     public function calculateInsurance()
 
-     {
 
-         $insuranceAmount = 0;
 
-         foreach ($this->_data as $row) {
 
-             $insuranceAmount += $row[self::DATA_LISTING][self::FLD_INSURANCE];
 
-         }
 
-         return $insuranceAmount;
 
-     }
 
-     /**
 
-      *
 
-      * get all locations the item(s) can be posted to
 
-      *
 
-      * @param bool $dropDown
 
-      *
 
-      * @return array
 
-      */
 
-     public function getShippableLocations($dropDown = false)
 
-     {
 
-         $regions = false;
 
-         if ($this->getPostageType() == self::POSTAGE_TYPE_ITEM) {
 
-             foreach ($this->_data as $row) {
 
-                 $listingRegions = array();
 
-                 $listingPostageRegions = isset($row[self::DATA_LISTING][self::FLD_POSTAGE][FlatRatesLocationGroups::FIELD_LOCATIONS]) ?
 
-                     $row[self::DATA_LISTING][self::FLD_POSTAGE][FlatRatesLocationGroups::FIELD_LOCATIONS] : array();
 
-                 $listingPostageRegions = array_filter($listingPostageRegions);
 
-                 if (count($listingPostageRegions) > 0) {
 
-                     $listingRegions = array_unique(
 
-                         call_user_func_array('array_merge', $listingPostageRegions));
 
-                 }
 
-                 $regions = (is_array($regions)) ? array_intersect($regions, $listingRegions) : $listingRegions;
 
-             }
 
-         }
 
-         $locations = $this->_getShippingLocations($regions);
 
- //        if (empty($locations)) {
 
- //            throw new \RuntimeException($translate->_("No shipping available for the selected items."));
 
- //        }
 
-         if ($dropDown === true) {
 
-             $locations = $this->getLocations()->getMultiOptions((array)$locations);
 
-         }
 
-         return $locations;
 
-     }
 
-     /**
 
-      *
 
-      * get an array containing the ids of the shipping locations from the user's postage settings
 
-      * and optionally a set of regions
 
-      *
 
-      * by default users will be set to ship domestically, based on the location of the item(s) and not the one of the seller
 
-      *
 
-      * @param array|bool $regions
 
-      *
 
-      * @return array
 
-      */
 
-     protected function _getShippingLocations($regions = false)
 
-     {
 
-         $locations = array();
 
-         $shippingLocations = (isset($this->_postageSettings[self::SETUP_SHIPPING_LOCATIONS])) ?
 
-             $this->_postageSettings[self::SETUP_SHIPPING_LOCATIONS] : self::POSTAGE_LOCATION_DOMESTIC;
 
-         switch ($shippingLocations) {
 
-             case self::POSTAGE_LOCATION_DOMESTIC:
 
-                 $locations = array($this->_data[0][self::DATA_LISTING]['country']);
 
- //                $locations = array($this->_store['country']); // changed to the item's location.
 
-                 break;
 
-             case self::POSTAGE_LOCATION_WORLDWIDE:
 
-                 $locationsService = new Service\Table\Relational\Locations();
 
-                 $locations = array_keys($locationsService->getMultiOptions());
 
-                 break;
 
-             case self::POSTAGE_LOCATION_CUSTOM:
 
-                 $postageLocations = array_filter($this->_postageSettings[self::SETUP_LOCATION_GROUPS][FlatRatesLocationGroups::FIELD_LOCATIONS]);
 
-                 if ($regions !== false) {
 
-                     foreach ($postageLocations as $key => $val) {
 
-                         if (!in_array($key, $regions)) {
 
-                             unset($postageLocations[$key]);
 
-                         }
 
-                     }
 
-                     if (count($postageLocations) > 0) {
 
-                         $locations = $this->_mergeLocations($postageLocations);
 
-                     }
 
-                 }
 
-                 else {
 
-                     $locations = $this->_mergeLocations($postageLocations);
 
-                 }
 
-                 break;
 
-         }
 
-         return $locations;
 
-     }
 
-     /**
 
-      *
 
-      * rebuild locations array and remove duplicate locations
 
-      *
 
-      * @param $locations
 
-      *
 
-      * @return array
 
-      */
 
-     protected function _mergeLocations(array $locations)
 
-     {
 
-         if (count($locations) > 0) {
 
-             $locations = array_unique(
 
-                 call_user_func_array('array_merge', $locations));
 
-         }
 
-         return $locations;
 
-     }
 
-     protected function _flipArray(array $array)
 
-     {
 
-         $output = array();
 
-         foreach ($array['method'] as $key => $value) {
 
-             if (!empty($value)) {
 
-                 if (isset($array['price'])) {
 
-                     $output[$key]['price'] = $array['price'][$key];
 
-                 }
 
-                 $output[$key]['method'] = $array['method'][$key];
 
-                 if (isset($array['locations'])) {
 
-                     $output[$key]['locations'] = (isset($array['locations'][$key])) ? $array['locations'][$key] : null;
 
-                 }
 
-             }
 
-         }
 
-         return $output;
 
-     }
 
-     /**
 
-      *
 
-      * accepts an array returned by the calculatePostage() method and converts the amounts and currencies
 
-      * to the currency of the listings in the model
 
-      *
 
-      * @param array $data
 
-      *
 
-      * @throws \RuntimeException
 
-      * @return array
 
-      */
 
-     protected function _convertCurrency($data)
 
-     {
 
-         $translate = $this->getTranslate();
 
-         foreach ($data as $key => $value) {
 
-             if (!array_key_exists('currency', $value)
 
-                 && !array_key_exists('price', $value)
 
-             ) {
 
-                 throw new \RuntimeException($translate->_("Invalid array input in the _convertCurrency() method."));
 
-             }
 
-             if ($value['currency'] != $this->_currency) {
 
-                 $data[$key]['currency'] = $this->_currency;
 
-                 $data[$key]['price'] = $this->getCurrencies()->convertAmount($value['price'], $value['currency'],
 
-                     $this->_currency);
 
-             }
 
-         }
 
-         return $data;
 
-     }
 
-     /**
 
-      *
 
-      * this method will calculate the total invoice amount and if the total is over the minimum
 
-      * amount required for the postage to be free, it will return true; otherwise it will return false
 
-      *
 
-      * @return bool
 
-      */
 
-     protected function _isFreePostage()
 
-     {
 
-         if ($this->_postageSettings[self::SETUP_FREE_POSTAGE]) {
 
-             $total = 0;
 
-             foreach ($this->_data as $data) {
 
-                 $total += $data[self::DATA_LISTING]['buyout_price'] * $data[self::DATA_QUANTITY];
 
-             }
 
-             $settings = Front::getInstance()->getBootstrap()->getResource('settings');
 
-             $freePostageAmount = $this->getCurrencies()->convertAmount($this->_postageSettings[self::SETUP_FREE_POSTAGE_AMOUNT],
 
-                 $settings['currency'], $this->_currency);
 
-             if ($total >= $freePostageAmount) {
 
-                 return true;
 
-             }
 
-         }
 
-         return false;
 
-     }
 
-     /**
 
-      *
 
-      * calculate the total weight of the items added in the shipping model
 
-      *
 
-      * @return float
 
-      */
 
-     protected function _calculateTotalWeight()
 
-     {
 
-         $weight = 0;
 
-         foreach ($this->_data as $row) {
 
-             $weight += $row[self::DATA_LISTING][self::FLD_ITEM_WEIGHT] * $row[self::DATA_QUANTITY];
 
-         }
 
-         return ($weight > 0) ? $weight : self::MIN_WEIGHT;
 
-     }
 
-     /**
 
-      *
 
-      * we first order the dimensions to have the same orientation for the items
 
-      * the total dimension is calculated as follows:
 
-      * max(length) & max(width) & sum(height)
 
-      *
 
-      *
 
-      * @return array
 
-      */
 
-     protected function _calculateTotalDimensions()
 
-     {
 
-         $dimensions = null;
 
-         $lengths = array();
 
-         $widths = array();
 
-         $heights = array();
 
-         $counter = 0;
 
-         foreach ($this->_data as $row) {
 
-             $listingDimensions = (!empty($row[self::DATA_LISTING][self::FLD_DIMENSIONS])) ?
 
-                 $row[self::DATA_LISTING][self::FLD_DIMENSIONS] : null;
 
-             if ($listingDimensions !== null) {
 
-                 $sortedDimensions = array_values($listingDimensions);
 
-                 rsort($sortedDimensions);
 
-                 for ($i = 0; $i < $row[self::DATA_QUANTITY]; $i++) {
 
-                     $lengths[] = $sortedDimensions[0];
 
-                     $widths[] = $sortedDimensions[1];
 
-                     $heights[] = $sortedDimensions[2];
 
-                     $counter++;
 
-                 }
 
-             }
 
-         }
 
-         if ($counter > 0) {
 
-             return array(
 
-                 self::DIMENSION_LENGTH => max($lengths),
 
-                 self::DIMENSION_WIDTH  => max($widths),
 
-                 self::DIMENSION_HEIGHT => array_sum($heights),
 
-             );
 
-         }
 
-         return null;
 
-     }
 
- }
 
 
  |