@dynamatix/gb-schemas 2.3.392 → 2.3.394
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.
|
@@ -1,155 +1,148 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
import { applyWorkflowPlugin } from "../shared/workflow.plugin";
|
|
3
|
-
import { SortCode } from '../value-objects/sort-code';
|
|
4
|
-
import { AccountNumber } from "../value-objects/account-number";
|
|
5
|
-
import { applyAuditMiddleware } from "@dynamatix/cat-shared/middlewares";
|
|
6
|
-
const applicationDirectDebitSchema = new mongoose.Schema({
|
|
7
|
-
applicationId: {
|
|
8
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
9
|
-
ref: 'Application',
|
|
10
|
-
description: 'Reference to the application this direct debit belongs to',
|
|
11
|
-
},
|
|
12
|
-
pageValidFlag: { type: Boolean, default: false },
|
|
13
|
-
primaryApplicantId: {
|
|
14
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
15
|
-
ref: 'Applicant',
|
|
16
|
-
description: 'Reference to the primary applicant',
|
|
17
|
-
},
|
|
18
|
-
accountNumber: {
|
|
19
|
-
type: AccountNumber,
|
|
20
|
-
isRequired: true,
|
|
21
|
-
maxLength: 8,
|
|
22
|
-
description: 'Bank account number of the applicant',
|
|
23
|
-
},
|
|
24
|
-
addressLine1: {
|
|
25
|
-
type: String,
|
|
26
|
-
description: 'First line of the applicant’s address'
|
|
27
|
-
},
|
|
28
|
-
addressLine2: {
|
|
29
|
-
type: String,
|
|
30
|
-
description: 'Second line of the applicant’s address'
|
|
31
|
-
},
|
|
32
|
-
applicantId: {
|
|
33
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
34
|
-
ref: 'Applicant',
|
|
35
|
-
description: 'List of applicant IDs associated with this direct debit',
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
type:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
type: String,
|
|
44
|
-
description: '
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
type: String,
|
|
53
|
-
description: '
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
type:
|
|
58
|
-
description: '
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
type:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
type:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
type:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
default:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
type: String,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Index for applicationId queries
|
|
150
|
-
applicationDirectDebitSchema.index({ applicationId: 1 });
|
|
151
|
-
applyAuditMiddleware(applicationDirectDebitSchema, "application_directdebit");
|
|
152
|
-
// Apply workflow plugin to the schema
|
|
153
|
-
applyWorkflowPlugin(applicationDirectDebitSchema, 'application_directdebit');
|
|
154
|
-
const ApplicationDirectDebitModel = mongoose.model("Application_DirectDebit", applicationDirectDebitSchema);
|
|
155
|
-
export default ApplicationDirectDebitModel;
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
import { applyWorkflowPlugin } from "../shared/workflow.plugin";
|
|
3
|
+
import { SortCode } from '../value-objects/sort-code';
|
|
4
|
+
import { AccountNumber } from "../value-objects/account-number";
|
|
5
|
+
import { applyAuditMiddleware } from "@dynamatix/cat-shared/middlewares";
|
|
6
|
+
const applicationDirectDebitSchema = new mongoose.Schema({
|
|
7
|
+
applicationId: {
|
|
8
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
9
|
+
ref: 'Application',
|
|
10
|
+
description: 'Reference to the application this direct debit belongs to',
|
|
11
|
+
},
|
|
12
|
+
pageValidFlag: { type: Boolean, default: false },
|
|
13
|
+
primaryApplicantId: {
|
|
14
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
15
|
+
ref: 'Applicant',
|
|
16
|
+
description: 'Reference to the primary applicant',
|
|
17
|
+
},
|
|
18
|
+
accountNumber: {
|
|
19
|
+
type: AccountNumber,
|
|
20
|
+
isRequired: true,
|
|
21
|
+
maxLength: 8,
|
|
22
|
+
description: 'Bank account number of the applicant',
|
|
23
|
+
},
|
|
24
|
+
addressLine1: {
|
|
25
|
+
type: String,
|
|
26
|
+
description: 'First line of the applicant’s address'
|
|
27
|
+
},
|
|
28
|
+
addressLine2: {
|
|
29
|
+
type: String,
|
|
30
|
+
description: 'Second line of the applicant’s address'
|
|
31
|
+
},
|
|
32
|
+
applicantId: {
|
|
33
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
34
|
+
ref: 'Applicant',
|
|
35
|
+
description: 'List of applicant IDs associated with this direct debit',
|
|
36
|
+
},
|
|
37
|
+
branch: {
|
|
38
|
+
type: String,
|
|
39
|
+
description: 'Branch name or code of the bank',
|
|
40
|
+
required: true
|
|
41
|
+
},
|
|
42
|
+
city: {
|
|
43
|
+
type: String,
|
|
44
|
+
description: 'City of the applicant’s address',
|
|
45
|
+
},
|
|
46
|
+
contactPostcode: {
|
|
47
|
+
type: String,
|
|
48
|
+
description: 'Postcode for correspondence',
|
|
49
|
+
requird: true
|
|
50
|
+
},
|
|
51
|
+
institution: {
|
|
52
|
+
type: String,
|
|
53
|
+
description: 'Name of the financial institution',
|
|
54
|
+
required: true,
|
|
55
|
+
},
|
|
56
|
+
isConfirmDeclaration: {
|
|
57
|
+
type: Boolean,
|
|
58
|
+
description: 'Whether the applicant has confirmed the declaration'
|
|
59
|
+
},
|
|
60
|
+
nameOfAccountHolder: {
|
|
61
|
+
type: String,
|
|
62
|
+
description: 'Full name of the bank account holder',
|
|
63
|
+
required: true,
|
|
64
|
+
},
|
|
65
|
+
selectedPaymentDayLid: {
|
|
66
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
67
|
+
ref: 'Lookup',
|
|
68
|
+
description: 'Lookup reference for selected payment day',
|
|
69
|
+
},
|
|
70
|
+
sortCode: {
|
|
71
|
+
type: SortCode,
|
|
72
|
+
description: 'UK bank sort code in XX-XX-XX format',
|
|
73
|
+
required: true,
|
|
74
|
+
},
|
|
75
|
+
accountErrorLid: {
|
|
76
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
77
|
+
ref: 'Lookup',
|
|
78
|
+
default: null,
|
|
79
|
+
description: 'Lookup reference for account error status for algbra',
|
|
80
|
+
},
|
|
81
|
+
accountStatusLid: {
|
|
82
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
83
|
+
ref: 'Lookup',
|
|
84
|
+
default: null,
|
|
85
|
+
description: 'Lookup reference for account status for algbra',
|
|
86
|
+
},
|
|
87
|
+
bankAccountRequired: {
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: false,
|
|
90
|
+
},
|
|
91
|
+
accountErrorMessage: {
|
|
92
|
+
type: String,
|
|
93
|
+
default: "",
|
|
94
|
+
description: 'Error message for the account error for algbra',
|
|
95
|
+
},
|
|
96
|
+
bankWizardCheck: {
|
|
97
|
+
nameAndDobMatch: { type: String },
|
|
98
|
+
addressMatch: { type: String },
|
|
99
|
+
ddCapable: { type: String },
|
|
100
|
+
validation: { type: String },
|
|
101
|
+
status: { type: String },
|
|
102
|
+
failedMessage: { type: String },
|
|
103
|
+
overrideReason: { type: String, default: "" },
|
|
104
|
+
nameAddressOverride: {
|
|
105
|
+
firstName: { type: String },
|
|
106
|
+
middleName: { type: String },
|
|
107
|
+
lastName: { type: String },
|
|
108
|
+
buildingName: { type: String },
|
|
109
|
+
buildingNumber: { type: String },
|
|
110
|
+
street: { type: String },
|
|
111
|
+
addressLine2: { type: String },
|
|
112
|
+
city: { type: String },
|
|
113
|
+
country: { type: String },
|
|
114
|
+
postcode: { type: String }
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
}, {
|
|
118
|
+
timestamps: true,
|
|
119
|
+
toJSON: { virtuals: true, getters: true },
|
|
120
|
+
toObject: { virtuals: true, getters: true }
|
|
121
|
+
});
|
|
122
|
+
const virtualselectedPaymentDay = applicationDirectDebitSchema.virtual('selectedPaymentDay', {
|
|
123
|
+
ref: 'Lookup',
|
|
124
|
+
localField: 'selectedPaymentDayLid',
|
|
125
|
+
foreignField: '_id',
|
|
126
|
+
justOne: true,
|
|
127
|
+
options: {
|
|
128
|
+
select: 'label' // Only fetch the 'label' field from the Lookup collection
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
virtualselectedPaymentDay.description = 'Populated lookup value for the selected payment day';
|
|
132
|
+
const virtualApplicants = applicationDirectDebitSchema.virtual('applicants', {
|
|
133
|
+
ref: 'Applicant',
|
|
134
|
+
localField: 'applicantId',
|
|
135
|
+
foreignField: '_id',
|
|
136
|
+
justOne: true,
|
|
137
|
+
options: {
|
|
138
|
+
select: 'fullName'
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
virtualApplicants.description = 'Full Name of the applicant';
|
|
142
|
+
// Index for applicationId queries
|
|
143
|
+
applicationDirectDebitSchema.index({ applicationId: 1 });
|
|
144
|
+
applyAuditMiddleware(applicationDirectDebitSchema, "application_directdebit");
|
|
145
|
+
// Apply workflow plugin to the schema
|
|
146
|
+
applyWorkflowPlugin(applicationDirectDebitSchema, 'application_directdebit');
|
|
147
|
+
const ApplicationDirectDebitModel = mongoose.model("Application_DirectDebit", applicationDirectDebitSchema);
|
|
148
|
+
export default ApplicationDirectDebitModel;
|
|
@@ -115,12 +115,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
115
115
|
lastUpdated?: string | null | undefined;
|
|
116
116
|
submittedDate?: string | null | undefined;
|
|
117
117
|
riskNarrative?: {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
119
|
+
call1RequestedOn: string;
|
|
120
|
+
call2RequestedOn: string;
|
|
121
|
+
retryCount: string;
|
|
122
|
+
riskRating: string;
|
|
123
|
+
statusLid: mongoose.Types.ObjectId;
|
|
124
124
|
} | null | undefined;
|
|
125
125
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
126
126
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -212,12 +212,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
212
212
|
lastUpdated?: string | null | undefined;
|
|
213
213
|
submittedDate?: string | null | undefined;
|
|
214
214
|
riskNarrative?: {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
215
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
216
|
+
call1RequestedOn: string;
|
|
217
|
+
call2RequestedOn: string;
|
|
218
|
+
retryCount: string;
|
|
219
|
+
riskRating: string;
|
|
220
|
+
statusLid: mongoose.Types.ObjectId;
|
|
221
221
|
} | null | undefined;
|
|
222
222
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
223
223
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -309,12 +309,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
309
309
|
lastUpdated?: string | null | undefined;
|
|
310
310
|
submittedDate?: string | null | undefined;
|
|
311
311
|
riskNarrative?: {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
312
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
313
|
+
call1RequestedOn: string;
|
|
314
|
+
call2RequestedOn: string;
|
|
315
|
+
retryCount: string;
|
|
316
|
+
riskRating: string;
|
|
317
|
+
statusLid: mongoose.Types.ObjectId;
|
|
318
318
|
} | null | undefined;
|
|
319
319
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
320
320
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -418,12 +418,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
418
418
|
lastUpdated?: string | null | undefined;
|
|
419
419
|
submittedDate?: string | null | undefined;
|
|
420
420
|
riskNarrative?: {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
421
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
422
|
+
call1RequestedOn: string;
|
|
423
|
+
call2RequestedOn: string;
|
|
424
|
+
retryCount: string;
|
|
425
|
+
riskRating: string;
|
|
426
|
+
statusLid: mongoose.Types.ObjectId;
|
|
427
427
|
} | null | undefined;
|
|
428
428
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
429
429
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -515,12 +515,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
515
515
|
lastUpdated?: string | null | undefined;
|
|
516
516
|
submittedDate?: string | null | undefined;
|
|
517
517
|
riskNarrative?: {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
518
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
519
|
+
call1RequestedOn: string;
|
|
520
|
+
call2RequestedOn: string;
|
|
521
|
+
retryCount: string;
|
|
522
|
+
riskRating: string;
|
|
523
|
+
statusLid: mongoose.Types.ObjectId;
|
|
524
524
|
} | null | undefined;
|
|
525
525
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
526
526
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -612,12 +612,12 @@ declare const ApplicationModel: mongoose.Model<{
|
|
|
612
612
|
lastUpdated?: string | null | undefined;
|
|
613
613
|
submittedDate?: string | null | undefined;
|
|
614
614
|
riskNarrative?: {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
615
|
+
call2StatusLid: mongoose.Types.ObjectId;
|
|
616
|
+
call1RequestedOn: string;
|
|
617
|
+
call2RequestedOn: string;
|
|
618
|
+
retryCount: string;
|
|
619
|
+
riskRating: string;
|
|
620
|
+
statusLid: mongoose.Types.ObjectId;
|
|
621
621
|
} | null | undefined;
|
|
622
622
|
valuationId?: mongoose.Types.ObjectId | null | undefined;
|
|
623
623
|
valuationReportId?: mongoose.Types.ObjectId | null | undefined;
|
|
@@ -1,246 +1,238 @@
|
|
|
1
|
-
import mongoose from "mongoose";
|
|
2
|
-
import { applyAuditMiddleware } from "@dynamatix/cat-shared/middlewares";
|
|
3
|
-
import creditProfileSchema from "./application-credit-profile.model";
|
|
4
|
-
import { applyWorkflowPlugin } from "../shared/workflow.plugin";
|
|
5
|
-
const applicationSchema = new mongoose.Schema({
|
|
6
|
-
queueId: [{
|
|
7
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
8
|
-
ref: "Queue",
|
|
9
|
-
default: null,
|
|
10
|
-
}],
|
|
11
|
-
underwriterReviewDate: { type: Date, default: null },
|
|
12
|
-
assignedToUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
13
|
-
assignedToUserDate: { type: Date, default: null },
|
|
14
|
-
firstAssignedToUserDate: { type: Date, default: null },
|
|
15
|
-
slaClockStart: { type: Date, default: null },
|
|
16
|
-
slaClockStop: { type: Date, default: null },
|
|
17
|
-
applicationId: { type: String, required: true },
|
|
18
|
-
isApplicationFeePaid: { type: String, required: true },
|
|
19
|
-
applicationNumber: { type: String, required: true },
|
|
20
|
-
applicationTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
21
|
-
bankSolicitor: { type: String, default: "" },
|
|
22
|
-
brokerId: { type: mongoose.Schema.Types.ObjectId, ref: "Broker", default: null },
|
|
23
|
-
caseManager: { type: String, default: "" },
|
|
24
|
-
caseManagerAccepted: { type: String, default: false },
|
|
25
|
-
completedReason: { type: String, default: "" },
|
|
26
|
-
isIntendToOccupy: { type: String, required: true },
|
|
27
|
-
introducer: { type: String, default: "" },
|
|
28
|
-
isIntroducerSubmission: { type: String, required: true },
|
|
29
|
-
isBrokerAssigned: { type: String, default: false },
|
|
30
|
-
isFinanceRecommendedToApplicant: { type: String, required: true },
|
|
31
|
-
isWorkflowTaskCreated: { type: String, required: true },
|
|
32
|
-
lastUpdated: { type: String },
|
|
33
|
-
lendingTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
34
|
-
networkClubName: { type: String, default: "" },
|
|
35
|
-
isNetworkClubSubmission: { type: String, required: true },
|
|
36
|
-
newReason: { type: String, default: "" },
|
|
37
|
-
purchaseTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
38
|
-
rejectedReason: { type: String, default: "" },
|
|
39
|
-
repaymentTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
40
|
-
selectedProduct: { type: String, required: false },
|
|
41
|
-
statusLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
42
|
-
submitReason: { type: String, default: "" },
|
|
43
|
-
submittedDate: { type: String },
|
|
44
|
-
underwriter: { type: String, default: "" },
|
|
45
|
-
isValuationFeePaid: { type: String, required: true },
|
|
46
|
-
withdrawalReasonLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
47
|
-
declineReasonLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
48
|
-
isPortfolioConfirmed: { type: Boolean, default: false },
|
|
49
|
-
productId: { type: mongoose.Schema.Types.ObjectId, ref: "Product", default: null },
|
|
50
|
-
product: { type: String },
|
|
51
|
-
securityId: { type: mongoose.Schema.Types.ObjectId, ref: "Security", default: null },
|
|
52
|
-
solicitorId: { type: mongoose.Schema.Types.ObjectId, ref: "Solicitor", default: null },
|
|
53
|
-
riskNarrativeId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationRiskNarrative", default: null },
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
type: Number,
|
|
91
|
-
default: 0
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
type:
|
|
95
|
-
default:
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
type:
|
|
99
|
-
default:
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
//
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
});
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
applicationSchema.index({
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
applicationSchema.index({ applicants: 1 }); // For array membership queries
|
|
240
|
-
// Compound indexes for common query combinations
|
|
241
|
-
applicationSchema.index({ applicants: 1, _id: 1 }); // For finding application by applicant
|
|
242
|
-
applicationSchema.index({ assignedToUserId: 1, statusLid: 1 }); // For filtering by assignee and status
|
|
243
|
-
// Text index for search functionality
|
|
244
|
-
applicationSchema.index({ applicationNumber: "text" });
|
|
245
|
-
const ApplicationModel = mongoose.model("Application", applicationSchema);
|
|
246
|
-
export default ApplicationModel;
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
import { applyAuditMiddleware } from "@dynamatix/cat-shared/middlewares";
|
|
3
|
+
import creditProfileSchema from "./application-credit-profile.model";
|
|
4
|
+
import { applyWorkflowPlugin } from "../shared/workflow.plugin";
|
|
5
|
+
const applicationSchema = new mongoose.Schema({
|
|
6
|
+
queueId: [{
|
|
7
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
8
|
+
ref: "Queue",
|
|
9
|
+
default: null,
|
|
10
|
+
}],
|
|
11
|
+
underwriterReviewDate: { type: Date, default: null },
|
|
12
|
+
assignedToUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
13
|
+
assignedToUserDate: { type: Date, default: null },
|
|
14
|
+
firstAssignedToUserDate: { type: Date, default: null },
|
|
15
|
+
slaClockStart: { type: Date, default: null },
|
|
16
|
+
slaClockStop: { type: Date, default: null },
|
|
17
|
+
applicationId: { type: String, required: true },
|
|
18
|
+
isApplicationFeePaid: { type: String, required: true },
|
|
19
|
+
applicationNumber: { type: String, required: true },
|
|
20
|
+
applicationTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
21
|
+
bankSolicitor: { type: String, default: "" },
|
|
22
|
+
brokerId: { type: mongoose.Schema.Types.ObjectId, ref: "Broker", default: null },
|
|
23
|
+
caseManager: { type: String, default: "" },
|
|
24
|
+
caseManagerAccepted: { type: String, default: false },
|
|
25
|
+
completedReason: { type: String, default: "" },
|
|
26
|
+
isIntendToOccupy: { type: String, required: true },
|
|
27
|
+
introducer: { type: String, default: "" },
|
|
28
|
+
isIntroducerSubmission: { type: String, required: true },
|
|
29
|
+
isBrokerAssigned: { type: String, default: false },
|
|
30
|
+
isFinanceRecommendedToApplicant: { type: String, required: true },
|
|
31
|
+
isWorkflowTaskCreated: { type: String, required: true },
|
|
32
|
+
lastUpdated: { type: String },
|
|
33
|
+
lendingTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
34
|
+
networkClubName: { type: String, default: "" },
|
|
35
|
+
isNetworkClubSubmission: { type: String, required: true },
|
|
36
|
+
newReason: { type: String, default: "" },
|
|
37
|
+
purchaseTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
38
|
+
rejectedReason: { type: String, default: "" },
|
|
39
|
+
repaymentTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
40
|
+
selectedProduct: { type: String, required: false },
|
|
41
|
+
statusLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
42
|
+
submitReason: { type: String, default: "" },
|
|
43
|
+
submittedDate: { type: String },
|
|
44
|
+
underwriter: { type: String, default: "" },
|
|
45
|
+
isValuationFeePaid: { type: String, required: true },
|
|
46
|
+
withdrawalReasonLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
47
|
+
declineReasonLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
48
|
+
isPortfolioConfirmed: { type: Boolean, default: false },
|
|
49
|
+
productId: { type: mongoose.Schema.Types.ObjectId, ref: "Product", default: null },
|
|
50
|
+
product: { type: String },
|
|
51
|
+
securityId: { type: mongoose.Schema.Types.ObjectId, ref: "Security", default: null },
|
|
52
|
+
solicitorId: { type: mongoose.Schema.Types.ObjectId, ref: "Solicitor", default: null },
|
|
53
|
+
riskNarrativeId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationRiskNarrative", default: null },
|
|
54
|
+
applicants: [
|
|
55
|
+
{ type: mongoose.Schema.Types.ObjectId, ref: "Applicant", default: null }
|
|
56
|
+
],
|
|
57
|
+
isActive: { type: String, default: false },
|
|
58
|
+
riskRating: { type: String },
|
|
59
|
+
directDebitId: { type: mongoose.Schema.Types.ObjectId, ref: "Application_DirectDebit", default: null },
|
|
60
|
+
creditProfile: creditProfileSchema,
|
|
61
|
+
mortgageId: { type: mongoose.Schema.Types.ObjectId, ref: "Mortgage", default: null },
|
|
62
|
+
companyId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationCompany", default: null },
|
|
63
|
+
offerId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationOffer", default: null },
|
|
64
|
+
newAuditRecordsCount: { type: Number, default: 0 }, // Ensure it is a Number
|
|
65
|
+
currentApprivoAuditId: Number,
|
|
66
|
+
propertyIds: [{ type: mongoose.Schema.Types.ObjectId, ref: "Property" }],
|
|
67
|
+
valuationId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationValuation" },
|
|
68
|
+
valuationReportId: { type: mongoose.Schema.Types.ObjectId, ref: "ApplicationValuationReport" },
|
|
69
|
+
isMandateRequested: { type: Boolean, default: false },
|
|
70
|
+
isMandateApproved: { type: Boolean, default: null },
|
|
71
|
+
mandateReviewComments: { type: String, default: "" },
|
|
72
|
+
mandateRequestedByUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
73
|
+
mandateRequestedDate: { type: Date, default: null },
|
|
74
|
+
mandateReviewedByUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
75
|
+
mandateReviewedDate: { type: Date, default: null },
|
|
76
|
+
isReferred: { type: Boolean, default: false },
|
|
77
|
+
referredByUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
78
|
+
referredDate: { type: Date, default: null },
|
|
79
|
+
referralClearedByUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null },
|
|
80
|
+
referralClearedDate: { type: Date, default: null },
|
|
81
|
+
brokerTaskCount: {
|
|
82
|
+
type: Number,
|
|
83
|
+
default: 0
|
|
84
|
+
},
|
|
85
|
+
lenderTaskCount: {
|
|
86
|
+
type: Number,
|
|
87
|
+
default: 0
|
|
88
|
+
},
|
|
89
|
+
pendingTaskCountForUser: {
|
|
90
|
+
type: Number,
|
|
91
|
+
default: 0
|
|
92
|
+
},
|
|
93
|
+
applicationFormSignedDate: {
|
|
94
|
+
type: Date, // Stores as ISODate in MongoDB (e.g., "2023-11-15T12:30:45.123Z")
|
|
95
|
+
default: null
|
|
96
|
+
},
|
|
97
|
+
isUkResident: {
|
|
98
|
+
type: Boolean,
|
|
99
|
+
default: false
|
|
100
|
+
},
|
|
101
|
+
creditReportId: { type: String, default: null },
|
|
102
|
+
isAlgbraEligible: { type: Boolean, default: false },
|
|
103
|
+
}, {
|
|
104
|
+
timestamps: true,
|
|
105
|
+
toJSON: { virtuals: true },
|
|
106
|
+
toObject: { virtuals: true }
|
|
107
|
+
});
|
|
108
|
+
applyAuditMiddleware(applicationSchema, "Application");
|
|
109
|
+
// Apply workflow plugin to the schema
|
|
110
|
+
applyWorkflowPlugin(applicationSchema, 'application');
|
|
111
|
+
// Virtual property 'noOfApplicants'
|
|
112
|
+
applicationSchema.virtual('noOfApplicants').get(function () {
|
|
113
|
+
return this.applicants ? this.applicants.length : 0;
|
|
114
|
+
});
|
|
115
|
+
// Virtual property 'applicationTypeName'
|
|
116
|
+
applicationSchema.virtual('applicationTypeName').get(function () {
|
|
117
|
+
return this.applicationTypeLid instanceof mongoose.Types.ObjectId
|
|
118
|
+
? null
|
|
119
|
+
: this.applicationTypeLid?.name ?? null;
|
|
120
|
+
});
|
|
121
|
+
// Virtual property 'lendingType'
|
|
122
|
+
applicationSchema.virtual('lendingType').get(function () {
|
|
123
|
+
return this.lendingTypeLid instanceof mongoose.Types.ObjectId
|
|
124
|
+
? null
|
|
125
|
+
: this.lendingTypeLid?.name ?? null;
|
|
126
|
+
});
|
|
127
|
+
// Virtual property 'purchaseType'
|
|
128
|
+
applicationSchema.virtual('purchaseType').get(function () {
|
|
129
|
+
return this.purchaseTypeLid instanceof mongoose.Types.ObjectId
|
|
130
|
+
? null
|
|
131
|
+
: this.purchaseTypeLid?.text ?? null;
|
|
132
|
+
});
|
|
133
|
+
// Virtual property 'status'
|
|
134
|
+
applicationSchema.virtual('status').get(function () {
|
|
135
|
+
return this.statusLid instanceof mongoose.Types.ObjectId ? null : this.statusLid?.name ?? null;
|
|
136
|
+
});
|
|
137
|
+
// Ensure the fields are populated when querying
|
|
138
|
+
applicationSchema.pre('find', function () {
|
|
139
|
+
this.populate('applicationTypeLid').populate('lendingTypeLid').populate('statusLid');
|
|
140
|
+
});
|
|
141
|
+
applicationSchema.pre('findOne', function () {
|
|
142
|
+
this.populate('applicationTypeLid').populate('lendingTypeLid').populate('statusLid');
|
|
143
|
+
});
|
|
144
|
+
// Virtual property 'LTV %'
|
|
145
|
+
applicationSchema.virtual('ltv').get(function () {
|
|
146
|
+
const purchasePrice = this.mortgageId?.purchasePrice;
|
|
147
|
+
const loanRequired = this.mortgageId?.loanRequired;
|
|
148
|
+
if (purchasePrice && loanRequired) {
|
|
149
|
+
const parseCurrency = (value) => {
|
|
150
|
+
if (typeof value === 'string') {
|
|
151
|
+
return parseFloat(value.replace(/[^0-9.-]+/g, ""));
|
|
152
|
+
}
|
|
153
|
+
return value;
|
|
154
|
+
};
|
|
155
|
+
const parsedPurchasePrice = parseCurrency(purchasePrice);
|
|
156
|
+
const parsedLoanRequired = parseCurrency(loanRequired);
|
|
157
|
+
const ltv = (parsedLoanRequired / parsedPurchasePrice) * 100;
|
|
158
|
+
return ltv.toFixed(2) + "%";
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
});
|
|
162
|
+
applicationSchema.virtual('submittedDateFormatted').get(function () {
|
|
163
|
+
if (!this.submittedDate)
|
|
164
|
+
return null;
|
|
165
|
+
const date = new Date(this.submittedDate);
|
|
166
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
167
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
168
|
+
const year = date.getFullYear();
|
|
169
|
+
return `${day}-${month}-${year}`;
|
|
170
|
+
});
|
|
171
|
+
// Virtual property for broker name
|
|
172
|
+
applicationSchema.virtual('brokerName').get(function () {
|
|
173
|
+
if (this.brokerId && typeof this.brokerId === 'object' && this.brokerId.firstName && this.brokerId.lastName) {
|
|
174
|
+
return this.brokerId.firstName + " " + this.brokerId.lastName;
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
});
|
|
178
|
+
applicationSchema.virtual('brokerEmail').get(function () {
|
|
179
|
+
return this.brokerId && typeof this.brokerId === 'object' ? this.brokerId.email : null;
|
|
180
|
+
});
|
|
181
|
+
applicationSchema.virtual('solicitorName').get(function () {
|
|
182
|
+
return this.solicitorId && typeof this.solicitorId === 'object' ? this.solicitorId.nameOfAccountHolder : null;
|
|
183
|
+
});
|
|
184
|
+
applicationSchema.virtual('solicitorEmail').get(function () {
|
|
185
|
+
return this.solicitorId && typeof this.solicitorId === 'object' ? this.solicitorId.email : null;
|
|
186
|
+
});
|
|
187
|
+
applicationSchema.virtual('brokerPhone').get(function () {
|
|
188
|
+
return this.brokerId && typeof this.brokerId === 'object' ? this.brokerId.mobileTelephone : null;
|
|
189
|
+
});
|
|
190
|
+
applicationSchema.virtual('solicitorPhone').get(function () {
|
|
191
|
+
return this.solicitorId && typeof this.solicitorId === 'object' ? this.solicitorId.telephone : null;
|
|
192
|
+
});
|
|
193
|
+
// Virtual property 'pendingDays'
|
|
194
|
+
applicationSchema.virtual('pendingDays').get(function () {
|
|
195
|
+
if (!this.applicationFormSignedDate)
|
|
196
|
+
return null;
|
|
197
|
+
// Get current date at midnight (ignoring time)
|
|
198
|
+
const now = new Date();
|
|
199
|
+
const todayMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
200
|
+
// Get signed date at midnight (ignoring time)
|
|
201
|
+
const signedDate = new Date(this.applicationFormSignedDate);
|
|
202
|
+
const signedMidnight = new Date(signedDate.getFullYear(), signedDate.getMonth(), signedDate.getDate());
|
|
203
|
+
// Calculate difference in just date
|
|
204
|
+
const diffTime = todayMidnight.getTime() - signedMidnight.getTime();
|
|
205
|
+
// Convert to days
|
|
206
|
+
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
207
|
+
return diffDays;
|
|
208
|
+
});
|
|
209
|
+
// Virtual property 'taskCompletionPercent'
|
|
210
|
+
applicationSchema.virtual('taskCompletionPercent').get(function () {
|
|
211
|
+
const broker = typeof this.brokerTaskCount === 'number' ? this.brokerTaskCount : 0;
|
|
212
|
+
const lender = typeof this.lenderTaskCount === 'number' ? this.lenderTaskCount : 0;
|
|
213
|
+
const total = broker + lender;
|
|
214
|
+
// If both broker and lender are 0, return 100.00
|
|
215
|
+
if (broker === 0 && lender === 0)
|
|
216
|
+
return 100.00;
|
|
217
|
+
// If broker is 0 and lender is not, return 100.00
|
|
218
|
+
if (broker === 0 && lender > 0)
|
|
219
|
+
return 100.00;
|
|
220
|
+
// If lender is 0 and broker is not, return 0.00
|
|
221
|
+
if (lender === 0 && broker > 0)
|
|
222
|
+
return 0.00;
|
|
223
|
+
// Calculate (lender/total)*100
|
|
224
|
+
return Number(((lender / total) * 100).toFixed(2));
|
|
225
|
+
});
|
|
226
|
+
// Database indexes for performance optimization
|
|
227
|
+
// Single field indexes
|
|
228
|
+
applicationSchema.index({ applicationId: 1 });
|
|
229
|
+
applicationSchema.index({ assignedToUserId: 1 });
|
|
230
|
+
applicationSchema.index({ brokerId: 1 });
|
|
231
|
+
applicationSchema.index({ applicants: 1 }); // For array membership queries
|
|
232
|
+
// Compound indexes for common query combinations
|
|
233
|
+
applicationSchema.index({ applicants: 1, _id: 1 }); // For finding application by applicant
|
|
234
|
+
applicationSchema.index({ assignedToUserId: 1, statusLid: 1 }); // For filtering by assignee and status
|
|
235
|
+
// Text index for search functionality
|
|
236
|
+
applicationSchema.index({ applicationNumber: "text" });
|
|
237
|
+
const ApplicationModel = mongoose.model("Application", applicationSchema);
|
|
238
|
+
export default ApplicationModel;
|