fix(ui): payment due date calculation, datepicker colors, scrollable tabs, optional receipt, default today date
This commit is contained in:
@@ -164,11 +164,11 @@
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">تاریخ سررسید *</label>
|
||||
<DatePicker v-model="trxForm.dueDate" class="w-full text-sm" placeholder="1403/01/01" />
|
||||
<DatePicker v-model="trxForm.dueDate" class="w-full text-sm" :placeholder="getTodayJalali()" />
|
||||
</div>
|
||||
<div v-if="trxForm.status === 'paid'" class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">تاریخ پرداخت</label>
|
||||
<DatePicker v-model="trxForm.date" class="w-full text-sm" placeholder="1403/01/01" />
|
||||
<DatePicker v-model="trxForm.date" class="w-full text-sm" :placeholder="getTodayJalali()" />
|
||||
</div>
|
||||
<div v-if="trxForm.status === 'paid'" class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">شماره فیش / پیگیری</label>
|
||||
@@ -185,6 +185,7 @@
|
||||
placeholder="یادداشت داخلی درباره این تراکنش…"
|
||||
/>
|
||||
</div>
|
||||
<NotifyChannelsField :notify="trxNotify" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<Button label="انصراف" text severity="secondary" @click="showTransactionModal = false" />
|
||||
@@ -209,11 +210,11 @@
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">تاریخ سررسید *</label>
|
||||
<DatePicker v-model="editForm.dueDate" class="w-full text-sm" placeholder="1403/01/01" />
|
||||
<DatePicker v-model="editForm.dueDate" class="w-full text-sm" :placeholder="getTodayJalali()" />
|
||||
</div>
|
||||
<div v-if="editForm.status === 'paid'" class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">تاریخ پرداخت</label>
|
||||
<DatePicker v-model="editForm.date" class="w-full text-sm" placeholder="1403/01/01" />
|
||||
<DatePicker v-model="editForm.date" class="w-full text-sm" :placeholder="getTodayJalali()" />
|
||||
</div>
|
||||
<div v-if="editForm.status === 'paid'" class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">شماره فیش / پیگیری</label>
|
||||
@@ -231,6 +232,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<Button label="انصراف" text severity="secondary" @click="showEditModal = false" />
|
||||
<Button label="ذخیره تغییرات" icon="pi pi-check" severity="success" :loading="isSubmittingEdit" @click="handleUpdateTransaction" />
|
||||
@@ -263,6 +265,7 @@ import { getPayableAmount } from '@/utils/paymentAmount';
|
||||
import PageHeader from '@/components/common/PageHeader.vue';
|
||||
import PermissionGate from '@/components/common/PermissionGate.vue';
|
||||
import StatusTag from '@/components/common/StatusTag.vue';
|
||||
import NotifyChannelsField from '@/components/common/NotifyChannelsField.vue';
|
||||
import Button from 'primevue/button';
|
||||
import Tag from 'primevue/tag';
|
||||
import DataTable from 'primevue/datatable';
|
||||
@@ -276,7 +279,7 @@ import DatePicker from 'vue3-persian-datetime-picker';
|
||||
|
||||
const route = useRoute();
|
||||
const paymentId = route.params.id;
|
||||
const { toPersianDigits, formatJalali, toJalaliPickerValue, toGregorianIso } = usePersianDate();
|
||||
const { toPersianDigits, formatJalali, toJalaliPickerValue, toGregorianIso, getTodayJalali } = usePersianDate();
|
||||
const { showSuccess, showError } = useToast();
|
||||
|
||||
const payment = ref(null);
|
||||
@@ -288,6 +291,7 @@ const isSubmittingEdit = ref(false);
|
||||
const isSubmittingCancel = ref(false);
|
||||
const editingTransactionId = ref(null);
|
||||
const cancellingTransactionId = ref(null);
|
||||
const trxNotify = reactive({ sms: true, email: true, bot: true });
|
||||
|
||||
const methodOptions = [
|
||||
{ label: 'کارت به کارت', value: 'card' },
|
||||
@@ -305,8 +309,8 @@ const defaultTrxForm = () => ({
|
||||
status: 'paid',
|
||||
method: 'card',
|
||||
receiptNumber: '',
|
||||
dueDate: '',
|
||||
date: '',
|
||||
dueDate: getTodayJalali(),
|
||||
date: getTodayJalali(),
|
||||
notes: ''
|
||||
});
|
||||
|
||||
@@ -348,10 +352,6 @@ const handleRecordTransaction = async () => {
|
||||
if (!trxForm.dueDate) { showError('لطفا تاریخ سررسید را وارد کنید'); return; }
|
||||
const dueDate = toGregorianIso(trxForm.dueDate);
|
||||
if (!dueDate) { showError('تاریخ سررسید نامعتبر است'); return; }
|
||||
if (trxForm.status === 'paid' && !trxForm.receiptNumber) {
|
||||
showError('لطفا شماره فیش یا پیگیری را وارد کنید');
|
||||
return;
|
||||
}
|
||||
|
||||
isSubmittingTrx.value = true;
|
||||
try {
|
||||
@@ -359,11 +359,12 @@ const handleRecordTransaction = async () => {
|
||||
amount: trxForm.amount,
|
||||
status: trxForm.status,
|
||||
dueDate,
|
||||
notes: trxForm.notes || undefined
|
||||
notes: trxForm.notes || undefined,
|
||||
notify: { ...trxNotify }
|
||||
};
|
||||
if (trxForm.status === 'paid') {
|
||||
payload.method = trxForm.method;
|
||||
payload.receiptNumber = trxForm.receiptNumber;
|
||||
payload.receiptNumber = trxForm.receiptNumber || '';
|
||||
const paymentDate = toGregorianIso(trxForm.date);
|
||||
if (paymentDate) payload.date = paymentDate;
|
||||
}
|
||||
@@ -373,6 +374,9 @@ const handleRecordTransaction = async () => {
|
||||
showSuccess('تراکنش جدید با موفقیت ثبت شد');
|
||||
showTransactionModal.value = false;
|
||||
Object.assign(trxForm, defaultTrxForm());
|
||||
trxNotify.sms = true;
|
||||
trxNotify.email = true;
|
||||
trxNotify.bot = true;
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
} finally {
|
||||
@@ -380,6 +384,7 @@ const handleRecordTransaction = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const openEditTransaction = (trx) => {
|
||||
if (isTransactionCancelled(trx)) return;
|
||||
editingTransactionId.value = trx._id || trx.id;
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
|
||||
<div class="flex flex-column gap-2">
|
||||
<label class="font-semibold text-sm">تاریخ سررسید *</label>
|
||||
<DatePicker v-model="createForm.dueDate" class="w-full text-sm" placeholder="1403/01/01" />
|
||||
<DatePicker v-model="createForm.dueDate" class="w-full text-sm" :placeholder="getTodayJalali()" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column gap-2">
|
||||
@@ -187,6 +187,7 @@ import PermissionGate from '@/components/common/PermissionGate.vue';
|
||||
import StatusTag from '@/components/common/StatusTag.vue';
|
||||
import NotifyChannelsField from '@/components/common/NotifyChannelsField.vue';
|
||||
import { getPayableAmount } from '@/utils/paymentAmount';
|
||||
import { calculateClassMidDate } from '@/utils/classSchedule';
|
||||
import Button from 'primevue/button';
|
||||
import Column from 'primevue/column';
|
||||
import Tag from 'primevue/tag';
|
||||
@@ -198,7 +199,8 @@ import Checkbox from 'primevue/checkbox';
|
||||
import Textarea from 'primevue/textarea';
|
||||
import DatePicker from 'vue3-persian-datetime-picker';
|
||||
|
||||
const { toPersianDigits, formatJalali, toGregorianIso } = usePersianDate();
|
||||
const { toPersianDigits, formatJalali, toGregorianIso, getTodayJalali } = usePersianDate();
|
||||
|
||||
const { showSuccess, showError } = useToast();
|
||||
|
||||
const {
|
||||
@@ -269,11 +271,12 @@ const onClassesSelected = () => {
|
||||
if (!createForm.classes || createForm.classes.length === 0) {
|
||||
createForm.amount = 0;
|
||||
createForm.discount = 0;
|
||||
createForm.dueDate = getTodayJalali();
|
||||
return;
|
||||
}
|
||||
let totalFee = 0;
|
||||
createForm.classes.forEach((classId) => {
|
||||
const c = classesList.value.find((item) => (item._id || item.id) === classId);
|
||||
const c = classesList.value.find((item) => String(item._id || item.id) === String(classId));
|
||||
if (c) {
|
||||
totalFee += (c.tuitionFee || c.course?.price || 0);
|
||||
}
|
||||
@@ -284,6 +287,11 @@ const onClassesSelected = () => {
|
||||
if ((createForm.discount || 0) > (createForm.amount || 0)) {
|
||||
createForm.discount = createForm.amount || 0;
|
||||
}
|
||||
|
||||
const firstSelectedClass = classesList.value.find((item) => String(item._id || item.id) === String(createForm.classes[0]));
|
||||
if (firstSelectedClass) {
|
||||
createForm.dueDate = calculateClassMidDate(firstSelectedClass);
|
||||
}
|
||||
};
|
||||
|
||||
const resetCreateForm = () => {
|
||||
@@ -292,13 +300,14 @@ const resetCreateForm = () => {
|
||||
createForm.amount = 0;
|
||||
createForm.discount = 0;
|
||||
createForm.notes = '';
|
||||
createForm.dueDate = '';
|
||||
createForm.dueDate = getTodayJalali();
|
||||
hasDiscount.value = false;
|
||||
createNotify.sms = true;
|
||||
createNotify.email = true;
|
||||
createNotify.bot = true;
|
||||
};
|
||||
|
||||
|
||||
const openCreateModal = () => {
|
||||
resetCreateForm();
|
||||
showCreateModal.value = true;
|
||||
|
||||
Reference in New Issue
Block a user