Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOL-864 Full Refund with Flow Builder + Refund Manager after partial refund throws error #516

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Components\RefundManager\RefundCalculationHelper;

use Kiener\MolliePayments\Service\Refund\Item\RefundItem;

class RefundCalculationHelper
{
/** @var RefundItem[] */
protected $refundItems;

public function __construct()
{
$this->refundItems = [];
}

/**
* @param RefundItem $refundItem
* @return void
*/
public function addRefundItem(RefundItem $refundItem)
{
$this->refundItems[] = $refundItem;
}

/**
* @param string $orderLineId
* @return int
*/
public function getRefundQuantityForMollieId(string $orderLineId): int
{
$refundQuantity = 0;
foreach ($this->refundItems as $refundItem) {
if ($refundItem->getMollieLineID()===$orderLineId) {
$refundQuantity += $refundItem->getQuantity();
}
}
return $refundQuantity;
}

/**
* @param string $orderLineId
* @return float
*/
public function getRefundAmountForMollieId(string $orderLineId): float
{
$refundAmount = 0;
foreach ($this->refundItems as $refundItem) {
if ($refundItem->getMollieLineID()===$orderLineId) {
$refundAmount += $refundItem->getAmount();
}
}
return $refundAmount;
}
}
82 changes: 73 additions & 9 deletions src/Components/RefundManager/RefundManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,27 @@

use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderDispatcherAdapterInterface;
use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderEventFactory;
use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderFactory;
use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderFactoryInterface;
use Kiener\MolliePayments\Components\RefundManager\Builder\RefundDataBuilder;
use Kiener\MolliePayments\Components\RefundManager\Integrators\StockManagerInterface;
use Kiener\MolliePayments\Components\RefundManager\RefundCalculationHelper\RefundCalculationHelper;
use Kiener\MolliePayments\Components\RefundManager\RefundData\RefundData;
use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequest;
use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequestItem;
use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequestItemRoundingDiff;
use Kiener\MolliePayments\Exception\CouldNotCreateMollieRefundException;
use Kiener\MolliePayments\Service\MollieApi\Order;
use Kiener\MolliePayments\Service\OrderService;
use Kiener\MolliePayments\Service\OrderServiceInterface;
use Kiener\MolliePayments\Service\Refund\Item\RefundItem;
use Kiener\MolliePayments\Service\Refund\RefundService;
use Kiener\MolliePayments\Service\Refund\RefundServiceInterface;
use Kiener\MolliePayments\Service\Stock\StockManager;
use Kiener\MolliePayments\Struct\MollieApi\OrderLineMetaDataStruct;
use Kiener\MolliePayments\Struct\Order\OrderAttributes;
use Kiener\MolliePayments\Struct\OrderLineItemEntity\OrderLineItemEntityAttributes;
use Mollie\Api\Resources\OrderLine;
use Mollie\Api\Resources\Refund;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Checkout\Order\OrderEntity;
Expand Down Expand Up @@ -213,7 +211,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont
}


