@bisondesk/core-sdk 1.0.442 → 1.0.444
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/opportunities.d.ts +1 -0
- package/lib/apis/opportunities.d.ts.map +1 -1
- package/lib/apis/opportunities.js +12 -0
- package/lib/apis/opportunities.js.map +1 -1
- package/lib/apis/vehicles.js +1 -1
- package/lib/apis/vehicles.js.map +1 -1
- package/lib/types/opportunities.d.ts +15 -36
- package/lib/types/opportunities.d.ts.map +1 -1
- package/lib/types/opportunities.js.map +1 -1
- package/lib/types/user-performance.d.ts +85 -0
- package/lib/types/user-performance.d.ts.map +1 -0
- package/lib/types/user-performance.js +7 -0
- package/lib/types/user-performance.js.map +1 -0
- package/lib/types/vehicle-performance.d.ts +78 -0
- package/lib/types/vehicle-performance.d.ts.map +1 -0
- package/lib/types/vehicle-performance.js +2 -0
- package/lib/types/vehicle-performance.js.map +1 -0
- package/lib/utils/vehicles.js +1 -1
- package/lib/utils/vehicles.js.map +1 -1
- package/package.json +1 -1
- package/src/apis/opportunities.ts +20 -0
- package/src/apis/vehicles.ts +1 -1
- package/src/types/opportunities.ts +16 -37
- package/src/types/user-performance.ts +103 -0
- package/src/types/vehicle-performance.ts +106 -0
- package/src/utils/vehicles.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { OpportunityType } from '../constants.js';
|
|
2
|
+
import { VehicleSaleDealStatus, VehicleSaleLogisticsStatus } from './opportunities.js';
|
|
3
|
+
import { VehiclePurchaseDealStatus, VehiclePurchaseLogisticsStatus } from './vehicles.js';
|
|
4
|
+
export type VehicleSaleOverview = {
|
|
5
|
+
opportunityId: string;
|
|
6
|
+
type: OpportunityType;
|
|
7
|
+
userId: string;
|
|
8
|
+
clientId: string;
|
|
9
|
+
clientCode: number;
|
|
10
|
+
clientCountryCode: string;
|
|
11
|
+
clientVat?: string;
|
|
12
|
+
conglomerate?: boolean;
|
|
13
|
+
clientEmail?: string;
|
|
14
|
+
clientPhone?: string;
|
|
15
|
+
dealStatus: VehicleSaleDealStatus;
|
|
16
|
+
logisticsStatus: VehicleSaleLogisticsStatus;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
engagedAt?: string;
|
|
19
|
+
acceptedAt?: string;
|
|
20
|
+
validatedAt?: string;
|
|
21
|
+
reviewedAt?: string;
|
|
22
|
+
preparedAt?: string;
|
|
23
|
+
deliveredAt?: string;
|
|
24
|
+
wonAt?: string;
|
|
25
|
+
saleAt?: string;
|
|
26
|
+
firstInvoiceIssuedAt?: string;
|
|
27
|
+
lastInvoiceIssuedAt?: string;
|
|
28
|
+
firstPaymentAt?: string;
|
|
29
|
+
fullPaymentAt?: string;
|
|
30
|
+
expectedAmount: string;
|
|
31
|
+
actualAmount: string;
|
|
32
|
+
lifetimeActualAmount: string;
|
|
33
|
+
hasMainInvoice?: boolean;
|
|
34
|
+
};
|
|
35
|
+
export type VehiclePurchaseOverview = {
|
|
36
|
+
userId: string;
|
|
37
|
+
dealStatus: VehiclePurchaseDealStatus;
|
|
38
|
+
logisticsStatus: VehiclePurchaseLogisticsStatus;
|
|
39
|
+
supplierId: string;
|
|
40
|
+
supplierCode: string;
|
|
41
|
+
supplierCountryCode: string;
|
|
42
|
+
supplierVat?: string;
|
|
43
|
+
conglomerate?: boolean;
|
|
44
|
+
supplierEmail?: string;
|
|
45
|
+
supplierPhone?: string;
|
|
46
|
+
firstInvoiceIssuedAt?: string;
|
|
47
|
+
lastInvoiceIssuedAt?: string;
|
|
48
|
+
firstPaymentAt?: string;
|
|
49
|
+
fullPaymentAt?: string;
|
|
50
|
+
expectedAmount: string;
|
|
51
|
+
actualAmount: string;
|
|
52
|
+
purchaseAt?: string;
|
|
53
|
+
marketingAt?: string;
|
|
54
|
+
evaluationAt?: string;
|
|
55
|
+
purchaseAgreedAt?: string;
|
|
56
|
+
arrivedAt?: string;
|
|
57
|
+
checkedInAt?: string;
|
|
58
|
+
hasMainInvoice?: boolean;
|
|
59
|
+
};
|
|
60
|
+
export type VehicleProfitOverview = {
|
|
61
|
+
expectedProfit?: string;
|
|
62
|
+
expectedRoi?: string;
|
|
63
|
+
actualProfit?: string;
|
|
64
|
+
actualRoi?: string;
|
|
65
|
+
};
|
|
66
|
+
type VehicleSummary = {
|
|
67
|
+
branch: string;
|
|
68
|
+
stockNumber: string;
|
|
69
|
+
id: string;
|
|
70
|
+
};
|
|
71
|
+
export type VehicleBusinessOverview = {
|
|
72
|
+
vehicle: VehicleSummary;
|
|
73
|
+
purchase: VehiclePurchaseOverview;
|
|
74
|
+
sale?: VehicleSaleOverview;
|
|
75
|
+
profit?: VehicleProfitOverview;
|
|
76
|
+
};
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=vehicle-performance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vehicle-performance.d.ts","sourceRoot":"/","sources":["types/vehicle-performance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vehicle-performance.js","sourceRoot":"/","sources":["types/vehicle-performance.ts"],"names":[],"mappings":"","sourcesContent":["import { OpportunityType } from '../constants.js';\nimport { VehicleSaleDealStatus, VehicleSaleLogisticsStatus } from './opportunities.js';\nimport { VehiclePurchaseDealStatus, VehiclePurchaseLogisticsStatus } from './vehicles.js';\n\nexport type VehicleSaleOverview = {\n opportunityId: string;\n type: OpportunityType;\n userId: string; // account manager of the latest opportunity (if opportunity is >= review)\n\n // client details\n clientId: string;\n clientCode: number;\n clientCountryCode: string;\n clientVat?: string;\n conglomerate?: boolean;\n clientEmail?: string;\n clientPhone?: string;\n\n // vehicle details\n dealStatus: VehicleSaleDealStatus;\n logisticsStatus: VehicleSaleLogisticsStatus;\n\n // opportunity dates\n createdAt: string;\n engagedAt?: string;\n acceptedAt?: string;\n validatedAt?: string;\n reviewedAt?: string;\n preparedAt?: string;\n deliveredAt?: string;\n wonAt?: string;\n\n saleAt?: string; // this is the date that should be considered for the sale according to TJ (often the same as fullPaymentAt)\n\n // money-related details\n firstInvoiceIssuedAt?: string;\n lastInvoiceIssuedAt?: string;\n firstPaymentAt?: string;\n fullPaymentAt?: string;\n expectedAmount: string; // from quote(s)\n actualAmount: string; // from all invoices\n lifetimeActualAmount: string; // sum of all invoices from all opportunities for this vehicle\n\n // is there an invoice with category related to the purchase of commercial vehicle\n // (we probably need a way to flag those categories since it is also important for the stocklist)\n hasMainInvoice?: boolean;\n};\n\nexport type VehiclePurchaseOverview = {\n userId: string; // purchaser\n\n dealStatus: VehiclePurchaseDealStatus;\n logisticsStatus: VehiclePurchaseLogisticsStatus;\n\n supplierId: string;\n supplierCode: string;\n supplierCountryCode: string;\n supplierVat?: string;\n conglomerate?: boolean;\n supplierEmail?: string;\n supplierPhone?: string;\n\n // money-related details\n firstInvoiceIssuedAt?: string;\n lastInvoiceIssuedAt?: string;\n firstPaymentAt?: string;\n fullPaymentAt?: string;\n expectedAmount: string;\n actualAmount: string;\n\n purchaseAt?: string; // this is the date that should be considered for the purchase according to TJ (often the same as fullPaymentAt)\n\n // log\n marketingAt?: string; // no vehicle in our parking, just digital marketing\n evaluationAt?: string; // in consignation\n purchaseAgreedAt?: string;\n // firstPaymentAllowedAt?: string;\n // firstPaymentSentAt?: string;\n // fullPaymentAllowedAt?: string;\n // fullPaymentSentAt?: string;\n arrivedAt?: string;\n checkedInAt?: string;\n\n hasMainInvoice?: boolean;\n};\n\nexport type VehicleProfitOverview = {\n expectedProfit?: string;\n expectedRoi?: string;\n\n actualProfit?: string;\n actualRoi?: string;\n};\n\ntype VehicleSummary = {\n branch: string;\n stockNumber: string;\n id: string;\n};\n\nexport type VehicleBusinessOverview = {\n vehicle: VehicleSummary;\n purchase: VehiclePurchaseOverview;\n sale?: VehicleSaleOverview;\n profit?: VehicleProfitOverview;\n};\n"]}
|
package/lib/utils/vehicles.js
CHANGED
|
@@ -30,7 +30,7 @@ export const extractCustomFeatures = (vehicle) => {
|
|
|
30
30
|
};
|
|
31
31
|
export const getInternalTitle = ({ make, category, modelName, bodywork, modelTypeName, }) => {
|
|
32
32
|
if (category === Categories.Trailer || category === Categories.SemiTrailer) {
|
|
33
|
-
return [make, modelName, bodywork]
|
|
33
|
+
return [make, modelName, modelTypeName, bodywork]
|
|
34
34
|
.filter((v) => !!v)
|
|
35
35
|
.map((v) => v.trim())
|
|
36
36
|
.join(' ')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vehicles.js","sourceRoot":"/","sources":["utils/vehicles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAA4B,EAAY,EAAE;IAC9E,MAAM,QAAQ,GAGR;QACJ;YACE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO;YAC7D,eAAe,EAAE,OAAO;SACzB;QACD;YACE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO;YAChE,eAAe,EAAE,UAAU;SAC5B;QACD,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE;QAC1E;YACE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,gBAAgB;YAC3D,eAAe,EAAE,kBAAkB;SACpC;QACD;YACE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,kBAAkB;YAC7D,eAAe,EAAE,oBAAoB;SACtC;QACD;YACE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO;YAClD,eAAe,EAAE,SAAS;SAC3B;KACF,CAAC;IAEF,OAAO,QAAQ;SACZ,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,aAAa,GAOd,EAAU,EAAE;IACX,IAAI,QAAQ,KAAK,UAAU,CAAC,OAAO,IAAI,QAAQ,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3E,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"vehicles.js","sourceRoot":"/","sources":["utils/vehicles.ts"],"names":[],"mappings":"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","sourcesContent":["import { XError } from '@bisondesk/commons-sdk/errors';\nimport { Categories } from '../constants.js';\nimport { VehicleExternalInfo } from '../types/vehicles.js';\n\nexport const extractCustomFeatures = (vehicle: VehicleExternalInfo): string[] => {\n const features: {\n getValue: (vehicle: VehicleExternalInfo) => any;\n picklistValueId: string;\n }[] = [\n {\n getValue: (vehicle) => vehicle.superstructure?.crane?.present,\n picklistValueId: 'crane',\n },\n {\n getValue: (vehicle) => vehicle.superstructure?.tailgate?.present,\n picklistValueId: 'tailgate',\n },\n { getValue: (vehicle) => vehicle.accessories.adr, picklistValueId: 'adr' },\n {\n getValue: (vehicle) => vehicle.accessories.retarderIntarder,\n picklistValueId: 'retarderIntarder',\n },\n {\n getValue: (vehicle) => vehicle.accessories.hydraulicTipperKit,\n picklistValueId: 'hydraulicTipperKit',\n },\n {\n getValue: (vehicle) => vehicle.accessories.lowDeck,\n picklistValueId: 'lowDeck',\n },\n ];\n\n return features\n .filter((feature) => !!feature.getValue(vehicle))\n .map((feature) => feature.picklistValueId);\n};\n\nexport const getInternalTitle = ({\n make,\n category,\n modelName,\n bodywork,\n modelTypeName,\n}: {\n category: string;\n make?: string;\n modelName?: string;\n modelTypeName?: string;\n bodywork?: string;\n}): string => {\n if (category === Categories.Trailer || category === Categories.SemiTrailer) {\n return [make, modelName, modelTypeName, bodywork]\n .filter((v): v is string => !!v)\n .map((v) => v.trim())\n .join(' ')\n .trim();\n }\n\n return [make, modelName, modelTypeName]\n .filter((v): v is string => !!v)\n .map((v) => v.trim())\n .join(' ')\n .trim();\n};\n\nconst ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n// example: 1 -> A, 2 -> B, 26 -> Z, 27 -> AA, 28 -> AB, 52 -> AZ, 53 -> BA, 54 -> BB, 702 -> ZZ\nexport const convertNumberToLetters = (num: number): string => {\n const lettersLength = ALPHABET.length;\n\n if (num < 1) {\n return '';\n }\n\n let remainder = num % lettersLength;\n let quotient = Math.floor(num / lettersLength);\n\n // If remainder is 0, it means we should map it to 'Z' and reduce the quotient by 1\n if (remainder === 0) {\n remainder = lettersLength;\n quotient -= 1;\n }\n\n return convertNumberToLetters(quotient) + ALPHABET.charAt(remainder - 1);\n};\n\n// example: A -> 1, B -> 2, Z -> 26, AA -> 27, AB -> 28, AZ -> 52, BA -> 53, BB -> 54, ZZ -> 702\nexport const convertLettersToNumber = (letters: string): number => {\n const base = ALPHABET.length;\n\n let result = 0;\n\n for (let i = 0; i < letters.length; i++) {\n const charValue = ALPHABET.indexOf(letters[i]) + 1;\n result = result * base + charValue;\n }\n\n return result;\n};\n\nexport const getNextRelatedStockNumber = (stockNumber: string): string => {\n const counterPattern = /^([A-Z]+\\d{5})([A-Z]{0,2})$/;\n const match = stockNumber.match(counterPattern);\n if (match == null) {\n throw new XError('core-sdk.vehicles.bad-stock-number', { stockNumber });\n }\n\n const baseStockNumber = match[1];\n const counterLetters = match[2];\n const counterNumber = convertLettersToNumber(counterLetters);\n const nextCounterNumber = counterNumber + 1;\n const nextCounterLetters = convertNumberToLetters(nextCounterNumber);\n return `${baseStockNumber}${nextCounterLetters}`;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -10,6 +10,26 @@ import { LeasingQuoteParams } from '../types/quote-settings.js';
|
|
|
10
10
|
import { Quote } from '../types/quotes.js';
|
|
11
11
|
import { OpportunityReservation } from '../types/reservations.js';
|
|
12
12
|
|
|
13
|
+
export const listOpportunities = async (
|
|
14
|
+
tenantId: string,
|
|
15
|
+
filterOptions?: {}
|
|
16
|
+
): Promise<Opportunity[]> => {
|
|
17
|
+
const auth = await getAdminAuth();
|
|
18
|
+
const result = await fetchJson<Opportunity[]>(
|
|
19
|
+
`${process.env.CORE_API_ORIGIN}/api/opportunities/list`,
|
|
20
|
+
{
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: cleanHeaders({
|
|
23
|
+
Authorization: auth,
|
|
24
|
+
[TENANT_ID_ADMIN_HEADER]: tenantId,
|
|
25
|
+
}),
|
|
26
|
+
body: JSON.stringify(filterOptions),
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return result ?? [];
|
|
31
|
+
};
|
|
32
|
+
|
|
13
33
|
export const getOpportunityById = async (
|
|
14
34
|
tenantId: string,
|
|
15
35
|
opportunityId: string
|
package/src/apis/vehicles.ts
CHANGED
|
@@ -120,7 +120,7 @@ export const listVehiclesMarketing = async (
|
|
|
120
120
|
});
|
|
121
121
|
|
|
122
122
|
if (response.ok) {
|
|
123
|
-
return response.status === 200 ? (response.json() as any) :
|
|
123
|
+
return response.status === 200 ? (response.json() as any) : [];
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const body = await response.text();
|
|
@@ -10,6 +10,19 @@ import { BaseSearchRequest } from './search.js';
|
|
|
10
10
|
import { DataRecord, ReferenceData } from './utils.js';
|
|
11
11
|
import { Vehicle } from './vehicles.js';
|
|
12
12
|
|
|
13
|
+
export type ListOpportunitiesFilters = {
|
|
14
|
+
offset?: number;
|
|
15
|
+
limit?: number;
|
|
16
|
+
organizationId?: string;
|
|
17
|
+
contactId?: string;
|
|
18
|
+
vehicleId?: string;
|
|
19
|
+
excludeOpportunityId?: string;
|
|
20
|
+
excludeLost?: boolean;
|
|
21
|
+
statuses?: OpportunityStatus[];
|
|
22
|
+
since?: string;
|
|
23
|
+
until?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
13
26
|
export enum OpportunityActions {
|
|
14
27
|
ADD_COMMISSION = 'add_commission',
|
|
15
28
|
CREATE_QUOTE = 'create_quote',
|
|
@@ -362,7 +375,6 @@ export type LeasingQuoteTemplateData = {
|
|
|
362
375
|
leasing: {
|
|
363
376
|
deposit: string;
|
|
364
377
|
totalMonthlyAmount: string;
|
|
365
|
-
totalMonthlyAmountExclVat: string;
|
|
366
378
|
depositExclVat: string;
|
|
367
379
|
startupFee: string;
|
|
368
380
|
startupFeeExclVat: string;
|
|
@@ -433,7 +445,7 @@ export type LeasingProformaTemplateData = {
|
|
|
433
445
|
};
|
|
434
446
|
};
|
|
435
447
|
|
|
436
|
-
export type
|
|
448
|
+
export type SalesTemplateData = {
|
|
437
449
|
opportunity: {
|
|
438
450
|
id: string;
|
|
439
451
|
offerNumber: string;
|
|
@@ -456,6 +468,7 @@ export type SalesProformaTemplateData = {
|
|
|
456
468
|
type?: string;
|
|
457
469
|
km: string | number;
|
|
458
470
|
vin: string;
|
|
471
|
+
year: string;
|
|
459
472
|
};
|
|
460
473
|
c: {
|
|
461
474
|
organizationId?: string;
|
|
@@ -468,41 +481,7 @@ export type SalesProformaTemplateData = {
|
|
|
468
481
|
address?: string;
|
|
469
482
|
country: string;
|
|
470
483
|
};
|
|
471
|
-
|
|
472
|
-
t: {
|
|
473
|
-
totalExclVat: string;
|
|
474
|
-
vatAmount: string;
|
|
475
|
-
total: string;
|
|
476
|
-
};
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
export type SalesAgreementTemplateData = {
|
|
480
|
-
opportunity: {
|
|
481
|
-
id: string;
|
|
482
|
-
offerNumber: string;
|
|
483
|
-
};
|
|
484
|
-
currentDate: string;
|
|
485
|
-
accountManager: {
|
|
486
|
-
fullName: string;
|
|
487
|
-
email: string;
|
|
488
|
-
phone: string;
|
|
489
|
-
};
|
|
490
|
-
vehicle: {
|
|
491
|
-
line1: string;
|
|
492
|
-
line2: string;
|
|
493
|
-
stockNumber: string;
|
|
494
|
-
};
|
|
495
|
-
c: {
|
|
496
|
-
organizationId?: string;
|
|
497
|
-
clientId: string;
|
|
498
|
-
company: string;
|
|
499
|
-
fullName: string;
|
|
500
|
-
vatNumber?: string;
|
|
501
|
-
email?: string;
|
|
502
|
-
phone?: string;
|
|
503
|
-
address?: string;
|
|
504
|
-
country: string;
|
|
505
|
-
};
|
|
484
|
+
iExtended: LineItemPdfTemplate[];
|
|
506
485
|
i: LineItemPdfTemplate[];
|
|
507
486
|
t: {
|
|
508
487
|
totalExclVat: string;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// The commission can be expressed either as a percentage (for profit-based metrics)
|
|
2
|
+
// or as an amount per unit (for unit-based metrics).
|
|
3
|
+
export type CommissionType = 'percentage' | 'unit';
|
|
4
|
+
|
|
5
|
+
// Comprehensive metric configuration
|
|
6
|
+
export type MetricConfig = {
|
|
7
|
+
id: string;
|
|
8
|
+
commissionType: CommissionType;
|
|
9
|
+
format?: Intl.NumberFormatOptions;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// A tier defines a range of performance (using lower and optional upper bounds)
|
|
13
|
+
// along with the associated commission rate. For example, 0–100 units, then 100–400 units, etc.
|
|
14
|
+
export type CommissionTier = {
|
|
15
|
+
lowerBound: number; // inclusive
|
|
16
|
+
upperBound?: number; // inclusive (omit for the last tier)
|
|
17
|
+
commissionRate: number;
|
|
18
|
+
default?: boolean; // if true, this tier's upper bound is used as reference for dashboards visualizations
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Each target (metric) has one or more tiers.
|
|
22
|
+
// For example, for UnitsSold you might have three tiers corresponding to bare minimum, normal, and above average.
|
|
23
|
+
export type TargetCommission = {
|
|
24
|
+
metricId: string;
|
|
25
|
+
tiers: CommissionTier[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type UserCommissionPlan = {
|
|
29
|
+
userId: string;
|
|
30
|
+
year: number;
|
|
31
|
+
targets: TargetCommission[];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export enum CommissionGrade {
|
|
35
|
+
TooLow = 'tooLow',
|
|
36
|
+
Low = 'low',
|
|
37
|
+
OnTarget = 'onTarget',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type UserCommissionStatus = {
|
|
41
|
+
userId: string;
|
|
42
|
+
createdAt: string; // iso date string
|
|
43
|
+
year: number;
|
|
44
|
+
performance: {
|
|
45
|
+
[metricId: string]: {
|
|
46
|
+
value: string; // actual metric achieved
|
|
47
|
+
estimated?: string; // estimated commission for the metric, based on the current trend
|
|
48
|
+
grade?: CommissionGrade; // grade for the metric
|
|
49
|
+
target?: string; // the upper bound of the default tier
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
commission: {
|
|
53
|
+
total: string;
|
|
54
|
+
potential?: string;
|
|
55
|
+
estimated?: string; // estimated commission for the year, based on the current trend
|
|
56
|
+
grade?: CommissionGrade;
|
|
57
|
+
detailed?: {
|
|
58
|
+
[metricId: string]: {
|
|
59
|
+
earned: string; // commission amount for each target
|
|
60
|
+
potential?: string; // potential commission for the metric, based on the actual metric achieved and the commission tiers
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
payments: {
|
|
65
|
+
total: string;
|
|
66
|
+
yearly?: {
|
|
67
|
+
// details for each year for which the outstanding commission is > 0
|
|
68
|
+
[year: number]: {
|
|
69
|
+
paid: string;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
outstanding: {
|
|
74
|
+
total: string;
|
|
75
|
+
// details for each year for which the outstanding commission is > 0
|
|
76
|
+
yearly?: {
|
|
77
|
+
[year: number]: {
|
|
78
|
+
outstanding: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type NewUserCommissionPayment = {
|
|
85
|
+
userId: string; // who was the payment made to
|
|
86
|
+
paidBy: string;
|
|
87
|
+
paidAt: string;
|
|
88
|
+
amount: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type UserCommissionPayment = {
|
|
92
|
+
id: string;
|
|
93
|
+
} & NewUserCommissionPayment;
|
|
94
|
+
|
|
95
|
+
export type UserCommissionsPaymentRequest = {
|
|
96
|
+
limit?: number;
|
|
97
|
+
nextToken?: string;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type UserCommissionInfo = {
|
|
101
|
+
manager?: boolean;
|
|
102
|
+
performance: boolean;
|
|
103
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { OpportunityType } from '../constants.js';
|
|
2
|
+
import { VehicleSaleDealStatus, VehicleSaleLogisticsStatus } from './opportunities.js';
|
|
3
|
+
import { VehiclePurchaseDealStatus, VehiclePurchaseLogisticsStatus } from './vehicles.js';
|
|
4
|
+
|
|
5
|
+
export type VehicleSaleOverview = {
|
|
6
|
+
opportunityId: string;
|
|
7
|
+
type: OpportunityType;
|
|
8
|
+
userId: string; // account manager of the latest opportunity (if opportunity is >= review)
|
|
9
|
+
|
|
10
|
+
// client details
|
|
11
|
+
clientId: string;
|
|
12
|
+
clientCode: number;
|
|
13
|
+
clientCountryCode: string;
|
|
14
|
+
clientVat?: string;
|
|
15
|
+
conglomerate?: boolean;
|
|
16
|
+
clientEmail?: string;
|
|
17
|
+
clientPhone?: string;
|
|
18
|
+
|
|
19
|
+
// vehicle details
|
|
20
|
+
dealStatus: VehicleSaleDealStatus;
|
|
21
|
+
logisticsStatus: VehicleSaleLogisticsStatus;
|
|
22
|
+
|
|
23
|
+
// opportunity dates
|
|
24
|
+
createdAt: string;
|
|
25
|
+
engagedAt?: string;
|
|
26
|
+
acceptedAt?: string;
|
|
27
|
+
validatedAt?: string;
|
|
28
|
+
reviewedAt?: string;
|
|
29
|
+
preparedAt?: string;
|
|
30
|
+
deliveredAt?: string;
|
|
31
|
+
wonAt?: string;
|
|
32
|
+
|
|
33
|
+
saleAt?: string; // this is the date that should be considered for the sale according to TJ (often the same as fullPaymentAt)
|
|
34
|
+
|
|
35
|
+
// money-related details
|
|
36
|
+
firstInvoiceIssuedAt?: string;
|
|
37
|
+
lastInvoiceIssuedAt?: string;
|
|
38
|
+
firstPaymentAt?: string;
|
|
39
|
+
fullPaymentAt?: string;
|
|
40
|
+
expectedAmount: string; // from quote(s)
|
|
41
|
+
actualAmount: string; // from all invoices
|
|
42
|
+
lifetimeActualAmount: string; // sum of all invoices from all opportunities for this vehicle
|
|
43
|
+
|
|
44
|
+
// is there an invoice with category related to the purchase of commercial vehicle
|
|
45
|
+
// (we probably need a way to flag those categories since it is also important for the stocklist)
|
|
46
|
+
hasMainInvoice?: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type VehiclePurchaseOverview = {
|
|
50
|
+
userId: string; // purchaser
|
|
51
|
+
|
|
52
|
+
dealStatus: VehiclePurchaseDealStatus;
|
|
53
|
+
logisticsStatus: VehiclePurchaseLogisticsStatus;
|
|
54
|
+
|
|
55
|
+
supplierId: string;
|
|
56
|
+
supplierCode: string;
|
|
57
|
+
supplierCountryCode: string;
|
|
58
|
+
supplierVat?: string;
|
|
59
|
+
conglomerate?: boolean;
|
|
60
|
+
supplierEmail?: string;
|
|
61
|
+
supplierPhone?: string;
|
|
62
|
+
|
|
63
|
+
// money-related details
|
|
64
|
+
firstInvoiceIssuedAt?: string;
|
|
65
|
+
lastInvoiceIssuedAt?: string;
|
|
66
|
+
firstPaymentAt?: string;
|
|
67
|
+
fullPaymentAt?: string;
|
|
68
|
+
expectedAmount: string;
|
|
69
|
+
actualAmount: string;
|
|
70
|
+
|
|
71
|
+
purchaseAt?: string; // this is the date that should be considered for the purchase according to TJ (often the same as fullPaymentAt)
|
|
72
|
+
|
|
73
|
+
// log
|
|
74
|
+
marketingAt?: string; // no vehicle in our parking, just digital marketing
|
|
75
|
+
evaluationAt?: string; // in consignation
|
|
76
|
+
purchaseAgreedAt?: string;
|
|
77
|
+
// firstPaymentAllowedAt?: string;
|
|
78
|
+
// firstPaymentSentAt?: string;
|
|
79
|
+
// fullPaymentAllowedAt?: string;
|
|
80
|
+
// fullPaymentSentAt?: string;
|
|
81
|
+
arrivedAt?: string;
|
|
82
|
+
checkedInAt?: string;
|
|
83
|
+
|
|
84
|
+
hasMainInvoice?: boolean;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type VehicleProfitOverview = {
|
|
88
|
+
expectedProfit?: string;
|
|
89
|
+
expectedRoi?: string;
|
|
90
|
+
|
|
91
|
+
actualProfit?: string;
|
|
92
|
+
actualRoi?: string;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
type VehicleSummary = {
|
|
96
|
+
branch: string;
|
|
97
|
+
stockNumber: string;
|
|
98
|
+
id: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export type VehicleBusinessOverview = {
|
|
102
|
+
vehicle: VehicleSummary;
|
|
103
|
+
purchase: VehiclePurchaseOverview;
|
|
104
|
+
sale?: VehicleSaleOverview;
|
|
105
|
+
profit?: VehicleProfitOverview;
|
|
106
|
+
};
|
package/src/utils/vehicles.ts
CHANGED
|
@@ -49,7 +49,7 @@ export const getInternalTitle = ({
|
|
|
49
49
|
bodywork?: string;
|
|
50
50
|
}): string => {
|
|
51
51
|
if (category === Categories.Trailer || category === Categories.SemiTrailer) {
|
|
52
|
-
return [make, modelName, bodywork]
|
|
52
|
+
return [make, modelName, modelTypeName, bodywork]
|
|
53
53
|
.filter((v): v is string => !!v)
|
|
54
54
|
.map((v) => v.trim())
|
|
55
55
|
.join(' ')
|