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.
82 lines
1.9 KiB
JavaScript
82 lines
1.9 KiB
JavaScript
// /components/payments/paymentModel.js
|
|
'use strict';
|
|
|
|
const mongoose = require('mongoose');
|
|
|
|
const { getPayableAmount, normalizeDiscount } = require('../../utils/paymentAmount');
|
|
|
|
const transactionSchema = new mongoose.Schema({
|
|
amount: { type: Number, required: true },
|
|
method: {
|
|
type: String,
|
|
enum: ['online', 'card', 'cash'],
|
|
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 });
|
|
|
|
const paymentSchema = new mongoose.Schema({
|
|
user: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'User',
|
|
required: true,
|
|
index: true
|
|
},
|
|
classes: [{
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Class'
|
|
}],
|
|
course: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Course'
|
|
},
|
|
amount: {
|
|
type: Number,
|
|
required: true,
|
|
min: 0
|
|
},
|
|
discount: {
|
|
type: Number,
|
|
default: 0,
|
|
min: 0
|
|
},
|
|
paidAmount: {
|
|
type: Number,
|
|
default: 0,
|
|
min: 0
|
|
},
|
|
dueDate: {
|
|
type: Date
|
|
},
|
|
status: {
|
|
type: String,
|
|
enum: ['pending', 'partial', 'paid', 'overdue'],
|
|
default: 'pending'
|
|
},
|
|
transactions: [transactionSchema],
|
|
notes: { type: String, trim: true, maxlength: 5000 }
|
|
}, {
|
|
timestamps: true
|
|
});
|
|
|
|
// Auto-update status based on paid amount vs payable (amount - discount)
|
|
paymentSchema.pre('save', function (next) {
|
|
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';
|
|
} else if (this.dueDate && new Date() > this.dueDate) {
|
|
this.status = 'overdue';
|
|
} else {
|
|
this.status = 'pending';
|
|
}
|
|
next();
|
|
});
|
|
|
|
module.exports = mongoose.model('Payment', paymentSchema);
|