Skip to content

Commit

Permalink
Add missing order details
Browse files Browse the repository at this point in the history
  • Loading branch information
lruozzi9 committed Jun 25, 2024
1 parent ddf5fc3 commit 6648dc7
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 275 deletions.
3 changes: 3 additions & 0 deletions config/services/converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
$services->set('webgriffe_sylius_klarna.converter.order', OrderConverter::class)
->args([
service('webgriffe_sylius_klarna.resolver.payment_country'),
service('translator'),
service('router'),
service('liip_imagine.cache.manager'),
])
;
};
91 changes: 72 additions & 19 deletions src/Client/ValueObject/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,49 @@
namespace Webgriffe\SyliusKlarnaPlugin\Client\ValueObject;

use JsonSerializable;
use Webgriffe\SyliusKlarnaPlugin\Client\Enum\Locale;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Payments\MerchantUrls;

final readonly class Order implements JsonSerializable
{
/**
* @param OrderLine[] $orderLines
* @param string[]|null $customPaymentMethodIds
*/
public function __construct(
private PaymentCountry $paymentCountry,
private Address $billingAddress,
private Address $shippingAddress,
private Amount $amount,
private Amount $taxAmount,
private array $lines,
private MerchantUrls $merchantUrls,
private string $merchantReference1,
private array $orderLines,
private Locale $locale = Locale::EnglishUnitedStates,
private ?Address $billingAddress = null,
private ?Address $shippingAddress = null,
private bool $autoCapture = false,
private ?MerchantUrls $merchantUrls = null,
private ?string $merchantReference1 = null,
private ?string $merchantReference2 = null,
private ?Customer $customer = null,
private ?string $merchantData = null,
private ?array $customPaymentMethodIds = null,
) {
}

public function isAutoCapture(): bool
{
return $this->autoCapture;
}

public function getPaymentCountry(): PaymentCountry
{
return $this->paymentCountry;
}

public function getBillingAddress(): Address
public function getBillingAddress(): ?Address
{
return $this->billingAddress;
}

public function getShippingAddress(): Address
public function getShippingAddress(): ?Address
{
return $this->shippingAddress;
}
Expand All @@ -46,33 +62,70 @@ public function getTaxAmount(): Amount
return $this->taxAmount;
}

public function getLines(): array
/**
* @return OrderLine[]
*/
public function getOrderLines(): array
{
return $this->lines;
return $this->orderLines;
}

public function getMerchantUrls(): MerchantUrls
public function getMerchantUrls(): ?MerchantUrls
{
return $this->merchantUrls;
}

public function getMerchantReference1(): string
public function getMerchantReference1(): ?string
{
return $this->merchantReference1;
}

public function getMerchantReference2(): ?string
{
return $this->merchantReference2;
}

public function getLocale(): Locale
{
return $this->locale;
}

/**
* @return string[]|null
*/
public function getCustomPaymentMethodIds(): ?array
{
return $this->customPaymentMethodIds;
}

public function getMerchantData(): ?string
{
return $this->merchantData;
}

public function getCustomer(): ?Customer
{
return $this->customer;
}

public function jsonSerialize(): array
{
return [
'purchase_country' => $this->getPaymentCountry()->getCountry()->value,
'purchase_currency' => $this->getPaymentCountry()->getCurrency()->value,
return array_filter([
'auto_capture' => $this->isAutoCapture(),
'billing_address' => $this->getBillingAddress(),
'shipping_address' => $this->getShippingAddress(),
'custom_payment_method_ids' => $this->getCustomPaymentMethodIds(),
'customer' => $this->getCustomer(),
'locale' => $this->getLocale(),
'merchant_data' => $this->getMerchantData(),
'merchant_reference1' => $this->getMerchantReference1(),
'merchant_reference2' => $this->getMerchantReference2(),
'merchant_urls' => $this->getMerchantUrls(),
'order_amount' => $this->getAmount()->getISO4217Amount(),
'order_lines' => $this->getOrderLines(),
'order_tax_amount' => $this->getTaxAmount()->getISO4217Amount(),
'order_lines' => $this->getLines(),
'merchant_urls' => $this->getMerchantUrls(),
'merchant_reference1' => $this->getMerchantReference1(),
];
'purchase_country' => $this->getPaymentCountry()->getCountry()->value,
'purchase_currency' => $this->getPaymentCountry()->getCurrency()->value,
'shipping_address' => $this->getShippingAddress(),
], static fn ($value): bool => $value !== null);
}
}
232 changes: 232 additions & 0 deletions src/Converter/CommonOrderConverterTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
<?php

declare(strict_types=1);

namespace Webgriffe\SyliusKlarnaPlugin\Converter;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Sylius\Component\Core\Model\AddressInterface;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ShipmentInterface;
use Sylius\Component\Customer\Model\CustomerInterface as ModelCustomerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Contracts\Translation\TranslatorInterface;
use Webgriffe\SyliusKlarnaPlugin\Client\Enum\OrderLineType;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Address;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Amount;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Customer;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\OrderLine;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\ProductIdentifiers;

