Skip to content

Commit

Permalink
Add more info on order lines
Browse files Browse the repository at this point in the history
  • Loading branch information
lruozzi9 committed Jun 24, 2024
1 parent cde48d3 commit 35d6fc1
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 46 deletions.
3 changes: 3 additions & 0 deletions config/services/converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
$services->set('webgriffe_sylius_klarna.converter.payment', PaymentConverter::class)
->args([
service('webgriffe_sylius_klarna.resolver.payment_country'),
service('translator'),
service('router'),
service('liip_imagine.cache.manager'),
])
;

Expand Down
2 changes: 1 addition & 1 deletion src/Client/ValueObject/OrderLine.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public function jsonSerialize(): array
'total_amount' => $this->getTotalAmount()->getISO4217Amount(),
'total_discount_amount' => $this->getTotalDiscountAmount()->getISO4217Amount(),
'total_tax_amount' => $this->getTotalTaxAmount()->getISO4217Amount(),
'type' => $this->getType()->value,
'type' => $this->getType()?->value,
'unit_price' => $this->getUnitPrice()->getISO4217Amount(),
'subscription' => $this->getSubscription(),
], static fn ($value) => $value !== null);
Expand Down
4 changes: 2 additions & 2 deletions src/Client/ValueObject/Subscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public function getIntervalCount(): int

public function jsonSerialize(): array
{
return array_filter([
return [
'name' => $this->getName(),
'interval' => $this->getInterval(),
'interval_count' => $this->getIntervalCount(),
], static fn ($value) => $value !== null);
];
}
}
189 changes: 146 additions & 43 deletions src/Converter/PaymentConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@

namespace Webgriffe\SyliusKlarnaPlugin\Converter;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use LogicException;
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\PaymentInterface;
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\AcquiringChannel;
use Webgriffe\SyliusKlarnaPlugin\Client\Enum\Intent;
use Webgriffe\SyliusKlarnaPlugin\Client\Enum\OrderLineType;
Expand All @@ -20,13 +27,17 @@
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\OrderLine;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Payment;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\Payments\MerchantUrls;
use Webgriffe\SyliusKlarnaPlugin\Client\ValueObject\ProductIdentifiers;
use Webgriffe\SyliusKlarnaPlugin\Resolver\PaymentCountryResolverInterface;
use Webmozart\Assert\Assert;

