-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add shipping cost sales order data mapper
- Loading branch information
Showing
4 changed files
with
144 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Setono\SyliusPeakPlugin\DataMapper; | ||
|
||
use Setono\PeakWMS\DataTransferObject\SalesOrder\SalesOrder; | ||
use function Setono\SyliusPeakPlugin\formatAmount; | ||
use Setono\SyliusPeakPlugin\Model\OrderInterface; | ||
use Sylius\Component\Core\Model\AdjustmentInterface; | ||
use Webmozart\Assert\Assert; | ||
|
||
final class ShippingCostSalesOrderDataMapper implements SalesOrderDataMapperInterface | ||
{ | ||
public function map(OrderInterface $order, SalesOrder $salesOrder): void | ||
{ | ||
$shipping = $shippingTax = 0; | ||
|
||
foreach ($order->getShipments() as $shipment) { | ||
$shippingAdjustments = $shipment->getAdjustments(AdjustmentInterface::SHIPPING_ADJUSTMENT); | ||
if ($shippingAdjustments->isEmpty()) { | ||
continue; | ||
} | ||
|
||
// Sylius only adds one shipping adjustment per shipment | ||
Assert::count($shippingAdjustments, 1); | ||
|
||
$shippingAdjustment = $shippingAdjustments->first(); | ||
Assert::isInstanceOf($shippingAdjustment, AdjustmentInterface::class); | ||
|
||
$taxAdjustments = $shipment->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); | ||
Assert::lessThanEq($taxAdjustments->count(), 1); | ||
|
||
// Because of the way shipping and shipping taxes are done in Sylius, we need to do some gymnastics to calculate the correct unit price. | ||
// If the tax adjustment is neutral we know that the tax is included in the shipping adjustment's amount and hence we subtract the tax. | ||
// If the tax adjustment is not neutral we know that the tax is not included and hence we don't subtract the tax. | ||
// The tax is still the same though, and we need that to calculate the vat percentage | ||
$tax = 0; | ||
$amount = $shippingAdjustment->getAmount(); | ||
|
||
$taxAdjustment = $taxAdjustments->first(); | ||
if (false !== $taxAdjustment) { | ||
$tax = $taxAdjustment->getAmount(); | ||
|
||
if ($taxAdjustment->isNeutral()) { | ||
$amount -= $tax; | ||
} | ||
} | ||
|
||
$shipping += $amount; | ||
$shippingTax += $tax; | ||
} | ||
|
||
$salesOrder->shippingCost = formatAmount($shipping); | ||
$salesOrder->shippingTaxCost = formatAmount($shippingTax); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Setono\SyliusPeakPlugin\DataMapper; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Prophecy\PhpUnit\ProphecyTrait; | ||
use Setono\PeakWMS\DataTransferObject\SalesOrder\SalesOrder; | ||
use Setono\SyliusPeakPlugin\DataMapper\ShippingCostSalesOrderDataMapper; | ||
use Setono\SyliusPeakPlugin\Model\OrderInterface; | ||
use Sylius\Component\Core\Model\Adjustment; | ||
use Sylius\Component\Core\Model\AdjustmentInterface; | ||
use Sylius\Component\Core\Model\Shipment; | ||
use Tests\Setono\SyliusPeakPlugin\Application\Model\Order; | ||
|
||
final class ShippingCostSalesOrderDataMapperTest extends TestCase | ||
{ | ||
use ProphecyTrait; | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_maps_shipping_with_tax_included_in_price(): void | ||
{ | ||
$order = self::getOrder(); | ||
self::addShipment($order, 100, 20, true); | ||
|
||
$salesOrder = new SalesOrder(); | ||
|
||
$mapper = new ShippingCostSalesOrderDataMapper(); | ||
$mapper->map($order, $salesOrder); | ||
|
||
self::assertSame(0.8, $salesOrder->shippingCost); | ||
self::assertSame(0.2, $salesOrder->shippingTaxCost); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_maps_shipping_with_tax_not_included_in_price(): void | ||
{ | ||
$order = self::getOrder(); | ||
self::addShipment($order, 100, 20, false); | ||
|
||
$salesOrder = new SalesOrder(); | ||
|
||
$mapper = new ShippingCostSalesOrderDataMapper(); | ||
$mapper->map($order, $salesOrder); | ||
|
||
self::assertSame(1.0, $salesOrder->shippingCost); | ||
self::assertSame(0.2, $salesOrder->shippingTaxCost); | ||
} | ||
|
||
private static function getOrder(): Order | ||
{ | ||
$order = new Order(); | ||
$order->setCurrencyCode('USD'); | ||
|
||
return $order; | ||
} | ||
|
||
private static function addShipment(OrderInterface $order, int $shippingAmount, int $taxAmount, bool $taxNeutral): void | ||
{ | ||
$shipment = new Shipment(); | ||
$order->addShipment($shipment); | ||
|
||
$taxAdjustment = new Adjustment(); | ||
$taxAdjustment->setAmount($taxAmount); | ||
$taxAdjustment->setNeutral($taxNeutral); | ||
$taxAdjustment->setType(AdjustmentInterface::TAX_ADJUSTMENT); | ||
|
||
$shippingAdjustment = new Adjustment(); | ||
$shippingAdjustment->setAmount($shippingAmount); | ||
$shippingAdjustment->setNeutral(false); | ||
$shippingAdjustment->setType(AdjustmentInterface::SHIPPING_ADJUSTMENT); | ||
|
||
$shipment->addAdjustment($shippingAdjustment); | ||
$shipment->addAdjustment($taxAdjustment); | ||
} | ||
} |