payservedb 8.5.2 → 8.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js
CHANGED
|
@@ -142,6 +142,7 @@ const models = {
|
|
|
142
142
|
DefaultPaymentDetails: require("./src/models/default_payment_details"),
|
|
143
143
|
Currency: require("./src/models/currency_settings"),
|
|
144
144
|
WaterMeterAccount: require("./src/models/water_meter_account"),
|
|
145
|
+
WaterMeterLoanDeduction: require("./src/models/water_meter_loan_deduction"),
|
|
145
146
|
SingleDayWaterMeterHistory: require("./src/models/water_meter_single_day_history"),
|
|
146
147
|
DailyWaterMeterHistory: require("./src/models/water_meter_daily_history"),
|
|
147
148
|
MonthlyWaterMeterHistory: require("./src/models/water_meter_monthly_history"),
|
package/package.json
CHANGED
|
@@ -104,7 +104,7 @@ const leaseAgreementSchema = new mongoose.Schema({
|
|
|
104
104
|
}],
|
|
105
105
|
securityDeposit: { type: Number, required: true },
|
|
106
106
|
balanceBroughtForward: { type: Number, required: true, default: 0 },
|
|
107
|
-
taxEnabled: { type: Boolean, default:
|
|
107
|
+
taxEnabled: { type: Boolean, default: false },
|
|
108
108
|
penaltyId: {
|
|
109
109
|
type: mongoose.Schema.Types.ObjectId,
|
|
110
110
|
ref: 'Penalty'
|
|
@@ -234,4 +234,4 @@ leaseAgreementSchema.index({ lastInvoiceYearMonth: 1 });
|
|
|
234
234
|
|
|
235
235
|
const LeaseAgreement = mongoose.model('LeaseAgreement', leaseAgreementSchema);
|
|
236
236
|
|
|
237
|
-
module.exports = LeaseAgreement;
|
|
237
|
+
module.exports = LeaseAgreement;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const waterMeterLoanDeductionSchema = new mongoose.Schema({
|
|
4
|
+
customerId: {
|
|
5
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
+
ref: 'Customer',
|
|
7
|
+
required: true,
|
|
8
|
+
index: true
|
|
9
|
+
},
|
|
10
|
+
accountId: {
|
|
11
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
12
|
+
ref: 'WaterMeterAccount',
|
|
13
|
+
required: true,
|
|
14
|
+
index: true
|
|
15
|
+
},
|
|
16
|
+
meterId: {
|
|
17
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
18
|
+
ref: 'WaterMeter',
|
|
19
|
+
required: true,
|
|
20
|
+
index: true
|
|
21
|
+
},
|
|
22
|
+
amount: {
|
|
23
|
+
type: Number,
|
|
24
|
+
required: true,
|
|
25
|
+
min: 0
|
|
26
|
+
},
|
|
27
|
+
yearMonth: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: true,
|
|
30
|
+
index: true,
|
|
31
|
+
// Format: YYYY-MM (e.g., "2026-01")
|
|
32
|
+
validate: {
|
|
33
|
+
validator: function(v) {
|
|
34
|
+
return /^\d{4}-(0[1-9]|1[0-2])$/.test(v);
|
|
35
|
+
},
|
|
36
|
+
message: "yearMonth must be in YYYY-MM format"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
deductionDate: {
|
|
40
|
+
type: Date,
|
|
41
|
+
required: true,
|
|
42
|
+
default: Date.now
|
|
43
|
+
},
|
|
44
|
+
status: {
|
|
45
|
+
type: String,
|
|
46
|
+
enum: ['pending', 'completed', 'insufficient_balance'],
|
|
47
|
+
required: true,
|
|
48
|
+
default: 'pending',
|
|
49
|
+
index: true
|
|
50
|
+
},
|
|
51
|
+
debitRecordId: {
|
|
52
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
53
|
+
ref: 'WaterPrepaidDebit',
|
|
54
|
+
// Will be populated when deduction is completed
|
|
55
|
+
},
|
|
56
|
+
balanceAtAttempt: {
|
|
57
|
+
type: Number,
|
|
58
|
+
// Store balance when deduction was attempted
|
|
59
|
+
},
|
|
60
|
+
attempts: {
|
|
61
|
+
type: Number,
|
|
62
|
+
default: 0,
|
|
63
|
+
min: 0
|
|
64
|
+
},
|
|
65
|
+
lastAttemptDate: {
|
|
66
|
+
type: Date
|
|
67
|
+
},
|
|
68
|
+
completedDate: {
|
|
69
|
+
type: Date
|
|
70
|
+
},
|
|
71
|
+
notes: {
|
|
72
|
+
type: String,
|
|
73
|
+
trim: true
|
|
74
|
+
}
|
|
75
|
+
}, {
|
|
76
|
+
timestamps: true
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Compound index to ensure one deduction per customer per month
|
|
80
|
+
waterMeterLoanDeductionSchema.index(
|
|
81
|
+
{ customerId: 1, yearMonth: 1 },
|
|
82
|
+
{ unique: true }
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// Index for finding pending deductions
|
|
86
|
+
waterMeterLoanDeductionSchema.index({ status: 1, yearMonth: 1 });
|
|
87
|
+
|
|
88
|
+
// Index for finding deductions by account
|
|
89
|
+
waterMeterLoanDeductionSchema.index({ accountId: 1, yearMonth: 1 });
|
|
90
|
+
|
|
91
|
+
// Static method to check if deduction exists for a customer in a given month
|
|
92
|
+
waterMeterLoanDeductionSchema.statics.deductionExists = async function(customerId, yearMonth) {
|
|
93
|
+
const count = await this.countDocuments({ customerId, yearMonth });
|
|
94
|
+
return count > 0;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Static method to get pending deductions
|
|
98
|
+
waterMeterLoanDeductionSchema.statics.getPendingDeductions = async function() {
|
|
99
|
+
return this.find({ status: 'pending' })
|
|
100
|
+
.populate('accountId')
|
|
101
|
+
.populate('meterId')
|
|
102
|
+
.sort({ createdAt: 1 });
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Static method to get pending deductions for a specific month
|
|
106
|
+
waterMeterLoanDeductionSchema.statics.getPendingDeductionsForMonth = async function(yearMonth) {
|
|
107
|
+
return this.find({
|
|
108
|
+
status: 'pending',
|
|
109
|
+
yearMonth: yearMonth
|
|
110
|
+
})
|
|
111
|
+
.populate('accountId')
|
|
112
|
+
.populate('meterId')
|
|
113
|
+
.sort({ createdAt: 1 });
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Instance method to mark as completed
|
|
117
|
+
waterMeterLoanDeductionSchema.methods.markCompleted = async function(debitRecordId) {
|
|
118
|
+
this.status = 'completed';
|
|
119
|
+
this.debitRecordId = debitRecordId;
|
|
120
|
+
this.completedDate = new Date();
|
|
121
|
+
return this.save();
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Instance method to mark as insufficient balance
|
|
125
|
+
waterMeterLoanDeductionSchema.methods.markInsufficientBalance = async function(balance) {
|
|
126
|
+
this.status = 'insufficient_balance';
|
|
127
|
+
this.balanceAtAttempt = balance;
|
|
128
|
+
this.attempts += 1;
|
|
129
|
+
this.lastAttemptDate = new Date();
|
|
130
|
+
return this.save();
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const WaterMeterLoanDeduction = mongoose.model('WaterMeterLoanDeduction', waterMeterLoanDeductionSchema);
|
|
134
|
+
|
|
135
|
+
module.exports = WaterMeterLoanDeduction;
|