Skip to content

Commit

Permalink
CET-579/feat: Multiple invoice email support
Browse files Browse the repository at this point in the history
  • Loading branch information
SalmanTwo committed Jan 27, 2025
1 parent 185790b commit d247f1d
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 38 deletions.
10 changes: 10 additions & 0 deletions Api/Config/RepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface RepositoryInterface
public const XML_PATH_ENABLE_ADDRESS_SEARCH = 'payment/two_payment/enable_address_search';
public const XML_PATH_ENABLE_TAX_SUBTOTALS = 'payment/two_payment/enable_tax_subtotals';
public const XML_PATH_ENABLE_ORDER_INTENT = 'payment/two_payment/enable_order_intent';
public const XML_PATH_ENABLE_MULTIPLE_INVOICE_EMAILS = 'payment/two_payment/enable_multiple_invoice_emails';
public const XML_PATH_ENABLE_DEPARTMENT_NAME = 'payment/two_payment/enable_department';
public const XML_PATH_ENABLE_PROJECT_NAME = 'payment/two_payment/enable_project';
public const XML_PATH_ENABLE_ORDER_NOTE = 'payment/two_payment/enable_order_note';
Expand Down Expand Up @@ -122,6 +123,15 @@ public function isCompanySearchEnabled(?int $storeId = null): bool;
*/
public function isOrderIntentEnabled(?int $storeId = null): bool;

/**
* Check if order intent is enabled
*
* @param int|null $storeId
*
* @return bool
*/
public function isMultipleInvoiceEmailsEnabled(?int $storeId = null): bool;

/**
* Check if tax subtotals is enabled
*
Expand Down
8 changes: 8 additions & 0 deletions Model/Config/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ public function isOrderIntentEnabled(?int $storeId = null): bool
return $this->isSetFlag(self::XML_PATH_ENABLE_ORDER_INTENT, $storeId);
}

/**
* @inheritDoc
*/
public function isMultipleInvoiceEmailsEnabled(?int $storeId = null): bool
{
return $this->isSetFlag(self::XML_PATH_ENABLE_MULTIPLE_INVOICE_EMAILS, $storeId);
}

/**
* @inheritDoc
*/
Expand Down
9 changes: 8 additions & 1 deletion Model/Two.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,19 @@ public function authorize(InfoInterface $payment, $amount)
$order = $payment->getOrder();
$this->urlCookie->delete();
$orderReference = (string)rand();

$additionalInformation = $payment->getAdditionalInformation();

$multipleInvoiceEmails = $additionalInformation['multipleInvoiceEmails'] ?? null;

$payload = $this->compositeOrder->execute(
$order,
$orderReference,
$payment->getAdditionalInformation()
$additionalInformation
);



// Create order
$response = $this->apiAdapter->execute('/v1/order', $payload);
$error = $this->getErrorFromResponse($response);
Expand Down
2 changes: 2 additions & 0 deletions Model/Ui/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public function getConfig(): array
'checkoutPageUrl' => $this->configRepository->getCheckoutPageUrl(),
'redirectUrlCookieCode' => UrlCookie::COOKIE_NAME,
'isOrderIntentEnabled' => $this->configRepository->isOrderIntentEnabled(),
'isMultipleInvoiceEmailsEnabled' => $this->configRepository->isMultipleInvoiceEmailsEnabled(),
'orderIntentConfig' => $orderIntentConfig,
'isCompanySearchEnabled' => $this->configRepository->isCompanySearchEnabled(),
'isAddressSearchEnabled' => $this->configRepository->isAddressSearchEnabled(),
Expand All @@ -115,6 +116,7 @@ public function getConfig(): array
$provider,
$tryAgainLater
),
'invalidEmailListMessage' => __('Please ensure your forward to email list only contains valid emails seperated by commas.'),
'paymentTermsMessage' => __(
'By checking this box, I confirm that I have read and agree to %1.',
sprintf('<a href="%s" target="_blank">%s</a>', $paymentTermsLink, $paymentTerms)
Expand Down
1 change: 1 addition & 0 deletions Observer/DataAssignObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class DataAssignObserver extends AbstractDataAssignObserver
'department',
'orderNote',
'poNumber',
'multipleInvoiceEmails'
];

