diff --git a/Client.php b/Client.php index cf1cae7..e0db2b3 100644 --- a/Client.php +++ b/Client.php @@ -4,6 +4,8 @@ use LAShowroom\TaxJarBundle\Model\Order; use LAShowroom\TaxJarBundle\Model\Response\TaxResponse; +use LAShowroom\TaxJarBundle\Model\Tax\TaxRequest; +use LAShowroom\TaxJarBundle\Model\Transaction\OrderTransaction; use Psr\Cache\CacheItemPoolInterface; use TaxJar\Client as TaxJarClient; @@ -28,15 +30,13 @@ public function __construct(TaxJarClient $apiClient) } /** - * @param Order $order + * @param TaxRequest $order * * @return TaxResponse */ - public function getTaxesForOrder(Order $order) + public function getTaxesForOrder(TaxRequest $order) { $request = $order->toArray(); - unset($request['transaction_id']); - unset($request['transaction_date']); if (null === $this->cacheItemPool) { return new TaxResponse($this->apiClient->taxForOrder($request)); @@ -55,17 +55,13 @@ public function getTaxesForOrder(Order $order) } /** - * @param Order $order + * @param OrderTransaction $orderTransaction * * @return TaxResponse */ - public function createOrderTransaction(Order $order) + public function createOrderTransaction(OrderTransaction $orderTransaction) { - $request = $order->toArray(); - - $response = new TaxResponse($this->apiClient->createOrder($request)); - - return $response; + return new TaxResponse($this->apiClient->createOrder($orderTransaction->toArray())); } /** diff --git a/Model/BaseRequest.php b/Model/BaseRequest.php new file mode 100644 index 0000000..09e7a10 --- /dev/null +++ b/Model/BaseRequest.php @@ -0,0 +1,116 @@ +fromAddress; + } + + /** + * @param Address $fromAddress + */ + public function setFromAddress(Address $fromAddress) + { + $this->fromAddress = $fromAddress; + } + + /** + * @return Address + */ + public function getToAddress() + { + return $this->toAddress; + } + + /** + * @param Address $toAddress + */ + public function setToAddress(Address $toAddress) + { + $this->toAddress = $toAddress; + } + + /** + * @return float + */ + public function getAmount() + { + return $this->amount; + } + + /** + * @param float $amount + */ + public function setAmount($amount) + { + Assert::float($amount); + + $this->amount = $amount; + } + + /** + * @return float + */ + public function getShipping() + { + return $this->shipping; + } + + /** + * @param float $shipping + */ + public function setShipping($shipping) + { + Assert::float($shipping); + + $this->shipping = $shipping; + } + + protected function toArray() + { + $result = []; + + if (!empty($this->fromAddress)) { + $result = array_merge($result, $this->fromAddress->toArray('from_')); + } + + if (!empty($this->toAddress)) { + $result = array_merge($result, $this->toAddress->toArray('to_')); + } + + $result = array_merge($result, [ + 'amount' => $this->getAmount(), + 'shipping' => $this->getShipping(), + ]); + + return $result; + } +} diff --git a/Model/LineItem.php b/Model/LineItem.php index 8d610ff..4b50635 100644 --- a/Model/LineItem.php +++ b/Model/LineItem.php @@ -38,7 +38,7 @@ class LineItem * @param float $unitPrice * @param float $discount */ - public function __construct($id, $quantity, $productTaxCode, $unitPrice, $discount) + public function __construct($id, $quantity, $productTaxCode, $unitPrice, $discount = 0.0) { Assert::integer($quantity); Assert::float($unitPrice); diff --git a/Model/Order.php b/Model/Order.php deleted file mode 100644 index a0063fe..0000000 --- a/Model/Order.php +++ /dev/null @@ -1,260 +0,0 @@ -fromAddress; - } - - /** - * @param Address $fromAddress - */ - public function setFromAddress(Address $fromAddress) - { - $this->fromAddress = $fromAddress; - } - - /** - * @return Address - */ - public function getToAddress() - { - return $this->toAddress; - } - - /** - * @param Address $toAddress - */ - public function setToAddress(Address $toAddress) - { - $this->toAddress = $toAddress; - } - - /** - * @return float - */ - public function getAmount() - { - return $this->amount; - } - - /** - * @param float $amount - */ - public function setAmount($amount) - { - Assert::float($amount); - - $this->amount = $amount; - } - - /** - * @return float - */ - public function getShipping() - { - return $this->shipping; - } - - /** - * @param float $shipping - */ - public function setShipping($shipping) - { - Assert::float($shipping); - - $this->shipping = $shipping; - } - - /** - * @return Address[] - */ - public function getNexusAddresses() - { - return $this->nexusAddresses; - } - - /** - * @param Address[] $nexusAddresses - */ - public function setNexusAddresses(array $nexusAddresses) - { - Assert::allIsInstanceOf($nexusAddresses, Address::class); - - $this->nexusAddresses = $nexusAddresses; - } - - /** - * @return LineItem[] - */ - public function getLineItems() - { - return $this->lineItems; - } - - /** - * @param LineItem[] $lineItems - */ - public function setLineItems(array $lineItems) - { - Assert::allIsInstanceOf($lineItems, LineItem::class); - - $this->lineItems = $lineItems; - } - - public function addLineItem(LineItem $lineItem) - { - $this->lineItems[] = $lineItem; - } - - public function addNexusAddress($id, Address $address) - { - $this->nexusAddresses[$id] = $address; - } - - /** - * @return string - */ - public function getTransactionId() - { - return $this->transactionId; - } - - /** - * @param string $transactionId - */ - public function setTransactionId($transactionId) - { - $this->transactionId = $transactionId; - } - - /** - * @return \DateTime - */ - public function getTransactionDate() - { - return $this->transactionDate; - } - - /** - * @param \DateTime $transactionDate - */ - public function setTransactionDate(\DateTime $transactionDate) - { - $this->transactionDate = $transactionDate; - } - - /** - * @return float - */ - public function getSalesTax() - { - return $this->salesTax; - } - - /** - * @param float $salesTax - */ - public function setSalesTax($salesTax) - { - Assert::float($salesTax); - - $this->salesTax = $salesTax; - } - - public function toArray() - { - $result = []; - - if (!empty($this->fromAddress)) { - $result = array_merge($result, $this->fromAddress->toArray('from_')); - } - - if (!empty($this->toAddress)) { - $result = array_merge($result, $this->toAddress->toArray('to_')); - } - - if (!empty($this->salesTax)) { - $result['sales_tax'] = $this->salesTax; - } - - $result = array_merge($result, [ - 'line_items' => array_map(function(LineItem $elem) { - return $elem->toArray(); - }, $this->lineItems), - 'amount' => $this->getAmount(), - 'shipping' => $this->getShipping(), - 'nexus_addresses' => array_map(function(Address $elem, $id) { - return array_merge($elem->toArray(), ['id' => $id, ]); - }, $this->nexusAddresses, array_keys($this->nexusAddresses)), - ]); - - if (!empty($this->transactionId)) { - $result['transaction_id'] = $this->transactionId; - } - - if (!empty($this->transactionDate)) { - $result['transaction_date'] = $this->transactionDate->format(\DateTime::ISO8601); - } - - return $result; - } - - public function getCacheKey() - { - return sprintf('order_%s', md5(json_encode($this->toArray()))); - } -} diff --git a/Model/Tax/TaxRequest.php b/Model/Tax/TaxRequest.php new file mode 100644 index 0000000..ebeb7a7 --- /dev/null +++ b/Model/Tax/TaxRequest.php @@ -0,0 +1,85 @@ +nexusAddresses; + } + + /** + * @param Address[] $nexusAddresses + */ + public function setNexusAddresses(array $nexusAddresses) + { + Assert::allIsInstanceOf($nexusAddresses, Address::class); + + $this->nexusAddresses = $nexusAddresses; + } + + public function addNexusAddress($id, Address $address) + { + $this->nexusAddresses[$id] = $address; + } + + /** + * @return LineItem[] + */ + public function getLineItems() + { + return $this->lineItems; + } + + /** + * @param LineItem[] $lineItems + */ + public function setLineItems(array $lineItems) + { + Assert::allIsInstanceOf($lineItems, LineItem::class); + + $this->lineItems = $lineItems; + } + + public function addLineItem(LineItem $lineItem) + { + $this->lineItems[] = $lineItem; + } + + public function toArray() + { + return array_merge(parent::toArray(), + [ + 'line_items' => array_map(function(LineItem $elem) { + return $elem->toArray(); + }, $this->lineItems), + 'nexus_addresses' => array_map(function(Address $elem, $id) { + return array_merge($elem->toArray(), ['id' => $id, ]); + }, $this->nexusAddresses, array_keys($this->nexusAddresses)), + ]); + } + + public function getCacheKey() + { + return sprintf('tax_request_%s', md5(json_encode($this->toArray()))); + } +} diff --git a/Model/Transaction/LineItem.php b/Model/Transaction/LineItem.php new file mode 100644 index 0000000..eee9681 --- /dev/null +++ b/Model/Transaction/LineItem.php @@ -0,0 +1,74 @@ +description; + } + + /** + * @param string $description + */ + public function setDescription($description) + { + $this->description = $description; + } + + /** + * @return string + */ + public function getProductIdentifier() + { + return $this->productIdentifier; + } + + /** + * @param string $productIdentifier + */ + public function setProductIdentifier($productIdentifier) + { + $this->productIdentifier = $productIdentifier; + } + + /** + * @return float + */ + public function getSalesTax() + { + return $this->salesTax; + } + + /** + * @param float $salesTax + */ + public function setSalesTax($salesTax) + { + Assert::float($salesTax); + + $this->salesTax = $salesTax; + } +} diff --git a/Model/Transaction/OrderTransaction.php b/Model/Transaction/OrderTransaction.php new file mode 100644 index 0000000..b7b6984 --- /dev/null +++ b/Model/Transaction/OrderTransaction.php @@ -0,0 +1,121 @@ +transactionId; + } + + /** + * @param string $transactionId + */ + public function setTransactionId($transactionId) + { + $this->transactionId = $transactionId; + } + + /** + * @return \DateTime + */ + public function getTransactionDate() + { + return $this->transactionDate; + } + + /** + * @param \DateTime $transactionDate + */ + public function setTransactionDate(\DateTime $transactionDate) + { + $this->transactionDate = $transactionDate; + } + + /** + * @return float + */ + public function getSalesTax() + { + return $this->salesTax; + } + + /** + * @param float $salesTax + */ + public function setSalesTax($salesTax) + { + Assert::float($salesTax); + + $this->salesTax = $salesTax; + } + + /** + * @return LineItem[] + */ + public function getLineItems() + { + return $this->lineItems; + } + + /** + * @param LineItem[] $lineItems + */ + public function setLineItems(array $lineItems) + { + Assert::allIsInstanceOf($lineItems, LineItem::class); + + $this->lineItems = $lineItems; + } + + public function addLineItem(LineItem $lineItem) + { + $this->lineItems[] = $lineItem; + } + + public function toArray() + { + $result = []; + + if (!empty($this->transactionId)) { + $result['transaction_id'] = $this->transactionId; + } + + if (!empty($this->transactionDate)) { + $result['transaction_date'] = $this->transactionDate->format(\DateTime::ISO8601); + } + + if (!empty($this->salesTax)) { + $result['sales_tax'] = $this->salesTax; + } + + return array_merge(parent::toArray(), $result); + } +} diff --git a/Tests/ClientTest.php b/Tests/ClientTest.php index 3f6e441..6dbf1d2 100644 --- a/Tests/ClientTest.php +++ b/Tests/ClientTest.php @@ -10,6 +10,8 @@ use LAShowroom\TaxJarBundle\Model\Response\TaxDetail; use LAShowroom\TaxJarBundle\Model\Response\TaxResponse; use LAShowroom\TaxJarBundle\Tests\Model\OrderTest; +use LAShowroom\TaxJarBundle\Tests\Model\Tax\TaxRequestTest; +use LAShowroom\TaxJarBundle\Tests\Model\Transaction\OrderTransactionTest; use Prophecy\Argument; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\CacheItem; @@ -48,7 +50,7 @@ protected function setup() public function testGetRatesForOrder() { - $order = OrderTest::getTestOrder(); + $order = TaxRequestTest::getTestRequest(); $result = $this->client->getTaxesForOrder($order); @@ -69,24 +71,24 @@ public function testGetRatesForOrder() public function testCacheCold() { $cache = new ArrayAdapter(); - $this->assertFalse($cache->hasItem(OrderTest::getTestOrder()->getCacheKey())); + $this->assertFalse($cache->hasItem(TaxRequestTest::getTestRequest()->getCacheKey())); $this->client->setCacheItemPool($cache); - $result = $this->client->getTaxesForOrder(OrderTest::getTestOrder()); + $result = $this->client->getTaxesForOrder(TaxRequestTest::getTestRequest()); $this->assertInstanceOf(TaxResponse::class, $result); - $this->assertTrue($cache->hasItem(OrderTest::getTestOrder()->getCacheKey())); - $this->assertEquals($result, $cache->getItem(OrderTest::getTestOrder()->getCacheKey())->get()); + $this->assertTrue($cache->hasItem(TaxRequestTest::getTestRequest()->getCacheKey())); + $this->assertEquals($result, $cache->getItem(TaxRequestTest::getTestRequest()->getCacheKey())->get()); } public function testCacheWarm() { $cache = new ArrayAdapter(); - $this->assertFalse($cache->hasItem(OrderTest::getTestOrder()->getCacheKey())); - $cacheItem = $cache->getItem(OrderTest::getTestOrder()->getCacheKey()); + $this->assertFalse($cache->hasItem(TaxRequestTest::getTestRequest()->getCacheKey())); + $cacheItem = $cache->getItem(TaxRequestTest::getTestRequest()->getCacheKey()); - $result = $this->client->getTaxesForOrder(OrderTest::getTestOrder()); + $result = $this->client->getTaxesForOrder(TaxRequestTest::getTestRequest()); $cacheItem->set($result); $cache->save($cacheItem); @@ -100,7 +102,7 @@ public function testCacheWarm() $client = new Client($clientProphesy->reveal()); $client->setCacheItemPool($cache); - $resultFromCache = $client->getTaxesForOrder(OrderTest::getTestOrder()); + $resultFromCache = $client->getTaxesForOrder(TaxRequestTest::getTestRequest()); $this->assertInstanceOf(TaxResponse::class, $resultFromCache); $this->assertEquals($result, $resultFromCache); @@ -108,15 +110,13 @@ public function testCacheWarm() public function testCreateTransaction() { - $order = OrderTest::getTestOrder(); + $order = OrderTransactionTest::getTestOrderTransaction(); $order->setTransactionId('1234567'); $order->setTransactionDate($now = new \DateTime); $order->setSalesTax(1.23); $result = $this->client->createOrderTransaction($order); - print_r($result); - $this->assertInstanceOf(TaxResponse::class, $result); $this->assertEquals(16.5, $result->getTotalAmount()); $this->assertEquals(1.5, $result->getShipping()); diff --git a/Tests/Model/OrderTest.php b/Tests/Model/Tax/TaxRequestTest.php similarity index 69% rename from Tests/Model/OrderTest.php rename to Tests/Model/Tax/TaxRequestTest.php index 851d3ca..9100147 100644 --- a/Tests/Model/OrderTest.php +++ b/Tests/Model/Tax/TaxRequestTest.php @@ -1,17 +1,18 @@ assertEquals([ 'from_country' => 'US', @@ -45,12 +46,12 @@ public function testJsonSerialize() 'street' => '9500 Gilman Drive', ] ], - ], $order->toArray()); + ], $request->toArray()); } public function testSetNexusAddresses() { - $order = new Order(); + $order = new TaxRequest(); $order->setNexusAddresses([ 'Main Location' => new Address('9500 Gilman Drive', 'La Jolla', 'CA', '92093', 'US'), @@ -64,7 +65,7 @@ public function testSetNexusAddresses() public function testSetAddresses() { - $order = new Order(); + $order = new TaxRequest(); $order->setFromAddress($address1 = new Address('9500 Gilman Drive', 'La Jolla', 'CA', '92093', 'US')); $order->setToAddress($address2 = new Address('1335 E 103rd St', 'Los Angeles', 'CA', '90002', 'US')); @@ -74,7 +75,7 @@ public function testSetAddresses() public function testSetLineItems() { - $order = new Order(); + $order = new TaxRequest(); $order->setLineItems([ $firstLineItem = new LineItem('1', 1, TaxCategory::CLOTHING, 15.00, 0.0), $secondLineItem = new LineItem('2', 1, TaxCategory::CLOTHING, 16.00, 0.0) @@ -86,43 +87,28 @@ public function testSetLineItems() public function testCacheKeySameForSameData() { - $this->assertEquals('order_c3e3b1ddda8a59ac5b4158c64461536f', self::getTestOrder()->getCacheKey()); - $this->assertEquals('order_c3e3b1ddda8a59ac5b4158c64461536f', self::getTestOrder()->getCacheKey()); + $this->assertEquals('tax_request_6e176a6f7410495036bb4980fdef538d', self::getTestRequest()->getCacheKey()); + $this->assertEquals('tax_request_6e176a6f7410495036bb4980fdef538d', self::getTestRequest()->getCacheKey()); } public function testCacheKeyChangesAsDataChanged() { - $order = self::getTestOrder(); - $this->assertEquals('order_c3e3b1ddda8a59ac5b4158c64461536f', $order->getCacheKey()); + $order = self::getTestRequest(); + $this->assertEquals('tax_request_6e176a6f7410495036bb4980fdef538d', $order->getCacheKey()); $order->setAmount(20.00); - $this->assertEquals('order_0b0aa4abd232d4d9b88e6e710cb2ae9b', $order->getCacheKey()); + $this->assertEquals('tax_request_5c42a8050be9a9aec8a42c9e807939ac', $order->getCacheKey()); } +// - public function testTransactionData() - { - $order = new Order(); - $order->setTransactionId('doge'); - $this->assertEquals('doge', $order->getTransactionId()); - $date = new \DateTime(); - $order->setTransactionDate($date); - $this->assertEquals($date, $order->getTransactionDate()); - $order->setSalesTax(1.23); - $this->assertEquals(1.23, $order->getSalesTax()); - - - $this->assertEquals('doge', $order->toArray()['transaction_id']); - $this->assertEquals($date->format(\DATE_ISO8601), $order->toArray()['transaction_date']); - $this->assertEquals(1.23, $order->toArray()['sales_tax']); - } /** - * @return Order + * @return TaxRequest */ - public static function getTestOrder() + public static function getTestRequest() { - $order = new Order(); + $order = new TaxRequest(); $order->setFromAddress(new Address('9500 Gilman Drive', 'La Jolla', 'CA', '92093', 'US')); $order->setToAddress(new Address('1335 E 103rd St', 'Los Angeles', 'CA', '90002', 'US')); $order->addLineItem(new LineItem('1', 1, TaxCategory::CLOTHING, 15.00, 0.0)); diff --git a/Tests/Model/Transaction/OrderTransactionTest.php b/Tests/Model/Transaction/OrderTransactionTest.php new file mode 100644 index 0000000..41b44c2 --- /dev/null +++ b/Tests/Model/Transaction/OrderTransactionTest.php @@ -0,0 +1,87 @@ +setFromAddress(new Address('9500 Gilman Drive', 'La Jolla', 'CA', '92093', 'US')); + $order->setToAddress(new Address('1335 E 103rd St', 'Los Angeles', 'CA', '90002', 'US')); + $order->addLineItem(new LineItem('1', 1, TaxCategory::CLOTHING, 15.00, 0.0)); + $order->setAmount(15.0); + $order->setShipping(1.5); + + return $order; + } + + public function testTransactionData() + { + $order = new OrderTransaction(); + $order->setTransactionId('doge'); + $this->assertEquals('doge', $order->getTransactionId()); + $date = new \DateTime(); + $order->setTransactionDate($date); + $this->assertEquals($date, $order->getTransactionDate()); + $order->setSalesTax(1.23); + $this->assertEquals(1.23, $order->getSalesTax()); + + $this->assertEquals('doge', $order->toArray()['transaction_id']); + $this->assertEquals($date->format(\DATE_ISO8601), $order->toArray()['transaction_date']); + $this->assertEquals(1.23, $order->toArray()['sales_tax']); + } + + public function testAddLineItem() + { + $firstLineItem = new LineItem('1', 1, TaxCategory::CLOTHING, 15.00, 0.0); + $firstLineItem->setDescription($expectedDescription = 'description_1'); + $firstLineItem->setSalesTax($expectedSalesTax = 1.50); + $firstLineItem->setProductIdentifier($expectedProductIdentifier = 'identifier_1'); + + $secondLineItem = new LineItem('2', 1, TaxCategory::CLOTHING, 16.00, 0.0); + $secondLineItem->setDescription('description_2'); + $secondLineItem->setSalesTax(1.60); + $secondLineItem->setProductIdentifier('identifier_2'); + $order = new OrderTransaction(); + $order->addLineItem($firstLineItem); + + $this->assertCount(1, $order->getLineItems()); + $this->assertContainsOnlyInstancesOf(LineItem::class, $order->getLineItems()); + $this->assertEquals($expectedDescription, $order->getLineItems()[0]->getDescription()); + $this->assertEquals($expectedSalesTax, $order->getLineItems()[0]->getSalesTax()); + $this->assertEquals($expectedProductIdentifier, $order->getLineItems()[0]->getProductIdentifier()); + + $order->addLineItem($firstLineItem); + $this->assertCount(2, $order->getLineItems()); + $this->assertContainsOnlyInstancesOf(LineItem::class, $order->getLineItems()); + } + + public function testSetLineItem() + { + $firstLineItem = new LineItem('1', 1, TaxCategory::CLOTHING, 15.00, 0.0); + $firstLineItem->setDescription('description_1'); + $firstLineItem->setSalesTax(1.50); + $firstLineItem->setProductIdentifier('identifier_1'); + + $secondLineItem = new LineItem('2', 1, TaxCategory::CLOTHING, 16.00, 0.0); + $secondLineItem->setDescription('description_2'); + $secondLineItem->setSalesTax(1.60); + $secondLineItem->setProductIdentifier('identifier_2'); + + $order = new OrderTransaction(); + $order->setLineItems($expected = [$firstLineItem, $secondLineItem]); + + $this->assertCount(2, $order->getLineItems()); + $this->assertContainsOnlyInstancesOf(LineItem::class, $order->getLineItems()); + $this->assertEquals($expected, $order->getLineItems()); + } +}