// /components/payments/paymentModel.js 'use strict'; const mongoose = require('mongoose'); const { getPayableAmount, normalizeDiscount } = require('../../utils/paymentAmount'); const uniqueCodePlugin = require('../../utils/mongooseUniqueCodePlugin'); require('./transactionModel'); 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', 'cancelled', 'reverted'], default: 'pending' }, type: { type: String, enum: ['regular', 'waiting_list'], default: 'regular', index: true }, notes: { type: String, trim: true, maxlength: 5000 }, isDeleted: { type: Boolean, default: false, index: true }, deletedAt: { type: Date, default: null } }, { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }); paymentSchema.plugin(uniqueCodePlugin); paymentSchema.virtual('transactions', { ref: 'Transaction', localField: '_id', foreignField: 'payment' }); paymentSchema.pre('save', function (next) { this.discount = normalizeDiscount(this.discount, this.amount); const payable = getPayableAmount(this); if (this.status === 'cancelled' || this.status === 'reverted') { return next(); } 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);