/**
Expand Down
90 changes: 55 additions & 35 deletions Service/Order/ComposeOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,41 +27,61 @@ class ComposeOrder extends OrderService
* @throws LocalizedException
*/
public function execute(Order $order, string $orderReference, array $additionalData): array
{
$lineItems = $this->getLineItemsOrder($order);
{
// Fetch line items from the order
$lineItems = $this->getLineItemsOrder($order);


// Initialize invoice_details only if multipleInvoiceEmails is present
$invoiceDetails = [];
if (!empty($additionalData['multipleInvoiceEmails'])) {
$invoiceDetails['invoice_emails'] = explode(',', $additionalData['multipleInvoiceEmails']);
// Required placeholders to pass create order API Schema requirements
$invoiceDetails['payment_reference_message'] = "";
$invoiceDetails['payment_reference_ocr'] = "";
}

// Compose the final payload for the API call
$payload = [
'billing_address' => $this->getAddress($order, $additionalData, 'billing'),
'shipping_address' => $this->getAddress($order, $additionalData, 'shipping'),
'buyer' => $this->getBuyer($order, $additionalData),
'buyer_department' => $additionalData['department'] ?? '',
'buyer_project' => $additionalData['project'] ?? '',
'buyer_purchase_order_number' => $additionalData['poNumber'] ?? '',
'currency' => $order->getOrderCurrencyCode(),
'discount_amount' => $this->roundAmt($this->getDiscountAmountItem($order)),
'gross_amount' => $this->roundAmt($order->getGrandTotal()),
'net_amount' => $this->roundAmt($order->getGrandTotal() - $order->getTaxAmount()),
'tax_amount' => $this->roundAmt($order->getTaxAmount()),
'tax_subtotals' => $this->getTaxSubtotals($lineItems),
'invoice_type' => 'FUNDED_INVOICE',
'line_items' => $lineItems,
'merchant_order_id' => (string)($order->getIncrementId()),
'merchant_urls' => [
'merchant_confirmation_url' => $this->url->getUrl(
'two/payment/confirm',
['_two_order_reference' => base64_encode($orderReference)]
),
'merchant_cancel_order_url' => $this->url->getUrl(
'two/payment/cancel',
['_two_order_reference' => base64_encode($orderReference)]
),
'merchant_edit_order_url' => '',
'merchant_order_verification_failed_url' => $this->url->getUrl(
'two/payment/verificationfailed',
['_two_order_reference' => base64_encode($orderReference)]
),
],
'order_note' => $additionalData['orderNote'] ?? ''
];

// Add invoice_details only if invoiceEmails are present
if (!empty($invoiceDetails)) {
$payload['invoice_details'] = $invoiceDetails;
}


return [
'billing_address' => $this->getAddress($order, $additionalData, 'billing'),
'shipping_address' => $this->getAddress($order, $additionalData, 'shipping'),
'buyer' => $this->getBuyer($order, $additionalData),
'buyer_department' => $additionalData['department'] ?? '',
'buyer_project' => $additionalData['project'] ?? '',
'buyer_purchase_order_number' => $additionalData['poNumber'] ?? '',
'currency' => $order->getOrderCurrencyCode(),
'discount_amount' => $this->roundAmt($this->getDiscountAmountItem($order)),
'gross_amount' => $this->roundAmt($order->getGrandTotal()),
'net_amount' => $this->roundAmt($order->getGrandTotal() - $order->getTaxAmount()),
'tax_amount' => $this->roundAmt($order->getTaxAmount()),
'tax_subtotals' => $this->getTaxSubtotals($lineItems),
'invoice_type' => 'FUNDED_INVOICE',
'line_items' => $lineItems,
'merchant_order_id' => (string)($order->getIncrementId()),
'merchant_urls' => [
'merchant_confirmation_url' => $this->url->getUrl(
'two/payment/confirm',
['_two_order_reference' => base64_encode($orderReference)]
),
'merchant_cancel_order_url' => $this->url->getUrl(
'two/payment/cancel',
['_two_order_reference' => base64_encode($orderReference)]
),
'merchant_edit_order_url' => '',
'merchant_order_verification_failed_url' => $this->url->getUrl(
'two/payment/verificationfailed',
['_two_order_reference' => base64_encode($orderReference)]
),
],
'order_note' => $additionalData['orderNote'] ?? ''
];
return $payload;
}
}
10 changes: 10 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@
</depends>
<config_path>payment/two_payment/enable_order_intent</config_path>
</field>
<field id="enable_multiple_invoice_emails" translate="label" type="select" sortOrder="75" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>Enable multiple invoice emails</label>
<comment>Let your buyer input additional emails to forward the invoice to on order fulfilment.</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<depends>
<field id="active">1</field>
</depends>
<config_path>payment/two_payment/enable_multiple_invoice_emails</config_path>
</field>
<field id="enable_tax_subtotals" translate="label" type="select" sortOrder="75" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>Enable tax subtotals</label>
Expand Down
2 changes: 1 addition & 1 deletion etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<days_on_invoice>14</days_on_invoice>
<finalize_purchase>1</finalize_purchase>
<enable_order_intent>1</enable_order_intent>
<enable_multiple_invoice_emails>0</enable_multiple_invoice_emails>
<enable_tax_subtotals>1</enable_tax_subtotals>
<fulfill_trigger>shipment</fulfill_trigger>
<fulfill_order_status>complete</fulfill_order_status>
Expand All @@ -35,4 +36,3 @@
</payment>
</default>
</config>

