@bisondesk/core-sdk 1.0.442 → 1.0.443

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.
@@ -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":"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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, 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"]}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bisondesk/core-sdk",
3
- "version": "1.0.442",
3
+ "version": "1.0.443",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -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
@@ -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) : undefined;
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',
@@ -295,7 +308,6 @@ export type SearchOpportunity = {
295
308
  vehicle?: Vehicle;
296
309
  quote?: QuoteInfo;
297
310
  custom: {
298
- web2Lead: boolean;
299
311
  payment: { status: OpportunityPaymentStatus; percentagePaid: string };
300
312
  unassigned: boolean;
301
313
  lost: boolean;
@@ -362,7 +374,6 @@ export type LeasingQuoteTemplateData = {
362
374
  leasing: {
363
375
  deposit: string;
364
376
  totalMonthlyAmount: string;
365
- totalMonthlyAmountExclVat: string;
366
377
  depositExclVat: string;
367
378
  startupFee: string;
368
379
  startupFeeExclVat: 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
+ };
@@ -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(' ')