payservedb 3.8.9 → 3.9.1

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
@@ -108,6 +108,7 @@ const models = {
108
108
  CountryTaxRate: require('./src/models/country_tax'),
109
109
  Meter: require('./src/models/smart_water_meter'),
110
110
  DailyConsumption: require('./src/models/smart_meter_daily_consumption'),
111
+ WaterMeterSettings: require('./src/models/water_meter_settings'),
111
112
  AnalogMeter: require('./src/models/analog_water_meter'),
112
113
  MeterSize: require('./src/models/water_meter_size'),
113
114
  MeterProtocol: require('./src/models/water_meter_communication'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payservedb",
3
- "version": "3.8.9",
3
+ "version": "3.9.1",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -1,139 +1,245 @@
1
- const mongoose = require("mongoose");
1
+ const mongoose = require('mongoose');
2
2
 
3
- // Schema for Handover Checklist Items
4
- const checklistItemSchema = new mongoose.Schema({
5
- itemName: {
3
+ const handoverItemSchema = new mongoose.Schema({
4
+ name: {
6
5
  type: String,
7
6
  required: true,
7
+ trim: true
8
8
  },
9
9
  category: {
10
10
  type: String,
11
11
  required: true,
12
- enum: ["Appliances", "Furniture", "Electronics", "Utilities", "Structure", "Other"]
12
+ trim: true,
13
+ enum: ['Furniture', 'Appliance', 'Electronics', 'Fixture', 'Utility', 'Other']
13
14
  },
14
- status: {
15
+ description: {
15
16
  type: String,
16
- required: true,
17
- enum: ["Working", "Not Working"]
17
+ trim: true
18
18
  },
19
- notes: {
19
+ condition: {
20
20
  type: String,
21
- default: ""
21
+ required: true,
22
+ enum: ['Excellent', 'Good', 'Fair', 'Poor', 'Damaged', 'Non-functional']
22
23
  },
23
- photos: [{
24
- url: String,
25
- uploadedAt: Date
26
- }]
27
- }, {
28
- timestamps: true
29
- });
30
-
31
- // Main Handover Schema
32
- const handoverSchema = new mongoose.Schema({
33
- // Basic Information
34
- handoverType: {
35
- type: String,
24
+ quantity: {
25
+ type: Number,
36
26
  required: true,
37
- enum: ["Move-In", "Move-Out"]
27
+ default: 1,
28
+ min: [1, 'Quantity must be at least 1']
38
29
  },
39
- facility: {
40
- type: mongoose.Schema.Types.ObjectId,
41
- ref: "Facility",
42
- required: true
30
+ serialNumber: {
31
+ type: String,
32
+ trim: true
43
33
  },
44
- unit: {
34
+ images: [{
35
+ type: String, // URLs to stored images
36
+ trim: true
37
+ }],
38
+ notes: {
39
+ type: String,
40
+ trim: true
41
+ }
42
+ }, { _id: true });
43
+
44
+ // Define the main Handover schema
45
+ const handoverSchema = new mongoose.Schema({
46
+ // References
47
+ facilityId: {
45
48
  type: mongoose.Schema.Types.ObjectId,
46
- ref: "Unit",
49
+ ref: 'Facility',
47
50
  required: true
48
51
  },
49
- tenant: {
52
+ unitId: {
50
53
  type: mongoose.Schema.Types.ObjectId,
51
- ref: "Customer",
54
+ ref: 'Unit',
52
55
  required: true
53
56
  },
54
- landlord: {
57
+ customerId: {
55
58
  type: mongoose.Schema.Types.ObjectId,
56
- ref: "Customer",
59
+ ref: 'Customer',
57
60
  required: true
58
61
  },
59
- lease: {
62
+ propertyManagerId: {
60
63
  type: mongoose.Schema.Types.ObjectId,
61
- ref: "LeaseAgreement",
64
+ ref: 'User', // Reference to your User model
62
65
  required: true
63
66
  },
64
- propertyManager: {
65
- type: mongoose.Schema.Types.ObjectId,
66
- ref: "User",
67
- required: true
67
+
68
+ // Handover details
69
+ handoverType: {
70
+ type: String,
71
+ required: true,
72
+ enum: ['MoveIn', 'MoveOut'],
73
+ trim: true
68
74
  },
69
-
70
- // Handover Details
71
- scheduledDate: {
75
+ handoverDate: {
72
76
  type: Date,
73
- required: true
74
- },
75
- actualHandoverDate: {
76
- type: Date
77
+ required: true,
78
+ default: Date.now
77
79
  },
78
80
  status: {
79
81
  type: String,
80
82
  required: true,
81
- enum: ["Pending", "In Progress", "Completed", "Cancelled"],
82
- default: "Pending"
83
+ enum: ['Draft', 'Completed', 'Disputed', 'Resolved'],
84
+ default: 'Draft'
83
85
  },
84
-
85
- // Checklist Items
86
- checklistItems: [checklistItemSchema],
87
-
88
- // Utility Readings
89
- utilityReadings: {
86
+
87
+ // If this is a move-out handover, reference the original move-in handover
88
+ relatedHandoverId: {
89
+ type: mongoose.Schema.Types.ObjectId,
90
+ ref: 'Handover',
91
+ default: null // Only populated for move-out handovers
92
+ },
93
+
94
+ // Items included in the handover
95
+ items: [handoverItemSchema],
96
+
97
+ // Additional information
98
+ meterReadings: {
90
99
  electricity: {
91
- meterNumber: String,
92
100
  reading: Number,
93
- photo: String
101
+ imageUrl: String
94
102
  },
95
103
  water: {
96
- meterNumber: String,
97
104
  reading: Number,
98
- photo: String
105
+ imageUrl: String
99
106
  },
100
107
  gas: {
101
- meterNumber: String,
102
108
  reading: Number,
103
- photo: String
109
+ imageUrl: String
104
110
  }
105
111
  },
106
-
107
- // Documents (Optional)
108
- documents: [{
109
- type: {
110
- type: String,
111
- enum: ["Welcome Pack", "User Manual", "Inspection Report", "Utility Transfer", "Other"]
112
+
113
+ // Key handover confirmation
114
+ keysHandedOver: {
115
+ type: Number,
116
+ default: 0,
117
+ min: 0
118
+ },
119
+
120
+ // Security deposit info (for move-out)
121
+ securityDeposit: {
122
+ amount: {
123
+ type: Number,
124
+ default: 0
112
125
  },
113
- name: String,
114
- url: String,
115
- uploadedAt: Date
116
- }],
117
-
118
- // Feedback (for Move-Out)
119
- feedback: {
120
- rating: {
126
+ deductions: [{
127
+ reason: {
128
+ type: String,
129
+ trim: true
130
+ },
131
+ amount: {
132
+ type: Number,
133
+ min: 0
134
+ },
135
+ description: String
136
+ }],
137
+ refundAmount: {
121
138
  type: Number,
122
- min: 1,
123
- max: 5
139
+ default: 0
140
+ }
141
+ },
142
+
143
+ // Signature and agreement info
144
+ signatures: {
145
+ propertyManager: {
146
+ signature: String, // URL to stored signature image or digital signature data
147
+ date: Date
124
148
  },
125
- comments: String,
126
- submittedAt: Date
149
+ customer: {
150
+ signature: String, // URL to stored signature image or digital signature data
151
+ date: Date,
152
+ agreement: {
153
+ type: Boolean,
154
+ default: false
155
+ }
156
+ }
127
157
  },
128
-
129
- // Additional Notes
158
+
159
+ // General notes
130
160
  notes: {
131
- type: String
132
- }
161
+ type: String,
162
+ trim: true
163
+ },
164
+
165
+ // Any attached documents
166
+ attachments: [{
167
+ name: String,
168
+ fileUrl: String,
169
+ uploadDate: {
170
+ type: Date,
171
+ default: Date.now
172
+ }
173
+ }]
133
174
  }, {
134
- timestamps: true
175
+ timestamps: true,
176
+ toJSON: { virtuals: true }, // Enable virtuals when converting to JSON
177
+ toObject: { virtuals: true } // Enable virtuals when converting to object
135
178
  });
136
179
 
137
- const Handover = mongoose.model("Handover", handoverSchema);
180
+ // Add indexes for common queries
181
+ handoverSchema.index({ facilityId: 1, unitId: 1, handoverType: 1 });
182
+ handoverSchema.index({ customerId: 1, handoverType: 1 });
183
+ handoverSchema.index({ handoverDate: -1 });
184
+
185
+ // Virtual for calculating total deductions
186
+ handoverSchema.virtual('totalDeductions').get(function() {
187
+ if (!this.securityDeposit.deductions || this.securityDeposit.deductions.length === 0) {
188
+ return 0;
189
+ }
190
+ return this.securityDeposit.deductions.reduce((total, deduction) => total + (deduction.amount || 0), 0);
191
+ });
192
+
193
+ // Add method to compare move-in and move-out states
194
+ handoverSchema.methods.compareWithMoveIn = async function() {
195
+ if (this.handoverType !== 'MoveOut' || !this.relatedHandoverId) {
196
+ throw new Error('This method can only be called on a move-out handover with a related move-in handover');
197
+ }
198
+
199
+ // Find the related move-in handover
200
+ const MoveInHandover = mongoose.model('Handover');
201
+ const moveInHandover = await MoveInHandover.findById(this.relatedHandoverId);
202
+
203
+ if (!moveInHandover) {
204
+ throw new Error('Related move-in handover not found');
205
+ }
206
+
207
+ // Compare items and return differences
208
+ const differences = {
209
+ missing: [],
210
+ damaged: [],
211
+ changed: []
212
+ };
213
+
214
+ // Check for missing or damaged items
215
+ moveInHandover.items.forEach(moveInItem => {
216
+ const moveOutItem = this.items.find(item =>
217
+ item.name === moveInItem.name &&
218
+ item.category === moveInItem.category
219
+ );
220
+
221
+ if (!moveOutItem) {
222
+ differences.missing.push(moveInItem);
223
+ } else if (moveOutItem.condition !== moveInItem.condition) {
224
+ if (['Poor', 'Damaged', 'Non-functional'].includes(moveOutItem.condition)) {
225
+ differences.damaged.push({
226
+ item: moveOutItem,
227
+ originalCondition: moveInItem.condition,
228
+ currentCondition: moveOutItem.condition
229
+ });
230
+ } else {
231
+ differences.changed.push({
232
+ item: moveOutItem,
233
+ originalCondition: moveInItem.condition,
234
+ currentCondition: moveOutItem.condition
235
+ });
236
+ }
237
+ }
238
+ });
239
+
240
+ return differences;
241
+ };
242
+
243
+ const Handover = mongoose.model('Handover', handoverSchema);
138
244
 
139
- module.exports = Handover;
245
+ module.exports = Handover;
@@ -0,0 +1,61 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const waterMeterSettingsSchema = new mongoose.Schema({
4
+ facilityId: {
5
+ type: mongoose.Schema.Types.ObjectId,
6
+ ref: 'Facility',
7
+ required: true
8
+ },
9
+ minAmount: {
10
+ type: Number,
11
+ required: true,
12
+ default: 1
13
+ },
14
+ maxAmount: {
15
+ type: Number,
16
+ required: true,
17
+ default: 10000
18
+ },
19
+ gracePeriod: {
20
+ type: Number,
21
+ required: true,
22
+ default: 10
23
+ },
24
+ enforcePayment: {
25
+ type: String,
26
+ enum: ['yes', 'no'],
27
+ required: true,
28
+ default: 'no'
29
+ },
30
+ minimumPaymentAmount: {
31
+ type: Number,
32
+ required: true,
33
+ default: 0
34
+ },
35
+ tariff: {
36
+ type: String,
37
+ enum: ['yes', 'no'],
38
+ required: true,
39
+ default: 'no'
40
+ },
41
+ tariffAmount: {
42
+ type: Number,
43
+ required: true,
44
+ default: 0
45
+ },
46
+ fixedTariffAmount: {
47
+ type: Number,
48
+ required: true,
49
+ default: 0
50
+ },
51
+ notifications: {
52
+ type: Boolean,
53
+ default: false
54
+ }
55
+ }, {
56
+ timestamps: true
57
+ });
58
+
59
+ const WaterMeterSettings = mongoose.model('WaterMeterSettings', waterMeterSettingsSchema);
60
+
61
+ module.exports = WaterMeterSettings;