diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e7c1d61
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+.idea/
+composer.lock
+
diff --git a/src/Fedex/Rate.php b/src/Fedex/Rate.php
index 1275416..5f91875 100644
--- a/src/Fedex/Rate.php
+++ b/src/Fedex/Rate.php
@@ -88,17 +88,6 @@ class Rate extends RateAdapter
protected function prepare()
{
- $to = Arr::get($this->shipment, 'to');
- $shipper = Arr::get($this->shipment, 'from');
- $dimensions = Arr::get($this->shipment, 'dimensions');
-
- $pounds = (int) Arr::get($this->shipment, 'weight');
- $ounces = 0;
-
- if ($pounds < 1) {
- throw new Exception('Weight missing');
- }
-
$date = time();
$day_name = date('l', $date);
@@ -111,6 +100,28 @@ class Rate extends RateAdapter
// http://www.fedex.com/templates/components/apps/wpor/secure/downloads/pdf/Aug13/PropDevGuide.pdf
// http://www.fedex.com/us/developer/product/WebServices/MyWebHelp_August2010/Content/Proprietary_Developer_Guide/Rate_Services_conditionalized.htm
+
+ $packages = '';
+ $sequence_number = 0;
+ foreach ($this->shipment->getPackages() as $p) {
+ $sequence_number++;
+
+ $packages .= '
+ ' . $sequence_number . '
+ 1
+
+ LB
+ ' . $p->getWeight() . '
+
+
+ ' . $p->getLength() . '
+ ' . $p->getWidth() . '
+ ' . $p->getHeight() . '
+ IN
+
+ ';
+ }
+
$this->data =
'
@@ -136,37 +147,24 @@ class Rate extends RateAdapter
' . date('c') . '
' . $this->drop_off_type . '
- ' . Arr::get($this->shipment, 'packaging_type') . '
+ YOUR_PACKAGING
- ' . Arr::get($shipper, 'postal_code') . '
- ' . Arr::get($shipper, 'country_code') . '
- ' . ((Arr::get($shipper, 'is_residential')) ? '1' : '') . '
+ ' . $this->shipment->getFromPostalCode() . '
+ ' . $this->shipment->getFromCountryCode() . '
+ ' . (($this->shipment->isFromResidential()) ? '1' : '') . '
- ' . Arr::get($to, 'postal_code') . '
- ' . Arr::get($to, 'country_code') . '
- ' . ((Arr::get($to, 'is_residential')) ? '1' : '') . '
+ ' . $this->shipment->getToPostalCode() . '
+ ' . $this->shipment->getToCountryCode() . '
+ ' . (($this->shipment->isToResidential()) ? '1' : '') . '
LIST
- 1
-
- 1
- 1
-
- LB
- ' . $pounds . '
-
-
- ' . Arr::get($dimensions, 'length') . '
- ' . Arr::get($dimensions, 'width') . '
- ' . Arr::get($dimensions, 'height') . '
- IN
-
-
+ ' . $this->shipment->packageCount() . '
+ ' . $packages . '
diff --git a/src/Package.php b/src/Package.php
new file mode 100644
index 0000000..07414ce
--- /dev/null
+++ b/src/Package.php
@@ -0,0 +1,123 @@
+size_classification;
+ }
+
+ /**
+ * @param mixed $size_classification
+ * @return $this
+ */
+ public function setSizeClassification($size_classification)
+ {
+ $this->size_classification = $size_classification;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getPackaging()
+ {
+ return $this->packaging;
+ }
+
+ /**
+ * @param mixed $packaging
+ * @return $this
+ */
+ public function setPackaging($packaging)
+ {
+ $this->packaging = $packaging;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getWeight()
+ {
+ return $this->weight;
+ }
+
+ /**
+ * @param mixed $weight
+ * @return $this
+ */
+ public function setWeight($weight)
+ {
+ $this->weight = $weight;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getWidth()
+ {
+ return $this->width;
+ }
+
+ /**
+ * @param mixed $width
+ * @return $this
+ */
+ public function setWidth($width)
+ {
+ $this->width = $width;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getLength()
+ {
+ return $this->length;
+ }
+
+ /**
+ * @param mixed $length
+ * @return $this
+ */
+ public function setLength($length)
+ {
+ $this->length = $length;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getHeight()
+ {
+ return $this->height;
+ }
+
+ /**
+ * @param mixed $height
+ * @return $this
+ */
+ public function setHeight($height)
+ {
+ $this->height = $height;
+ return $this;
+ }
+}
diff --git a/src/RateAdapter.php b/src/RateAdapter.php
index 430305b..8fd7dbb 100644
--- a/src/RateAdapter.php
+++ b/src/RateAdapter.php
@@ -7,6 +7,7 @@ abstract class RateAdapter
{
protected $is_prod = FALSE;
+ /** @var Shipment */
protected $shipment;
protected $data;
protected $response;
@@ -27,18 +28,6 @@ abstract class RateAdapter
if (isset($options['shipment'])) {
$this->shipment = $options['shipment'];
}
-
- if (empty($this->shipment['to'])) {
- throw new Exception('Shipment "to" missing');
- }
-
- if (empty($this->shipment['from'])) {
- throw new Exception('Shipment "from" missing');
- }
-
- if (empty($this->shipment['dimensions'])) {
- throw new Exception('Shipment "dimensions" missing');
- }
}
public function set_request_adapter(RateRequest\Adapter $rate_request)
diff --git a/src/Shipment.php b/src/Shipment.php
new file mode 100644
index 0000000..c7f2a9d
--- /dev/null
+++ b/src/Shipment.php
@@ -0,0 +1,169 @@
+packages[] = $package;
+ return $this;
+ }
+
+ /**
+ * @return Package[]
+ */
+ public function getPackages()
+ {
+ return $this->packages;
+ }
+
+ /**
+ * @return int
+ */
+ public function packageCount()
+ {
+ return count($this->getPackages());
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getFromPostalCode()
+ {
+ return $this->from_postal_code;
+ }
+
+ /**
+ * @param mixed $from_postal_code
+ * @return $this
+ */
+ public function setFromPostalCode($from_postal_code)
+ {
+ $this->from_postal_code = $from_postal_code;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getFromCountryCode()
+ {
+ return $this->from_country_code;
+ }
+
+ /**
+ * @param mixed $from_country_code
+ * @return $this
+ */
+ public function setFromCountryCode($from_country_code)
+ {
+ $this->from_country_code = $from_country_code;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getToPostalCode()
+ {
+ return $this->to_postal_code;
+ }
+
+ /**
+ * @param mixed $to_postal_code
+ * @return $this
+ */
+ public function setToPostalCode($to_postal_code)
+ {
+ $this->to_postal_code = $to_postal_code;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getToCountryCode()
+ {
+ return $this->to_country_code;
+ }
+
+ /**
+ * @param mixed $to_country_code
+ * @return $this
+ */
+ public function setToCountryCode($to_country_code)
+ {
+ $this->to_country_code = $to_country_code;
+ return $this;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isToResidential()
+ {
+ return $this->to_is_residential;
+ }
+
+ /**
+ * @param boolean $to_is_residential
+ * @return $this
+ */
+ public function setToResidential($to_is_residential)
+ {
+ $this->to_is_residential = $to_is_residential;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isFromResidential()
+ {
+ return $this->from_is_residential;
+ }
+
+ /**
+ * @param $from_is_residential
+ * @return $this
+ */
+ public function setFromResidential($from_is_residential)
+ {
+ $this->from_is_residential = $from_is_residential;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getFromStateProvinceCode()
+ {
+ return $this->from_state_province;
+ }
+
+ /**
+ * @param $from_state_province
+ * @return $this
+ */
+ public function setFromStateProvinceCode($from_state_province)
+ {
+ $this->from_state_province = $from_state_province;
+ return $this;
+ }
+}
diff --git a/src/UPS/Rate.php b/src/UPS/Rate.php
index 45b1962..53a4cbb 100644
--- a/src/UPS/Rate.php
+++ b/src/UPS/Rate.php
@@ -114,19 +114,31 @@ class Rate extends RateAdapter
protected function prepare()
{
- $to = Arr::get($this->shipment, 'to');
- $shipper = Arr::get($this->shipment, 'from');
- $dimensions = Arr::get($this->shipment, 'dimensions');
-
- $pounds = (int) Arr::get($this->shipment, 'weight');
- $ounces = 0;
+ $service_code = '03';
- if ($pounds < 1) {
- throw new Exception('Weight missing');
+ $packages = '';
+ foreach ($this->shipment->getPackages() as $p) {
+ $packages .= '
+
+ 02
+
+
+
+ IN
+
+ ' . $p->getLength() . '
+ ' . $p->getWidth() . '
+ ' . $p->getHeight() . '
+
+
+
+ LBS
+
+ ' . $p->getWeight() . '
+
+ ';
}
- $service_code = '03';
-
$this->data =
'
@@ -142,48 +154,31 @@ class Rate extends RateAdapter
- ' . Arr::get($shipper, 'postal_code') . '
- ' . Arr::get($shipper, 'country_code') . '
- ' . ((Arr::get($shipper, 'is_residential')) ? '1' : '') . '
+ ' . $this->shipment->getFromPostalCode() . '
+ ' . $this->shipment->getFromCountryCode() . '
+ ' . (($this->shipment->isFromResidential()) ? '1' : '') . '
' . $this->shipper_number . '
- ' . Arr::get($to, 'postal_code') . '
- ' . Arr::get($to, 'country_code') . '
- ' . ((Arr::get($to, 'is_residential')) ? '1' : '') . '
+ ' . $this->shipment->getToPostalCode() . '
+ ' . $this->shipment->getToCountryCode() . '
+ ' . (($this->shipment->isToResidential()) ? '1' : '') . '
- ' . Arr::get($shipper, 'postal_code') . '
- ' . Arr::get($shipper, 'country_code') . '
- ' . ((Arr::get($shipper, 'is_residential')) ? '1' : '') . '
+ ' . $this->shipment->getFromStateProvinceCode() . '
+ ' . $this->shipment->getFromPostalCode() . '
+ ' . $this->shipment->getFromCountryCode() . '
+ ' . (($this->shipment->isFromResidential()) ? '1' : '') . '
' . $service_code . '
-
-
- 02
-
-
-
- IN
-
- ' . Arr::get($dimensions, 'length') . '
- ' . Arr::get($dimensions, 'width') . '
- ' . Arr::get($dimensions, 'height') . '
-
-
-
- LBS
-
- ' . $pounds . '
-
-
+ ' . $packages . '
diff --git a/src/USPS/Rate.php b/src/USPS/Rate.php
index c54351d..48bcc95 100644
--- a/src/USPS/Rate.php
+++ b/src/USPS/Rate.php
@@ -95,34 +95,31 @@ class Rate extends RateAdapter
protected function prepare()
{
- $to = Arr::get($this->shipment, 'to');
- $shipper = Arr::get($this->shipment, 'from');
- $dimensions = Arr::get($this->shipment, 'dimensions');
- // https://www.usps.com/business/web-tools-apis/rate-calculators-v1-7a.htm
- $pounds = (int) Arr::get($this->shipment, 'weight');
- $ounces = 0;
-
- if ($pounds < 1) {
- throw new Exception('Weight missing');
+ $packages = '';
+ $sequence_number = 0;
+ foreach ($this->shipment->getPackages() as $p) {
+ $sequence_number++;
+
+ $packages .= '
+ ALL
+ ' . $this->shipment->getFromPostalCode() . '
+ ' . $this->shipment->getToPostalCode() . '
+ ' . $p->getWeight() . '
+ 0
+ ' . $p->getPackaging() . '
+ ' . $p->getSizeClassification() . '
+ ' . $p->getWidth() . '
+ ' . $p->getLength() . '
+ ' . $p->getHeight() . '
+ ' . 'False' . '
+ ';
}
$this->data =
'
-
- ALL
- ' . Arr::get($shipper, 'postal_code') . '
- ' . Arr::get($to, 'postal_code') . '
- ' . $pounds . '
- ' . $ounces . '
- ' . Arr::get($this->shipment, 'container') . '
- ' . Arr::get($this->shipment, 'size') . '
- ' . Arr::get($dimensions, 'width') . '
- ' . Arr::get($dimensions, 'length') . '
- ' . Arr::get($dimensions, 'height') . '
- ' . 'False' . '
-
+ ' . $packages . '
';
return $this;
@@ -160,6 +157,8 @@ class Rate extends RateAdapter
throw $e;
}
+ $rates = [];
+
foreach ($postage_list as $postage) {
$code = @$postage->getAttribute('CLASSID');
$cost = @$postage->getElementsByTagName('Rate')->item(0)->nodeValue;
@@ -170,13 +169,21 @@ class Rate extends RateAdapter
continue;
}
- $this->rates[] = array(
+ if (array_key_exists($code, $rates)) {
+ $cost = $rates[$code]['cost'] + ($cost * 100);
+ } else {
+ $cost = $cost * 100;
+ }
+
+ $rates[$code] = [
'code' => $code,
'name' => $name,
- 'cost' => (int) $cost * 100,
- );
+ 'cost' => (int) $cost,
+ ];
}
+ $this->rates = array_values($rates);
+
return $this;
}
}
diff --git a/tests/ShipTest.php b/tests/ShipTest.php
index 9467d7f..34c6e2c 100644
--- a/tests/ShipTest.php
+++ b/tests/ShipTest.php
@@ -1,5 +1,7 @@
3, // lbs
- 'dimensions' => [
- 'width' => 9,
- 'length' => 9,
- 'height' => 9,
- ],
- 'from' => [
- 'postal_code' => '90401',
- 'country_code' => 'US',
- ],
- 'to' => [
- 'postal_code' => '78703',
- 'country_code' => 'US',
- 'is_residential' => TRUE,
- ],
- ];
+ /** @var Shipment */
+ public $shipment;
public $shipping_options = [
'Standard Shipping' => [
@@ -60,6 +47,29 @@ class ShipTest extends PHPUnit_Framework_TestCase
],
];
+ public function setUp()
+ {
+ $s = new Shipment;
+ $s->setFromStateProvinceCode('CA')
+ ->setFromPostalCode('90401')
+ ->setFromCountryCode('US')
+ ->setToPostalCode('78703')
+ ->setToCountryCode('US')
+ ->setToResidential(true);
+
+ $p = new Package;
+ $p->setWeight(3)
+ ->setWidth(9)
+ ->setLength(9)
+ ->setHeight(9)
+ ->setPackaging(Package::USPS_CONTAINER_RECTANGULAR)
+ ->setSizeClassification(Package::USPS_SIZE_LARGE);
+
+ $s->addPackage($p);
+
+ $this->shipment = $s;
+ }
+
private function getUSPSOptions()
{
$ship = Ship::factory($this->shipping_options);
@@ -69,10 +79,7 @@ class ShipTest extends PHPUnit_Framework_TestCase
'prod' => FALSE,
'username' => 'XXXX',
'password' => 'XXXX',
- 'shipment' => array_merge($this->shipment, [
- 'size' => 'LARGE',
- 'container' => 'RECTANGULAR',
- ]),
+ 'shipment' => $this->shipment,
'approved_codes' => $approved_codes,
'request_adapter' => new RateRequest\StubUSPS(),
];
@@ -100,6 +107,11 @@ class ShipTest extends PHPUnit_Framework_TestCase
$ship = Ship::factory($this->shipping_options);
$approved_codes = $ship->get_approved_codes('fedex');
+ $ps = $this->shipment->getPackages();
+ foreach ($ps as $p) {
+ $p->setPackaging(Package::FEDEX_YOUR_PACKAGING);
+ }
+
return [
'prod' => FALSE,
'key' => 'XXXX',
@@ -107,9 +119,7 @@ class ShipTest extends PHPUnit_Framework_TestCase
'account_number' => 'XXXX',
'meter_number' => 'XXXX',
'drop_off_type' => 'BUSINESS_SERVICE_CENTER',
- 'shipment' => array_merge($this->shipment, [
- 'packaging_type' => 'YOUR_PACKAGING',
- ]),
+ 'shipment' => $this->shipment,
'approved_codes' => $approved_codes,
'request_adapter' => new RateRequest\StubFedex(),
];
@@ -124,12 +134,12 @@ class ShipTest extends PHPUnit_Framework_TestCase
1 => [
'code' => '4',
'name' => 'Parcel Post',
- 'cost' => 1000,
+ 'cost' => 1001,
],
0 => [
'code' => '1',
'name' => 'Priority Mail',
- 'cost' => 1200,
+ 'cost' => 1220,
],
]), json_encode($usps_rates));
}
@@ -221,7 +231,7 @@ class ShipTest extends PHPUnit_Framework_TestCase
0 => [
'code' => '4',
'name' => 'Parcel Post',
- 'cost' => 1000,
+ 'cost' => 1001,
'carrier' => 'usps',
],
],
@@ -248,114 +258,6 @@ class ShipTest extends PHPUnit_Framework_TestCase
]), json_encode($display_rates));
}
- /**
- * @expectedException Exception
- */
- public function testUSPSRateMissingTo()
- {
- $usps_options = $this->getUSPSOptions();
- unset($usps_options['shipment']['to']);
-
- $usps = new USPS\Rate($usps_options);
- $usps_rates = $usps->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testUSPSRateMissingFrom()
- {
- $usps_options = $this->getUSPSOptions();
- unset($usps_options['shipment']['from']);
-
- $usps = new USPS\Rate($usps_options);
- $usps_rates = $usps->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testUSPSRateMissingDimensions()
- {
- $usps_options = $this->getUSPSOptions();
- unset($usps_options['shipment']['dimensions']);
-
- $usps = new USPS\Rate($usps_options);
- $usps_rates = $usps->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testUPSRateMissingTo()
- {
- $ups_options = $this->getUPSOptions();
- unset($ups_options['shipment']['to']);
-
- $ups = new UPS\Rate($ups_options);
- $ups_rates = $ups->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testUPSRateMissingFrom()
- {
- $ups_options = $this->getUPSOptions();
- unset($ups_options['shipment']['from']);
-
- $ups = new UPS\Rate($ups_options);
- $ups_rates = $ups->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testUPSRateMissingDimensions()
- {
- $ups_options = $this->getUPSOptions();
- unset($ups_options['shipment']['dimensions']);
-
- $ups = new UPS\Rate($ups_options);
- $ups_rates = $ups->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testFedexRateMissingTo()
- {
- $fedex_options = $this->getFedexOptions();
- unset($fedex_options['shipment']['to']);
-
- $fedex = new Fedex\Rate($fedex_options);
- $fedex_rates = $fedex->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testFedexRateMissingFrom()
- {
- $fedex_options = $this->getFedexOptions();
- unset($fedex_options['shipment']['from']);
-
- $fedex = new Fedex\Rate($fedex_options);
- $fedex_rates = $fedex->get_rates();
- }
-
- /**
- * @expectedException Exception
- */
- public function testFedexRateMissingDimensions()
- {
- $fedex_options = $this->getFedexOptions();
- unset($fedex_options['shipment']['dimensions']);
-
- $fedex = new Fedex\Rate($fedex_options);
- $fedex_rates = $fedex->get_rates();
- }
-
// // Readme Examples:
// public function testUSPSReadmeExample()
// {