@bisondesk/core-sdk 1.0.599 → 1.0.601

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 (41) hide show
  1. package/lib/apis/leasing.d.ts +1 -0
  2. package/lib/apis/leasing.d.ts.map +1 -1
  3. package/lib/apis/leasing.js +18 -0
  4. package/lib/apis/leasing.js.map +1 -1
  5. package/lib/types/activities.d.ts +7 -0
  6. package/lib/types/activities.d.ts.map +1 -1
  7. package/lib/types/activities.js.map +1 -1
  8. package/lib/types/analysis-purchases.d.ts +77 -0
  9. package/lib/types/analysis-purchases.d.ts.map +1 -0
  10. package/lib/types/analysis-purchases.js +2 -0
  11. package/lib/types/analysis-purchases.js.map +1 -0
  12. package/lib/types/import-markup.d.ts +6 -0
  13. package/lib/types/import-markup.d.ts.map +1 -0
  14. package/lib/types/import-markup.js +2 -0
  15. package/lib/types/import-markup.js.map +1 -0
  16. package/lib/types/leasing-debtors.d.ts +4 -1
  17. package/lib/types/leasing-debtors.d.ts.map +1 -1
  18. package/lib/types/leasing-debtors.js.map +1 -1
  19. package/lib/types/leasing-search.d.ts +2 -0
  20. package/lib/types/leasing-search.d.ts.map +1 -1
  21. package/lib/types/leasing-search.js.map +1 -1
  22. package/lib/types/offers.d.ts +1 -0
  23. package/lib/types/offers.d.ts.map +1 -1
  24. package/lib/types/offers.js.map +1 -1
  25. package/lib/types/opportunities.d.ts +1 -1
  26. package/lib/types/opportunities.d.ts.map +1 -1
  27. package/lib/types/opportunities.js.map +1 -1
  28. package/lib/types/vehicles.d.ts +1 -0
  29. package/lib/types/vehicles.d.ts.map +1 -1
  30. package/lib/types/vehicles.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/apis/leasing.ts +26 -0
  33. package/src/types/activities.ts +9 -0
  34. package/src/types/analysis-purchases.ts +128 -0
  35. package/src/types/import-markup.ts +34 -0
  36. package/src/types/leasing-debtors.ts +6 -1
  37. package/src/types/leasing-search.ts +2 -0
  38. package/src/types/offers.ts +1 -0
  39. package/src/types/opportunities.ts +10 -7
  40. package/src/types/vehicles.ts +2 -0
  41. package/tsconfig.tsbuildinfo +1 -1
@@ -14,6 +14,12 @@ export enum ActivityActions {
14
14
  EDIT = 'edit',
15
15
  }
16
16
 
