Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 75 additions & 11 deletions Gateway/Request/NexiCheckout/GlobalRequestBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
use libphonenumber\PhoneNumberUtil;
use Magento\Bundle\Model\Product\Price;
use Magento\Bundle\Model\Product\Type as BundleType;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable as ConfigurableType;
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\UrlInterface;
use Magento\Quote\Model\Quote;
use Magento\Sales\Api\Data\CreditmemoInterface;
use Magento\Sales\Api\Data\InvoiceInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Item as OrderItem;
use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector;
Expand All @@ -35,13 +39,15 @@ class GlobalRequestBuilder
* @param EncryptorInterface $encryptor
* @param WebhookHandler $webhookHandler
* @param AmountConverter $amountConverter
* @param ProductRepositoryInterface $productRepository
*/
public function __construct(
private readonly UrlInterface $url,
private readonly Config $config,
private readonly EncryptorInterface $encryptor,
private readonly WebhookHandler $webhookHandler,
private readonly AmountConverter $amountConverter,
private readonly ProductRepositoryInterface $productRepository
) {
}

Expand Down Expand Up @@ -185,21 +191,21 @@ public function getShippingTaxRate(Order|Quote $paymentSubject)
/**
* Build payload with order items data based on product type
*
* @param Order|Quote $paymentSubject
* @param Order|Quote|CreditmemoInterface|InvoiceInterface $paymentSubject
*
* @return array
*/
public function getProductsData(Order|Quote $paymentSubject): array
public function getProductsData(Order|Quote|CreditmemoInterface|InvoiceInterface $paymentSubject): array
{
$items = [];
/** @var OrderItem|Quote\Item $item */
foreach ($paymentSubject->getAllVisibleItems() as $item) {
foreach ($paymentSubject->getAllItems() as $item) {

if ($item->getParentItem()) {
if ($item->getParentItem() || (double)$item->getBasePrice() === 0.0) {
continue;
}

switch ($item->getProductType()) {
switch ($this->getProductType($item)) {
case ConfigurableType::TYPE_CODE:
$children = $this->getChildren($item);
foreach ($children as $childItem) {
Expand Down Expand Up @@ -275,15 +281,38 @@ private function createItemBaseData(mixed $item): array
/**
* Get children items of a given order item or quote item.
*
* @param OrderItem|Quote\Item $item
*
* @param mixed $item
* @return array|Quote\Item\AbstractItem[]
*/
private function getChildren(OrderItem|Quote\Item $item): array
private function getChildren(mixed $item): array
{
$children = $item instanceof OrderItem ? $item->getChildrenItems() : $item->getChildren();
if ($item instanceof \Magento\Sales\Model\Order\Item) {
return $item->getChildrenItems();
}

if ($item instanceof \Magento\Quote\Model\Quote\Item\AbstractItem) {
return $item->getChildren();
}

if ($item instanceof \Magento\Sales\Model\Order\Invoice\Item
|| $item instanceof \Magento\Sales\Model\Order\Creditmemo\Item
) {
$orderItem = $item->getOrderItem();
$childOrderItems = $orderItem->getChildrenItems();

$saleDocument = $item->getInvoice() ?? $item->getCreditmemo();
$childrenItems = [];

return $children;
foreach ($saleDocument->getAllItems() as $saleDocChild) {
if (in_array($saleDocChild->getOrderItem(), $childOrderItems, true)) {
$childrenItems[] = $saleDocChild;
}
}

return $childrenItems;
}

return [];
}

/**
Expand Down Expand Up @@ -319,7 +348,7 @@ private function appendPriceData(array $data, mixed $item): array
$data['netTotalAmount'] = $this->amountConverter->convertToNexiAmount(
$item->getBaseRowTotal() - $item->getBaseDiscountAmount()
);
$data['taxRate'] = $this->amountConverter->convertToNexiAmount($item->getTaxPercent());
$data['taxRate'] = $this->amountConverter->convertToNexiAmount($this->getTaxRate($item));
$data['taxAmount'] = $this->amountConverter->convertToNexiAmount($item->getBaseTaxAmount());

return $data;
Expand Down Expand Up @@ -347,4 +376,39 @@ public function buildPaymentMethodsConfiguration(Quote|Order $salesObject): arra
)
];
}

/**
* Calculate the tax rate for a given item.
*
* @param mixed $item
*
* @return mixed
*/
private function getTaxRate(mixed $item): mixed
{
if ($item->getTaxPercent()) {
return $item->getTaxPercent();
}
return $item->getTaxAmount() * 100 / $item->getRowTotal();
}

/**
* Get product type by product ID
*
* @param mixed $item
* @return string|null
*/
private function getProductType(mixed $item) : string|null
{
if ($item->getProductType()) {
return $item->getProductType();
}

try {
$product = $this->productRepository->getById($item->getProductId());
return $product->getTypeId();
} catch (NoSuchEntityException $e) {
return null;
}
}
}
32 changes: 3 additions & 29 deletions Gateway/Request/NexiCheckout/SalesDocumentItemsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ class SalesDocumentItemsBuilder
*
* @param AmountConverter $amountConverter
* @param StringSanitizer $stringSanitizer
* @param GlobalRequestBuilder $globalRequestBuilder
*/
public function __construct(
private readonly AmountConverter $amountConverter,
private readonly StringSanitizer $stringSanitizer,
private readonly GlobalRequestBuilder $globalRequestBuilder,
) {
}

Expand All @@ -35,23 +37,7 @@ public function __construct(
*/
public function build(CreditmemoInterface|InvoiceInterface $salesObject): array
{
$items = [];
foreach ($salesObject->getAllItems() as $item) {
if ((double)$item->getBasePrice() === 0.0) {
continue;
}
$items[] = new Item(
name : $this->stringSanitizer->sanitize($item->getName()),
quantity : (float)$item->getQty(),
unit : 'pcs',
unitPrice : $this->amountConverter->convertToNexiAmount($item->getBasePrice()),
grossTotalAmount: $this->amountConverter->convertToNexiAmount($item->getBaseRowTotalInclTax()),
netTotalAmount : $this->amountConverter->convertToNexiAmount($item->getBaseRowTotal()),
reference : $this->stringSanitizer->sanitize($item->getSku()),
taxRate : $this->amountConverter->convertToNexiAmount($this->calculateTaxRate($item)),
taxAmount : $this->amountConverter->convertToNexiAmount($item->getBaseTaxAmount()),
);
}
$items = $this->globalRequestBuilder->getProductsData($salesObject);

if ($salesObject->getShippingInclTax()) {
$items[] = new Item(
Expand All @@ -73,18 +59,6 @@ public function build(CreditmemoInterface|InvoiceInterface $salesObject): array
return $items;
}

/**
* Calculate the tax rate for a given item.
*
* @param mixed $item
*
* @return mixed
*/
private function calculateTaxRate(mixed $item): mixed
{
return $item->getTaxAmount() / $item->getRowTotal() * 100;
}

/**
* Calculate the shipping tax rate for a given sales object.
*
Expand Down
9 changes: 8 additions & 1 deletion Observer/ScheduledCartValidation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Nexi\Checkout\Observer;

use Magento\Customer\Model\Session;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\LocalizedException;
Expand All @@ -18,10 +19,12 @@ class ScheduledCartValidation implements ObserverInterface
*
* @param CartRepositoryInterface $cartRepository
* @param TotalConfigProvider $totalConfigProvider
* @param Session $customerSession
*/
public function __construct(
private CartRepositoryInterface $cartRepository,
private TotalConfigProvider $totalConfigProvider
private TotalConfigProvider $totalConfigProvider,
private Session $customerSession
) {
}

Expand All @@ -46,6 +49,10 @@ public function execute(Observer $observer)
->getProduct()
->getCustomAttribute(PreventDifferentScheduledCart::SCHEDULE_CODE);

if (!$this->customerSession->isLoggedIn() && $cartItemSchedule) {
throw new LocalizedException(__("Can't place order with scheduled products when not logged in"));
}

if ($cartItemSchedule && $cartItemSchedule->getValue()) {
if (null !== $cartSchedule && $cartSchedule !== $cartItemSchedule->getValue()) {
throw new LocalizedException(__("Can't place order with different scheduled products in cart"));
Expand Down
30 changes: 30 additions & 0 deletions view/frontend/templates/info/checkout.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Nexi\Checkout\Block\Info\Nexi;

/** @var $block Nexi */
/** @var $escaper \Magento\Framework\Escaper */
?>

<?= $block->getChildHtml() ?>
<table class="admin__table-secondary order-information-table">
<tbody>
<tr>
<th><?= $escaper->escapeHtml(__('Payment Provider')) ?></th>
<td><img alt="Nexi Logo" style="width: 45px; height: 15px; background-color: white; "
src="<?= $escaper->escapeHtml($block->getLogo() ? $block->getLogo() : ''); ?>"/></td>
</tr>
<tr>
<th><?= $escaper->escapeHtml(__('Payment Method')) ?></th>
<td><?= $escaper->escapeHtml(
$block->getSelectedPaymentMethodData()[Nexi::SELECTED_PATMENT_METHOD] ?? ''
) ?></td>
</tr>
<tr>
<th><?= $escaper->escapeHtml(__('Payment Type')) ?></th>
<td><?= $escaper->escapeHtml(
$block->getSelectedPaymentMethodData()[Nexi::SELECTED_PATMENT_TYPE] ?? ''
) ?></td>
</tr>
</tbody>
</table>
Loading