@bisondesk/core-sdk 1.0.611 → 1.0.612

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.
Files changed (116) hide show
  1. package/lib/constants.d.ts +2 -0
  2. package/lib/constants.d.ts.map +1 -1
  3. package/lib/constants.js +2 -0
  4. package/lib/constants.js.map +1 -1
  5. package/lib/types/activities.d.ts.map +1 -1
  6. package/lib/types/activities.js.map +1 -1
  7. package/lib/types/crm.d.ts +7 -1
  8. package/lib/types/crm.d.ts.map +1 -1
  9. package/lib/types/crm.js.map +1 -1
  10. package/lib/types/interests.d.ts +9 -14
  11. package/lib/types/interests.d.ts.map +1 -1
  12. package/lib/types/interests.js +2 -3
  13. package/lib/types/interests.js.map +1 -1
  14. package/lib/types/opportunities.d.ts +3 -2
  15. package/lib/types/opportunities.d.ts.map +1 -1
  16. package/lib/types/opportunities.js.map +1 -1
  17. package/lib/types/prospects.d.ts +126 -5
  18. package/lib/types/prospects.d.ts.map +1 -1
  19. package/lib/types/prospects.js +28 -0
  20. package/lib/types/prospects.js.map +1 -1
  21. package/lib/types/reports-sales.d.ts +8 -0
  22. package/lib/types/reports-sales.d.ts.map +1 -1
  23. package/lib/types/reports-sales.js +1 -0
  24. package/lib/types/reports-sales.js.map +1 -1
  25. package/lib/types/users.d.ts +2 -0
  26. package/lib/types/users.d.ts.map +1 -1
  27. package/lib/types/users.js.map +1 -1
  28. package/lib/types/vehicle-timeline.d.ts +96 -0
  29. package/lib/types/vehicle-timeline.d.ts.map +1 -0
  30. package/lib/types/vehicle-timeline.js +20 -0
  31. package/lib/types/vehicle-timeline.js.map +1 -0
  32. package/lib/types/vehicles.d.ts +4 -0
  33. package/lib/types/vehicles.d.ts.map +1 -1
  34. package/lib/types/vehicles.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/constants.ts +2 -0
  37. package/src/types/activities.js +13 -0
  38. package/src/types/activities.js.map +1 -0
  39. package/src/types/activities.ts +0 -1
  40. package/src/types/comparables.js +2 -0
  41. package/src/types/comparables.js.map +1 -0
  42. package/src/types/crm.js +58 -0
  43. package/src/types/crm.js.map +1 -0
  44. package/src/types/crm.ts +20 -1
  45. package/src/types/dashboard.js +2 -0
  46. package/src/types/dashboard.js.map +1 -0
  47. package/src/types/definitions.js +2 -0
  48. package/src/types/definitions.js.map +1 -0
  49. package/src/types/fields.js +2 -0
  50. package/src/types/fields.js.map +1 -0
  51. package/src/types/insights.js +2 -0
  52. package/src/types/insights.js.map +1 -0
  53. package/src/types/interests.js +6 -0
  54. package/src/types/interests.js.map +1 -0
  55. package/src/types/interests.ts +25 -20
  56. package/src/types/internal-events.js +18 -0
  57. package/src/types/internal-events.js.map +1 -0
  58. package/src/types/internet-opportunities.js +2 -0
  59. package/src/types/internet-opportunities.js.map +1 -0
  60. package/src/types/internet-vehicles.js +2 -0
  61. package/src/types/internet-vehicles.js.map +1 -0
  62. package/src/types/leasing-administration.js +2 -0
  63. package/src/types/leasing-administration.js.map +1 -0
  64. package/src/types/leasing-debtors.js +2 -0
  65. package/src/types/leasing-debtors.js.map +1 -0
  66. package/src/types/leasing-search.js +2 -0
  67. package/src/types/leasing-search.js.map +1 -0
  68. package/src/types/leasing-settings.js +7 -0
  69. package/src/types/leasing-settings.js.map +1 -0
  70. package/src/types/leasing.js +38 -0
  71. package/src/types/leasing.js.map +1 -0
  72. package/src/types/marketing.js +35 -0
  73. package/src/types/marketing.js.map +1 -0
  74. package/src/types/offers.js +56 -0
  75. package/src/types/opportunities.js +107 -0
  76. package/src/types/opportunities.js.map +1 -0
  77. package/src/types/opportunities.ts +5 -2
  78. package/src/types/payments.js +7 -0
  79. package/src/types/picklists.js +2 -0
  80. package/src/types/picklists.js.map +1 -0
  81. package/src/types/prospects.ts +281 -4
  82. package/src/types/quotes.js +42 -0
  83. package/src/types/recently-viewed.js +2 -0
  84. package/src/types/recently-viewed.js.map +1 -0
  85. package/src/types/reports-sales.ts +32 -0
  86. package/src/types/reservations.js +5 -0
  87. package/src/types/reservations.js.map +1 -0
  88. package/src/types/roi-ratings.js +5 -0
  89. package/src/types/roi-ratings.js.map +1 -0
  90. package/src/types/saved-filters.js +9 -0
  91. package/src/types/saved-filters.js.map +1 -0
  92. package/src/types/search.js +2 -0
  93. package/src/types/search.js.map +1 -0
  94. package/src/types/settings.js +2 -0
  95. package/src/types/settings.js.map +1 -0
  96. package/src/types/templates.js +2 -0
  97. package/src/types/templates.js.map +1 -0
  98. package/src/types/tenants.js +21 -0
  99. package/src/types/tenants.js.map +1 -0
  100. package/src/types/user-performance.js +7 -0
  101. package/src/types/user-performance.js.map +1 -0
  102. package/src/types/users.ts +2 -0
  103. package/src/types/utils.js +2 -0
  104. package/src/types/validation.js +2 -0
  105. package/src/types/validation.js.map +1 -0
  106. package/src/types/vehicle-sales.js +6 -0
  107. package/src/types/vehicle-sales.js.map +1 -0
  108. package/src/types/vehicle-timeline.ts +143 -0
  109. package/src/types/vehicles.js +98 -0
  110. package/src/types/vehicles.js.map +1 -0
  111. package/src/types/vehicles.ts +7 -0
  112. package/src/utils/leasing.js +6 -0
  113. package/src/utils/leasing.js.map +1 -0
  114. package/src/utils/opportunities.js +48 -0
  115. package/src/utils/opportunities.js.map +1 -0
  116. package/tsconfig.tsbuildinfo +1 -1
