@bisondesk/core-sdk 1.0.602 → 1.0.604
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/types/activities.d.ts +1 -0
- package/lib/types/activities.d.ts.map +1 -1
- package/lib/types/activities.js.map +1 -1
- package/lib/types/crm.d.ts +1 -0
- package/lib/types/crm.d.ts.map +1 -1
- package/lib/types/crm.js.map +1 -1
- package/lib/types/opportunities.d.ts +1 -0
- package/lib/types/opportunities.d.ts.map +1 -1
- package/lib/types/opportunities.js.map +1 -1
- package/lib/types/reports-sales.d.ts +67 -0
- package/lib/types/reports-sales.d.ts.map +1 -0
- package/lib/types/reports-sales.js +13 -0
- package/lib/types/reports-sales.js.map +1 -0
- package/lib/types/vehicle-performance.d.ts +2 -0
- package/lib/types/vehicle-performance.d.ts.map +1 -1
- package/lib/types/vehicle-performance.js.map +1 -1
- package/package.json +1 -1
- package/src/types/activities.ts +1 -0
- package/src/types/crm.ts +1 -0
- package/src/types/opportunities.ts +1 -0
- package/src/types/reports-sales.ts +126 -0
- package/src/types/vehicle-performance.ts +3 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sales report — the payload for the `Reports → Sales` tab. Everything is computed
|
|
3
|
+
* from the per-tenant `opportunities` OpenSearch index, keyed on
|
|
4
|
+
* `opportunity.reviewedAt` (the moment an opportunity ENTERS Preparation — our
|
|
5
|
+
* "sale" event; `preparedAt` is when it leaves Preparation into Delivery).
|
|
6
|
+
*
|
|
7
|
+
* The API returns raw numbers only; the client formats (€, %, pp, "younger") and
|
|
8
|
+
* colors the deltas.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Period presets driving every metric except the fixed 18-month histogram, in
|
|
13
|
+
* selector order. Single source of truth — `SalesPeriodKey` is derived from it.
|
|
14
|
+
* `mtd`/`ytd` are to-date ranges (start of month/year → now); `lastMonth`/`lastYear`
|
|
15
|
+
* are the previous complete calendar month/year.
|
|
16
|
+
*/
|
|
17
|
+
export const SALES_PERIOD_KEYS = [
|
|
18
|
+
'30d',
|
|
19
|
+
'45d',
|
|
20
|
+
'60d',
|
|
21
|
+
'90d',
|
|
22
|
+
'lastMonth',
|
|
23
|
+
'mtd',
|
|
24
|
+
'ytd',
|
|
25
|
+
'lastYear',
|
|
26
|
+
'12m',
|
|
27
|
+
] as const;
|
|
28
|
+
|
|
29
|
+
export type SalesPeriodKey = (typeof SALES_PERIOD_KEYS)[number];
|
|
30
|
+
|
|
31
|
+
export const DEFAULT_SALES_PERIOD: SalesPeriodKey = 'mtd';
|
|
32
|
+
|
|
33
|
+
export type SalesReportRequest = { period: SalesPeriodKey };
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A metric for the selected window with its year-over-year counterpart.
|
|
37
|
+
* - `value`: current window (null when undefined, e.g. no data / no median).
|
|
38
|
+
* - `prev`: same metric in the window shifted back exactly one year.
|
|
39
|
+
* - `pct`: fractional change `(value - prev) / prev` (null when prev is 0 or
|
|
40
|
+
* either side is undefined). The client renders/colors the delta.
|
|
41
|
+
*/
|
|
42
|
+
export type YoyMetric = { value: number | null; prev: number | null; pct: number | null };
|
|
43
|
+
|
|
44
|
+
/** Tenure buckets for returning-customer analysis (share of buyers in the window). */
|
|
45
|
+
export type TenureBucketKey = '2y' | '1-2y' | '<1y' | 'new';
|
|
46
|
+
|
|
47
|
+
export type TenureBucket = {
|
|
48
|
+
bucket: TenureBucketKey;
|
|
49
|
+
/** Share of buyers in this bucket, 0–100. */
|
|
50
|
+
sharePct: number;
|
|
51
|
+
/** Year-over-year change in this share, as a fractional relative change (null when no prior data). */
|
|
52
|
+
yoyPct: number | null;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type SalesReportCountry = {
|
|
56
|
+
/** ISO country code (lowercase) from `org.countryCode`. */
|
|
57
|
+
code: string;
|
|
58
|
+
units: number;
|
|
59
|
+
yoyPct: number | null;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type SalesReportSalesperson = {
|
|
63
|
+
/** User id from `opportunity.accountManager`; the client resolves name + avatar. */
|
|
64
|
+
id: string;
|
|
65
|
+
units: number;
|
|
66
|
+
yoyPct: number | null;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** A conglomerate-flagged organization (there is no group/parent model — each org stands alone). */
|
|
70
|
+
export type SalesReportConglomerateOrg = {
|
|
71
|
+
/** `org.id`. */
|
|
72
|
+
id: string;
|
|
73
|
+
/** `org.name` (resolved server-side); falls back to the id when missing. */
|
|
74
|
+
name: string;
|
|
75
|
+
units: number;
|
|
76
|
+
yoyPct: number | null;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type SalesReportConglomerate = {
|
|
80
|
+
/** Share of units going to conglomerate-flagged customers, 0–100 (null when no sales). */
|
|
81
|
+
sharePct: number | null;
|
|
82
|
+
/** Year-over-year change in that share, as a fractional relative change (null when no prior data). */
|
|
83
|
+
yoyPct: number | null;
|
|
84
|
+
/** The conglomerate share in the year-ago window, 0–100. */
|
|
85
|
+
lastYearPct: number | null;
|
|
86
|
+
/** Top conglomerate-flagged organizations by units in the current window. */
|
|
87
|
+
orgs: SalesReportConglomerateOrg[];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type SalesReportHistogramBucket = {
|
|
91
|
+
/** Calendar month, `YYYY-MM`. */
|
|
92
|
+
month: string;
|
|
93
|
+
count: number;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type SalesReportResponse = {
|
|
97
|
+
period: {
|
|
98
|
+
key: SalesPeriodKey;
|
|
99
|
+
/** Current window, half-open `[start, end)` (ISO strings). */
|
|
100
|
+
start: string;
|
|
101
|
+
end: string;
|
|
102
|
+
/** Number of days in the window (the `salesPerDay` denominator). */
|
|
103
|
+
days: number;
|
|
104
|
+
/** Year-ago window `[yoyStart, yoyEnd)`. */
|
|
105
|
+
yoyStart: string;
|
|
106
|
+
yoyEnd: string;
|
|
107
|
+
};
|
|
108
|
+
/** All-types overview KPIs. `medianAge` is in years (a decrease is good — younger stock). */
|
|
109
|
+
overview: {
|
|
110
|
+
salesPerDay: YoyMetric;
|
|
111
|
+
salesTotal: YoyMetric;
|
|
112
|
+
medianRoi: YoyMetric;
|
|
113
|
+
medianPrice: YoyMetric;
|
|
114
|
+
medianAge: YoyMetric;
|
|
115
|
+
uniqueCustomers: YoyMetric;
|
|
116
|
+
};
|
|
117
|
+
/** Top countries by units in the current window. */
|
|
118
|
+
countries: SalesReportCountry[];
|
|
119
|
+
/** All sales people with units in either window (capped; the client list scrolls). */
|
|
120
|
+
salespeople: SalesReportSalesperson[];
|
|
121
|
+
/** Returning-customer tenure shares (4 buckets). */
|
|
122
|
+
returning: TenureBucket[];
|
|
123
|
+
conglomerate: SalesReportConglomerate;
|
|
124
|
+
/** Fixed last-18-calendar-months histogram of opps into Preparation (period-independent). */
|
|
125
|
+
histogram: SalesReportHistogramBucket[];
|
|
126
|
+
};
|
|
@@ -33,6 +33,7 @@ export type VehicleSaleOverview = {
|
|
|
33
33
|
createdAt: string;
|
|
34
34
|
engagedAt?: string;
|
|
35
35
|
acceptedAt?: string;
|
|
36
|
+
firstAcceptedAt?: string;
|
|
36
37
|
validatedAt?: string;
|
|
37
38
|
reviewedAt?: string;
|
|
38
39
|
preparedAt?: string;
|
|
@@ -47,6 +48,7 @@ export type VehicleSaleOverview = {
|
|
|
47
48
|
lastInvoiceIssuedAt?: string;
|
|
48
49
|
firstPaymentAt?: string;
|
|
49
50
|
fullPaymentAt?: string;
|
|
51
|
+
daysSaleUnpaid?: number;
|
|
50
52
|
expectedAmount: string; // from quote(s)
|
|
51
53
|
actualAmount: string; // from all invoices
|
|
52
54
|
lifetimeActualAmount: string; // sum of all invoices from all opportunities for this vehicle
|
|
@@ -146,7 +148,7 @@ export type VehicleBusinessOverviewXL = VehicleBusinessOverview & {
|
|
|
146
148
|
daysInRealInventory?: number; // days since check-in until opportunity goes to Review (vehicle reserved)
|
|
147
149
|
daysInVirtualInventory?: number; // days since vehicle created in the system until opportunity goes to Review
|
|
148
150
|
cashConversionCycle?: number; // days since full payment sent until full payment received
|
|
149
|
-
daysSaleUnpaid?: number; // days
|
|
151
|
+
daysSaleUnpaid?: number; // days from first Review until fully paid
|
|
150
152
|
};
|
|
151
153
|
};
|
|
152
154
|
|