@bisondesk/core-sdk 1.0.494 → 1.0.495
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/lib/constants.d.ts +2 -2
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +2 -2
- package/lib/constants.js.map +1 -1
- package/lib/types/activities.d.ts +5 -15
- package/lib/types/activities.d.ts.map +1 -1
- package/lib/types/activities.js +0 -1
- package/lib/types/activities.js.map +1 -1
- package/lib/types/comparables.d.ts +2 -0
- package/lib/types/comparables.d.ts.map +1 -1
- package/lib/types/comparables.js.map +1 -1
- package/lib/types/crm.d.ts +8 -0
- package/lib/types/crm.d.ts.map +1 -1
- package/lib/types/crm.js.map +1 -1
- package/lib/types/interests.d.ts +8 -0
- package/lib/types/interests.d.ts.map +1 -1
- package/lib/types/interests.js +2 -0
- package/lib/types/interests.js.map +1 -1
- package/lib/types/internal-events.d.ts +1 -2
- package/lib/types/internal-events.d.ts.map +1 -1
- package/lib/types/internal-events.js +0 -1
- package/lib/types/internal-events.js.map +1 -1
- package/lib/types/journeys.d.ts +0 -6
- package/lib/types/journeys.d.ts.map +1 -1
- package/lib/types/journeys.js.map +1 -1
- package/lib/types/leasing-debtors.d.ts +0 -202
- package/lib/types/leasing-debtors.d.ts.map +1 -1
- package/lib/types/leasing-debtors.js +1 -58
- package/lib/types/leasing-debtors.js.map +1 -1
- package/lib/types/leasing.d.ts +22 -1
- package/lib/types/leasing.d.ts.map +1 -1
- package/lib/types/leasing.js.map +1 -1
- package/lib/types/marketing-emails.d.ts +57 -0
- package/lib/types/marketing-emails.d.ts.map +1 -0
- package/lib/types/marketing-emails.js +2 -0
- package/lib/types/marketing-emails.js.map +1 -0
- package/lib/types/tenants.d.ts +1 -0
- package/lib/types/tenants.d.ts.map +1 -1
- package/lib/types/tenants.js +1 -0
- package/lib/types/tenants.js.map +1 -1
- package/lib/utils/interests.d.ts +4 -0
- package/lib/utils/interests.d.ts.map +1 -0
- package/lib/utils/interests.js +110 -0
- package/lib/utils/interests.js.map +1 -0
- package/lib/utils/search.d.ts +2 -3
- package/lib/utils/search.d.ts.map +1 -1
- package/lib/utils/search.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +2 -2
- package/src/types/activities.ts +4 -49
- package/src/types/comparables.ts +2 -0
- package/src/types/crm.ts +11 -0
- package/src/types/interests.ts +14 -0
- package/src/types/internal-events.ts +0 -1
- package/src/types/journeys.ts +0 -7
- package/src/types/leasing-debtors.ts +0 -309
- package/src/types/leasing.ts +20 -0
- package/src/types/marketing-emails.ts +67 -0
- package/src/types/tenants.ts +1 -0
- package/src/utils/interests.ts +150 -0
- package/src/utils/search.ts +2 -9
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/debtors-dossiers.d.ts +0 -15
- package/lib/utils/debtors-dossiers.d.ts.map +0 -1
- package/lib/utils/debtors-dossiers.js +0 -51
- package/lib/utils/debtors-dossiers.js.map +0 -1
- package/src/utils/debtors-dossiers.ts +0 -73
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { EmailMessage } from '@bisondesk/commons-sdk/messages';
|
|
2
|
-
import { NextList, PaginatedList } from '@bisondesk/commons-sdk/types';
|
|
3
1
|
import { Contact, Organization } from './crm.js';
|
|
4
|
-
import { LeasingContract } from './leasing.js';
|
|
5
|
-
import { BaseSearchRequest, SortFilter } from './search.js';
|
|
6
|
-
import { DataRecord, ReferenceData } from './utils.js';
|
|
7
2
|
|
|
8
3
|
export type MonthData = {
|
|
9
4
|
activeContractIds: string[];
|
|
@@ -38,307 +33,3 @@ export type SearchDebtorInfo = {
|
|
|
38
33
|
hasActiveContracts: boolean;
|
|
39
34
|
};
|
|
40
35
|
};
|
|
41
|
-
|
|
42
|
-
export enum DebtorsDossierStatus {
|
|
43
|
-
AUTO_REMINDER = 'auto_reminder',
|
|
44
|
-
OVERDUE = 'overdue',
|
|
45
|
-
CONTACT_ATTEMPTED = 'contact_attempted',
|
|
46
|
-
DIALOGUE = 'dialogue',
|
|
47
|
-
PROMISE_TO_PAY = 'promise_to_pay',
|
|
48
|
-
FAILURE = 'failure',
|
|
49
|
-
RESOLVED = 'resolved',
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const debtorsDossierStatusToDateFieldMap: Record<
|
|
53
|
-
DebtorsDossierStatus,
|
|
54
|
-
{ date: keyof DossierStatusLogFields; author: keyof DossierStatusLogFields } | null
|
|
55
|
-
> = {
|
|
56
|
-
[DebtorsDossierStatus.AUTO_REMINDER]: null,
|
|
57
|
-
[DebtorsDossierStatus.OVERDUE]: { date: 'overdueAt', author: 'overdueBy' },
|
|
58
|
-
[DebtorsDossierStatus.CONTACT_ATTEMPTED]: { date: 'contactedAt', author: 'contactedBy' },
|
|
59
|
-
[DebtorsDossierStatus.DIALOGUE]: { date: 'dialogueAt', author: 'dialogueBy' },
|
|
60
|
-
[DebtorsDossierStatus.PROMISE_TO_PAY]: { date: 'promiseToPayAt', author: 'promiseToPayBy' },
|
|
61
|
-
[DebtorsDossierStatus.FAILURE]: { date: 'failedAt', author: 'failedBy' },
|
|
62
|
-
[DebtorsDossierStatus.RESOLVED]: { date: 'resolvedAt', author: 'resolvedBy' },
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/******
|
|
66
|
-
* Auto Follow-Up Types
|
|
67
|
-
******/
|
|
68
|
-
|
|
69
|
-
export type DebtorAutoFollowUp = {
|
|
70
|
-
id: string;
|
|
71
|
-
organizationId: string;
|
|
72
|
-
organizationName: string;
|
|
73
|
-
status: 'ONGOING' | 'ERROR' | 'SUCCESS' | 'EXPIRED' | 'DISCARDED';
|
|
74
|
-
emails: EmailMessage[];
|
|
75
|
-
createdAt: string;
|
|
76
|
-
modifiedAt: string;
|
|
77
|
-
completedAt?: string;
|
|
78
|
-
nextActionAt: string;
|
|
79
|
-
riskLevel: number;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type ListOverdueRemindersResponse = PaginatedList<DebtorAutoFollowUp, ReferenceData>;
|
|
83
|
-
export type ListOverdueRemindersRequest = {
|
|
84
|
-
offset: number;
|
|
85
|
-
limit: number;
|
|
86
|
-
sortBy: SortFilter;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/******
|
|
90
|
-
* Debtor Dossier Types
|
|
91
|
-
******/
|
|
92
|
-
|
|
93
|
-
export enum DebtorsDossierActions {
|
|
94
|
-
SET_METADATA = 'set_metadata',
|
|
95
|
-
ADD_ACTIVITY = 'add_activity',
|
|
96
|
-
FINISH = 'finish',
|
|
97
|
-
SET_DOCUMENTS = 'set_documents',
|
|
98
|
-
SET_PAYMENT_PLAN = 'set_payment_plan',
|
|
99
|
-
SET_LEGAL_DOSSIER = 'set_legal_dossier',
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export type DossierStatusLogFields = {
|
|
103
|
-
failedAt?: string;
|
|
104
|
-
failedBy?: string;
|
|
105
|
-
resolvedAt?: string;
|
|
106
|
-
contactedAt?: string;
|
|
107
|
-
contactedBy?: string;
|
|
108
|
-
overdueAt?: string;
|
|
109
|
-
overdueBy?: string;
|
|
110
|
-
resolvedBy?: string;
|
|
111
|
-
dialogueAt?: string;
|
|
112
|
-
dialogueBy?: string;
|
|
113
|
-
promiseToPayAt?: string;
|
|
114
|
-
promiseToPayBy?: string;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export type BaseDebtorsDossier = {
|
|
118
|
-
organizationId: string;
|
|
119
|
-
contactId?: string;
|
|
120
|
-
tags: string[];
|
|
121
|
-
origin: 'manual' | 'auto';
|
|
122
|
-
autoFollowUpId?: string;
|
|
123
|
-
administrativeUserId?: string;
|
|
124
|
-
branchId: string;
|
|
125
|
-
tenantId: string;
|
|
126
|
-
};
|
|
127
|
-
export type DebtorsDossierStatusAudit = {
|
|
128
|
-
from: DebtorsDossierStatus;
|
|
129
|
-
to: DebtorsDossierStatus;
|
|
130
|
-
changedAt: string;
|
|
131
|
-
changedBy: string;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export type DebtorsDossier = BaseDebtorsDossier &
|
|
135
|
-
DossierStatusLogFields & {
|
|
136
|
-
id: string;
|
|
137
|
-
createdAt: string;
|
|
138
|
-
createdBy: string;
|
|
139
|
-
updatedAt: string;
|
|
140
|
-
updatedBy: string;
|
|
141
|
-
status: DebtorsDossierStatus;
|
|
142
|
-
statusAudit: DebtorsDossierStatusAudit[];
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
export type NewDebtorsDossier = BaseDebtorsDossier & {
|
|
146
|
-
id?: undefined;
|
|
147
|
-
createdBy?: undefined;
|
|
148
|
-
createdAt?: undefined;
|
|
149
|
-
updatedBy?: undefined;
|
|
150
|
-
updatedAt?: undefined;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export type DebtorsDossierBff = {
|
|
154
|
-
dossier: DataRecord<DebtorsDossier>;
|
|
155
|
-
organization?: Organization;
|
|
156
|
-
contact?: Contact;
|
|
157
|
-
leasingContracts: LeasingContract[];
|
|
158
|
-
debt?: DebtorInfo;
|
|
159
|
-
paymentPlan?: DebtorsPaymentPlan;
|
|
160
|
-
legalDossier?: LegalDossier;
|
|
161
|
-
trackAndTraceDevices: {
|
|
162
|
-
/* odometer: TrackAndTraceOdometerData;
|
|
163
|
-
device: TrackAndTraceDevice; */
|
|
164
|
-
}[];
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
export type UpdateDebtorsDossier = Partial<
|
|
168
|
-
Pick<
|
|
169
|
-
DebtorsDossier,
|
|
170
|
-
'status' | 'tags' | 'contactId' | 'administrativeUserId' | 'branchId' | 'organizationId'
|
|
171
|
-
>
|
|
172
|
-
> & {
|
|
173
|
-
overdue?: boolean;
|
|
174
|
-
resolve?: boolean;
|
|
175
|
-
terminate?: boolean;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
/******
|
|
179
|
-
* Payment Plan Types
|
|
180
|
-
******/
|
|
181
|
-
|
|
182
|
-
export type DebtorsPaymentPlan = {
|
|
183
|
-
id: string;
|
|
184
|
-
debtorDossierId: string;
|
|
185
|
-
|
|
186
|
-
notes?: string;
|
|
187
|
-
|
|
188
|
-
reminders?: {
|
|
189
|
-
frequency: {
|
|
190
|
-
every: number;
|
|
191
|
-
period: 'days' | 'weeks' | 'months';
|
|
192
|
-
};
|
|
193
|
-
endCondition:
|
|
194
|
-
| {
|
|
195
|
-
endDate: string; // ISO date string
|
|
196
|
-
}
|
|
197
|
-
| {
|
|
198
|
-
occurrences: number; // Number of reminders to send
|
|
199
|
-
};
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
createdAt: string;
|
|
203
|
-
createdBy: string;
|
|
204
|
-
updatedAt: string;
|
|
205
|
-
updatedBy: string;
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
export type NewPaymentPlan = Omit<
|
|
209
|
-
DebtorsPaymentPlan,
|
|
210
|
-
'id' | 'createdAt' | 'updatedAt' | 'createdBy' | 'updatedBy'
|
|
211
|
-
>;
|
|
212
|
-
|
|
213
|
-
export type UpdatePaymentPlan = Partial<Pick<DebtorsPaymentPlan, 'notes' | 'reminders'>>;
|
|
214
|
-
|
|
215
|
-
/******
|
|
216
|
-
* Legal Dossier Types
|
|
217
|
-
******/
|
|
218
|
-
|
|
219
|
-
export enum LegalDossierStatus {
|
|
220
|
-
ASSESSMENT = 'assessment',
|
|
221
|
-
PRE_LEGAL_NOTICE = 'pre_legal_notice',
|
|
222
|
-
SENT_TO_LAWYER = 'sent_to_lawyer',
|
|
223
|
-
FILED = 'filed',
|
|
224
|
-
IN_COURT = 'in_court',
|
|
225
|
-
JUDGMENT = 'judgment',
|
|
226
|
-
ENFORCEMENT = 'enforcement',
|
|
227
|
-
SETTLEMENT = 'settlement',
|
|
228
|
-
CLOSED_RECOVERED = 'closed_recovered',
|
|
229
|
-
CLOSED_UNRECOVERABLE = 'closed_unrecoverable',
|
|
230
|
-
ON_HOLD = 'on_hold',
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export type LegalDossier = {
|
|
234
|
-
id: string;
|
|
235
|
-
debtorDossierId: string;
|
|
236
|
-
caseNumber?: string;
|
|
237
|
-
notes?: string;
|
|
238
|
-
createdAt: string;
|
|
239
|
-
createdBy: string;
|
|
240
|
-
updatedAt: string;
|
|
241
|
-
updatedBy: string;
|
|
242
|
-
status: LegalDossierStatus;
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
export type NewLegalDossier = Omit<
|
|
246
|
-
LegalDossier,
|
|
247
|
-
'id' | 'createdAt' | 'updatedAt' | 'createdBy' | 'updatedBy'
|
|
248
|
-
>;
|
|
249
|
-
|
|
250
|
-
export type UpdateLegalDossier = Partial<Pick<LegalDossier, 'caseNumber' | 'status' | 'notes'>>;
|
|
251
|
-
|
|
252
|
-
/******
|
|
253
|
-
* Debtor Dossier Events
|
|
254
|
-
******/
|
|
255
|
-
|
|
256
|
-
export type DebtorsDossierCreateEvent = {
|
|
257
|
-
action: 'created';
|
|
258
|
-
data: DebtorsDossier;
|
|
259
|
-
previousData?: undefined;
|
|
260
|
-
tenantId: string;
|
|
261
|
-
userId: string;
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
export type DebtorsDossierUpdateEvent = {
|
|
265
|
-
action: 'updated';
|
|
266
|
-
data: DebtorsDossier;
|
|
267
|
-
previousData: DebtorsDossier;
|
|
268
|
-
tenantId: string;
|
|
269
|
-
userId: string;
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
export type DebtorsDossierDeleteEvent = {
|
|
273
|
-
action: 'deleted';
|
|
274
|
-
data?: undefined;
|
|
275
|
-
previousData: DebtorsDossier;
|
|
276
|
-
tenantId: string;
|
|
277
|
-
userId: string;
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
export type DebtorsDossierEvent =
|
|
281
|
-
| DebtorsDossierCreateEvent
|
|
282
|
-
| DebtorsDossierUpdateEvent
|
|
283
|
-
| DebtorsDossierDeleteEvent;
|
|
284
|
-
|
|
285
|
-
/************
|
|
286
|
-
*
|
|
287
|
-
* Search
|
|
288
|
-
*/
|
|
289
|
-
|
|
290
|
-
export type SearchDebtorsDossier = {
|
|
291
|
-
contact?: Contact;
|
|
292
|
-
debtorsDossier: DebtorsDossier;
|
|
293
|
-
org?: Organization;
|
|
294
|
-
legalDossier?: LegalDossier;
|
|
295
|
-
paymentPlan?: DebtorsPaymentPlan;
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
/************
|
|
299
|
-
*
|
|
300
|
-
* Kanban
|
|
301
|
-
*/
|
|
302
|
-
|
|
303
|
-
export type DebtorsDossierKanbanColumn = {
|
|
304
|
-
status: string;
|
|
305
|
-
results: SearchDebtorsDossier[];
|
|
306
|
-
totalCount: number;
|
|
307
|
-
totalValue: string;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
export type MSearchDebtorsDossierKanbanColumn = {
|
|
311
|
-
column: DebtorsDossierKanbanColumn;
|
|
312
|
-
nextToken?: string;
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
export type KanbanDebtorsDossierSearchRequest = BaseSearchRequest & {
|
|
316
|
-
nextTokens?: Record<string, string | undefined>;
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
export type KanbanDebtorsDossierNextList = Omit<
|
|
320
|
-
NextList<DebtorsDossierKanbanColumn, ReferenceData>,
|
|
321
|
-
'nextToken'
|
|
322
|
-
> & {
|
|
323
|
-
nextTokens?: Record<string, string | undefined>;
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
export const DebtorsDossierStatusOrder: DebtorsDossierStatus[] = [
|
|
327
|
-
DebtorsDossierStatus.AUTO_REMINDER,
|
|
328
|
-
DebtorsDossierStatus.OVERDUE,
|
|
329
|
-
DebtorsDossierStatus.CONTACT_ATTEMPTED,
|
|
330
|
-
DebtorsDossierStatus.DIALOGUE,
|
|
331
|
-
DebtorsDossierStatus.PROMISE_TO_PAY,
|
|
332
|
-
];
|
|
333
|
-
|
|
334
|
-
export const DebtorsDossierWonColumnId = DebtorsDossierStatus.RESOLVED;
|
|
335
|
-
|
|
336
|
-
export const DebtorsDossierKanbanEndColumns: string[] = [
|
|
337
|
-
DebtorsDossierStatus.RESOLVED,
|
|
338
|
-
DebtorsDossierStatus.FAILURE,
|
|
339
|
-
];
|
|
340
|
-
|
|
341
|
-
export const DebtorsDossierKanbanColumns = [
|
|
342
|
-
...DebtorsDossierStatusOrder,
|
|
343
|
-
...DebtorsDossierKanbanEndColumns,
|
|
344
|
-
];
|
package/src/types/leasing.ts
CHANGED
|
@@ -42,6 +42,19 @@ export type LeasingConditionEvent = {
|
|
|
42
42
|
tenantId: string;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
export type OverdueDossier = {
|
|
46
|
+
id: string;
|
|
47
|
+
organizationId: string;
|
|
48
|
+
organizationName: string;
|
|
49
|
+
status: 'ONGOING' | 'ERROR' | 'SUCCESS' | 'EXPIRED' | 'DISCARDED';
|
|
50
|
+
emails: EmailMessage[];
|
|
51
|
+
createdAt: string;
|
|
52
|
+
modifiedAt: string;
|
|
53
|
+
completedAt?: string;
|
|
54
|
+
nextActionAt: string;
|
|
55
|
+
riskLevel: number;
|
|
56
|
+
};
|
|
57
|
+
|
|
45
58
|
export type LeasingContractClient = {
|
|
46
59
|
organizationId: string;
|
|
47
60
|
contactIds: string[];
|
|
@@ -180,6 +193,13 @@ export type OpportunityRef = BaseRef & {
|
|
|
180
193
|
//Since VAT is client specific and contracts can be transferred between clients, we always handle values without VAT
|
|
181
194
|
};
|
|
182
195
|
|
|
196
|
+
export type ListOverdueRemindersResponse = PaginatedList<OverdueDossier, ReferenceData>;
|
|
197
|
+
export type ListOverdueRemindersRequest = {
|
|
198
|
+
offset: number;
|
|
199
|
+
limit: number;
|
|
200
|
+
sortBy: SortFilter;
|
|
201
|
+
};
|
|
202
|
+
|
|
183
203
|
export type NewLeasingConditions = {
|
|
184
204
|
parameters: {
|
|
185
205
|
yearlyRoadTax: string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { EmailDestination } from '@bisondesk/commons-sdk/messages';
|
|
2
|
+
import { AttachmentValue, NextRequest } from '@bisondesk/commons-sdk/types';
|
|
3
|
+
import { SearchRequest } from './search.js';
|
|
4
|
+
|
|
5
|
+
export type CampaignSearchRequest = {
|
|
6
|
+
fullText?: string;
|
|
7
|
+
query: NonNullable<SearchRequest['query']>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type MarketingEmailCampaign = {
|
|
11
|
+
id: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
createdBy: string;
|
|
14
|
+
name: string;
|
|
15
|
+
|
|
16
|
+
vehicleIds: string[];
|
|
17
|
+
subject: string;
|
|
18
|
+
message: string;
|
|
19
|
+
pictures?: AttachmentValue[];
|
|
20
|
+
|
|
21
|
+
targets: {
|
|
22
|
+
emails?: EmailDestination[];
|
|
23
|
+
queries?: CampaignSearchRequest[];
|
|
24
|
+
leads?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
runAt?: string;
|
|
28
|
+
// determined on the moment of sending by merging all the targets
|
|
29
|
+
fullEmailList?: string[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type MarketingCampaignSentEmail = {
|
|
33
|
+
campaignId: string;
|
|
34
|
+
contactId?: string;
|
|
35
|
+
email: string;
|
|
36
|
+
runAt: string;
|
|
37
|
+
|
|
38
|
+
sentAt?: string;
|
|
39
|
+
deliveredAt?: string;
|
|
40
|
+
bouncedAt?: string;
|
|
41
|
+
complaintAt?: string;
|
|
42
|
+
openedAt?: string;
|
|
43
|
+
clickedAt?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type MarketingCampaignEmailEvent = {
|
|
47
|
+
tenantId: string;
|
|
48
|
+
campaignId: string;
|
|
49
|
+
email: string;
|
|
50
|
+
runAt: string;
|
|
51
|
+
contactId?: string;
|
|
52
|
+
name?: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type MarketingCampaignStatistics = {
|
|
56
|
+
totalEmails: number;
|
|
57
|
+
successfulDeliveries: number;
|
|
58
|
+
bouncedEmails: number;
|
|
59
|
+
sentEmails: number;
|
|
60
|
+
complaints: number;
|
|
61
|
+
openedEmails: number;
|
|
62
|
+
clickedEmails: number;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export type SentEmailsSearchRequest = NextRequest & {
|
|
66
|
+
fullText?: string;
|
|
67
|
+
};
|
package/src/types/tenants.ts
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isoString } from '@bisondesk/commons-sdk/date-utils';
|
|
2
|
+
import { generateId } from '@bisondesk/commons-sdk/ids';
|
|
3
|
+
import { UTCDate } from '@date-fns/utc';
|
|
4
|
+
import { first, range, uniq } from 'lodash-es';
|
|
5
|
+
import { KM_ROUNDING, MAX_AGE, MAX_KM, MAX_PRICE, PRICE_ROUNDING } from '../constants.js';
|
|
6
|
+
import { Interest } from '../types/interests.js';
|
|
7
|
+
import { VehicleExternalInfo } from '../types/vehicles.js';
|
|
8
|
+
|
|
9
|
+
export const mapVehicleToInterest = (
|
|
10
|
+
userId: string,
|
|
11
|
+
vehicleExternalInfo: VehicleExternalInfo,
|
|
12
|
+
referenceDate: Date = new UTCDate()
|
|
13
|
+
): Interest => {
|
|
14
|
+
return {
|
|
15
|
+
id: generateId(),
|
|
16
|
+
createdAt: isoString(),
|
|
17
|
+
createdBy: userId,
|
|
18
|
+
modifiedAt: isoString(),
|
|
19
|
+
modifiedBy: userId,
|
|
20
|
+
bodystyle: vehicleExternalInfo.general.bodystyle,
|
|
21
|
+
cabins: toCabins(toArray(vehicleExternalInfo.body?.cabin?.type)),
|
|
22
|
+
category: vehicleExternalInfo.general.category,
|
|
23
|
+
retarderIntarder: vehicleExternalInfo.accessories.retarderIntarder ? true : undefined,
|
|
24
|
+
adr: vehicleExternalInfo.accessories.adr,
|
|
25
|
+
damaged: vehicleExternalInfo.condition?.damaged ?? false,
|
|
26
|
+
extended: toArray(vehicleExternalInfo.superstructure?.dimensions?.extended),
|
|
27
|
+
heightened: toArray(vehicleExternalInfo.superstructure?.dimensions?.heightened),
|
|
28
|
+
used: vehicleExternalInfo.condition?.used,
|
|
29
|
+
crane: vehicleExternalInfo.superstructure?.crane?.present,
|
|
30
|
+
tailgate: vehicleExternalInfo.superstructure?.tailgate?.present,
|
|
31
|
+
axleConfigurations: toArray(vehicleExternalInfo.powertrain?.axles?.configuration),
|
|
32
|
+
suspensions: toSuspensions(toArray(vehicleExternalInfo.powertrain?.axles?.suspension)),
|
|
33
|
+
transmissions: toTransmissions(toArray(vehicleExternalInfo.powertrain?.transmission?.type)),
|
|
34
|
+
euronorms: toEuronorms(vehicleExternalInfo),
|
|
35
|
+
kilometers: vehicleExternalInfo.condition?.used
|
|
36
|
+
? toRound(KM_ROUNDING, vehicleExternalInfo.condition?.odometer?.km, MAX_KM)
|
|
37
|
+
: undefined,
|
|
38
|
+
horsepower: toMinHorsepower(vehicleExternalInfo, -0.1),
|
|
39
|
+
versions:
|
|
40
|
+
vehicleExternalInfo.general.make != null
|
|
41
|
+
? [
|
|
42
|
+
{
|
|
43
|
+
make: vehicleExternalInfo.general.make,
|
|
44
|
+
models: toArray(vehicleExternalInfo.general.model),
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
: undefined,
|
|
48
|
+
price: toMaxPrice(vehicleExternalInfo.salesConditions.price),
|
|
49
|
+
age: vehicleExternalInfo.condition?.used
|
|
50
|
+
? toAge(referenceDate, vehicleExternalInfo.history?.advertisingYear)
|
|
51
|
+
: undefined,
|
|
52
|
+
autoGenerated: true,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const isHeavyVehicle = (vehicleExternalInfo: VehicleExternalInfo) =>
|
|
57
|
+
['Tractor Head', 'Truck'].includes(vehicleExternalInfo.general.category);
|
|
58
|
+
|
|
59
|
+
const toCabins = (values: string[] | undefined): string[] | undefined => {
|
|
60
|
+
if (values == null || values.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (values.some((v) => v.startsWith('Sleep'))) {
|
|
65
|
+
// If it allows sleep, then add the two largest sleep options as well
|
|
66
|
+
return uniq([...values, 'Sleep / Medium', 'Sleep / Large']);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return values;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const toSuspensions = (values: string[] | undefined): string[] | undefined => {
|
|
73
|
+
if (values == null || values.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (values.includes('Air/Steel')) {
|
|
78
|
+
// If it allows some axles with air suspension, then allow all
|
|
79
|
+
return uniq([...values, 'Air']);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return values;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const toTransmissions = (values: string[] | undefined): string[] | undefined => {
|
|
86
|
+
if (values == null || values.length === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (values.includes('Manual')) {
|
|
91
|
+
// ignore transmission restriction
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (values.includes('Semi-Automatic')) {
|
|
96
|
+
// also consider values that are better
|
|
97
|
+
return uniq([...values, 'Automatic']);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return values;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const toEuronorms = (vehicleExternalInfo: VehicleExternalInfo): string[] | undefined => {
|
|
104
|
+
const values = toArray(vehicleExternalInfo.powertrain?.emissions?.class);
|
|
105
|
+
if (values == null || values.length === 0 || !isHeavyVehicle(vehicleExternalInfo)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const minEuronorm = 5;
|
|
110
|
+
const maxEuronorm = 6;
|
|
111
|
+
|
|
112
|
+
const lowestEuronorm = first(values.map((v) => Number(v.charAt(v.length - 1))).sort())!;
|
|
113
|
+
if (lowestEuronorm < minEuronorm) {
|
|
114
|
+
return; // ignore Euronorm restriction
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return range(lowestEuronorm, maxEuronorm + 1).map((r) => `Euro ${r}`);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const toAge = (referenceDate: Date, year?: number) => {
|
|
121
|
+
if (year == null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (year > referenceDate.getUTCFullYear()) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return toRound(1, referenceDate.getUTCFullYear() - year, MAX_AGE);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const toMaxPrice = (value?: number | string) =>
|
|
133
|
+
value != null ? toRound(PRICE_ROUNDING, Number(value) * 1.15, MAX_PRICE) : undefined;
|
|
134
|
+
|
|
135
|
+
const toMinHorsepower = (
|
|
136
|
+
vehicleExternalInfo: VehicleExternalInfo,
|
|
137
|
+
shiftRatio: number
|
|
138
|
+
): number | undefined => {
|
|
139
|
+
const hasHorsepower = vehicleExternalInfo.powertrain?.engine?.power?.hp != null;
|
|
140
|
+
const isHorsepowerImportant = isHeavyVehicle(vehicleExternalInfo);
|
|
141
|
+
|
|
142
|
+
if (hasHorsepower && isHorsepowerImportant) {
|
|
143
|
+
return toRound(5, vehicleExternalInfo.powertrain!.engine!.power!.hp! * (1 + shiftRatio));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const toRound = (r: number, value?: number | string, max: number = Infinity) =>
|
|
148
|
+
value != null ? Math.min(Math.ceil(Number(value) / r) * r, max) : undefined;
|
|
149
|
+
|
|
150
|
+
const toArray = (value?: string): string[] => (value ? [value] : []);
|
package/src/utils/search.ts
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
import { joinWithSeparator } from '@bisondesk/commons-sdk/formatting';
|
|
2
2
|
import { BusinessEntityIds } from '../constants.js';
|
|
3
3
|
import { Contact, Organization, SearchOrganization } from '../types/crm.js';
|
|
4
|
-
import { DebtorsDossier, SearchDebtorsDossier } from '../types/leasing-debtors.js';
|
|
5
4
|
import { SearchLeasingContract } from '../types/leasing-search.js';
|
|
6
5
|
import { LeasingContract } from '../types/leasing.js';
|
|
7
6
|
import { Opportunity, SearchOpportunity } from '../types/opportunities.js';
|
|
8
7
|
import { SearchVehicle, Vehicle } from '../types/vehicles.js';
|
|
9
8
|
|
|
10
|
-
export type GlobalBusinessEntity =
|
|
11
|
-
| Opportunity
|
|
12
|
-
| Vehicle
|
|
13
|
-
| Organization
|
|
14
|
-
| LeasingContract
|
|
15
|
-
| DebtorsDossier;
|
|
9
|
+
export type GlobalBusinessEntity = Opportunity | Vehicle | Organization | LeasingContract;
|
|
16
10
|
export type GlobalSearchEntity =
|
|
17
11
|
| SearchOpportunity
|
|
18
12
|
| SearchVehicle
|
|
19
13
|
| SearchOrganization
|
|
20
|
-
| SearchLeasingContract
|
|
21
|
-
| SearchDebtorsDossier;
|
|
14
|
+
| SearchLeasingContract;
|
|
22
15
|
|
|
23
16
|
export const getCustomerInformation = (org?: Organization, contact?: Contact) => {
|
|
24
17
|
if (org != null) {
|