if (! $refund instanceof Refund) {
if (!$refund instanceof Refund) {
# a problem happened, lets finish with an exception
throw new CouldNotCreateMollieRefundException('', (string)$order->getOrderNumber());
}
Expand Down Expand Up @@ -300,25 +298,66 @@ private function getOrderItem(OrderEntity $orderEntity, string $lineID): ?OrderL
*/
private function buildRequestItemsFromOrder(OrderEntity $order)
{
$refunds = $this->refundService->getRefunds($order);

$refundCalculationHelper = new RefundCalculationHelper();
/** @var array<mixed> $refund */
foreach ($refunds as $refund) {
smemoict marked this conversation as resolved.
Show resolved Hide resolved
if (!isset($refund['metadata'])) {
continue;
}

$metadata = $refund['metadata'];
if (!isset($metadata['composition'])) {
continue;
}

$composition = $metadata['composition'];

foreach ($composition as $compositionItem) {
$refundCalculationHelper->addRefundItem(
new RefundItem(
$compositionItem['swLineId'],
$compositionItem['mollieLineId'],
$compositionItem['swReference'],
$compositionItem['quantity'],
$compositionItem['amount']
)
);
}
}

$items = [];

if ($order->getLineItems() instanceof OrderLineItemCollection) {
/** @var OrderLineItemEntity $lineItem */
foreach ($order->getLineItems() as $lineItem) {
$orderLineId = $this->getOrderLineId($lineItem);

$alreadyRefundedQuantity = $refundCalculationHelper->getRefundQuantityForMollieId($orderLineId);
$alreadyRefundedAmount = $refundCalculationHelper->getRefundAmountForMollieId($orderLineId);

$items[] = new RefundRequestItem(
$lineItem->getId(),
$lineItem->getTotalPrice(),
$lineItem->getQuantity(),
$lineItem->getTotalPrice() - $alreadyRefundedAmount,
$lineItem->getQuantity() - $alreadyRefundedQuantity,
0
);
}
}

if ($order->getDeliveries() instanceof OrderDeliveryCollection) {
/** @var OrderDeliveryEntity $delivery */
foreach ($order->getDeliveries() as $delivery) {
$orderLineId = $this->getOrderLineId($delivery);

$alreadyRefundedQuantity = $refundCalculationHelper->getRefundQuantityForMollieId($orderLineId);
$alreadyRefundedAmount = $refundCalculationHelper->getRefundAmountForMollieId($orderLineId);

$items[] = new RefundRequestItem(
$delivery->getId(),
$delivery->getShippingCosts()->getTotalPrice(),
$delivery->getShippingCosts()->getQuantity(),
$delivery->getShippingCosts()->getTotalPrice() - $alreadyRefundedAmount,
$delivery->getShippingCosts()->getQuantity() - $alreadyRefundedQuantity,
0
);
}
Expand Down Expand Up @@ -426,4 +465,29 @@ private function convertToRefundItems(RefundRequest $request, OrderEntity $order

return $serviceItems;
}

/**
* @param OrderDeliveryEntity|OrderLineItemEntity $lineItem
* @return string
*/
public function getOrderLineId($lineItem): string
smemoict marked this conversation as resolved.
Show resolved Hide resolved
{
$customFields = $lineItem->getCustomFields();

if (!isset($customFields)) {
return "";
}

if (!isset($customFields['mollie_payments'])) {
return "";
}

$molliePayments = $customFields['mollie_payments'];

if (!isset($molliePayments['order_line_id'])) {
return "";
}

return $molliePayments['order_line_id'];
}
}
1 change: 1 addition & 0 deletions src/Resources/config/services/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@

<service id="Kiener\MolliePayments\Service\Order\UpdateOrderLineItems">
<argument type="service" id="order_line_item.repository"/>
<argument type="service" id="order_delivery.repository"/>
</service>


Expand Down
19 changes: 13 additions & 6 deletions src/Service/Order/UpdateOrderLineItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ class UpdateOrderLineItems
*/
private $orderLineRepository;

/**
* @var EntityRepositoryInterface
*/
private $orderDeliveryRepository;


/**
* @param EntityRepositoryInterface $orderLineRepository
*/
public function __construct(EntityRepositoryInterface $orderLineRepository)
public function __construct(EntityRepositoryInterface $orderLineRepository, EntityRepositoryInterface $orderDeliveryRepository)
{
$this->orderLineRepository = $orderLineRepository;
$this->orderDeliveryRepository = $orderDeliveryRepository;
}

/**
Expand All @@ -34,10 +40,7 @@ public function updateOrderLineItems(Order $mollieOrder, SalesChannelContext $sa
{
/** @var OrderLine $orderLine */
foreach ($mollieOrder->lines() as $orderLine) {
if ($orderLine->type === OrderLineType::TYPE_SHIPPING_FEE) {
continue;
}

##Contrary to the name, this can also be an order_delivery id since these are also kind of line items
$shopwareLineItemId = (string)$orderLine->metadata->orderLineItemId;

if (empty($shopwareLineItemId)) {
Expand All @@ -53,7 +56,11 @@ public function updateOrderLineItems(Order $mollieOrder, SalesChannelContext $sa
]
];

$this->orderLineRepository->update([$data], $salesChannelContext->getContext());
if ($orderLine->type === OrderLineType::TYPE_SHIPPING_FEE) {
$this->orderDeliveryRepository->update([$data], $salesChannelContext->getContext());
} else {
$this->orderLineRepository->update([$data], $salesChannelContext->getContext());
}
}
}
}
3 changes: 2 additions & 1 deletion tests/PHPUnit/Fakes/FakeRefundService.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public function cancel(OrderEntity $order, string $refundId): bool
*/
public function getRefunds(OrderEntity $order): array
{
// TODO: Implement getRefunds() method.
// FIXME: Only implements that nothing has been refunded yet, this might have to be changed.
return [];
}

/**
Expand Down