From 54e6041fe5111ce80aae25545c91fc509d64eb23 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 15 Nov 2024 18:34:08 +0800 Subject: [PATCH] Laravel Vapor - Enhancement to prevent customer from underpay when a payment transaction include storage invoice(s) --- .../CustomerPaymentBillingInnerComponent.vue | 4 +- .../CustomerPaymentsBillingComponent.vue | 57 +++++++++++++++++-- ...merPaymentsBillingWithStorageComponent.vue | 4 +- ...minPaymentsBillingWithStorageComponent.vue | 4 +- ...PaymentsBillingWithoutStorageComponent.vue | 57 +++++++++++++++++-- .../forms/GroupPaymentFormComponent.vue | 8 ++- .../forms/PaymentFormComponent.vue | 53 +++++++++++++---- 7 files changed, 156 insertions(+), 31 deletions(-) diff --git a/resources/assets/vue/components/companies/elements/CustomerPaymentBillingInnerComponent.vue b/resources/assets/vue/components/companies/elements/CustomerPaymentBillingInnerComponent.vue index e41aa9fa..d9be388e 100644 --- a/resources/assets/vue/components/companies/elements/CustomerPaymentBillingInnerComponent.vue +++ b/resources/assets/vue/components/companies/elements/CustomerPaymentBillingInnerComponent.vue @@ -208,10 +208,10 @@ successHandler(response){ const totalAmount = response.payload.data.reduce((total, item) => { const topLevelAmount = item.amount || 0; - const storagesAmount = item.storages.reduce((sum, storage) => { + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { const storageInvoiceAmount = storage.storageInvoice?.amount || 0; return sum + storageInvoiceAmount; - }, 0); + }, 0) : 0; return total + topLevelAmount + storagesAmount; diff --git a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingComponent.vue index fcd25eb0..b64311c9 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingComponent.vue @@ -191,9 +191,20 @@
-
Make Payment
+
Make Payment
- +
+ +
+ + +
@@ -236,6 +247,8 @@ transaction_details: [], }, expanded: true, + showPaymentProceedModal: false, + showPaymentOutdatedModal: false, } }, computed: { @@ -265,9 +278,43 @@ this.parameters.packing_list_id = this.data.id; }, methods: { - successHandler(response){ - this.item = response.payload.data; - // this.$forceUpdate(); + handleMakePaymentClick(event) { + let selectedShippingInvoicesOnlyIds = []; + this.showPaymentProceedModal = false; + this.showPaymentOutdatedModal = false; + selectedShippingInvoicesOnlyIds.push(this.item.id); + this.submit(this.route('api.transaction.verify.transactions', JSON.stringify(selectedShippingInvoicesOnlyIds)), 'get', 'verifyPaymentForOrderProfileV2Section', false, false); + }, + successHandler(response, section){ + if(section === "verifyPaymentForOrderProfileV2Section") + { + const totalAmount = response.payload.data.reduce((total, item) => { + const topLevelAmount = item.amount || 0; + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { + const storageInvoiceAmount = storage.storageInvoice?.amount || 0; + return sum + storageInvoiceAmount; + }, 0) : 0; + + return total + topLevelAmount + storagesAmount; + + }, 0); + + const epsilon = 0.0001; + if(Math.abs(this.item.outstanding - totalAmount) < epsilon){ + this.showPaymentProceedModal = true; + } + else{ + this.showPaymentOutdatedModal = true; + } + } + else{ + this.item = response.payload.data; + // this.$forceUpdate(); + } + }, + paymentOutdated(){ + this.showPaymentProceedModal = false; + this.showPaymentOutdatedModal = true; } }, mixins: [componentHandler] diff --git a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue index 86563d3a..35e66e92 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue @@ -399,10 +399,10 @@ { const totalAmount = response.payload.data.reduce((total, item) => { const topLevelAmount = item.amount || 0; - const storagesAmount = item.storages.reduce((sum, storage) => { + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { const storageInvoiceAmount = storage.storageInvoice?.amount || 0; return sum + storageInvoiceAmount; - }, 0); + }, 0) : 0; return total + topLevelAmount + storagesAmount; diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue index 919e7935..a5a5d322 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue @@ -309,10 +309,10 @@ { const totalAmount = response.payload.data.reduce((total, item) => { const topLevelAmount = item.amount || 0; - const storagesAmount = item.storages.reduce((sum, storage) => { + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { const storageInvoiceAmount = storage.storageInvoice?.amount || 0; return sum + storageInvoiceAmount; - }, 0); + }, 0) : 0; return total + topLevelAmount + storagesAmount; diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue index 03f2780a..fbef8c66 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue @@ -263,13 +263,24 @@
-
Make Payment
+
Make Payment
- +
+ +
+ + +
@@ -298,6 +309,8 @@ transaction_details: [], }, expanded: false, + showPaymentProceedModal: false, + showPaymentOutdatedModal: false, } }, computed: { @@ -315,9 +328,43 @@ generateInvoice() { this.submit(this.route('api.transaction.invoice.create'), 'post', this.section, true, true); }, - successHandler(response){ - this.item = response.payload.data; - this.updateList(); + handleMakePaymentClick(event) { + let selectedShippingInvoicesOnlyIds = []; + this.showPaymentProceedModal = false; + this.showPaymentOutdatedModal = false; + selectedShippingInvoicesOnlyIds.push(this.item.shipping_transaction.id); + this.submit(this.route('api.transaction.verify.transactions', JSON.stringify(selectedShippingInvoicesOnlyIds)), 'get', 'verifyPaymentForPendingPaymentSection', false, false); + }, + successHandler(response, section){ + if(section === "verifyPaymentForPendingPaymentSection") + { + const totalAmount = response.payload.data.reduce((total, item) => { + const topLevelAmount = item.amount || 0; + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { + const storageInvoiceAmount = storage.storageInvoice?.amount || 0; + return sum + storageInvoiceAmount; + }, 0) : 0; + + return total + topLevelAmount + storagesAmount; + + }, 0); + + const epsilon = 0.0001; + if(Math.abs(this.item.shipping_transaction.outstanding - totalAmount) < epsilon){ + this.showPaymentProceedModal = true; + } + else{ + this.showPaymentOutdatedModal = true; + } + } + else{ + this.item = response.payload.data; + this.updateList(); + } + }, + paymentOutdated(){ + this.showPaymentProceedModal = false; + this.showPaymentOutdatedModal = true; } }, mixins: [componentHandler] diff --git a/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue index d1a6cea8..6692ebe8 100644 --- a/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue @@ -227,15 +227,17 @@ if(section === 'verifyPendingPaymentInvoice'){ const totalAmount = response.payload.data.reduce((total, item) => { const topLevelAmount = item.amount || 0; - const storagesAmount = item.storages.reduce((sum, storage) => { + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { const storageInvoiceAmount = storage.storageInvoice?.amount || 0; return sum + storageInvoiceAmount; - }, 0); + }, 0) : 0; return total + topLevelAmount + storagesAmount; }, 0).toFixed(2); - if(this.sumAmount == totalAmount){ + + const epsilon = 0.0001; + if(Math.abs(this.sumAmount - totalAmount) < epsilon){ this.submitForm(); } else{ diff --git a/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue index 9b6992e9..4fddca38 100644 --- a/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue @@ -97,7 +97,7 @@
Cancel
-
Proceed
+
Proceed
@@ -146,21 +146,50 @@ } this.error = ''; }, - successHandler(response){ - if (response.payload) { - if (response.payload.data.payment_method === 5) { - window.location.href = this.route('billplz.bill', response.payload.data.payment_reference) + '?auto_submit=true'; + handleProceedClick(event) { + let selectedShippingInvoicesOnlyIds = []; + this.showPaymentProceedModal = false; + this.showPaymentOutdatedModal = false; + selectedShippingInvoicesOnlyIds.push(this.data.id); + this.submit(this.route('api.transaction.verify.transactions', JSON.stringify(selectedShippingInvoicesOnlyIds)), 'get', 'verifyPendingPaymentInvoice', false, false); + }, + successHandler(response, section){ + if(section === 'verifyPendingPaymentInvoice'){ + const totalAmount = response.payload.data.reduce((total, item) => { + const topLevelAmount = item.amount || 0; + const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => { + const storageInvoiceAmount = storage.storageInvoice?.amount || 0; + return sum + storageInvoiceAmount; + }, 0) : 0; + + return total + topLevelAmount + storagesAmount; + + }, 0).toFixed(2); + + const epsilon = 0.0001; + if(Math.abs(this.parameters.amount - totalAmount) < epsilon){ + this.submitForm(); + } + else{ + this.$emit('isPaymentOutdated', true); } } - - if(response.payload.data && response.payload.data.message){ - this.error = response.payload.data.message; - } else{ - this.closeModal(); - this.updateList(); + if (response.payload) { + if (response.payload.data.payment_method === 5) { + window.location.href = this.route('billplz.bill', response.payload.data.payment_reference) + '?auto_submit=true'; + } + } + + if(response.payload.data && response.payload.data.message){ + this.error = response.payload.data.message; + } + else{ + this.closeModal(); + this.updateList(); + } } - } + }, }, mixins: [formHandler] }