@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.
- package/lib/apis/leasing.d.ts +1 -0
- package/lib/apis/leasing.d.ts.map +1 -1
- package/lib/apis/leasing.js +18 -0
- package/lib/apis/leasing.js.map +1 -1
- package/lib/types/activities.d.ts +7 -0
- package/lib/types/activities.d.ts.map +1 -1
- package/lib/types/activities.js.map +1 -1
- package/lib/types/analysis-purchases.d.ts +77 -0
- package/lib/types/analysis-purchases.d.ts.map +1 -0
- package/lib/types/analysis-purchases.js +2 -0
- package/lib/types/analysis-purchases.js.map +1 -0
- package/lib/types/import-markup.d.ts +6 -0
- package/lib/types/import-markup.d.ts.map +1 -0
- package/lib/types/import-markup.js +2 -0
- package/lib/types/import-markup.js.map +1 -0
- package/lib/types/leasing-debtors.d.ts +4 -1
- package/lib/types/leasing-debtors.d.ts.map +1 -1
- package/lib/types/leasing-debtors.js.map +1 -1
- package/lib/types/leasing-search.d.ts +2 -0
- package/lib/types/leasing-search.d.ts.map +1 -1
- package/lib/types/leasing-search.js.map +1 -1
- package/lib/types/offers.d.ts +1 -0
- package/lib/types/offers.d.ts.map +1 -1
- package/lib/types/offers.js.map +1 -1
- package/lib/types/opportunities.d.ts +1 -1
- package/lib/types/opportunities.d.ts.map +1 -1
- package/lib/types/opportunities.js.map +1 -1
- package/lib/types/vehicles.d.ts +1 -0
- package/lib/types/vehicles.d.ts.map +1 -1
- package/lib/types/vehicles.js.map +1 -1
- package/package.json +1 -1
- package/src/apis/leasing.ts +26 -0
- package/src/types/activities.ts +9 -0
- package/src/types/analysis-purchases.ts +128 -0
- package/src/types/import-markup.ts +34 -0
- package/src/types/leasing-debtors.ts +6 -1
- package/src/types/leasing-search.ts +2 -0
- package/src/types/offers.ts +1 -0
- package/src/types/opportunities.ts +10 -7
- package/src/types/vehicles.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/types/activities.ts
CHANGED
|
@@ -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<
|
|
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;
|
package/src/types/offers.ts
CHANGED
|
@@ -140,13 +140,16 @@ type BaseOpportunity = {
|
|
|
140
140
|
branchCountry: string;
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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',
|
package/src/types/vehicles.ts
CHANGED
|
@@ -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;
|