Fix transaction due date parsing and preserve edited pending amounts.

Parse Jalali date strings correctly when saving transactions, and skip
reconcile amount overwrites when pending totals already match the balance.
This commit is contained in:
2026-08-16 14:53:46 +03:30
parent 4ad5630cb7
commit 8cd355c24b
+19 -6
View File
@@ -13,6 +13,7 @@ const Class = require('../classes/classModel');
const Session = require('../sessions/sessionModel'); const Session = require('../sessions/sessionModel');
const { sendInvoiceCreatedSms } = require('../../utils/senders/smsMessages'); const { sendInvoiceCreatedSms } = require('../../utils/senders/smsMessages');
const { buildClassScheduleContext } = require('../../utils/classSchedule'); const { buildClassScheduleContext } = require('../../utils/classSchedule');
const { parseImportDate } = require('../../utils/jalaliDate');
const { pickNotifyFlags, omitNotifyFields } = require('../../utils/notifyFlags'); const { pickNotifyFlags, omitNotifyFields } = require('../../utils/notifyFlags');
const { const {
getPayableAmount, getPayableAmount,
@@ -84,8 +85,11 @@ const reconcilePendingTransactions = async (payment) => {
} }
if (pending.length) { if (pending.length) {
pending[0].amount = remaining; const pendingTotal = pending.reduce((sum, row) => sum + row.amount, 0);
await pending[0].save(); if (pendingTotal !== remaining) {
pending[0].amount = remaining;
await pending[0].save();
}
if (pending.length > 1) { if (pending.length > 1) {
await Transaction.deleteMany({ _id: { $in: pending.slice(1).map((row) => row._id) } }); await Transaction.deleteMany({ _id: { $in: pending.slice(1).map((row) => row._id) } });
} }
@@ -123,8 +127,11 @@ const buildTransactionPayload = (payment, trxData, actorId = null) => {
const parseDate = (value) => { const parseDate = (value) => {
if (!value) return null; if (!value) return null;
const date = value instanceof Date ? value : new Date(value); if (value instanceof Date) {
return Number.isNaN(date.getTime()) ? null : date; return Number.isNaN(value.getTime()) ? null : value;
}
const parsed = parseImportDate(value);
return parsed && !Number.isNaN(parsed.getTime()) ? parsed : null;
}; };
const createTransactionsForPayment = async (payment, transactions, actorId = null) => { const createTransactionsForPayment = async (payment, transactions, actorId = null) => {
@@ -342,11 +349,17 @@ const updateTransaction = async (transactionId, body, actorId = null) => {
const payload = buildTransactionPayload(payment, merged, actorId); const payload = buildTransactionPayload(payment, merged, actorId);
trx.amount = payload.amount; trx.amount = payload.amount;
trx.status = payload.status; trx.status = payload.status;
trx.method = payload.method;
trx.receiptNumber = payload.receiptNumber; trx.receiptNumber = payload.receiptNumber;
trx.notes = payload.notes; trx.notes = payload.notes;
trx.dueDate = payload.dueDate; trx.dueDate = payload.dueDate;
trx.date = payload.date; if (payload.status === 'paid') {
trx.method = payload.method;
trx.date = payload.date;
} else {
trx.method = undefined;
trx.date = undefined;
trx.receiptNumber = '';
}
if (actorId) trx.recordedBy = actorId; if (actorId) trx.recordedBy = actorId;
await trx.save(); await trx.save();