This commit is contained in:
gsinghpal
2026-03-20 11:46:41 -04:00
parent 595dccc17d
commit 92369be6e0
71 changed files with 6588 additions and 8 deletions

View File

@@ -11,6 +11,8 @@ patch(PaymentForm.prototype, {
setup() {
super.setup();
this.poyntFormData = {};
this._detectedCardType = 'other';
this._selectedCardType = 'other';
},
// #=== DOM MANIPULATION ===#
@@ -42,6 +44,77 @@ patch(PaymentForm.prototype, {
this._setupCardFormatting(poyntContainer);
this._setupTerminalToggle(poyntContainer);
this._setupSurcharge(poyntContainer);
},
_detectCardBrand(number) {
const num = (number || '').replace(/\D/g, '');
if (num.length < 2) return 'other';
const prefix2 = num.substring(0, 2);
if (prefix2 === '34' || prefix2 === '37') return 'amex';
if (num[0] === '4') return 'visa';
const p2 = parseInt(prefix2, 10);
if (p2 >= 51 && p2 <= 55) return 'mastercard';
if (num.length >= 4) {
const p4 = parseInt(num.substring(0, 4), 10);
if (p4 >= 2221 && p4 <= 2720) return 'mastercard';
}
return 'other';
},
_setupSurcharge(container) {
const surchargeConfig = this.poyntFormData.surcharge;
if (!surchargeConfig || !surchargeConfig.enabled) return;
const cardTypeSection = container.querySelector('.o_poynt_card_type_section');
const surchargeNotice = container.querySelector('.o_poynt_surcharge_notice');
if (cardTypeSection) {
cardTypeSection.style.display = 'block';
}
const cardTypeRadios = container.querySelectorAll('input[name="poynt_card_type"]');
cardTypeRadios.forEach(radio => {
radio.addEventListener('change', () => {
this._selectedCardType = radio.value;
this._updateSurchargeDisplay(container);
});
});
this._updateSurchargeDisplay(container);
},
_updateSurchargeDisplay(container) {
const surchargeConfig = this.poyntFormData.surcharge;
if (!surchargeConfig || !surchargeConfig.enabled) return;
const cardType = this._detectedCardType !== 'other'
? this._detectedCardType
: this._selectedCardType;
const rate = surchargeConfig[cardType] || surchargeConfig['other'] || 0;
const amount = this.poyntFormData.minor_amount || 0;
const currencyName = this.poyntFormData.currency_name || 'CAD';
const baseAmount = amount / 100;
const feeAmount = Math.round(baseAmount * rate) / 100;
const rateEl = container.querySelector('#poynt_surcharge_rate');
const amountEl = container.querySelector('#poynt_surcharge_amount');
const noticeEl = container.querySelector('.o_poynt_surcharge_notice');
if (rateEl) rateEl.textContent = rate.toFixed(2);
if (amountEl) amountEl.textContent = `$${feeAmount.toFixed(2)}`;
if (noticeEl) {
noticeEl.style.display = rate > 0 ? 'block' : 'none';
}
const radioToCheck = container.querySelector(
`input[name="poynt_card_type"][value="${cardType}"]`
);
if (radioToCheck && !radioToCheck.checked) {
radioToCheck.checked = true;
}
},
_setupCardFormatting(container) {
@@ -57,6 +130,17 @@ patch(PaymentForm.prototype, {
formatted += value[i];
}
e.target.value = formatted;
const detected = this._detectCardBrand(value);
if (detected !== this._detectedCardType) {
this._detectedCardType = detected;
if (detected !== 'other') {
this._selectedCardType = detected;
}
this._updateSurchargeDisplay(
e.target.closest('.o_poynt_payment_form')
);
}
});
}
@@ -228,11 +312,19 @@ patch(PaymentForm.prototype, {
}
},
_getSelectedCardType(inlineForm) {
const checked = inlineForm.querySelector('input[name="poynt_card_type"]:checked');
return checked ? checked.value : 'other';
},
async _processCardPayment(processingValues, inlineForm) {
const cardNumber = inlineForm.querySelector('#poynt_card_number').value.replace(/\D/g, '');
const expiry = inlineForm.querySelector('#poynt_expiry').value;
const cvv = inlineForm.querySelector('#poynt_cvv').value;
const cardholder = inlineForm.querySelector('#poynt_cardholder').value;
const cardType = this._detectedCardType !== 'other'
? this._detectedCardType
: this._getSelectedCardType(inlineForm);
const [expMonth, expYear] = expiry.split('/').map(Number);
@@ -245,6 +337,7 @@ patch(PaymentForm.prototype, {
exp_year: 2000 + expYear,
cvv: cvv,
cardholder_name: cardholder,
card_type: cardType,
});
if (result.error) {
@@ -268,12 +361,14 @@ patch(PaymentForm.prototype, {
async _processTerminalPayment(processingValues, inlineForm) {
const terminalId = inlineForm.querySelector('#poynt_terminal_select').value;
const cardType = this._getSelectedCardType(inlineForm);
try {
const result = await rpc('/payment/poynt/send_to_terminal', {
reference: processingValues.reference,
terminal_id: parseInt(terminalId),
poynt_order_id: processingValues.poynt_order_id,
card_type: cardType,
});
if (result.error) {