final readonly class PaymentConverter implements PaymentConverterInterface
{
public function __construct(
private PaymentCountryResolverInterface $paymentCountryResolver,
private TranslatorInterface $translator,
private UrlGeneratorInterface $urlGenerator,
private CacheManager $cacheManager,
) {
}

Expand All @@ -39,7 +50,8 @@ public function convert(
): Payment {
$order = $payment->getOrder();
Assert::isInstanceOf($order, OrderInterface::class);
$purchaseCountry = $order->getBillingAddress()?->getCountryCode();
$billingAddress = $order->getBillingAddress();
$purchaseCountry = $billingAddress?->getCountryCode();
Assert::notNull($purchaseCountry, 'Purchase country is required to create a payment on Klarna');
$purchaseCurrency = $order->getCurrencyCode();
Assert::notNull($purchaseCurrency, 'Purchase currency is required to create a payment on Klarna');
Expand Down Expand Up @@ -72,11 +84,12 @@ public function convert(
$paymentCountry->matchUserLocale($order->getLocaleCode()),
$merchantUrls,
$this->getCustomer($order),
$this->getAddress($order->getBillingAddress(), $order->getCustomer()),
$this->getAddress($billingAddress, $order->getCustomer()),
$this->getAddress($order->getShippingAddress(), $order->getCustomer()),
(string) $order->getNumber(),
(string) $payment->getId(),
null,
Amount::fromSyliusAmount($order->getTaxTotal()),
sprintf('#%s@%s', $order->getId(), $payment->getId()),
);
}

Expand Down Expand Up @@ -108,15 +121,110 @@ private function getOrderLines(OrderInterface $order): array
{
$lines = [];
foreach ($order->getItems() as $orderItem) {
$lines[] = $this->createOrderLineFromOrderItem($orderItem);
$lines[] = $this->createOrderLineFromOrderItem($order, $orderItem);
}
$shipment = $order->getShipments()->first();
if ($shipment instanceof ShipmentInterface) {
$lines[] = $this->createOrderLineFromShipment($order, $shipment);
}

$taxRate = 2200; #TODO
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();
$taxRate = $this->getOrderTaxRate($order);
$previousContext = $this->urlGenerator->getContext();
$hostname = $order->getChannel()?->getHostname();
if ($hostname !== null) {
$this->urlGenerator->setContext(new RequestContext(
'',
'GET',
$hostname,
'https',
));
}
$slug = $orderItem->getProduct()?->getSlug();
$productUrl = null;
if ($slug !== null) {
$productUrl = $this->urlGenerator->generate(
'sylius_shop_product_show',
['slug' => $slug],
UrlGeneratorInterface::ABSOLUTE_URL,
);
}
$productImagePath = $this->getProductImagePath($orderItem->getProduct());
$imageUrl = null;
if ($productImagePath !== null) {
$this->cacheManager->getBrowserPath(
$productImagePath,
'sylius_shop_product_thumbnail',
);
}
$this->urlGenerator->setContext($previousContext);

$productIdentifiers = null;
if ($product !== null) {
$productIdentifiers = new ProductIdentifiers(
null,
$this->getCategoryPath($product),
);
}

return new OrderLine(
(string) $orderItem->getProductName(),
$orderItem->getQuantity(),
$taxRate,
Amount::fromSyliusAmount($orderItem->getTotal()),
Amount::fromSyliusAmount($orderItem->getFullDiscountedUnitPrice() * $orderItem->getQuantity()),
Amount::fromSyliusAmount($orderItem->getTaxTotal()),
Amount::fromSyliusAmount($orderItem->getUnitPrice()),
$productUrl,
$imageUrl,
$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();
$shippingTaxTotal = $totalAmount - (($totalAmount * 10000) / (10000 + $taxRate));

$lines[] = new OrderLine(
$order->getShipments()->first()?->getMethod()?->getName() ?? 'Shipping fee',
return new OrderLine(
$shipment->getMethod()?->getName() ?? $this->translator->trans('sylius.ui.shipping_charges'),
1,
$taxRate,
Amount::fromSyliusAmount($totalAmount),
Expand All @@ -130,52 +238,47 @@ private function getOrderLines(OrderInterface $order): array
null,
OrderLineType::ShippingFee,
);

return $lines;
}

private function createOrderLineFromOrderItem(OrderItemInterface $orderItem): OrderLine
private function getOrderTaxRate(OrderInterface $order): int
{
return new OrderLine(
(string) $orderItem->getProductName(),
$orderItem->getQuantity(),
2200, #TODO
Amount::fromSyliusAmount($orderItem->getTotal()),
Amount::fromSyliusAmount(0),
Amount::fromSyliusAmount($orderItem->getTaxTotal()),
Amount::fromSyliusAmount($orderItem->getUnitPrice()),
null,
null,
null,
'pcs',
$orderItem->getProduct()?->getCode(),
OrderLineType::Physical,
);
$taxRate = 0;
$taxAdjustment = $order->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)->first();
if ($taxAdjustment instanceof AdjustmentInterface) {
$taxRate = (int) ($taxAdjustment->getDetails()['taxRateAmount'] * 10000);
}

return $taxRate;
}

private function getAddress(?AddressInterface $address, ?\Sylius\Component\Customer\Model\CustomerInterface $customer): ?Address
private function getProductImagePath(?ProductInterface $product): ?string
{
if (!$address instanceof AddressInterface) {
if ($product === null) {
return null;
}
$images = $product->getImagesByType('main');
foreach ($images as $image) {
return $image->getPath();
}
$images = $product->getImages();
foreach ($images as $image) {
return $image->getPath();
}

$region = $address->getProvinceCode();
if ($region !== null && str_contains($region, '-')) {
$region = explode('-', $region)[1];
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() . ' > ';
}

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

0 comments on commit 35d6fc1

Please sign in to comment.