payservedb 5.7.9 → 5.8.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/.env +2 -2
- package/index.js +199 -198
- package/package.json +17 -17
- package/src/models/account.js +35 -35
- package/src/models/apilog.js +18 -18
- package/src/models/approvalsWorkflows.js +49 -49
- package/src/models/archivedapilog.js +18 -18
- package/src/models/archivedauditlog.js +83 -83
- package/src/models/asset.js +34 -34
- package/src/models/assetsAssignment.js +64 -64
- package/src/models/auditlog.js +83 -83
- package/src/models/bankdetails.js +40 -40
- package/src/models/billerAddress.js +119 -119
- package/src/models/booking_invoice.js +151 -151
- package/src/models/bookinganalytics.js +63 -63
- package/src/models/bookingconfig.js +45 -45
- package/src/models/bookingproperty.js +112 -112
- package/src/models/bookingreservation.js +192 -192
- package/src/models/bookingrevenuerecord.js +84 -84
- package/src/models/budget.js +91 -91
- package/src/models/budgetCategory.js +19 -19
- package/src/models/campaigns.js +72 -72
- package/src/models/cashpayment.js +262 -262
- package/src/models/combinedUnits.js +62 -62
- package/src/models/common_area_electricity.js +38 -38
- package/src/models/common_area_generator.js +41 -41
- package/src/models/common_area_utility_alert.js +37 -37
- package/src/models/common_area_water.js +39 -39
- package/src/models/company.js +53 -53
- package/src/models/country_tax.js +42 -42
- package/src/models/currency_settings.js +39 -39
- package/src/models/customer.js +200 -200
- package/src/models/default_payment_details.js +17 -17
- package/src/models/dutyroster.js +107 -107
- package/src/models/email.js +37 -37
- package/src/models/entry_exit.js +53 -53
- package/src/models/expense.js +99 -99
- package/src/models/expense_category.js +45 -45
- package/src/models/facility.js +61 -61
- package/src/models/facility_payment_details.js +20 -20
- package/src/models/facilityasset.js +25 -25
- package/src/models/faq.js +18 -18
- package/src/models/gl_account_double_entries.js +25 -25
- package/src/models/gl_accounts.js +56 -56
- package/src/models/gl_entries.js +49 -49
- package/src/models/goodsReceivedNotes.js +61 -0
- package/src/models/guard.js +47 -47
- package/src/models/handover.js +246 -246
- package/src/models/invoice.js +336 -336
- package/src/models/item_inspection.js +67 -67
- package/src/models/leaseagreement.js +221 -221
- package/src/models/leasetemplate.js +17 -17
- package/src/models/levy.js +206 -206
- package/src/models/levy_invoice_settings.js +26 -26
- package/src/models/levycontract.js +117 -117
- package/src/models/levytype.js +23 -23
- package/src/models/maintenance_service_vendor.js +38 -38
- package/src/models/maintenance_services.js +17 -17
- package/src/models/maintenancerequisition.js +31 -31
- package/src/models/message.js +38 -38
- package/src/models/module.js +21 -21
- package/src/models/notification.js +44 -44
- package/src/models/penalty.js +76 -76
- package/src/models/pendingCredentials.js +32 -32
- package/src/models/propertyManagerContract.js +171 -171
- package/src/models/propertyManagerRevenue.js +100 -100
- package/src/models/purchase_order.js +202 -202
- package/src/models/purchase_request.js +110 -110
- package/src/models/refresh_token.js +23 -23
- package/src/models/reminder.js +197 -197
- package/src/models/report.js +13 -13
- package/src/models/resident.js +121 -121
- package/src/models/rfq_details.js +131 -131
- package/src/models/rfq_response.js +110 -110
- package/src/models/service_charge_invoice_upload.js +42 -42
- package/src/models/service_charge_payments.js +27 -27
- package/src/models/servicerequest.js +55 -55
- package/src/models/settings.js +62 -62
- package/src/models/smart_meter_daily_consumption.js +44 -44
- package/src/models/sms_africastalking.js +20 -20
- package/src/models/sms_meliora.js +20 -20
- package/src/models/staff.js +36 -36
- package/src/models/stocksandspare.js +34 -34
- package/src/models/suppliers.js +74 -74
- package/src/models/tickets.js +121 -121
- package/src/models/unitManagementTemplate.js +44 -44
- package/src/models/unitasset.js +25 -25
- package/src/models/units.js +112 -112
- package/src/models/user.js +187 -187
- package/src/models/valueaddedservices.js +79 -79
- package/src/models/vas_invoices_upload.js +50 -50
- package/src/models/vas_payments.js +24 -24
- package/src/models/vasinvoice.js +192 -192
- package/src/models/vasvendor.js +57 -57
- package/src/models/visitLog.js +86 -86
- package/src/models/visitor.js +67 -67
- package/src/models/waitlist.js +45 -45
- package/src/models/wallet.js +39 -39
- package/src/models/wallet_transactions.js +50 -50
- package/src/models/water_invoice.js +193 -193
- package/src/models/water_meter_account.js +78 -78
- package/src/models/water_meter_billing.js +58 -58
- package/src/models/water_meter_communication.js +17 -17
- package/src/models/water_meter_communication_logs.js +30 -30
- package/src/models/water_meter_concentrator.js +63 -63
- package/src/models/water_meter_daily_history.js +32 -32
- package/src/models/water_meter_iot_cards.js +34 -34
- package/src/models/water_meter_manufacturer.js +35 -35
- package/src/models/water_meter_monthly_history.js +36 -36
- package/src/models/water_meter_settings.js +114 -114
- package/src/models/water_meter_single_day_history.js +34 -34
- package/src/models/water_meter_size.js +15 -15
- package/src/models/water_meters.js +117 -117
- package/src/models/water_meters_delivery.js +76 -76
- package/src/models/water_prepaid_credit.js +43 -43
- package/src/models/water_prepaid_debit.js +50 -50
- package/src/models/workorder.js +49 -49
package/src/models/penalty.js
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
const mongoose = require("mongoose");
|
|
2
|
-
|
|
3
|
-
const penaltySchema = new mongoose.Schema(
|
|
4
|
-
{
|
|
5
|
-
name: {
|
|
6
|
-
type: String,
|
|
7
|
-
required: true,
|
|
8
|
-
},
|
|
9
|
-
type: {
|
|
10
|
-
type: String,
|
|
11
|
-
required: true,
|
|
12
|
-
enum: ['percentage', 'fixed']
|
|
13
|
-
},
|
|
14
|
-
effectDays: {
|
|
15
|
-
type: Number,
|
|
16
|
-
required: true,
|
|
17
|
-
min: [1, "Effect days must be at least 1"]
|
|
18
|
-
},
|
|
19
|
-
percentage: {
|
|
20
|
-
type: Number,
|
|
21
|
-
required: function () {
|
|
22
|
-
return this.type === 'percentage';
|
|
23
|
-
},
|
|
24
|
-
min: [0, "Percentage must be at least 0"]
|
|
25
|
-
},
|
|
26
|
-
amount: {
|
|
27
|
-
type: Number,
|
|
28
|
-
required: function () {
|
|
29
|
-
return this.type === 'fixed';
|
|
30
|
-
},
|
|
31
|
-
min: [0, "Amount must be a positive number"]
|
|
32
|
-
},
|
|
33
|
-
module: {
|
|
34
|
-
type: String,
|
|
35
|
-
required: true,
|
|
36
|
-
enum: ['levy', 'lease', 'utility']
|
|
37
|
-
},
|
|
38
|
-
moduleId: {
|
|
39
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
40
|
-
required: true,
|
|
41
|
-
refPath: 'module'
|
|
42
|
-
},
|
|
43
|
-
isActive: {
|
|
44
|
-
type: Boolean,
|
|
45
|
-
default: true,
|
|
46
|
-
},
|
|
47
|
-
facilityId: {
|
|
48
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
49
|
-
ref: "Facility",
|
|
50
|
-
required: true,
|
|
51
|
-
index: true
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
timestamps: true,
|
|
56
|
-
indexes: [
|
|
57
|
-
{ facilityId: 1, isActive: 1 },
|
|
58
|
-
{ moduleId: 1, module: 1 },
|
|
59
|
-
{ name: 1, facilityId: 1 }
|
|
60
|
-
]
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
// Add any custom methods or middleware here if needed
|
|
65
|
-
penaltySchema.pre('save', function (next) {
|
|
66
|
-
// Clear the irrelevant field based on penalty type
|
|
67
|
-
if (this.type === 'percentage') {
|
|
68
|
-
this.amount = null;
|
|
69
|
-
} else if (this.type === 'fixed') {
|
|
70
|
-
this.percentage = null;
|
|
71
|
-
}
|
|
72
|
-
next();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const Penalty = mongoose.model("Penalty", penaltySchema);
|
|
76
|
-
|
|
1
|
+
const mongoose = require("mongoose");
|
|
2
|
+
|
|
3
|
+
const penaltySchema = new mongoose.Schema(
|
|
4
|
+
{
|
|
5
|
+
name: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true,
|
|
8
|
+
},
|
|
9
|
+
type: {
|
|
10
|
+
type: String,
|
|
11
|
+
required: true,
|
|
12
|
+
enum: ['percentage', 'fixed']
|
|
13
|
+
},
|
|
14
|
+
effectDays: {
|
|
15
|
+
type: Number,
|
|
16
|
+
required: true,
|
|
17
|
+
min: [1, "Effect days must be at least 1"]
|
|
18
|
+
},
|
|
19
|
+
percentage: {
|
|
20
|
+
type: Number,
|
|
21
|
+
required: function () {
|
|
22
|
+
return this.type === 'percentage';
|
|
23
|
+
},
|
|
24
|
+
min: [0, "Percentage must be at least 0"]
|
|
25
|
+
},
|
|
26
|
+
amount: {
|
|
27
|
+
type: Number,
|
|
28
|
+
required: function () {
|
|
29
|
+
return this.type === 'fixed';
|
|
30
|
+
},
|
|
31
|
+
min: [0, "Amount must be a positive number"]
|
|
32
|
+
},
|
|
33
|
+
module: {
|
|
34
|
+
type: String,
|
|
35
|
+
required: true,
|
|
36
|
+
enum: ['levy', 'lease', 'utility']
|
|
37
|
+
},
|
|
38
|
+
moduleId: {
|
|
39
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
40
|
+
required: true,
|
|
41
|
+
refPath: 'module'
|
|
42
|
+
},
|
|
43
|
+
isActive: {
|
|
44
|
+
type: Boolean,
|
|
45
|
+
default: true,
|
|
46
|
+
},
|
|
47
|
+
facilityId: {
|
|
48
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
49
|
+
ref: "Facility",
|
|
50
|
+
required: true,
|
|
51
|
+
index: true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
timestamps: true,
|
|
56
|
+
indexes: [
|
|
57
|
+
{ facilityId: 1, isActive: 1 },
|
|
58
|
+
{ moduleId: 1, module: 1 },
|
|
59
|
+
{ name: 1, facilityId: 1 }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Add any custom methods or middleware here if needed
|
|
65
|
+
penaltySchema.pre('save', function (next) {
|
|
66
|
+
// Clear the irrelevant field based on penalty type
|
|
67
|
+
if (this.type === 'percentage') {
|
|
68
|
+
this.amount = null;
|
|
69
|
+
} else if (this.type === 'fixed') {
|
|
70
|
+
this.percentage = null;
|
|
71
|
+
}
|
|
72
|
+
next();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const Penalty = mongoose.model("Penalty", penaltySchema);
|
|
76
|
+
|
|
77
77
|
module.exports = Penalty;
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
const mongoose = require("mongoose");
|
|
2
|
-
|
|
3
|
-
const pendingCredentialSchema = new mongoose.Schema({
|
|
4
|
-
userId: {
|
|
5
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
-
ref: 'User',
|
|
7
|
-
required: true
|
|
8
|
-
},
|
|
9
|
-
email: String,
|
|
10
|
-
phoneNumber: String,
|
|
11
|
-
fullName: String,
|
|
12
|
-
userType: String,
|
|
13
|
-
password: String, // Temporary storage of plain password for sending
|
|
14
|
-
facilityId: mongoose.Schema.Types.ObjectId,
|
|
15
|
-
status: {
|
|
16
|
-
type: String,
|
|
17
|
-
enum: ['pending', 'sent', 'failed'],
|
|
18
|
-
default: 'pending'
|
|
19
|
-
},
|
|
20
|
-
retryCount: {
|
|
21
|
-
type: Number,
|
|
22
|
-
default: 0
|
|
23
|
-
},
|
|
24
|
-
createdAt: {
|
|
25
|
-
type: Date,
|
|
26
|
-
default: Date.now,
|
|
27
|
-
expires: '7d' // Auto-delete after 7 days
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const PendingCredential = mongoose.model("PendingCredential", pendingCredentialSchema);
|
|
32
|
-
|
|
1
|
+
const mongoose = require("mongoose");
|
|
2
|
+
|
|
3
|
+
const pendingCredentialSchema = new mongoose.Schema({
|
|
4
|
+
userId: {
|
|
5
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
+
ref: 'User',
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
email: String,
|
|
10
|
+
phoneNumber: String,
|
|
11
|
+
fullName: String,
|
|
12
|
+
userType: String,
|
|
13
|
+
password: String, // Temporary storage of plain password for sending
|
|
14
|
+
facilityId: mongoose.Schema.Types.ObjectId,
|
|
15
|
+
status: {
|
|
16
|
+
type: String,
|
|
17
|
+
enum: ['pending', 'sent', 'failed'],
|
|
18
|
+
default: 'pending'
|
|
19
|
+
},
|
|
20
|
+
retryCount: {
|
|
21
|
+
type: Number,
|
|
22
|
+
default: 0
|
|
23
|
+
},
|
|
24
|
+
createdAt: {
|
|
25
|
+
type: Date,
|
|
26
|
+
default: Date.now,
|
|
27
|
+
expires: '7d' // Auto-delete after 7 days
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const PendingCredential = mongoose.model("PendingCredential", pendingCredentialSchema);
|
|
32
|
+
|
|
33
33
|
module.exports = PendingCredential;
|
|
@@ -1,172 +1,172 @@
|
|
|
1
|
-
const mongoose = require('mongoose');
|
|
2
|
-
const Schema = mongoose.Schema;
|
|
3
|
-
|
|
4
|
-
const PropertyManagerContractSchema = new Schema(
|
|
5
|
-
{
|
|
6
|
-
contractName: {
|
|
7
|
-
type: String,
|
|
8
|
-
required: [true, 'Contract name is required']
|
|
9
|
-
},
|
|
10
|
-
propertyManager: {
|
|
11
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
12
|
-
ref: 'User',
|
|
13
|
-
required: [true, 'Property manager is required']
|
|
14
|
-
},
|
|
15
|
-
units: [{
|
|
16
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
17
|
-
ref: 'Unit',
|
|
18
|
-
required: [true, 'At least one unit is required']
|
|
19
|
-
}],
|
|
20
|
-
customerId: {
|
|
21
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
22
|
-
ref: 'Customer',
|
|
23
|
-
required: [true, 'Customer ID is required']
|
|
24
|
-
},
|
|
25
|
-
facilityId: {
|
|
26
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
27
|
-
ref: 'Facility',
|
|
28
|
-
required: [true, 'Facility ID is required']
|
|
29
|
-
},
|
|
30
|
-
// Lease term details
|
|
31
|
-
startDate: {
|
|
32
|
-
type: Date,
|
|
33
|
-
required: function() {
|
|
34
|
-
return this.status === 'Active';
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
endDate: {
|
|
38
|
-
type: Date,
|
|
39
|
-
required: function() {
|
|
40
|
-
return this.status === 'Active';
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
// Payment details - aligned with LeaseAgreement
|
|
44
|
-
paymentDueDate: {
|
|
45
|
-
type: Number,
|
|
46
|
-
required: function() {
|
|
47
|
-
return this.status === 'Active';
|
|
48
|
-
},
|
|
49
|
-
min: [1, 'Payment due date must be between 1 and 31'],
|
|
50
|
-
max: [31, 'Payment due date must be between 1 and 31']
|
|
51
|
-
},
|
|
52
|
-
frequency: {
|
|
53
|
-
type: String,
|
|
54
|
-
enum: ['Monthly', 'Quarterly', 'Annually'],
|
|
55
|
-
default: 'Monthly',
|
|
56
|
-
required: function() {
|
|
57
|
-
return this.status === 'Active';
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
nextInvoiceDate: {
|
|
61
|
-
type: Date
|
|
62
|
-
},
|
|
63
|
-
lastInvoiceDate: {
|
|
64
|
-
type: Date
|
|
65
|
-
},
|
|
66
|
-
autoSend: {
|
|
67
|
-
type: Boolean,
|
|
68
|
-
default: false
|
|
69
|
-
},
|
|
70
|
-
balanceBroughtForward: {
|
|
71
|
-
type: Number,
|
|
72
|
-
default: 0
|
|
73
|
-
},
|
|
74
|
-
// Management fee
|
|
75
|
-
managementFee: {
|
|
76
|
-
type: {
|
|
77
|
-
type: String,
|
|
78
|
-
enum: ['percentage', 'amount'],
|
|
79
|
-
required: [true, 'Management fee type is required']
|
|
80
|
-
},
|
|
81
|
-
value: {
|
|
82
|
-
type: Number,
|
|
83
|
-
required: [true, 'Management fee value is required'],
|
|
84
|
-
min: [0, 'Management fee value cannot be negative']
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
// GL Account configurations
|
|
88
|
-
invoiceDoubleEntryAccount: {
|
|
89
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
90
|
-
ref: 'GLAccountDoubleEntries'
|
|
91
|
-
},
|
|
92
|
-
paymentDoubleEntryAccount: {
|
|
93
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
94
|
-
ref: 'GLAccountDoubleEntries'
|
|
95
|
-
},
|
|
96
|
-
glAccounts: {
|
|
97
|
-
invoice: {
|
|
98
|
-
debit: {
|
|
99
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
100
|
-
ref: 'GLAccount'
|
|
101
|
-
},
|
|
102
|
-
credit: {
|
|
103
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
104
|
-
ref: 'GLAccount'
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
payment: {
|
|
108
|
-
debit: {
|
|
109
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
110
|
-
ref: 'GLAccount'
|
|
111
|
-
},
|
|
112
|
-
credit: {
|
|
113
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
114
|
-
ref: 'GLAccount'
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
status: {
|
|
119
|
-
type: String,
|
|
120
|
-
enum: ['Active', 'Inactive', 'Completed', 'Suspended', 'Terminated'],
|
|
121
|
-
default: 'Inactive',
|
|
122
|
-
required: [true, 'Status is required']
|
|
123
|
-
},
|
|
124
|
-
createdBy: {
|
|
125
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
126
|
-
ref: 'User'
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
timestamps: true
|
|
131
|
-
}
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
// Basic validation
|
|
135
|
-
PropertyManagerContractSchema.pre('save', function (next) {
|
|
136
|
-
if (this.startDate && this.endDate && this.startDate >= this.endDate) {
|
|
137
|
-
next(new Error('End date must be after start date'));
|
|
138
|
-
} else if (!this.units || this.units.length === 0) {
|
|
139
|
-
next(new Error('At least one unit must be specified'));
|
|
140
|
-
} else if (this.managementFee.type === 'percentage' && this.managementFee.value > 100) {
|
|
141
|
-
next(new Error('Management fee percentage cannot exceed 100%'));
|
|
142
|
-
} else {
|
|
143
|
-
next();
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Sync with lease data
|
|
148
|
-
PropertyManagerContractSchema.methods.syncWithLeaseData = async function(leaseData) {
|
|
149
|
-
if (!leaseData) return;
|
|
150
|
-
|
|
151
|
-
this.startDate = leaseData.leaseTerms?.startDate || this.startDate;
|
|
152
|
-
this.endDate = leaseData.leaseTerms?.endDate || this.endDate;
|
|
153
|
-
this.paymentDueDate = leaseData.financialTerms?.paymentDueDate || this.paymentDueDate;
|
|
154
|
-
this.balanceBroughtForward = leaseData.financialTerms?.balanceBroughtForward || this.balanceBroughtForward;
|
|
155
|
-
this.frequency = leaseData.billingCycle?.frequency || this.frequency;
|
|
156
|
-
this.autoSend = leaseData.billingCycle?.autoSend !== undefined ? leaseData.billingCycle.autoSend : this.autoSend;
|
|
157
|
-
this.nextInvoiceDate = leaseData.billingCycle?.nextInvoiceDate || this.nextInvoiceDate;
|
|
158
|
-
this.lastInvoiceDate = leaseData.billingCycle?.lastInvoiceDate || this.lastInvoiceDate;
|
|
159
|
-
|
|
160
|
-
return this.save();
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// Basic indexes
|
|
164
|
-
PropertyManagerContractSchema.index({ customerId: 1, status: 1 });
|
|
165
|
-
PropertyManagerContractSchema.index({ facilityId: 1 });
|
|
166
|
-
PropertyManagerContractSchema.index({ propertyManager: 1 });
|
|
167
|
-
PropertyManagerContractSchema.index({ nextInvoiceDate: 1, status: 1 });
|
|
168
|
-
|
|
169
|
-
module.exports = {
|
|
170
|
-
schema: PropertyManagerContractSchema,
|
|
171
|
-
name: 'PropertyManagerContract'
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
const Schema = mongoose.Schema;
|
|
3
|
+
|
|
4
|
+
const PropertyManagerContractSchema = new Schema(
|
|
5
|
+
{
|
|
6
|
+
contractName: {
|
|
7
|
+
type: String,
|
|
8
|
+
required: [true, 'Contract name is required']
|
|
9
|
+
},
|
|
10
|
+
propertyManager: {
|
|
11
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
12
|
+
ref: 'User',
|
|
13
|
+
required: [true, 'Property manager is required']
|
|
14
|
+
},
|
|
15
|
+
units: [{
|
|
16
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
17
|
+
ref: 'Unit',
|
|
18
|
+
required: [true, 'At least one unit is required']
|
|
19
|
+
}],
|
|
20
|
+
customerId: {
|
|
21
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
22
|
+
ref: 'Customer',
|
|
23
|
+
required: [true, 'Customer ID is required']
|
|
24
|
+
},
|
|
25
|
+
facilityId: {
|
|
26
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
27
|
+
ref: 'Facility',
|
|
28
|
+
required: [true, 'Facility ID is required']
|
|
29
|
+
},
|
|
30
|
+
// Lease term details
|
|
31
|
+
startDate: {
|
|
32
|
+
type: Date,
|
|
33
|
+
required: function() {
|
|
34
|
+
return this.status === 'Active';
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
endDate: {
|
|
38
|
+
type: Date,
|
|
39
|
+
required: function() {
|
|
40
|
+
return this.status === 'Active';
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
// Payment details - aligned with LeaseAgreement
|
|
44
|
+
paymentDueDate: {
|
|
45
|
+
type: Number,
|
|
46
|
+
required: function() {
|
|
47
|
+
return this.status === 'Active';
|
|
48
|
+
},
|
|
49
|
+
min: [1, 'Payment due date must be between 1 and 31'],
|
|
50
|
+
max: [31, 'Payment due date must be between 1 and 31']
|
|
51
|
+
},
|
|
52
|
+
frequency: {
|
|
53
|
+
type: String,
|
|
54
|
+
enum: ['Monthly', 'Quarterly', 'Annually'],
|
|
55
|
+
default: 'Monthly',
|
|
56
|
+
required: function() {
|
|
57
|
+
return this.status === 'Active';
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
nextInvoiceDate: {
|
|
61
|
+
type: Date
|
|
62
|
+
},
|
|
63
|
+
lastInvoiceDate: {
|
|
64
|
+
type: Date
|
|
65
|
+
},
|
|
66
|
+
autoSend: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
default: false
|
|
69
|
+
},
|
|
70
|
+
balanceBroughtForward: {
|
|
71
|
+
type: Number,
|
|
72
|
+
default: 0
|
|
73
|
+
},
|
|
74
|
+
// Management fee
|
|
75
|
+
managementFee: {
|
|
76
|
+
type: {
|
|
77
|
+
type: String,
|
|
78
|
+
enum: ['percentage', 'amount'],
|
|
79
|
+
required: [true, 'Management fee type is required']
|
|
80
|
+
},
|
|
81
|
+
value: {
|
|
82
|
+
type: Number,
|
|
83
|
+
required: [true, 'Management fee value is required'],
|
|
84
|
+
min: [0, 'Management fee value cannot be negative']
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
// GL Account configurations
|
|
88
|
+
invoiceDoubleEntryAccount: {
|
|
89
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
90
|
+
ref: 'GLAccountDoubleEntries'
|
|
91
|
+
},
|
|
92
|
+
paymentDoubleEntryAccount: {
|
|
93
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
94
|
+
ref: 'GLAccountDoubleEntries'
|
|
95
|
+
},
|
|
96
|
+
glAccounts: {
|
|
97
|
+
invoice: {
|
|
98
|
+
debit: {
|
|
99
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
100
|
+
ref: 'GLAccount'
|
|
101
|
+
},
|
|
102
|
+
credit: {
|
|
103
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
104
|
+
ref: 'GLAccount'
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
payment: {
|
|
108
|
+
debit: {
|
|
109
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
110
|
+
ref: 'GLAccount'
|
|
111
|
+
},
|
|
112
|
+
credit: {
|
|
113
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
114
|
+
ref: 'GLAccount'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
status: {
|
|
119
|
+
type: String,
|
|
120
|
+
enum: ['Active', 'Inactive', 'Completed', 'Suspended', 'Terminated'],
|
|
121
|
+
default: 'Inactive',
|
|
122
|
+
required: [true, 'Status is required']
|
|
123
|
+
},
|
|
124
|
+
createdBy: {
|
|
125
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
126
|
+
ref: 'User'
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
timestamps: true
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Basic validation
|
|
135
|
+
PropertyManagerContractSchema.pre('save', function (next) {
|
|
136
|
+
if (this.startDate && this.endDate && this.startDate >= this.endDate) {
|
|
137
|
+
next(new Error('End date must be after start date'));
|
|
138
|
+
} else if (!this.units || this.units.length === 0) {
|
|
139
|
+
next(new Error('At least one unit must be specified'));
|
|
140
|
+
} else if (this.managementFee.type === 'percentage' && this.managementFee.value > 100) {
|
|
141
|
+
next(new Error('Management fee percentage cannot exceed 100%'));
|
|
142
|
+
} else {
|
|
143
|
+
next();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Sync with lease data
|
|
148
|
+
PropertyManagerContractSchema.methods.syncWithLeaseData = async function(leaseData) {
|
|
149
|
+
if (!leaseData) return;
|
|
150
|
+
|
|
151
|
+
this.startDate = leaseData.leaseTerms?.startDate || this.startDate;
|
|
152
|
+
this.endDate = leaseData.leaseTerms?.endDate || this.endDate;
|
|
153
|
+
this.paymentDueDate = leaseData.financialTerms?.paymentDueDate || this.paymentDueDate;
|
|
154
|
+
this.balanceBroughtForward = leaseData.financialTerms?.balanceBroughtForward || this.balanceBroughtForward;
|
|
155
|
+
this.frequency = leaseData.billingCycle?.frequency || this.frequency;
|
|
156
|
+
this.autoSend = leaseData.billingCycle?.autoSend !== undefined ? leaseData.billingCycle.autoSend : this.autoSend;
|
|
157
|
+
this.nextInvoiceDate = leaseData.billingCycle?.nextInvoiceDate || this.nextInvoiceDate;
|
|
158
|
+
this.lastInvoiceDate = leaseData.billingCycle?.lastInvoiceDate || this.lastInvoiceDate;
|
|
159
|
+
|
|
160
|
+
return this.save();
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Basic indexes
|
|
164
|
+
PropertyManagerContractSchema.index({ customerId: 1, status: 1 });
|
|
165
|
+
PropertyManagerContractSchema.index({ facilityId: 1 });
|
|
166
|
+
PropertyManagerContractSchema.index({ propertyManager: 1 });
|
|
167
|
+
PropertyManagerContractSchema.index({ nextInvoiceDate: 1, status: 1 });
|
|
168
|
+
|
|
169
|
+
module.exports = {
|
|
170
|
+
schema: PropertyManagerContractSchema,
|
|
171
|
+
name: 'PropertyManagerContract'
|
|
172
172
|
};
|