trait CommonOrderConverterTrait
{
abstract private function getUrlGenerator(): UrlGeneratorInterface;

abstract private function getCacheManager(): CacheManager;

abstract private function getTranslator(): TranslatorInterface;

private function getCustomer(OrderInterface $order): ?Customer
{
$customer = $order->getCustomer();
if (!$customer instanceof CustomerInterface) {
return null;
}
$isMale = null;
$gender = $customer->getGender();
if ($gender !== ModelCustomerInterface::UNKNOWN_GENDER) {
$isMale = $gender === ModelCustomerInterface::MALE_GENDER;
}

return new Customer(
$customer->getBirthday(),
$isMale,
null,
null,
null,
);
}

/**
* @return OrderLine[]
*/
private function getOrderLines(OrderInterface $order): array
{
$lines = [];
foreach ($order->getItems() as $orderItem) {
$lines[] = $this->createOrderLineFromOrderItem($order, $orderItem);
}
$shipment = $order->getShipments()->first();
if ($shipment instanceof ShipmentInterface) {
$lines[] = $this->createOrderLineFromShipment($order, $shipment);
}

return $lines;
}

private function getAddress(?AddressInterface $address, ?ModelCustomerInterface $customer): ?Address
{
if (!$address instanceof AddressInterface) {
return null;
}

$region = $address->getProvinceCode();
if ($region !== null && str_contains($region, '-')) {
$region = explode('-', $region)[1];
}

return new Address(
$address->getCity(),
$address->getCountryCode(),
$customer?->getEmail(),
$address->getLastName(),
$address->getFirstName(),
$address->getPhoneNumber(),
$address->getPostcode(),
$region,
$address->getStreet(),
null,
null,
);
}

private function createOrderLineFromOrderItem(OrderInterface $order, OrderItemInterface $orderItem): OrderLine
{
$product = $orderItem->getProduct();
$previousContext = $this->getUrlGenerator()->getContext();
$hostname = $order->getChannel()?->getHostname();
if ($hostname !== null) {
$this->getUrlGenerator()->setContext(new RequestContext(
'',
'GET',
$hostname,
'https',
));
}
$slug = $orderItem->getProduct()?->getSlug();
$productUrl = null;
if ($slug !== null) {
$productUrl = $this->getUrlGenerator()->generate(
'sylius_shop_product_show',
['slug' => $slug],
UrlGeneratorInterface::ABSOLUTE_URL,
);
}
$productImagePath = $this->getProductImagePath($orderItem->getProduct());
$imageUrl = null;
if ($productImagePath !== null) {
$imageUrl = $this->getCacheManager()->getBrowserPath(
$productImagePath,
'sylius_shop_product_thumbnail',
);
}
$this->getUrlGenerator()->setContext($previousContext);

$productIdentifiers = null;
if ($product !== null) {
$productIdentifiers = new ProductIdentifiers(
null,
$this->getCategoryPath($product),
);
}
$taxRate = $this->getOrderTaxRate($order);
$totalAmount = $orderItem->getTotal();
$totalTaxAmount = (int) ($totalAmount - (($totalAmount * 10000) / (10000 + $taxRate)));
$totalDiscountAmount = 0;
$firstOrderItemUnit = $orderItem->getUnits()->first();
if ($firstOrderItemUnit instanceof OrderItemUnitInterface) {
$totalDiscountAmount = -1 * $firstOrderItemUnit->getAdjustmentsTotal(AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT);
}

return new OrderLine(
(string) $orderItem->getProductName(),
$orderItem->getQuantity(),
$taxRate,
Amount::fromSyliusAmount($totalAmount),
Amount::fromSyliusAmount($totalDiscountAmount),
Amount::fromSyliusAmount($totalTaxAmount),
Amount::fromSyliusAmount($orderItem->getUnitPrice()),
$productUrl,
$imageUrl,
(string) $orderItem->getId(),
'pcs',
$orderItem->getProduct()?->getCode(),
OrderLineType::Physical,
$productIdentifiers,
null,
);
}

private function createOrderLineFromShipment(OrderInterface $order, ShipmentInterface $shipment): OrderLine
{
$taxRate = $this->getOrderTaxRate($order);
$totalAmount = $order->getShippingTotal();
$unitPrice = $order->getAdjustmentsTotalRecursively(AdjustmentInterface::SHIPPING_ADJUSTMENT);
$shippingTaxTotal = (int) ($totalAmount - (($totalAmount * 10000) / (10000 + $taxRate)));
$totalDiscountAmount = -1 * $order->getAdjustmentsTotalRecursively(AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT);

return new OrderLine(
$shipment->getMethod()?->getName() ?? $this->getTranslator()->trans('sylius.ui.shipping_charges'),
1,
$taxRate,
Amount::fromSyliusAmount($totalAmount),
Amount::fromSyliusAmount($totalDiscountAmount),
Amount::fromSyliusAmount($shippingTaxTotal),
Amount::fromSyliusAmount($unitPrice),
null,
null,
null,
null,
null,
OrderLineType::ShippingFee,
);
}

private function getOrderTaxRate(OrderInterface $order): int
{
$taxRate = 0;
$taxAdjustment = $order->getAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT)->first();
if ($taxAdjustment instanceof AdjustmentInterface) {
$taxRate = (int) ($taxAdjustment->getDetails()['taxRateAmount'] * 10000);
}

return $taxRate;
}

private function getProductImagePath(?ProductInterface $product): ?string
{
if ($product === null) {
return null;
}
$images = $product->getImagesByType('main_image');
foreach ($images as $image) {
return $image->getPath();
}
$images = $product->getImages();
foreach ($images as $image) {
return $image->getPath();
}

return null;
}

private function getCategoryPath(ProductInterface $product): ?string
{
$categoryPath = '';
$mainTaxon = $product->getMainTaxon();
if ($mainTaxon === null) {
return null;
}
foreach ($mainTaxon->getAncestors() as $taxon) {
$categoryPath = $taxon->getName() . ' > ' . $categoryPath;
}

return $categoryPath . $mainTaxon->getName();
}
}
Loading

0 comments on commit 6648dc7

Please sign in to comment.