2 changes: 2 additions & 0 deletions i18n/en_US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ Version,Version
"Your request to %1 failed. Reason: %2","Your request to %1 failed. Reason: %2"
"Your sole trader account could not be verified.","Your sole trader account could not be verified."
"Zip/Postal Code is not valid.","Zip/Postal Code is not valid."
"Forward invoice to email list (optional)","Forward invoice to email list (optional)"
"Please ensure your forward to email list only contains valid emails seperated by commas.", "Please ensure your forward to email list only contains valid emails seperated by commas."
2 changes: 2 additions & 0 deletions i18n/nb_NO.csv
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ Version,Versjon
"Your request to %1 failed. Reason: %2","Din forespørsel til %1 mislyktes. Årsak: %2"
"Your sole trader account could not be verified.","Din eneforhandlerkonto kunne ikke bekreftes."
"Zip/Postal Code is not valid.","Postnummer er ikke gyldig."
"Forward invoice to email list (optional)","Videresend faktura til e-postliste (valgfritt)"
"Please ensure your forward to email list only contains valid emails seperated by commas.","Sørg for at listen over videresending til e-post kun inneholder gyldige e-poster atskilt med komma."
2 changes: 2 additions & 0 deletions i18n/nl_NL.csv
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ Version,Versie
"Your request to %1 failed. Reason: %2","Uw verzoek aan %1 is mislukt. Reden: %2"
"Your sole trader account could not be verified.","Uw eenmanszaakaccount kon niet worden geverifieerd."
"Zip/Postal Code is not valid.","Postcode is niet geldig."
"Forward invoice to email list (optional)","Factuur doorsturen naar e-maillijst (optioneel)"
"Please ensure your forward to email list only contains valid emails seperated by commas.","Zorg ervoor dat uw doorstuur-naar-e-maillijst alleen geldige e-mails bevat, gescheiden door komma's."
2 changes: 2 additions & 0 deletions i18n/sv_SE.csv
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ Version,Version
"Your request to %1 failed. Reason: %2","Din begäran till %1 misslyckades. Orsak: %2"
"Your sole trader account could not be verified.","Ditt enskild näringsidkarekonto kunde inte verifieras."
"Zip/Postal Code is not valid.","Postnummer är inte giltigt."
"Forward invoice to email list (optional)","Vidarebefordra faktura till e-postlista (valfritt)"
"Please ensure your forward to email list only contains valid emails seperated by commas.","Se till att din vidarebefordran till e-postlista endast innehåller giltiga e-postmeddelanden separerade med kommatecken."
35 changes: 34 additions & 1 deletion view/frontend/web/js/view/payment/method-renderer/two_payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ define([
orderIntentApprovedMessage: config.orderIntentApprovedMessage,
orderIntentDeclinedMessage: config.orderIntentDeclinedMessage,
generalErrorMessage: config.generalErrorMessage,
invalidEmailListMessage: config.invalidEmailListMessage,
soleTraderErrorMessage: config.soleTraderErrorMessage,
isOrderIntentEnabled: config.isOrderIntentEnabled,
isMultipleInvoiceEmailsEnabled: config.isMultipleInvoiceEmailsEnabled,
isDepartmentFieldEnabled: config.isDepartmentFieldEnabled,
isProjectFieldEnabled: config.isProjectFieldEnabled,
isOrderNoteFieldEnabled: config.isOrderNoteFieldEnabled,
Expand All @@ -67,6 +69,7 @@ define([
autofillToken: '',
companyName: ko.observable(''),
companyId: ko.observable(''),
multipleInvoiceEmails: ko.observable(''),
project: ko.observable(''),
department: ko.observable(''),
orderNote: ko.observable(''),
Expand All @@ -84,6 +87,28 @@ define([
this.configureFormValidation();
this.popupMessageListener();
},
showErrorMessage: function (message, duration) {
messageList.addErrorMessage({ message: message });

if (duration) {
setTimeout(function () {
messageList.messages.remove(function (item) {
return item.message === message;
});
}, duration);
}
},
validateMultipleEmails: function () {
const emails = this.multipleInvoiceEmails();
let emailArray = emails.split(',').map((email) => email.trim());

const isValid = emailArray.every((email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email));
if (!isValid && emails) {
this.showErrorMessage(this.invalidEmailListMessage, 3);
return false;
}
return true;
},
logIsPaymentsAccepted: function (data, event) {
console.debug({
logger: 'logIsPaymentsAccepted',
Expand Down Expand Up @@ -217,6 +242,13 @@ define([
this.processTermsNotAcceptedErrorResponse();
return;
}

// Validate emails on the forward list
if (this.isMultipleInvoiceEmailsEnabled && !this.validateMultipleEmails()) {
this.showErrorMessage(this.invalidEmailListMessage);
return;
}

if (
this.validate() &&
additionalValidators.validate() &&
Expand Down Expand Up @@ -392,7 +424,8 @@ define([
project: this.project(),
department: this.department(),
orderNote: this.orderNote(),
poNumber: this.poNumber()
poNumber: this.poNumber(),
multipleInvoiceEmails: this.multipleInvoiceEmails()
}
};
},
Expand Down
13 changes: 13 additions & 0 deletions view/frontend/web/template/payment/two_payment.html
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@
/>
</div>
</div>
<div class="field field-text" data-bind="visible: isMultipleInvoiceEmailsEnabled">
<label for="multiple_invoice_emails" class="label">
<span data-bind="i18n: 'Forward invoice to email list (optional)'"></span>
</label>
<div class="control">
<input
type="text"
id="multiple_invoice_emails"
data-bind="value: multipleInvoiceEmails, event: { change: validateMultipleEmails }"
class="input-text"
/>
</div>
</div>
<div class="field field-text" data-bind="visible: isProjectFieldEnabled">
<label for="two_project" class="label">
<span> <!-- ko i18n: 'Project'--><!-- /ko --> </span>
Expand Down

0 comments on commit d247f1d

Please sign in to comment.