-
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.
Capture card and Automatic Capture during Document Creation for Invoi…
…ce B2C and B2B (#72)
- Loading branch information
1 parent
2362ecc
commit d3c8633
Showing
14 changed files
with
516 additions
and
6 deletions.
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
111 changes: 111 additions & 0 deletions
111
src/EventSubscriber/OrderInvoiceDocumentCreatedEventSubscriber.php
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,111 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace BetterPayment\EventSubscriber; | ||
|
||
|
||
use BetterPayment\PaymentMethod\Invoice; | ||
use BetterPayment\PaymentMethod\InvoiceB2B; | ||
use BetterPayment\Util\BetterPaymentClient; | ||
use BetterPayment\Util\ConfigReader; | ||
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity; | ||
use Shopware\Core\Checkout\Order\OrderEntity; | ||
use Shopware\Core\Framework\Context; | ||
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; | ||
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent; | ||
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; | ||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
|
||
/** | ||
* Class OrderInvoiceDocumentCreatedEventSubscriber | ||
* | ||
* This event subscriber listens to the 'document.written' event and performs actions when an invoice document is created. | ||
*/ | ||
class OrderInvoiceDocumentCreatedEventSubscriber implements EventSubscriberInterface | ||
{ | ||
private BetterPaymentClient $betterPaymentClient; | ||
private EntityRepositoryInterface $orderRepository; | ||
private ConfigReader $configReader; | ||
|
||
/** | ||
* OrderInvoiceDocumentCreatedEventSubscriber constructor. | ||
* | ||
* @param BetterPaymentClient $betterPaymentClient | ||
* @param EntityRepositoryInterface $orderRepository | ||
* @param ConfigReader $configReader | ||
*/ | ||
public function __construct(BetterPaymentClient $betterPaymentClient, EntityRepositoryInterface $orderRepository, ConfigReader $configReader) | ||
{ | ||
$this->betterPaymentClient = $betterPaymentClient; | ||
$this->orderRepository = $orderRepository; | ||
$this->configReader = $configReader; | ||
} | ||
|
||
/** | ||
* Returns the subscribed events and their corresponding methods. | ||
* | ||
* @return array The array of subscribed events and their methods. | ||
*/ | ||
public static function getSubscribedEvents(): array | ||
{ | ||
return [ | ||
'document.written' => 'onInvoiceDocumentCreated', | ||
]; | ||
} | ||
|
||
/** | ||
* Performs following actions when an invoice document is created: | ||
* 1. confirms whether this is really invoice type document to go on | ||
* 2. fetches order from DB, and its corresponding successful(last) order transaction | ||
* 3. checks whether this order transaction is capturable | ||
* 4. sends capture request using BetterPaymentClient | ||
* | ||
* @param EntityWrittenEvent $event | ||
*/ | ||
public function onInvoiceDocumentCreated(EntityWrittenEvent $event): void | ||
{ | ||
$payloads = $event->getPayloads(); | ||
foreach ($payloads as $payload) { | ||
if (isset($payload['config']['name']) && $payload['config']['name'] == 'invoice') { | ||
$orderId = $payload['orderId']; | ||
$criteria = new Criteria([$orderId]); | ||
$criteria->addAssociation('transactions.paymentMethod'); | ||
|
||
/** @var OrderEntity $order */ | ||
$order = $this->orderRepository->search( | ||
$criteria, | ||
Context::createDefaultContext() | ||
)->first(); | ||
|
||
$orderTransaction = $order->getTransactions()->last(); | ||
|
||
if ($this->isCapturable($orderTransaction)) { | ||
$invoiceId = $payload['config']['documentNumber']; | ||
$invoiceDate = $payload['config']['documentDate']; | ||
|
||
$captureParameters = [ | ||
'transaction_id' => $orderTransaction->getCustomFields()['better_payment_transaction_id'], | ||
'invoice_id' => $invoiceId, | ||
'amount' => $order->getAmountTotal(), | ||
'execution_date' => $invoiceDate, | ||
'comment' => 'Captured using Shopware 6 plugin', | ||
]; | ||
|
||
$this->betterPaymentClient->capture($captureParameters); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Checks if an order transaction is capturable based on the payment method and corresponding configuration flag. | ||
* | ||
* @param OrderTransactionEntity $orderTransaction | ||
* @return bool Whether the order transaction is capturable or not. | ||
*/ | ||
public function isCapturable(OrderTransactionEntity $orderTransaction): bool | ||
{ | ||
$paymentMethodShortname = $orderTransaction->getPaymentMethod()->getCustomFields()['shortname']; | ||
return ($paymentMethodShortname == Invoice::SHORTNAME && $this->configReader->getBool(ConfigReader::INVOICE_AUTOMATICALLY_CAPTURE_ON_ORDER_INVOICE_DOCUMENT_SENT)) | ||
|| ($paymentMethodShortname == InvoiceB2B::SHORTNAME && $this->configReader->getBool(ConfigReader::INVOICE_B2B_AUTOMATICALLY_CAPTURE_ON_ORDER_INVOICE_DOCUMENT_SENT)); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
src/Resources/app/administration/src/capture/capture-card.html.twig
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 @@ | ||
{% block sw_order_detail_base_line_items_card %} | ||
{% parent %} | ||
<sw-card | ||
v-if="captureCardIsVisible" | ||
:title="$tc('betterpayment.capture.cardTitle')"> | ||
<template #grid> | ||
<sw-card-section divider="bottom" :slim="true"> | ||
<sw-container> | ||
<sw-label variant="info" style="height: auto"> | ||
<div style="white-space: normal;"> | ||
<span v-if="paymentMethod == 'kar'"> | ||
{{ $tc('betterpayment.capture.labels.paymentMethodsInfo.invoice') }} | ||
</span> | ||
<span v-else-if="paymentMethod == 'kar_b2b'"> | ||
{{ $tc('betterpayment.capture.labels.paymentMethodsInfo.invoiceB2B') }} | ||
</span> | ||
</div> | ||
</sw-label> | ||
</sw-container> | ||
<sw-container v-if="!isCapturableState"> | ||
<sw-label variant="warning"> | ||
{{ $tc('betterpayment.capture.labels.notCapturableState') }} | ||
</sw-label> | ||
</sw-container> | ||
<sw-container columns="1fr 1fr" gap="0px 14px"> | ||
<sw-container rows="1fr 1fr 1fr 1fr" gap="10px 0px"> | ||
<sw-number-field | ||
required numberType="float" :digits="2" :allowEmpty="false" size="small" | ||
:disabled="!canCreateCapture" | ||
:label="$tc('betterpayment.capture.labels.amount')" | ||
v-model="capture.amount"> | ||
</sw-number-field> | ||
<sw-text-field | ||
required size="small" | ||
:disabled="!canCreateCapture" | ||
:label="$tc('betterpayment.capture.labels.invoiceId')" | ||
v-model="capture.invoice_id"> | ||
</sw-text-field> | ||
<sw-datepicker | ||
required size="small" :label="$tc('betterpayment.capture.labels.date')" | ||
:disabled="!canCreateCapture" | ||
v-model="capture.execution_date"> | ||
</sw-datepicker> | ||
<sw-text-field | ||
:copyable="true" :copyableTooltip="true" disabled size="small" | ||
v-model="betterPaymentTransactionId" | ||
:label="$tc('betterpayment.capture.labels.transactionId')"> | ||
</sw-text-field> | ||
</sw-container> | ||
<sw-textarea-field | ||
type="textarea" size="small" | ||
:disabled="!canCreateCapture" | ||
:label="$tc('betterpayment.capture.labels.comment')" | ||
v-model="capture.comment"> | ||
</sw-textarea-field> | ||
</sw-container> | ||
<sw-button-process | ||
style="float: right;" | ||
:processSuccess="processSuccess" | ||
:disabled="buttonDisabled || !canCreateCapture" | ||
@click="createCapture" | ||
variant="ghost" | ||
size="small" | ||
@process-finish="createCaptureFinished"> | ||
{{ $tc('betterpayment.capture.actions.createNew') }} | ||
</sw-button-process> | ||
</sw-card-section> | ||
<sw-data-grid | ||
:isLoading="isLoading" | ||
:showSelection="false" :showActions="false" | ||
:dataSource="captures" v-if="captures.length !== 0" | ||
:columns="[ | ||
{ property: 'amount', label: $tc('betterpayment.capture.labels.amount') }, | ||
{ property: 'message', label: $tc('betterpayment.capture.labels.comment') }, | ||
{# TODO: parse it according to shop setting for datetime #} | ||
{ property: 'created_at', label: $tc('betterpayment.capture.labels.date') } | ||
]"> | ||
</sw-data-grid> | ||
</template> | ||
</sw-card> | ||
{% endblock %} |
Oops, something went wrong.