payservedb 6.0.9 → 6.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payservedb",
3
- "version": "6.0.9",
3
+ "version": "6.1.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -6,45 +6,44 @@ const powerMeterPowerChargeSchema = new mongoose.Schema({
6
6
  ref: 'Facility',
7
7
  required: true
8
8
  },
9
- meterSerialNumber: {
10
- type: String,
9
+ // KPLC Power Charges
10
+ fuelCostCharge: {
11
+ type: Number,
11
12
  required: true
12
13
  },
13
- deviceId: {
14
+ forexAdjustment: {
14
15
  type: Number,
15
- required: false
16
-
16
+ required: true
17
17
  },
18
- gatewayId: {
19
- type: String,
18
+ inflationAdjustment: {
19
+ type: Number,
20
20
  required: true
21
-
22
21
  },
23
- meterReading: {
22
+ waterResourceManagementLevy: {
24
23
  type: Number,
25
- required: true,
26
-
24
+ required: true
27
25
  },
28
- lastUpdated: {
29
- type: Date,
26
+ energyRegulatoryLevy: {
27
+ type: Number,
30
28
  required: true
31
-
32
29
  },
33
- manufacturer: {
34
- type: String,
30
+ ruralElectrificationLevy: {
31
+ type: Number,
35
32
  required: true
36
33
  },
37
- type: {
38
- type: String,
39
- required: true,
40
- enum: ['2 phase', '3 phase'],
41
- default: '2 phase'
42
-
34
+ valueAddedTax: {
35
+ type: Number,
36
+ required: true
37
+ },
38
+ totalCharge: {
39
+ type: Number,
40
+ required: true
43
41
  }
42
+
44
43
  }, {
45
44
  timestamps: true
46
45
  });
47
46
 
48
47
  const PowerMeterPowerCharge = mongoose.model('PowerMeterPowerCharge', powerMeterPowerChargeSchema);
49
48
 
50
- module.exports = PowerMeterPowerCharge;
49
+ module.exports = PowerMeterPowerCharge;
@@ -40,6 +40,10 @@ const powerMeterSchema = new mongoose.Schema({
40
40
  enum: ['2 phase', '3 phase'],
41
41
  default: '2 phase'
42
42
 
43
+ },
44
+ status: {
45
+ type: String,
46
+ required: true
43
47
  }
44
48
  }, {
45
49
  timestamps: true
@@ -10,12 +10,14 @@ const propertyManagerRevenue = new mongoose.Schema({
10
10
  calculationDate: {
11
11
  type: Date,
12
12
  required: true,
13
- index: true
13
+ index: true,
14
+ default: Date.now
14
15
  },
15
16
  dateRange: {
16
17
  startDate: Date,
17
18
  endDate: Date
18
19
  },
20
+ // Direct revenue amounts - no calculations needed
19
21
  totalRevenue: {
20
22
  type: Number,
21
23
  required: true,
@@ -23,14 +25,14 @@ const propertyManagerRevenue = new mongoose.Schema({
23
25
  },
24
26
  totalOwnerAmount: {
25
27
  type: Number,
26
- required: true,
27
- default: 0
28
+ default: 0 // Usually 0 for direct PM invoices
28
29
  },
29
30
  totalPaidAmount: {
30
31
  type: Number,
31
32
  required: true,
32
33
  default: 0
33
34
  },
35
+ // Processing statistics
34
36
  unitsProcessed: {
35
37
  type: Number,
36
38
  default: 0
@@ -39,63 +41,156 @@ const propertyManagerRevenue = new mongoose.Schema({
39
41
  type: Number,
40
42
  default: 0
41
43
  },
44
+ contractsProcessed: {
45
+ type: Number,
46
+ default: 0
47
+ },
48
+ // CRITICAL: Track processed invoice numbers to prevent duplicates
49
+ processedInvoiceNumbers: [{
50
+ type: String,
51
+ required: false
52
+ }],
53
+ // Unit breakdown - simplified
42
54
  unitBreakdown: [{
43
55
  unit: {
44
56
  type: mongoose.Schema.Types.ObjectId,
45
57
  ref: 'Unit',
46
58
  required: true
47
59
  },
48
- unitName: String, // Denormalized for easier access
49
- propertyManagementFee: Number,
50
- totalPaid: Number,
51
- managerRevenue: Number,
52
- ownerAmount: Number,
53
- invoiceCount: Number,
60
+ unitName: String,
61
+ contractId: {
62
+ type: mongoose.Schema.Types.ObjectId,
63
+ ref: 'PropertyManagerContract'
64
+ },
65
+ contractName: String,
66
+ propertyManager: {
67
+ id: {
68
+ type: mongoose.Schema.Types.ObjectId,
69
+ ref: 'User'
70
+ },
71
+ fullName: String,
72
+ email: String,
73
+ phoneNumber: String
74
+ },
75
+ // Revenue amounts for this unit
76
+ totalPaid: {
77
+ type: Number,
78
+ default: 0
79
+ },
80
+ managerRevenue: {
81
+ type: Number,
82
+ default: 0
83
+ },
84
+ ownerAmount: {
85
+ type: Number,
86
+ default: 0
87
+ },
88
+ invoiceCount: {
89
+ type: Number,
90
+ default: 0
91
+ },
92
+ // Invoice details
54
93
  invoices: [{
55
94
  invoice: {
56
95
  type: mongoose.Schema.Types.ObjectId,
57
96
  ref: 'Invoice',
58
97
  required: true
59
98
  },
60
- invoiceNumber: String, // Denormalized for easier access
99
+ invoiceNumber: {
100
+ type: String,
101
+ required: true,
102
+ index: true
103
+ },
61
104
  invoiceType: String,
62
105
  totalAmount: Number,
63
106
  paidAmount: Number,
64
107
  managerCommission: Number,
65
108
  ownerAmount: Number,
66
109
  paymentDate: Date,
67
- managementFeePercent: Number
110
+ contractId: {
111
+ type: mongoose.Schema.Types.ObjectId,
112
+ ref: 'PropertyManagerContract'
113
+ },
114
+ contractName: String,
115
+ revenueSource: {
116
+ type: String,
117
+ enum: ['DirectPropertyManagerInvoice', 'CalculatedFromTenantInvoice', 'PropertyManagementInvoice'],
118
+ default: 'PropertyManagementInvoice'
119
+ }
68
120
  }]
69
121
  }],
70
122
  summary: {
71
123
  totalUnits: Number,
72
124
  totalInvoicesProcessed: Number,
73
- includesHistoricalRevenue: Boolean,
125
+ contractsProcessed: Number,
74
126
  calculationNote: String
75
127
  },
76
128
  status: {
77
129
  type: String,
78
- enum: ['calculated', 'paid', 'partially_paid', 'cancelled'],
130
+ enum: ['calculated', 'paid', 'cancelled'],
79
131
  default: 'calculated'
80
132
  },
81
133
  notes: String,
82
134
  createdBy: {
83
135
  type: mongoose.Schema.Types.ObjectId,
84
- ref: 'User' // Reference to User who created this record
136
+ ref: 'User'
85
137
  },
86
- createdAt: {
87
- type: Date,
88
- default: Date.now,
89
- index: true
90
- },
91
- updatedAt: {
92
- type: Date,
93
- default: Date.now
138
+ calculationType: {
139
+ type: String,
140
+ enum: [
141
+ 'direct_revenue',
142
+ 'bulk_direct_revenue',
143
+ 'retroactive_direct',
144
+ 'revenue_extraction',
145
+ 'bulk_revenue_extraction'
146
+ ],
147
+ default: 'direct_revenue'
94
148
  }
95
149
  }, {
96
150
  timestamps: true
97
151
  });
98
152
 
153
+ // Enhanced indexes for better performance and duplicate prevention
154
+ propertyManagerRevenue.index({ facility: 1, calculationDate: -1 });
155
+ propertyManagerRevenue.index({ facility: 1, 'unitBreakdown.unit': 1 });
156
+ propertyManagerRevenue.index({ facility: 1, calculationType: 1 });
157
+ propertyManagerRevenue.index({ createdAt: -1 });
158
+
159
+ // CRITICAL: Compound index for fast duplicate checking by invoice number
160
+ propertyManagerRevenue.index({
161
+ facility: 1,
162
+ 'unitBreakdown.invoices.invoiceNumber': 1
163
+ });
164
+
165
+ // CRITICAL: Index for processed invoice numbers array
166
+ propertyManagerRevenue.index({
167
+ facility: 1,
168
+ processedInvoiceNumbers: 1
169
+ });
170
+
171
+ // Simple pre-save middleware to auto-populate processedInvoiceNumbers
172
+ propertyManagerRevenue.pre('save', function(next) {
173
+ try {
174
+ // Auto-populate processedInvoiceNumbers from unitBreakdown if not set
175
+ if (!this.processedInvoiceNumbers || this.processedInvoiceNumbers.length === 0) {
176
+ const invoiceNumbers = [];
177
+ this.unitBreakdown.forEach(unit => {
178
+ if (unit.invoices && Array.isArray(unit.invoices)) {
179
+ unit.invoices.forEach(invoice => {
180
+ if (invoice.invoiceNumber) {
181
+ invoiceNumbers.push(invoice.invoiceNumber);
182
+ }
183
+ });
184
+ }
185
+ });
186
+ this.processedInvoiceNumbers = [...new Set(invoiceNumbers)];
187
+ }
188
+ next();
189
+ } catch (error) {
190
+ next(error);
191
+ }
192
+ });
193
+
99
194
  const PropertyManagerRevenue = mongoose.model('PropertyManagerRevenue', propertyManagerRevenue);
100
195
 
101
196
  module.exports = PropertyManagerRevenue;