diff --git a/package.json b/package.json index 8310faa..2d58419 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build": "vite build", "preview": "vite preview", - "test": "node --test src/utils/uploadResponse.test.js src/utils/classSchedule.test.js" + "test": "node --test src/utils/uploadResponse.test.js src/utils/classSchedule.test.js src/utils/paymentAmount.test.js" }, "dependencies": { "@fontsource/vazirmatn": "^5.3.0", diff --git a/src/api/userApi.js b/src/api/userApi.js index 3d8d79d..aaacdf3 100644 --- a/src/api/userApi.js +++ b/src/api/userApi.js @@ -7,6 +7,11 @@ export const userApi = { getOne: (id) => axiosInstance.get(`/users/admin/get-one/${id}`), create: (data) => axiosInstance.post('/users/admin/create', data), update: (id, data) => axiosInstance.put(`/users/admin/update/${id}`, data), + resetPasswordAndSms: (id) => axiosInstance.post( + `/users/admin/${id}/reset-password-sms`, + {}, + { timeout: 30000 } + ), delete: (id) => axiosInstance.delete(`/users/admin/delete/${id}`), enroll: (userId, data) => axiosInstance.post(`/users/admin/${userId}/enroll`, data) }; diff --git a/src/utils/paymentAmount.js b/src/utils/paymentAmount.js new file mode 100644 index 0000000..6881e2c --- /dev/null +++ b/src/utils/paymentAmount.js @@ -0,0 +1,7 @@ +export const getPayableAmount = (payment = {}) => { + const amount = Number(payment.amount); + const discount = Number(payment.discount); + const safeAmount = Number.isFinite(amount) && amount > 0 ? amount : 0; + const safeDiscount = Number.isFinite(discount) && discount > 0 ? discount : 0; + return Math.max(0, safeAmount - Math.min(safeDiscount, safeAmount)); +}; diff --git a/src/utils/paymentAmount.test.js b/src/utils/paymentAmount.test.js new file mode 100644 index 0000000..615058b --- /dev/null +++ b/src/utils/paymentAmount.test.js @@ -0,0 +1,18 @@ +import { describe, it } from 'node:test'; +import assert from 'node:assert/strict'; +import { getPayableAmount } from './paymentAmount.js'; + +describe('getPayableAmount', () => { + it('returns the original amount when there is no discount', () => { + assert.equal(getPayableAmount({ amount: 1_000_000 }), 1_000_000); + assert.equal(getPayableAmount({ amount: 1_000_000, discount: 0 }), 1_000_000); + }); + + it('subtracts a discount from the total', () => { + assert.equal(getPayableAmount({ amount: 1_000_000, discount: 150_000 }), 850_000); + }); + + it('never returns a negative payable amount', () => { + assert.equal(getPayableAmount({ amount: 100, discount: 250 }), 0); + }); +}); diff --git a/src/views/payments/PaymentDetailView.vue b/src/views/payments/PaymentDetailView.vue index 9a43ac1..8895406 100644 --- a/src/views/payments/PaymentDetailView.vue +++ b/src/views/payments/PaymentDetailView.vue @@ -27,7 +27,15 @@
مبلغ کل صورتحساب - {{ toPersianDigits(payment.amount?.toLocaleString()) }} تومان + {{ toPersianDigits((payment.amount || 0).toLocaleString()) }} تومان +
+
+ تخفیف + {{ toPersianDigits((payment.discount || 0).toLocaleString()) }} تومان +
+
+ مبلغ قابل پرداخت + {{ toPersianDigits(payableAmount.toLocaleString()) }} تومان
مبلغ کل دریافتی @@ -35,12 +43,16 @@
باقیمانده - {{ toPersianDigits((payment.amount - (payment.paidAmount || 0)).toLocaleString()) }} تومان + {{ toPersianDigits(remainingAmount.toLocaleString()) }} تومان
وضعیت پرداخت
+
+ یادداشت +

{{ payment.notes || '—' }}

+
@@ -76,6 +88,11 @@ {{ formatJalali(data.createdAt || data.date) }} + + + @@ -96,6 +113,16 @@ +
+ +