@@ -1,15 +1,21 @@
1
1
  import { Task } from '@bisondesk/commons-sdk/tasks';
2
- import { MultiLangValue, NextList } from '@bisondesk/commons-sdk/types';
2
+ import { MultiLangValue, NextList, PaginatedList } from '@bisondesk/commons-sdk/types';
3
+ import { Activity } from './activities.js';
3
4
  import { Contact, Organization } from './crm.js';
4
5
  import { Interest } from './interests.js';
5
6
  import { BaseEvent } from './internal-events.js';
6
- import { BaseSearchRequest } from './search.js';
7
+ import { Offer } from './offers.js';
8
+ import { Opportunity } from './opportunities.js';
9
+ import { BaseSearchRequest, SearchRequest, SortFilter } from './search.js';
7
10
  import { DataRecord, ReferenceData } from './utils.js';
8
11
 
9
12
  export enum ProspectActions {
10
13
  CLOSE = 'close',
11
14
  REOPEN = 'reopen',
12
15
  ENGAGE = 'engage',
16
+ // Claiming an unassigned prospect is open to any active sales rep — a deliberate widening of
17
+ // ADR-0013's permission matrix (ADR-0021 §7).
18
+ CLAIM = 'claim',
13
19
  SET_METADATA = 'set_metadata',
14
20
  SET_OBJECTIVES = 'set_objectives',
15
21
  SET_CUSTOMER = 'set_customer',
@@ -46,20 +52,170 @@ export enum ProspectPriority {
46
52
  LOW = 'low',
47
53
  NORMAL = 'normal',
48
54
  HIGH = 'high',
55
+ // "Call me" fast lane (ADR-0021 §8): a manual URGENT prospect sorts ahead of every
56
+ // engine-ranked card. Above NORMAL, priority dominates scoreTier in the "next" cursor.
57
+ URGENT = 'urgent',
49
58
  }
50
59
 
60
+ /**
61
+ * Numeric rank for priority, computed at index time into `custom.priorityRank` so OpenSearch
62
+ * can sort ordinally rather than alphabetically. Higher = more urgent.
63
+ */
64
+ export const PRIORITY_RANK: Record<ProspectPriority, number> = {
65
+ [ProspectPriority.LOW]: 1,
66
+ [ProspectPriority.NORMAL]: 2,
67
+ [ProspectPriority.HIGH]: 3,
68
+ [ProspectPriority.URGENT]: 4,
69
+ };
70
+
71
+ /**
72
+ * How a prospect entered the system (ADR-0021 §3). The engine's truncate-and-regenerate
73
+ * delete predicate only ever touches `AUTO` cards, so `MANUAL`/`IMPORT` cards survive
74
+ * regardless of status. `IMPORT` is reserved for the v2 import pipeline — nothing produces
75
+ * it in v1, but it stays in the enum because the discriminator is part of the delete-predicate
76
+ * safety contract.
77
+ */
78
+ export enum ProspectSource {
79
+ MANUAL = 'manual',
80
+ AUTO = 'auto',
81
+ IMPORT = 'import',
82
+ }
83
+
84
+ /**
85
+ * Discrete ranking band for an auto prospect (ADR-0021 §4). Each generator maps its own raw
86
+ * score into these bands via its own thresholds; the tier — not a raw number — is what the
87
+ * engine persists and the "next" cursor sorts on.
88
+ */
89
+ export enum ProspectScoreTier {
90
+ COLD = 'cold',
91
+ LUKEWARM = 'lukewarm',
92
+ WARM = 'warm',
93
+ HOT = 'hot',
94
+ }
95
+
96
+ /**
97
+ * Numeric rank for a score tier, computed at index time into `custom.scoreTierRank`
98
+ * (0 = unscored/no tier). Higher = warmer.
99
+ */
100
+ export const SCORE_TIER_RANK: Record<ProspectScoreTier, number> = {
101
+ [ProspectScoreTier.COLD]: 1,
102
+ [ProspectScoreTier.LUKEWARM]: 2,
103
+ [ProspectScoreTier.WARM]: 3,
104
+ [ProspectScoreTier.HOT]: 4,
105
+ };
106
+
107
+ /**
108
+ * Virtual sort field for search requests: "importance" is the compound priority → tier
109
+ * ranking (ADR-0021 §5). The backend expands it server-side, so clients never spell out
110
+ * the underlying fields.
111
+ */
112
+ export const PROSPECT_IMPORTANCE_SORT_FIELD = 'prospect.importance';
113
+
114
+ /** One line of the score breakdown recorded for explanation (raw score, thresholds, dampening). */
115
+ export type ProspectScoreDetail = {
116
+ name: string;
117
+ value: number | string;
118
+ };
119
+
120
+ /**
121
+ * Denormalized vehicle display data carried on each candidate vehicle, so the UI can render the
122
+ * anchor and runner-ups without a second fetch. Mirrors `InterestLead.vehicleData` (and extends it
123
+ * with make/model/category/vin), keeping the two card surfaces consistent.
124
+ */
125
+ export type ProspectVehicleData = {
126
+ title: string;
127
+ mainPictureUrl?: string;
128
+ stockNumber?: string;
129
+
130
+ category: string;
131
+ bodywork?: string;
132
+ makeName: string;
133
+ modelName?: string;
134
+ typeName?: string;
135
+
136
+ used?: boolean; // Vehicle.condition.used — false/absent means new.
137
+ damaged?: boolean;
138
+
139
+ advertisingYear?: number;
140
+ km?: number;
141
+ emissionsClass?: string;
142
+ emissionsSubClass?: string;
143
+ cabinModel?: string;
144
+ configuration?: string;
145
+ vin?: string;
146
+
147
+ // Notable boolean equipment, mirroring Vehicle.accessories (and superstructure.crane).
148
+ features?: {
149
+ adr?: boolean;
150
+ jumbo?: boolean;
151
+ crane?: boolean;
152
+ hydraulicTipperKit?: boolean;
153
+ lowDeck?: boolean;
154
+ retarderIntarder?: boolean;
155
+ };
156
+ };
157
+
158
+ /** A candidate anchor/runner-up vehicle, scored by the lead-engine matcher. */
159
+ export type ProspectVehicleCandidate = {
160
+ vehicleId: string;
161
+ /** Branch that holds this stock. The anchor's branch decides the card's branch (ADR-0021 §2). */
162
+ branchId: string;
163
+ score: number;
164
+ vehicleData: ProspectVehicleData;
165
+ };
166
+
167
+ /** A recommended account manager with an affinity score and the reasons behind it. */
168
+ export type ProspectRecommendedAm = {
169
+ userId: string;
170
+ score: number;
171
+ reasons: string[];
172
+ };
173
+
51
174
  export type ProspectObjective = {
52
175
  id: string;
53
176
  title: MultiLangValue;
54
177
  };
55
178
 
179
+ /**
180
+ * Inline identity for a card whose person/company matches no CRM record yet — the "draft party"
181
+ * of ADR-0021 §9. Carries enough structure to materialise a Contact (first/last name, phone,
182
+ * email) and/or an Organization (orgName, VAT, country) when the draft is converted
183
+ * (`SET_CUSTOMER`, grown). Drafts enter through import or manual entry only — the engine never
184
+ * produces them — and the nightly truncate never touches them.
185
+ */
186
+ export type ProspectPartyDraft = {
187
+ // contact identity
188
+ firstName?: string;
189
+ lastName?: string;
190
+ phone?: string;
191
+ email?: string;
192
+ // organization identity
193
+ orgName?: string;
194
+ vatNumber?: string;
195
+ countryCode?: string;
196
+ /**
197
+ * Client sector (Tier 1) and sub-industry (Tier 2), captured on the draft so they survive
198
+ * promotion to an Organization. Same picklists and semantics as the Organization fields of the
199
+ * same name (`ORG_INDUSTRY_PICKLIST_ID` / `SUB_INDUSTRY_PICKLIST_ID`).
200
+ */
201
+ industry?: string;
202
+ subIndustry?: string;
203
+ /**
204
+ * The draft party's interests, embedded on the card — a draft has no CRM record to hang
205
+ * interests on, so they ride the card until conversion copies them onto the linked
206
+ * Contact/Organization (where the lead engine picks them up; embedded ones never feed it).
207
+ */
208
+ interests?: Interest[];
209
+ };
210
+
56
211
  type BaseProspect = {
57
212
  contactId?: string;
58
213
  organizationId?: string;
214
+ /** Draft-party identity when the card is linked to no Contact/Organization yet (ADR §9). */
215
+ partyDraft?: ProspectPartyDraft;
59
216
  branchId: string;
60
217
  accountManager?: string;
61
218
  priority: ProspectPriority;
62
- score?: number;
63
219
  objectives: ProspectObjective[];
64
220
  };
65
221
 
@@ -76,6 +232,17 @@ export type Prospect = BaseProspect & {
76
232
 
77
233
  status: ProspectStatus;
78
234
 
235
+ // ── Engine-owned fields (ADR-0021). The manual write path treats these as read-only
236
+ // (Joi.forbidden in the user schemas) so a human edit is never silently overwritten by the
237
+ // next nightly run. `source` is always present on a persisted card; the rest exist only on
238
+ // scored auto cards.
239
+ source: ProspectSource;
240
+ scoreTier?: ProspectScoreTier;
241
+ scoreDetails?: ProspectScoreDetail[];
242
+ /** Ordered by score desc; `vehicles[0]` is the anchor the rep opens the call with. */
243
+ vehicles?: ProspectVehicleCandidate[];
244
+ recommendedAccountManagers?: ProspectRecommendedAm[];
245
+
79
246
  attemptingAt?: string;
80
247
  attemptingBy?: string;
81
248
  engagedAt?: string;
@@ -93,10 +260,10 @@ export type Prospect = BaseProspect & {
93
260
  export type ProspectUpdate = {
94
261
  contactId?: string | null;
95
262
  organizationId?: string | null;
263
+ partyDraft?: ProspectPartyDraft | null;
96
264
  branchId?: string;
97
265
  accountManager?: string | null;
98
266
  priority?: ProspectPriority;
99
- score?: number | null;
100
267
  objectives?: ProspectObjective[];
101
268
 
102
269
  close?: boolean;
@@ -110,6 +277,19 @@ export type ProspectBff = {
110
277
  contact?: DataRecord<Contact>;
111
278
  org?: DataRecord<Organization>;
112
279
  tasks: DataRecord<Task>[];
280
+
281
+ /** All interests in scope: the linked contact/org's, or the draft party's embedded ones. */
282
+ interests: Interest[];
283
+ /** Opportunities for the linked contact/org, deduped by id. */
284
+ opportunities: Opportunity[];
285
+ /** Offers for the linked contact/org, deduped by id, newest first. */
286
+ offers: Offer[];
287
+ /** The other prospect lines on the same contact/org (this one excluded), newest first. */
288
+ relatedProspects: Prospect[];
289
+ /** Most-recent interaction history (first page): the card's own + linked contact/org activities. */
290
+ activities: DataRecord<Activity>[];
291
+ /** Cursor for the next page of the merged activity history; absent when fully loaded. */
292
+ activitiesNextToken?: string;
113
293
  };
114
294
 
115
295
  /************
@@ -134,17 +314,107 @@ export type SearchProspect = {
134
314
  * Country of the lead, preferring contact country over org country when both are set.
135
315
  */
136
316
  country?: string;
317
+ /**
318
+ * Numeric ranks computed at index time so OpenSearch sorts ordinally, not alphabetically
319
+ * (ADR-0021 §4, §5). The "next" cursor sorts priorityRank desc → scoreTierRank desc → id asc.
320
+ */
321
+ priorityRank: number;
322
+ /** 0 = unscored (no tier yet). */
323
+ scoreTierRank: number;
324
+ /** User ids from `recommendedAccountManagers`, for the "suitable for me" filter (ADR §6). */
325
+ recommendedAmIds?: string[];
326
+ /**
327
+ * Collapse key for grouping by main vehicle (minimizing context switch): the anchor's
328
+ * vehicleId when the card carries vehicles, else the prospect id (a singleton group).
329
+ * Mirrors the opportunities kanban's `custom.groupKey` (group-by-client) convention.
330
+ */
331
+ groupKey: string;
332
+ };
333
+ /** Task counters denormalized at index time, for kanban/list badges. */
334
+ tasks?: {
335
+ totalTasks: number;
336
+ openTasks: number;
337
+ /** Soonest due date among open tasks. */
338
+ nextDueAt?: string;
137
339
  };
138
340
  };
139
341
 
342
+ /************
343
+ *
344
+ * Claim
345
+ */
346
+
347
+ /**
348
+ * Returned with HTTP 409 when a guarded claim finds the prospect already owned (a lost race). On
349
+ * success the endpoint returns the claimed `DataRecord<Prospect>` with 200 instead (ADR-0021 §7).
350
+ */
351
+ export type ProspectClaimConflict = {
352
+ claimed: false;
353
+ accountManager?: string;
354
+ };
355
+
356
+ /************
357
+ *
358
+ * Next cursor / play mode
359
+ */
360
+
361
+ /**
362
+ * The "next prospect" cursor (ADR-0021 §5). Accepts the same filter body as the list search, so
363
+ * "next" walks the rep's current view. Only the filter-defining fields are honored — sort, paging
364
+ * size and `nextToken` are owned by the endpoint (fixed priority→tier sort, `cursor` below). `cursor`
365
+ * is an opaque token embedding the sort position and a hash of the filters — it is rejected if the
366
+ * filter set changed. `claim: true` is play mode: the next matching unassigned card is served and
367
+ * claimed atomically (ADR §7).
368
+ */
369
+ export type ProspectNextRequest = Pick<SearchRequest, 'fullText' | 'query' | 'geoFilters'> & {
370
+ cursor?: string;
371
+ claim?: boolean;
372
+ /**
373
+ * Serve cards grouped by main vehicle (minimizing context switch): all matching cards anchored
374
+ * on the same vehicle come consecutively before "next" moves to the following vehicle group.
375
+ */
376
+ groupByVehicle?: boolean;
377
+ };
378
+
379
+ export type ProspectNextResponse = {
380
+ result?: SearchProspect;
381
+ cursor?: string;
382
+ meta: ReferenceData;
383
+ };
384
+
385
+ /** A main-vehicle group (ES collapse on `custom.groupKey`), shared by kanban and list. */
386
+ export type ProspectVehicleGroup = {
387
+ representative: SearchProspect;
388
+ items: SearchProspect[];
389
+ };
390
+
391
+ /** Flat list search, optionally collapsed by the card's main vehicle. */
392
+ export type ProspectsSearchRequest = SearchRequest & {
393
+ /** Collapse on `custom.groupKey`: the page then streams GROUPS (offset-paged), not rows. */
394
+ groupByVehicle?: boolean;
395
+ };
396
+
397
+ export type ProspectsSearchResponse = PaginatedList<SearchProspect, ReferenceData> & {
398
+ /**
399
+ * Populated only when `groupByVehicle` is requested; `results` is then empty and
400
+ * `totalCount` counts groups (collapse cardinality), not rows.
401
+ */
402
+ groups?: ProspectVehicleGroup[];
403
+ };
404
+
140
405
  /************
141
406
  *
142
407
  * Kanban
143
408
  */
144
409
 
410
+ /** A main-vehicle group inside a kanban column when `groupByVehicle` is on. */
411
+ export type KanbanProspectGroup = ProspectVehicleGroup;
412
+
145
413
  export type ProspectsKanbanColumn = {
146
414
  status: string;
147
415
  results: SearchProspect[];
416
+ /** Populated only when `groupByVehicle` is requested; `results` is then empty. */
417
+ groups?: KanbanProspectGroup[];
148
418
  totalCount: number;
149
419
  };
150
420
 
@@ -155,6 +425,13 @@ export type MSearchProspectsKanbanColumn = {
155
425
 
156
426
  export type KanbanProspectsSearchRequest = BaseSearchRequest & {
157
427
  nextTokens?: Record<string, string | undefined>;
428
+ /** Collapse each column by the card's main vehicle (mirrors opportunities' group-by-client). */
429
+ groupByVehicle?: boolean;
430
+ /**
431
+ * Per-column sort overrides, keyed by prospect status. Unlisted columns keep their defaults:
432
+ * the nurture column sorts by the priority→tier "next" order, the rest newest-first.
433
+ */
434
+ statusSortBy?: Partial<Record<ProspectStatus, SortFilter[]>>;
158
435
  };
159
436
 
160
437
  export type KanbanProspectsNextList = Omit<
@@ -0,0 +1,42 @@
1
+ export var QuoteActions;
2
+ (function (QuoteActions) {
3
+ QuoteActions["ACCEPT"] = "accept";
4
+ QuoteActions["VALIDATE"] = "validate";
5
+ QuoteActions["DONWLOAD_PDFS"] = "download-pdfs";
6
+ QuoteActions["CANCEL"] = "cancel";
7
+ })(QuoteActions || (QuoteActions = {}));
8
+ export var QuoteStatus;
9
+ (function (QuoteStatus) {
10
+ QuoteStatus["CREATED"] = "created";
11
+ QuoteStatus["VALIDATED"] = "validated";
12
+ QuoteStatus["INVALIDATED"] = "invalidated";
13
+ QuoteStatus["ACCEPTED"] = "accepted";
14
+ QuoteStatus["REJECTED"] = "rejected";
15
+ QuoteStatus["CANCELLED"] = "cancelled";
16
+ QuoteStatus["MANAGER_REJECTED"] = "managerRejected";
17
+ QuoteStatus["MANAGER_ACCEPTED"] = "managerAccepted";
18
+ })(QuoteStatus || (QuoteStatus = {}));
19
+ export var QuoteMetricsScore;
20
+ (function (QuoteMetricsScore) {
21
+ QuoteMetricsScore["DANGER"] = "danger";
22
+ QuoteMetricsScore["NEUTRAL"] = "neutral";
23
+ QuoteMetricsScore["GOOD"] = "good";
24
+ })(QuoteMetricsScore || (QuoteMetricsScore = {}));
25
+ export var DeliveryTypes;
26
+ (function (DeliveryTypes) {
27
+ DeliveryTypes["PICK_UP"] = "pickUp";
28
+ DeliveryTypes["ADDRESS"] = "address";
29
+ DeliveryTypes["PORT"] = "port";
30
+ })(DeliveryTypes || (DeliveryTypes = {}));
31
+ export var SpoilerInfo;
32
+ (function (SpoilerInfo) {
33
+ SpoilerInfo["MOUNT"] = "mount";
34
+ SpoilerInfo["UNMOUNT"] = "unmount";
35
+ SpoilerInfo["NO_ACTION"] = "noAction";
36
+ })(SpoilerInfo || (SpoilerInfo = {}));
37
+ export var TransportationMode;
38
+ (function (TransportationMode) {
39
+ TransportationMode["BY_ROAD"] = "byRoad";
40
+ TransportationMode["ON_LOW_BED"] = "onLowBed";
41
+ })(TransportationMode || (TransportationMode = {}));
42
+ //# sourceMappingURL=quotes.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=recently-viewed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recently-viewed.js","sourceRoot":"","sources":["recently-viewed.ts"],"names":[],"mappings":""}
@@ -108,6 +108,26 @@ export type SalesReportHistogramBucket = {
108
108
  count: number;
109
109
  };
110
110
 
111
+ /**
112
+ * Age-of-stock bands, in days of capital tied up. Cut points at 30 / 90 / 180 days,
113
+ * upper bound inclusive; the last band is open-ended, so `180+` means "181 and over".
114
+ */
115
+ export const STOCK_AGE_BANDS = ['0-30', '31-90', '91-180', '180+'] as const;
116
+
117
+ export type StockAgeBand = (typeof STOCK_AGE_BANDS)[number];
118
+
119
+ /**
120
+ * One day on the stock-age chart, measured by capital tied up in inventory. A vehicle
121
+ * counts on `date` when the supplier was fully paid on or before that day and it had not
122
+ * been sold yet; its age is `date − supplierFullyPaidAt` in days. Used vehicles only.
123
+ */
124
+ export type StockAgePoint = {
125
+ /** Snapshot day, `YYYY-MM-DD` (UTC). */
126
+ date: string;
127
+ /** In-stock vehicle count per age band on that day. */
128
+ counts: Record<StockAgeBand, number>;
129
+ };
130
+
111
131
  export type SalesReportResponse = {
112
132
  period: {
113
133
  key: SalesPeriodKey;
@@ -142,4 +162,16 @@ export type SalesReportResponse = {
142
162
  conglomerate: SalesReportConglomerate;
143
163
  /** Fixed last-18-calendar-months histogram of opps into Preparation (period-independent). */
144
164
  histogram: SalesReportHistogramBucket[];
165
+ /**
166
+ * Stock-age evolution measured as capital tied up in inventory: one daily snapshot of
167
+ * vehicles by days from supplier-fully-paid to sold (used vehicles). Fixed to the last
168
+ * 6 months, period-independent.
169
+ */
170
+ stockAge: StockAgePoint[];
171
+ /**
172
+ * Customer concentration: the 10 largest customers' share of units in the window, as a
173
+ * fraction (0–1); null when there are no sales. A risk signal — over-reliance on a few
174
+ * buyers.
175
+ */
176
+ concentration: number | null;
145
177
  };
@@ -0,0 +1,5 @@
1
+ export var ReservationActions;
2
+ (function (ReservationActions) {
3
+ ReservationActions["SET_RESERVATION_EXPIRE"] = "update_expires_at";
4
+ })(ReservationActions || (ReservationActions = {}));
5
+ //# sourceMappingURL=reservations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reservations.js","sourceRoot":"","sources":["reservations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,kBAEX;AAFD,WAAY,kBAAkB;IAC5B,kEAA4C,CAAA;AAC9C,CAAC,EAFW,kBAAkB,KAAlB,kBAAkB,QAE7B"}
@@ -0,0 +1,5 @@
1
+ export var DisplayType;
2
+ (function (DisplayType) {
3
+ DisplayType["StarsRating"] = "stars-rating";
4
+ })(DisplayType || (DisplayType = {}));
5
+ //# sourceMappingURL=roi-ratings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roi-ratings.js","sourceRoot":"","sources":["roi-ratings.ts"],"names":[],"mappings":"AAIA,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,2CAA4B,CAAA;AAC9B,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB"}
@@ -0,0 +1,9 @@
1
+ export var SavedFiltersActions;
2
+ (function (SavedFiltersActions) {
3
+ SavedFiltersActions["Share"] = "share";
4
+ SavedFiltersActions["Update"] = "update";
5
+ SavedFiltersActions["Delete"] = "delete";
6
+ SavedFiltersActions["SetPersonalDefault"] = "set_own_default";
7
+ SavedFiltersActions["SetGlobalDefault"] = "set_global_default";
8
+ })(SavedFiltersActions || (SavedFiltersActions = {}));
9
+ //# sourceMappingURL=saved-filters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-filters.js","sourceRoot":"","sources":["saved-filters.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,sCAAe,CAAA;IACf,wCAAiB,CAAA;IACjB,wCAAiB,CAAA;IACjB,6DAAsC,CAAA;IACtC,8DAAuC,CAAA;AACzC,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B"}
@@ -0,0 +1,2 @@
1
+ export * from '@bisondesk/commons-sdk/search';
2
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["search.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["settings.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["templates.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ export var TenantModule;
2
+ (function (TenantModule) {
3
+ TenantModule["Administration"] = "administration";
4
+ TenantModule["App"] = "app";
5
+ TenantModule["CRM"] = "crm";
6
+ TenantModule["Docs"] = "docs";
7
+ TenantModule["Leads"] = "leads";
8
+ TenantModule["Leasing"] = "leasing";
9
+ TenantModule["Marketing"] = "marketing";
10
+ TenantModule["Insights"] = "insights";
11
+ TenantModule["Opportunities"] = "opportunities";
12
+ TenantModule["Offers"] = "offers";
13
+ TenantModule["VehiclesMasterData"] = "vehicles_master_data";
14
+ TenantModule["Vehicles"] = "vehicles";
15
+ TenantModule["Tasks"] = "tasks";
16
+ TenantModule["TrackAndTrace"] = "track_and_trace";
17
+ TenantModule["Bootstrap"] = "bootstrap";
18
+ TenantModule["WhatsappNotifications"] = "whatsapp_notifications";
19
+ TenantModule["Hexon"] = "hexon";
20
+ })(TenantModule || (TenantModule = {}));
21
+ //# sourceMappingURL=tenants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenants.js","sourceRoot":"","sources":["tenants.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAN,IAAY,YAkBX;AAlBD,WAAY,YAAY;IACtB,iDAAiC,CAAA;IACjC,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,6BAAa,CAAA;IACb,+BAAe,CAAA;IACf,mCAAmB,CAAA;IACnB,uCAAuB,CAAA;IACvB,qCAAqB,CAAA;IACrB,+CAA+B,CAAA;IAC/B,iCAAiB,CAAA;IACjB,2DAA2C,CAAA;IAC3C,qCAAqB,CAAA;IACrB,+BAAe,CAAA;IACf,iDAAiC,CAAA;IACjC,uCAAuB,CAAA;IACvB,gEAAgD,CAAA;IAChD,+BAAe,CAAA;AACjB,CAAC,EAlBW,YAAY,KAAZ,YAAY,QAkBvB"}
@@ -0,0 +1,7 @@
1
+ export var CommissionGrade;
2
+ (function (CommissionGrade) {
3
+ CommissionGrade["TooLow"] = "tooLow";
4
+ CommissionGrade["Low"] = "low";
5
+ CommissionGrade["OnTarget"] = "onTarget";
6
+ })(CommissionGrade || (CommissionGrade = {}));
7
+ //# sourceMappingURL=user-performance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-performance.js","sourceRoot":"","sources":["user-performance.ts"],"names":[],"mappings":"AAsCA,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,oCAAiB,CAAA;IACjB,8BAAW,CAAA;IACX,wCAAqB,CAAA;AACvB,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B"}
@@ -13,8 +13,10 @@ type BaseUser = {
13
13
  jobTitle?: string;
14
14
  language: string;
15
15
  lastName: string;
16
+ nationality?: string;
16
17
  picture?: AttachmentValue;
17
18
  roles: AppRoles[];
19
+ spokenLanguages?: string[];
18
20
  preferredBranchIds?: string[];
19
21
  preferredOpportunityTypes?: OpportunityType[];
20
22
  };
@@ -0,0 +1,2 @@
1
+ export * from '@bisondesk/commons-sdk/utils';
2
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export var VehicleSaleInfoActions;
2
+ (function (VehicleSaleInfoActions) {
3
+ VehicleSaleInfoActions["VIEW_COSTS"] = "canSeeCosts";
4
+ VehicleSaleInfoActions["VIEW_CUSTOMER"] = "canSeeCustomer";
5
+ })(VehicleSaleInfoActions || (VehicleSaleInfoActions = {}));
6
+ //# sourceMappingURL=vehicle-sales.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vehicle-sales.js","sourceRoot":"","sources":["vehicle-sales.ts"],"names":[],"mappings":"AAOA,MAAM,CAAN,IAAY,sBAGX;AAHD,WAAY,sBAAsB;IAChC,oDAA0B,CAAA;IAC1B,0DAAgC,CAAA;AAClC,CAAC,EAHW,sBAAsB,KAAtB,sBAAsB,QAGjC"}