17
+ export type ActivityContact = {
18
+ id?: string;
19
+ phoneNumber?: string;
20
+ email?: string;
21
+ };
22
+
17
23
  export interface BaseActivity<Meta = ActivityV2Meta> {
18
24
  type: ActivityType;
19
25
  businessEntityId: BusinessEntityIds;
@@ -21,6 +27,8 @@ export interface BaseActivity<Meta = ActivityV2Meta> {
21
27
  description?: string;
22
28
  readonly?: boolean;
23
29
  meta?: Meta;
30
+ // The people called/emailed/etc in this activity.
31
+ contacts?: ActivityContact[];
24
32
  }
25
33
 
26
34
  export type NewActivity<Meta = ActivityV2Meta> = BaseActivity<Meta> & {
@@ -45,6 +53,7 @@ export type ActivityUpdate = {
45
53
  description?: string;
46
54
  type?: ActivityType;
47
55
  activityAt?: string;
56
+ contacts?: ActivityContact[];
48
57
  };
49
58
 
50
59
  export type ActivityEvent = BaseEvent &
@@ -0,0 +1,128 @@
1
+ import { ReferenceData } from '@bisondesk/commons-sdk/utils';
2
+
3
+ export type AnalysisPurchasesMeta = {
4
+ referenceData: ReferenceData;
5
+ };
6
+
7
+ // ──────────────────────────────────────────────────────────────────────────
8
+ // Segment insights ("what segment should we buy").
9
+ //
10
+ // A "segment" is a MINED combination of vehicle attributes (category + 1..N of
11
+ // make+model, body style, euro norm, axle config, HP/age/mileage band, features)
12
+ // discovered by frequent-itemset mining over the stock and sold
13
+ // populations — as shallow as `Tipper · 6x4` or as deep as a near-full spec,
14
+ // wherever the sales evidence sits. Segments overlap: one vehicle can belong
15
+ // to several. Hot/cold rank the two ends of days-of-supply.
16
+ // ──────────────────────────────────────────────────────────────────────────
17
+
18
+ export type AnalysisPurchasesRequest = {
19
+ /** ISO date, inclusive */
20
+ from: string;
21
+ /** ISO date, exclusive */
22
+ to: string;
23
+ };
24
+
25
+ /** One component of a composite segment key (e.g. `{ dimension: 'make', label: 'DAF' }`). */
26
+ export type SegmentPart = { dimension: string; key: string; label: string };
27
+
28
+ export type SegmentExampleVehicle = {
29
+ vehicleId: string;
30
+ stockNumber: string;
31
+ imageUrl?: string;
32
+ };
33
+
34
+ export type SegmentVehicle = {
35
+ vehicleId: string;
36
+ stockNumber: string;
37
+ /** Precomputed vehicle display title (`vehicle.internal.description.title`). */
38
+ title?: string;
39
+ imageUrl?: string;
40
+ make: string;
41
+ modelName?: string;
42
+ advertisingYear?: number;
43
+ axleConfiguration?: string;
44
+ horsepower?: number;
45
+ currentPrice?: number;
46
+ /** Odometer reading in km (`vehicle.external.condition.odometer.km`). */
47
+ mileage?: number;
48
+ /** Registration country code, e.g. "BE" (`…history.currentRegistration.country`). */
49
+ countryCode?: string;
50
+ /** Sold units: the winning opportunity (`sale.opportunityId`) — for price + future deal details. */
51
+ opportunityId?: string;
52
+ /** Sold units: realized sale price (the won opportunity's amount). */
53
+ soldPrice?: number;
54
+ /** Hot (sold) examples: days from virtual-inventory entry to sale. */
55
+ daysToSell?: number;
56
+ /** Cold (stock) examples: days the unit has sat in inventory. */
57
+ daysOnLot?: number;
58
+ };
59
+
60
+ export type SegmentSummary = {
61
+ /** Stable composite key (join of each key-dimension's bucket key). */
62
+ key: string;
63
+ /** Human label, e.g. "DAF XF · Euro 6 · 4x2 · 450–499 HP · Lowdeck + Retarder". */
64
+ label: string;
65
+ parts: SegmentPart[];
66
+ customers: number;
67
+ /** Vehicles in this segment sold within the window (vehicle `custom.sold` + `sale.soldAt`). */
68
+ sold: number;
69
+ /**
70
+ * Days of supply: how long current unsold stock lasts at the window's sales rate
71
+ * (`stock × windowDays / sold`). Lower = runs out sooner = buy more. Undefined
72
+ * when nothing sold. This is the Hot ranking signal.
73
+ */
74
+ supplyDays?: number;
75
+ /** Days since the most recent purchase (check-in) of a unit in this segment. */
76
+ daysSinceLastPurchase?: number;
77
+ /** Days since the most recent sale of a unit in this segment. */
78
+ daysSinceLastSale?: number;
79
+ daysAvailableMedian?: number;
80
+ stock: number;
81
+ /**
82
+ * Median price for the segment: realized SALE price on the hot list (the won
83
+ * opportunities' amounts), current LIST price on the cold list. Undefined when
84
+ * the underlying units carry no price.
85
+ */
86
+ priceMedian?: number;
87
+ /** Populated only on the hot / cold lists. */
88
+ examples?: SegmentExampleVehicle[];
89
+ };
90
+
91
+ export type AnalysisPurchasesResponse = {
92
+ totals: {
93
+ stock: number;
94
+ /** Vehicles sold in the window (core categories) — the hot coverage denominator. */
95
+ sold: number;
96
+ /** Of those, how many fall in at least one hot (fast-moving) segment. */
97
+ hotSold: number;
98
+ /** Stock units falling in at least one cold (overstocked) segment. */
99
+ coldStock: number;
100
+ };
101
+ /** Under-supplied segments (buy more), each with in-demand example vehicles. */
102
+ hot: SegmentSummary[];
103
+ /** Over-supplied segments (slow down), each with stock-on-lot example vehicles. */
104
+ cold: SegmentSummary[];
105
+ meta: AnalysisPurchasesMeta;
106
+ };
107
+
108
+ /** Expand one segment into its individual units (the detail drawer). */
109
+ export type SegmentUnitsRequest = AnalysisPurchasesRequest & {
110
+ /** Composite key of the segment to expand (a `SegmentSummary.key`). */
111
+ segmentKey: string;
112
+ /** Which list the segment came from — selects in-stock (cold) vs sold (hot) units. */
113
+ variant: 'hot' | 'cold';
114
+ };
115
+
116
+ export type SegmentUnitsResponse = {
117
+ key: string;
118
+ label: string;
119
+ parts: SegmentPart[];
120
+ variant: 'hot' | 'cold';
121
+ /** Segment-level counts (mirror SegmentSummary) so the drawer header needs no re-derivation. */
122
+ stock: number;
123
+ sold: number;
124
+ supplyDays?: number;
125
+ /** All units in the segment — in-stock with `daysOnLot` (cold) or sold with `daysToSell` (hot). */
126
+ units: SegmentVehicle[];
127
+ meta: AnalysisPurchasesMeta;
128
+ };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Per-tenant rule that marks up the **advertised** price of cross-tenant vehicle
3
+ * copies, without touching the cost recorded on the receiving tenant's purchase
4
+ * deal. Exactly one rule per tenant (singleton). Applied during cross-tenant sync
5
+ * while BisonDesk still owns the price (deal status `Marketing`); once an operator
6
+ * takes over pricing the rule no longer re-applies, so the markup never compounds.
7
+ *
8
+ * See `cross-tenant-sync/vehicles/markup.ts` for the application logic.
9
+ */
10
+ export type ImportMarkupRule = {
11
+ /**
12
+ * Percentage added on top of the converted cost, e.g. `15` for +15%. `0` (or an
13
+ * absent rule) is a no-op — behaviour is identical to having no markup at all.
14
+ */
15
+ markupPercent: number;
16
+ /**
17
+ * Optional absolute floor on the margin amount, expressed in the tenant's
18
+ * `defaultCurrency`. Converted to the target branch currency at apply-time. When
19
+ * the percentage markup yields a smaller margin than this, the floor wins:
20
+ * `price = max(cost × (1 + markupPercent/100), cost + minMargin)`. Only applied
21
+ * to the primary branch-currency `price`/`previousPrice`, never to the
22
+ * multi-currency `localizedPricing` entries (where an absolute floor is undefined
23
+ * without per-currency configuration).
24
+ */
25
+ minMargin?: number;
26
+ /**
27
+ * Optional rounding granularity for the primary branch-currency
28
+ * `price`/`previousPrice`. The marked-up amount is rounded **up** to the nearest
29
+ * multiple of `roundingStep`, so rounding never undercuts the intended margin.
30
+ * Example: `1000` turns 47 320 into 48 000. `localizedPricing` entries are rounded
31
+ * to whole units only.
32
+ */
33
+ roundingStep?: number;
34
+ };
@@ -18,6 +18,7 @@ export type MonthData = {
18
18
 
19
19
  export type DebtorInfo = {
20
20
  clientId: string;
21
+ branchIds: string[];
21
22
  months: MonthData[];
22
23
 
23
24
  // properties related to the current month
@@ -247,6 +248,7 @@ export type LegalDossier = {
247
248
  id: string;
248
249
  debtorDossierId: string;
249
250
  caseNumber?: string;
251
+ courtDate?: string; // ISO date string (YYYY-MM-DD)
250
252
  notes?: string;
251
253
  createdAt: string;
252
254
  createdBy: string;
@@ -260,7 +262,9 @@ export type NewLegalDossier = Omit<
260
262
  'id' | 'createdAt' | 'updatedAt' | 'createdBy' | 'updatedBy'
261
263
  >;
262
264
 
263
- export type UpdateLegalDossier = Partial<Pick<LegalDossier, 'caseNumber' | 'status' | 'notes'>>;
265
+ export type UpdateLegalDossier = Partial<
266
+ Pick<LegalDossier, 'caseNumber' | 'courtDate' | 'status' | 'notes'>
267
+ >;
264
268
 
265
269
  /******
266
270
  * Debtor Dossier Events
@@ -307,6 +311,7 @@ export type SearchDebtorsDossier = {
307
311
  legalDossier?: LegalDossier;
308
312
  paymentPlan?: DebtorsPaymentPlan;
309
313
  hasPaymentPlan?: boolean;
314
+ branchIds?: string[];
310
315
  tasks: {
311
316
  totalTasks: number;
312
317
  openTasks: number;
@@ -25,6 +25,8 @@ export type SearchLeasingContract = {
25
25
  lastIssuedInvoiceDate?: string;
26
26
  dealRating?: number;
27
27
  supplierName?: string;
28
+ hasActiveRecurrence?: boolean;
29
+ lastRecurrenceRunAt?: string;
28
30
  };
29
31
  };
30
32
 
@@ -274,6 +274,7 @@ export type SearchOffer = {
274
274
  totalBids: number;
275
275
  bidders: string[];
276
276
  missingSupplier: boolean;
277
+ accountManagers: string[];
277
278
  };
278
279
  };
279
280
 
@@ -140,13 +140,16 @@ type BaseOpportunity = {
140
140
  branchCountry: string;
141
141
  };
142
142
 
143
- export type NewOpportunity = BaseOpportunity & {
144
- id?: undefined;
145
- createdAt?: undefined;
146
- createdBy?: undefined;
147
- modifiedAt?: undefined;
148
- modifiedBy?: undefined;
149
- };
143
+ // type, branch and branchCountry are optional: when omitted, the server defaults them
144
+ // from the requester's preferred branches/opportunity types, then the tenant defaults.
145
+ export type NewOpportunity = Omit<BaseOpportunity, 'type' | 'branch' | 'branchCountry'> &
146
+ Partial<Pick<BaseOpportunity, 'type' | 'branch' | 'branchCountry'>> & {
147
+ id?: undefined;
148
+ createdAt?: undefined;
149
+ createdBy?: undefined;
150
+ modifiedAt?: undefined;
151
+ modifiedBy?: undefined;
152
+ };
150
153
 
151
154
  export enum VehicleSaleDealStatus {
152
155
  SaleAgreed = 'SALE_AGREED',
@@ -251,6 +251,8 @@ export type SearchVehicle = {
251
251
  priceChangedAt?: string;
252
252
  checkedInAt?: string;
253
253
  saleAgreementAt?: string;
254
+ /** Date the vehicle entered virtual inventory (marketing ?? evaluation ?? purchase-agreed). */
255
+ virtualInventoryStartedAt?: string;
254
256
  };
255
257
  purchase?: {
256
258
  supplierStockNumber?: string;