feat: add messaging toggles, password reset SMS, and payment discounts
Allow SuperAdmin to disable SMS, email, and bot from dashboard settings on top of env flags. Add admin password reset with credentials SMS, plus payment discounts, notes, and payable amount handling.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const { getPayableAmount, normalizeDiscount } = require('../../utils/paymentAmount');
|
||||
|
||||
const transactionSchema = new mongoose.Schema({
|
||||
amount: { type: Number, required: true },
|
||||
method: {
|
||||
@@ -11,6 +13,7 @@ const transactionSchema = new mongoose.Schema({
|
||||
default: 'card'
|
||||
},
|
||||
receiptNumber: { type: String, trim: true },
|
||||
notes: { type: String, trim: true, maxlength: 5000 },
|
||||
recordedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
date: { type: Date, default: Date.now }
|
||||
}, { _id: true });
|
||||
@@ -35,6 +38,11 @@ const paymentSchema = new mongoose.Schema({
|
||||
required: true,
|
||||
min: 0
|
||||
},
|
||||
discount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
min: 0
|
||||
},
|
||||
paidAmount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
@@ -49,14 +57,16 @@ const paymentSchema = new mongoose.Schema({
|
||||
default: 'pending'
|
||||
},
|
||||
transactions: [transactionSchema],
|
||||
notes: { type: String, trim: true }
|
||||
notes: { type: String, trim: true, maxlength: 5000 }
|
||||
}, {
|
||||
timestamps: true
|
||||
});
|
||||
|
||||
// Auto-update status based on paid amount
|
||||
// Auto-update status based on paid amount vs payable (amount - discount)
|
||||
paymentSchema.pre('save', function (next) {
|
||||
if (this.paidAmount >= this.amount) {
|
||||
this.discount = normalizeDiscount(this.discount, this.amount);
|
||||
const payable = getPayableAmount(this);
|
||||
if (this.paidAmount >= payable) {
|
||||
this.status = 'paid';
|
||||
} else if (this.paidAmount > 0) {
|
||||
this.status = 'partial';
|
||||
|
||||
@@ -13,6 +13,7 @@ const Session = require('../sessions/sessionModel');
|
||||
const { sendInvoiceCreatedSms } = require('../../utils/senders/smsMessages');
|
||||
const { buildClassScheduleContext } = require('../../utils/classSchedule');
|
||||
const { pickNotifyFlags, omitNotifyFields } = require('../../utils/notifyFlags');
|
||||
const { getPayableAmount, normalizeDiscount, sanitizeNotes } = require('../../utils/paymentAmount');
|
||||
const logger = require('../../utils/logger');
|
||||
|
||||
const getAllPayments = async (query) => {
|
||||
@@ -69,6 +70,8 @@ const createPayment = async (body, actorId = null) => {
|
||||
const payload = omitNotifyFields(body);
|
||||
const payment = await Payment.create({
|
||||
...payload,
|
||||
discount: normalizeDiscount(payload.discount, payload.amount),
|
||||
notes: sanitizeNotes(payload.notes),
|
||||
paidAmount: payload.paidAmount || 0
|
||||
});
|
||||
|
||||
@@ -110,7 +113,7 @@ const createPayment = async (body, actorId = null) => {
|
||||
|
||||
await sendInvoiceCreatedSms(user.phoneNumber, {
|
||||
fullName: user.name || '',
|
||||
amount: payment.amount,
|
||||
amount: getPayableAmount(payment),
|
||||
course: courseName || '-',
|
||||
...schedule
|
||||
}, user._id);
|
||||
@@ -129,6 +132,12 @@ const updatePayment = async (id, body, actorId = null) => {
|
||||
|
||||
const previousStatus = payment.status;
|
||||
Object.assign(payment, body);
|
||||
if (body.discount !== undefined) {
|
||||
payment.discount = normalizeDiscount(body.discount, payment.amount);
|
||||
}
|
||||
if (body.notes !== undefined) {
|
||||
payment.notes = sanitizeNotes(body.notes);
|
||||
}
|
||||
await payment.save();
|
||||
|
||||
if (body.status && body.status !== previousStatus) {
|
||||
@@ -158,6 +167,7 @@ const addTransaction = async (paymentId, trxData, actorId = null) => {
|
||||
|
||||
payment.transactions.push({
|
||||
...trxData,
|
||||
notes: sanitizeNotes(trxData.notes),
|
||||
recordedBy: actorId || trxData.recordedBy,
|
||||
date: trxData.date || new Date()
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user