payservedb 8.5.1 → 8.5.3
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
|
@@ -121,6 +121,7 @@ const models = {
|
|
|
121
121
|
WaterMeter: require("./src/models/water_meters"),
|
|
122
122
|
DailyConsumption: require("./src/models/smart_meter_daily_consumption"),
|
|
123
123
|
WaterMeterSettings: require("./src/models/water_meter_settings"),
|
|
124
|
+
WaterCombinedMeterAccount: require("./src/models/water_meter_combined_accounts"),
|
|
124
125
|
AnalogBilling: require("./src/models/water_meter_billing"),
|
|
125
126
|
MeterSize: require("./src/models/water_meter_size"),
|
|
126
127
|
WaterInvoice: require("./src/models/water_invoice"),
|
|
@@ -141,6 +142,7 @@ const models = {
|
|
|
141
142
|
DefaultPaymentDetails: require("./src/models/default_payment_details"),
|
|
142
143
|
Currency: require("./src/models/currency_settings"),
|
|
143
144
|
WaterMeterAccount: require("./src/models/water_meter_account"),
|
|
145
|
+
WaterMeterLoanDeduction: require("./src/models/water_meter_loan_deduction"),
|
|
144
146
|
SingleDayWaterMeterHistory: require("./src/models/water_meter_single_day_history"),
|
|
145
147
|
DailyWaterMeterHistory: require("./src/models/water_meter_daily_history"),
|
|
146
148
|
MonthlyWaterMeterHistory: require("./src/models/water_meter_monthly_history"),
|
package/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const waterCombinedMeterAccountSchema = new mongoose.Schema({
|
|
4
|
+
facilityId: {
|
|
5
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
+
ref: 'Facility',
|
|
7
|
+
required: true,
|
|
8
|
+
},
|
|
9
|
+
account_no: {
|
|
10
|
+
type: String,
|
|
11
|
+
required: true,
|
|
12
|
+
trim: true
|
|
13
|
+
},
|
|
14
|
+
customerId: {
|
|
15
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
16
|
+
ref: 'Customer',
|
|
17
|
+
},
|
|
18
|
+
customerName: {
|
|
19
|
+
type: String,
|
|
20
|
+
required: true,
|
|
21
|
+
trim: true
|
|
22
|
+
},
|
|
23
|
+
phoneNumber: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: true,
|
|
26
|
+
trim: true
|
|
27
|
+
},
|
|
28
|
+
email: {
|
|
29
|
+
type: String,
|
|
30
|
+
required: true,
|
|
31
|
+
trim: true
|
|
32
|
+
},
|
|
33
|
+
meterNumbers: [{
|
|
34
|
+
type: String,
|
|
35
|
+
required: true,
|
|
36
|
+
trim: true
|
|
37
|
+
}],
|
|
38
|
+
|
|
39
|
+
unitId: {
|
|
40
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
41
|
+
ref: 'Unit',
|
|
42
|
+
},
|
|
43
|
+
unitName: {
|
|
44
|
+
type: String,
|
|
45
|
+
required: true,
|
|
46
|
+
trim: true,
|
|
47
|
+
index: true
|
|
48
|
+
},
|
|
49
|
+
payment_type: {
|
|
50
|
+
type: String,
|
|
51
|
+
required: true,
|
|
52
|
+
enum: ['Postpaid', 'Prepaid']
|
|
53
|
+
},
|
|
54
|
+
previousReading: {
|
|
55
|
+
type: Number,
|
|
56
|
+
required: true,
|
|
57
|
+
default: 0
|
|
58
|
+
},
|
|
59
|
+
currentReading: {
|
|
60
|
+
type: Number,
|
|
61
|
+
required: true
|
|
62
|
+
},
|
|
63
|
+
status: {
|
|
64
|
+
type: String,
|
|
65
|
+
required: true,
|
|
66
|
+
enum: ['Active', 'Inactive'],
|
|
67
|
+
default: 'Active'
|
|
68
|
+
},
|
|
69
|
+
created_on: {
|
|
70
|
+
type: Date,
|
|
71
|
+
required: true,
|
|
72
|
+
default: Date.now
|
|
73
|
+
},
|
|
74
|
+
meter_ids: [{
|
|
75
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
76
|
+
ref: 'WaterMeter',
|
|
77
|
+
}],
|
|
78
|
+
|
|
79
|
+
accountBalance: {
|
|
80
|
+
type: Number,
|
|
81
|
+
default: 0
|
|
82
|
+
}
|
|
83
|
+
}, {
|
|
84
|
+
timestamps: true
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const WaterCombinedMeterAccount = mongoose.model(
|
|
88
|
+
'WaterCombinedMeterAccount',
|
|
89
|
+
waterCombinedMeterAccountSchema
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
module.exports = WaterCombinedMeterAccount;
|
|
@@ -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;
|