@bisondesk/core-sdk 1.0.655 → 1.0.656
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/deliveries.d.ts +74 -0
- package/lib/types/deliveries.d.ts.map +1 -0
- package/lib/types/deliveries.js +24 -0
- package/lib/types/deliveries.js.map +1 -0
- package/lib/types/quotes.d.ts +5 -65
- package/lib/types/quotes.d.ts.map +1 -1
- package/lib/types/quotes.js +1 -18
- package/lib/types/quotes.js.map +1 -1
- package/lib/types/transports.d.ts +10 -15
- package/lib/types/transports.d.ts.map +1 -1
- package/lib/types/transports.js +5 -5
- package/lib/types/transports.js.map +1 -1
- package/lib/types/vehicle-sales.d.ts +3 -2
- package/lib/types/vehicle-sales.d.ts.map +1 -1
- package/lib/types/vehicle-sales.js.map +1 -1
- package/lib/utils/deliveries.d.ts +3 -0
- package/lib/utils/deliveries.d.ts.map +1 -0
- package/lib/utils/deliveries.js +3 -0
- package/lib/utils/deliveries.js.map +1 -0
- package/lib/utils/deliveries.test.d.ts +2 -0
- package/lib/utils/deliveries.test.d.ts.map +1 -0
- package/lib/utils/deliveries.test.js +34 -0
- package/lib/utils/deliveries.test.js.map +1 -0
- package/lib/utils/transports.d.ts +1 -1
- package/lib/utils/transports.d.ts.map +1 -1
- package/lib/utils/transports.js.map +1 -1
- package/package.json +1 -1
- package/src/types/deliveries.ts +92 -0
- package/src/types/quotes.ts +17 -73
- package/src/types/transports.ts +24 -24
- package/src/types/vehicle-sales.ts +3 -2
- package/src/utils/deliveries.test.ts +50 -0
- package/src/utils/deliveries.ts +13 -0
- package/src/utils/transports.ts +3 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DeliveryTypes } from '@bisondesk/core-sdk/types/quotes';
|
|
2
|
+
import { expectTypeOf } from 'vitest';
|
|
3
|
+
import { PurchaseDeliveryTypes, SalesDeliveryTypes, } from '../types/deliveries.js';
|
|
4
|
+
import { isAddressDelivery } from './deliveries.js';
|
|
5
|
+
test('purchase and sales contracts keep supplier drop-off and customer pick-up separate', () => {
|
|
6
|
+
expectTypeOf().not.toMatchTypeOf();
|
|
7
|
+
expectTypeOf().not.toMatchTypeOf();
|
|
8
|
+
expectTypeOf().toMatchTypeOf();
|
|
9
|
+
expectTypeOf().toMatchTypeOf();
|
|
10
|
+
});
|
|
11
|
+
test('the previous quote export keeps its four sales methods', () => {
|
|
12
|
+
expect(DeliveryTypes).toEqual(SalesDeliveryTypes);
|
|
13
|
+
expect(Object.values(DeliveryTypes)).toEqual(['park', 'address', 'port', 'portAndShip']);
|
|
14
|
+
});
|
|
15
|
+
test.each([
|
|
16
|
+
SalesDeliveryTypes.ADDRESS,
|
|
17
|
+
PurchaseDeliveryTypes.ADDRESS,
|
|
18
|
+
])('reads the address fields for %s', (type) => {
|
|
19
|
+
const delivery = {
|
|
20
|
+
type,
|
|
21
|
+
address: { country: 'be', city: 'Gent' },
|
|
22
|
+
distanceKm: '100',
|
|
23
|
+
agreedPrice: '0',
|
|
24
|
+
technicalControlNeeded: false,
|
|
25
|
+
};
|
|
26
|
+
expect(isAddressDelivery(delivery)).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
test('a supplier drop-off has no collection address', () => {
|
|
29
|
+
expect(isAddressDelivery({
|
|
30
|
+
type: PurchaseDeliveryTypes.DROP_OFF,
|
|
31
|
+
agreedPrice: '0',
|
|
32
|
+
})).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=deliveries.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliveries.test.js","sourceRoot":"/","sources":["utils/deliveries.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAKL,qBAAqB,EAErB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,IAAI,CAAC,mFAAmF,EAAE,GAAG,EAAE;IAC7F,YAAY,EAAuB,CAAC,GAAG,CAAC,aAAa,EAAqB,CAAC;IAC3E,YAAY,EAAsB,CAAC,GAAG,CAAC,aAAa,EAAwB,CAAC;IAC7E,YAAY,EAAuB,CAAC,aAAa,EAAwB,CAAC;IAC1E,YAAY,EAET,CAAC,aAAa,EAAwB,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;IAClE,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAClD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAC3F,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,IAAI,CAAC;IACR,kBAAkB,CAAC,OAAO;IAC1B,qBAAqB,CAAC,OAAO;CACrB,CAAC,CAAC,iCAAiC,EAAE,CAAC,IAAI,EAAE,EAAE;IACtD,MAAM,QAAQ,GACZ;QACE,IAAI;QACJ,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE;QACxC,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,GAAG;QAChB,sBAAsB,EAAE,KAAK;KAC9B,CAAC;IACJ,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,CACJ,iBAAiB,CAAC;QAChB,IAAI,EAAE,qBAAqB,CAAC,QAAQ;QACpC,WAAW,EAAE,GAAG;KACjB,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC","sourcesContent":["import { DeliveryTypes } from '@bisondesk/core-sdk/types/quotes';\nimport { expectTypeOf } from 'vitest';\nimport {\n AddressDeliveryType,\n DropOffDeliveryType,\n PickUpDeliveryType,\n PurchaseDeliveryType,\n PurchaseDeliveryTypes,\n SalesDeliveryType,\n SalesDeliveryTypes,\n} from '../types/deliveries.js';\nimport { isAddressDelivery } from './deliveries.js';\n\ntest('purchase and sales contracts keep supplier drop-off and customer pick-up separate', () => {\n expectTypeOf<DropOffDeliveryType>().not.toMatchTypeOf<SalesDeliveryType>();\n expectTypeOf<PickUpDeliveryType>().not.toMatchTypeOf<PurchaseDeliveryType>();\n expectTypeOf<AddressDeliveryType>().toMatchTypeOf<PurchaseDeliveryType>();\n expectTypeOf<\n AddressDeliveryType<PurchaseDeliveryTypes.ADDRESS>\n >().toMatchTypeOf<PurchaseDeliveryType>();\n});\n\ntest('the previous quote export keeps its four sales methods', () => {\n expect(DeliveryTypes).toEqual(SalesDeliveryTypes);\n expect(Object.values(DeliveryTypes)).toEqual(['park', 'address', 'port', 'portAndShip']);\n});\n\ntest.each([\n SalesDeliveryTypes.ADDRESS,\n PurchaseDeliveryTypes.ADDRESS,\n] as const)('reads the address fields for %s', (type) => {\n const delivery: AddressDeliveryType<SalesDeliveryTypes.ADDRESS | PurchaseDeliveryTypes.ADDRESS> =\n {\n type,\n address: { country: 'be', city: 'Gent' },\n distanceKm: '100',\n agreedPrice: '0',\n technicalControlNeeded: false,\n };\n expect(isAddressDelivery(delivery)).toBe(true);\n});\n\ntest('a supplier drop-off has no collection address', () => {\n expect(\n isAddressDelivery({\n type: PurchaseDeliveryTypes.DROP_OFF,\n agreedPrice: '0',\n }),\n ).toBe(false);\n});\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Opportunity } from '../types/opportunities.js';
|
|
2
2
|
import { SearchTransport, Transport } from '../types/transports.js';
|
|
3
3
|
import { VehiclePurchase } from '../types/vehicles.js';
|
|
4
|
-
export declare const isPurchaseTransport: (transport: Transport) => boolean;
|
|
4
|
+
export declare const isPurchaseTransport: (transport: Pick<Transport, 'type'>) => boolean;
|
|
5
5
|
export declare const isTransportCompleted: (transport: Transport, context: {
|
|
6
6
|
opportunity?: Opportunity;
|
|
7
7
|
purchase?: VehiclePurchase;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transports.d.ts","sourceRoot":"/","sources":["utils/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAiB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"transports.d.ts","sourceRoot":"/","sources":["utils/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAiB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAOvD,eAAO,MAAM,mBAAmB,cAAe,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,KAAG,OAC1B,CAAC;AAchD,eAAO,MAAM,oBAAoB,cACpB,SAAS,WACX;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;CAAE,KACjE,OAMF,CAAC;AAGF,eAAO,MAAM,0BAA0B,WAAY,eAAe,KAAG,OAIjE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transports.js","sourceRoot":"/","sources":["utils/transports.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"transports.js","sourceRoot":"/","sources":["utils/transports.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAMnD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAkC,EAAW,EAAE,CACjF,SAAS,CAAC,IAAI,KAAK,aAAa,CAAC,YAAY,CAAC;AAchD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,SAAoB,EACpB,OAAkE,EACzD,EAAE;IACX,IAAI,SAAS,CAAC,IAAI,KAAK,aAAa,CAAC,YAAY,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,WAAW,EAAE,WAAW,IAAI,IAAI,CAAC;IAClD,CAAC;IAED,OAAO,OAAO,CAAC,QAAQ,IAAI,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC1E,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,MAAuB,EAAW,EAAE,CAC7E,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE;IACrC,WAAW,EAAE,MAAM,CAAC,WAAW;IAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;CAC1B,CAAC,CAAC","sourcesContent":["import { Opportunity } from '../types/opportunities.js';\nimport { SearchTransport, Transport, TransportType } from '../types/transports.js';\nimport { VehiclePurchase } from '../types/vehicles.js';\nimport { hasPurchaseArrived } from './vehicles.js';\n\n/**\n * Both purchase types bring a vehicle to our park: we collect a pickup, and the supplier brings\n * a drop-off. They share the purchase payment and arrival rules.\n */\nexport const isPurchaseTransport = (transport: Pick<Transport, 'type'>): boolean =>\n transport.type !== TransportType.SaleDelivery;\n\n/**\n * A transport is finished when the journey it describes has demonstrably happened: the customer has\n * the vehicle for a sale delivery, the vehicle is on our park for a purchase. From then on\n * the record is history and the server refuses edits to it.\n *\n * Not the same thing as the transport's own `doneAt`. Delivery can be declared on the opportunity\n * (a CMR, a delivery confirmation) and arrival on the purchase, without the transport ever being\n * moved — and reversing either of those is what unlocks the transport again, which a status stamped\n * on the transport itself could not express.\n *\n * Shared so the board, the drawer and the server all answer the question the same way.\n */\nexport const isTransportCompleted = (\n transport: Transport,\n context: { opportunity?: Opportunity; purchase?: VehiclePurchase },\n): boolean => {\n if (transport.type === TransportType.SaleDelivery) {\n return context.opportunity?.deliveredAt != null;\n }\n\n return context.purchase != null && hasPurchaseArrived(context.purchase);\n};\n\n/** The same question asked of a search document, which already carries both sides. */\nexport const isSearchTransportCompleted = (record: SearchTransport): boolean =>\n isTransportCompleted(record.transport, {\n opportunity: record.opportunity,\n purchase: record.purchase,\n });\n"]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { LocationValue } from '@bisondesk/commons-sdk/types';
|
|
2
|
+
|
|
3
|
+
/** Supplier collection keeps the existing address value in stored transports. */
|
|
4
|
+
export enum PurchaseDeliveryTypes {
|
|
5
|
+
ADDRESS = 'address',
|
|
6
|
+
DROP_OFF = 'park',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export enum SalesDeliveryTypes {
|
|
10
|
+
PICK_UP = 'park',
|
|
11
|
+
ADDRESS = 'address',
|
|
12
|
+
PORT = 'port',
|
|
13
|
+
PORT_AND_SHIP = 'portAndShip',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum SpoilerInfo {
|
|
17
|
+
MOUNT = 'mount',
|
|
18
|
+
UNMOUNT = 'unmount',
|
|
19
|
+
NO_ACTION = 'noAction',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export enum TransportationMode {
|
|
23
|
+
BY_ROAD = 'byRoad',
|
|
24
|
+
ON_LOW_BED = 'onLowBed',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type BaseDeliveryType = {
|
|
28
|
+
agreedPrice: string;
|
|
29
|
+
spoiler?: SpoilerInfo;
|
|
30
|
+
stackingVehicleNeeded?: boolean;
|
|
31
|
+
detailsStacking?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type PickUpDeliveryType = BaseDeliveryType & {
|
|
35
|
+
type: SalesDeliveryTypes.PICK_UP;
|
|
36
|
+
urgent: boolean;
|
|
37
|
+
transportationMode?: TransportationMode;
|
|
38
|
+
detailsBorderCrossing?: string;
|
|
39
|
+
technicalControlNeeded: boolean;
|
|
40
|
+
insuranceNeeded: boolean;
|
|
41
|
+
transitPlateBelgiumNeeded: boolean;
|
|
42
|
+
transitPlateAustriaNeeded: boolean;
|
|
43
|
+
licensePlateNeeded: boolean;
|
|
44
|
+
dateOfPickUpByCustomer?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** The supplier brings the vehicle to our park without a collection address or distance. */
|
|
48
|
+
export type DropOffDeliveryType = BaseDeliveryType & {
|
|
49
|
+
type: PurchaseDeliveryTypes.DROP_OFF;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type AddressDeliveryType<
|
|
53
|
+
T extends SalesDeliveryTypes.ADDRESS | PurchaseDeliveryTypes.ADDRESS = SalesDeliveryTypes.ADDRESS,
|
|
54
|
+
> = BaseDeliveryType & {
|
|
55
|
+
type: T;
|
|
56
|
+
address: LocationValue;
|
|
57
|
+
distanceKm: string;
|
|
58
|
+
technicalControlNeeded: boolean;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type PortDeliverytype = BaseDeliveryType & {
|
|
62
|
+
type: SalesDeliveryTypes.PORT | SalesDeliveryTypes.PORT_AND_SHIP;
|
|
63
|
+
portOriginId: string;
|
|
64
|
+
portDestination?: string;
|
|
65
|
+
shippingCompany?: string;
|
|
66
|
+
portToPortCostPrice: string;
|
|
67
|
+
parkToPortCostPrice?: string;
|
|
68
|
+
portToPortMargin: string;
|
|
69
|
+
ets?: string;
|
|
70
|
+
eta?: string;
|
|
71
|
+
etd?: string;
|
|
72
|
+
shipClosingDate?: string;
|
|
73
|
+
bookingRef?: string;
|
|
74
|
+
deliveryLocation?: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type SalesDeliveryType = PickUpDeliveryType | AddressDeliveryType | PortDeliverytype;
|
|
78
|
+
|
|
79
|
+
/** Earlier SDKs also used the sales address enum for purchase collection. Both store address. */
|
|
80
|
+
export type PurchaseDeliveryType =
|
|
81
|
+
| AddressDeliveryType<SalesDeliveryTypes.ADDRESS | PurchaseDeliveryTypes.ADDRESS>
|
|
82
|
+
| DropOffDeliveryType;
|
|
83
|
+
|
|
84
|
+
export type DeliveryLocationValue = Omit<LocationValue, 'addressLine1' | 'city'> & {
|
|
85
|
+
addressLine1: string;
|
|
86
|
+
city: string;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type DeliveryRoutesRequest = {
|
|
90
|
+
origin: DeliveryLocationValue;
|
|
91
|
+
destination: DeliveryLocationValue;
|
|
92
|
+
};
|
package/src/types/quotes.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AttachmentValue
|
|
1
|
+
import { AttachmentValue } from '@bisondesk/commons-sdk/types';
|
|
2
2
|
import { OpportunityType } from '../constants.js';
|
|
3
|
+
import { SalesDeliveryType } from './deliveries.js';
|
|
3
4
|
import {
|
|
4
5
|
CustomLeasingQuoteExtraInput,
|
|
5
6
|
CustomSalesQuoteExtraInput,
|
|
@@ -33,24 +34,6 @@ export enum QuoteMetricsScore {
|
|
|
33
34
|
NEUTRAL = 'neutral',
|
|
34
35
|
GOOD = 'good',
|
|
35
36
|
}
|
|
36
|
-
export enum DeliveryTypes {
|
|
37
|
-
PICK_UP = 'pickUp',
|
|
38
|
-
ADDRESS = 'address',
|
|
39
|
-
PORT = 'port',
|
|
40
|
-
PORT_AND_SHIP = 'portAndShip',
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export enum SpoilerInfo {
|
|
44
|
-
MOUNT = 'mount',
|
|
45
|
-
UNMOUNT = 'unmount',
|
|
46
|
-
NO_ACTION = 'noAction',
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export enum TransportationMode {
|
|
50
|
-
BY_ROAD = 'byRoad',
|
|
51
|
-
ON_LOW_BED = 'onLowBed',
|
|
52
|
-
}
|
|
53
|
-
|
|
54
37
|
export enum SelfFinancingType {
|
|
55
38
|
OWN_FINANCING = 'own_financing',
|
|
56
39
|
ALREADY_FINANCED = 'already_financed',
|
|
@@ -148,49 +131,6 @@ export type LeasingCalculatorInput = BaseQuoteCalculatorInput & {
|
|
|
148
131
|
customRequests: CustomLeasingQuoteExtraInput[];
|
|
149
132
|
};
|
|
150
133
|
|
|
151
|
-
type BaseDeliveryType = {
|
|
152
|
-
agreedPrice: string;
|
|
153
|
-
spoiler?: SpoilerInfo;
|
|
154
|
-
stackingVehicleNeeded?: boolean;
|
|
155
|
-
detailsStacking?: string;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export type PickUpDeliveryType = BaseDeliveryType & {
|
|
159
|
-
type: DeliveryTypes.PICK_UP;
|
|
160
|
-
urgent: boolean;
|
|
161
|
-
transportationMode?: TransportationMode;
|
|
162
|
-
detailsBorderCrossing?: string;
|
|
163
|
-
technicalControlNeeded: boolean;
|
|
164
|
-
insuranceNeeded: boolean;
|
|
165
|
-
transitPlateBelgiumNeeded: boolean;
|
|
166
|
-
transitPlateAustriaNeeded: boolean;
|
|
167
|
-
licensePlateNeeded: boolean;
|
|
168
|
-
dateOfPickUpByCustomer?: string;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
export type AddressDeliveryType = BaseDeliveryType & {
|
|
172
|
-
type: DeliveryTypes.ADDRESS;
|
|
173
|
-
address: LocationValue;
|
|
174
|
-
distanceKm: string;
|
|
175
|
-
technicalControlNeeded: boolean;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export type PortDeliverytype = BaseDeliveryType & {
|
|
179
|
-
type: DeliveryTypes.PORT | DeliveryTypes.PORT_AND_SHIP;
|
|
180
|
-
portOriginId: string;
|
|
181
|
-
portDestination?: string;
|
|
182
|
-
shippingCompany?: string;
|
|
183
|
-
portToPortCostPrice: string;
|
|
184
|
-
parkToPortCostPrice?: string;
|
|
185
|
-
portToPortMargin: string;
|
|
186
|
-
ets?: string;
|
|
187
|
-
eta?: string;
|
|
188
|
-
etd?: string;
|
|
189
|
-
shipClosingDate?: string;
|
|
190
|
-
bookingRef?: string;
|
|
191
|
-
deliveryLocation?: string;
|
|
192
|
-
};
|
|
193
|
-
|
|
194
134
|
// Sent by the Frontend to bootstrap the calculator
|
|
195
135
|
export type SalesCalculatorDefaultInput = Omit<BaseQuoteCalculatorInput, 'vehicle'> & {
|
|
196
136
|
vehicle: Omit<BaseQuoteCalculatorInput['vehicle'], 'vatRate'>;
|
|
@@ -206,7 +146,7 @@ export type SalesCalculatorInput = BaseQuoteCalculatorInput & {
|
|
|
206
146
|
internetPrice?: string;
|
|
207
147
|
comissionCost: string;
|
|
208
148
|
};
|
|
209
|
-
delivery?:
|
|
149
|
+
delivery?: SalesDeliveryType;
|
|
210
150
|
extras: SalesQuoteExtraInput[];
|
|
211
151
|
customRequests: CustomSalesQuoteExtraInput[];
|
|
212
152
|
financing?: {
|
|
@@ -418,16 +358,6 @@ export type CalculatorSalesIO = {
|
|
|
418
358
|
};
|
|
419
359
|
export type CalculatorQuoteIO = CalculatorLeasingIO | CalculatorSalesIO;
|
|
420
360
|
|
|
421
|
-
export type DeliveryLocationValue = Omit<LocationValue, 'addressLine1' | 'city'> & {
|
|
422
|
-
addressLine1: string;
|
|
423
|
-
city: string;
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
export type DeliveryRoutesRequest = {
|
|
427
|
-
origin: DeliveryLocationValue;
|
|
428
|
-
destination: DeliveryLocationValue;
|
|
429
|
-
};
|
|
430
|
-
|
|
431
361
|
export type NewQuoteValidator = {
|
|
432
362
|
userId: string;
|
|
433
363
|
countryCode: string;
|
|
@@ -442,3 +372,17 @@ export type QuoteValidator = NewQuoteValidator & {
|
|
|
442
372
|
export type QuoteValidatorUpdate = {
|
|
443
373
|
canValidateOwn: boolean;
|
|
444
374
|
};
|
|
375
|
+
|
|
376
|
+
export type {
|
|
377
|
+
AddressDeliveryType,
|
|
378
|
+
DeliveryLocationValue,
|
|
379
|
+
DeliveryRoutesRequest,
|
|
380
|
+
PickUpDeliveryType,
|
|
381
|
+
PortDeliverytype,
|
|
382
|
+
} from './deliveries.js';
|
|
383
|
+
/** @deprecated Import delivery types from ./deliveries.js. */
|
|
384
|
+
export {
|
|
385
|
+
SalesDeliveryTypes as DeliveryTypes,
|
|
386
|
+
SpoilerInfo,
|
|
387
|
+
TransportationMode,
|
|
388
|
+
} from './deliveries.js';
|
package/src/types/transports.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { GPSCoord, NextList, PaginatedList } from '@bisondesk/commons-sdk/types';
|
|
2
2
|
import { Organization } from './crm.js';
|
|
3
|
-
import { BaseEvent } from './internal-events.js';
|
|
4
|
-
import { Opportunity, OpportunityPaymentStatus } from './opportunities.js';
|
|
5
3
|
import {
|
|
6
4
|
AddressDeliveryType,
|
|
7
|
-
DeliveryTypes,
|
|
8
5
|
PickUpDeliveryType,
|
|
9
6
|
PortDeliverytype,
|
|
10
|
-
|
|
7
|
+
PurchaseDeliveryType,
|
|
8
|
+
SalesDeliveryTypes,
|
|
9
|
+
} from './deliveries.js';
|
|
10
|
+
import { BaseEvent } from './internal-events.js';
|
|
11
|
+
import { Opportunity, OpportunityPaymentStatus } from './opportunities.js';
|
|
11
12
|
import { BaseSearchRequest, SortOrder } from './search.js';
|
|
12
13
|
import { DataRecord, ReferenceData } from './utils.js';
|
|
13
14
|
import { Vehicle, VehiclePurchase } from './vehicles.js';
|
|
@@ -59,13 +60,6 @@ export enum TransportPriority {
|
|
|
59
60
|
Urgent = 'URGENT',
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
export const TransportSalesDeliveryType = {
|
|
63
|
-
Address: DeliveryTypes.ADDRESS,
|
|
64
|
-
Port: DeliveryTypes.PORT,
|
|
65
|
-
PortAndShip: DeliveryTypes.PORT_AND_SHIP,
|
|
66
|
-
PickUp: DeliveryTypes.PICK_UP,
|
|
67
|
-
} as const;
|
|
68
|
-
|
|
69
63
|
/**
|
|
70
64
|
* The customer collects the vehicle. Nothing is driven anywhere, but the papers still have to be
|
|
71
65
|
* arranged and paid for — transit plates, technical control, insurance — which is why it is a
|
|
@@ -76,11 +70,7 @@ export const TransportSalesDeliveryType = {
|
|
|
76
70
|
*/
|
|
77
71
|
export type TransportPickUpDeliveryType = Omit<PickUpDeliveryType, 'dateOfPickUpByCustomer'>;
|
|
78
72
|
|
|
79
|
-
|
|
80
|
-
| PortDeliverytype
|
|
81
|
-
| AddressDeliveryType
|
|
82
|
-
| TransportPickUpDeliveryType
|
|
83
|
-
) & {
|
|
73
|
+
type TransportDeliveryExtras = {
|
|
84
74
|
cleaningNeeded?: boolean;
|
|
85
75
|
driver?: string;
|
|
86
76
|
transportCompany?: string;
|
|
@@ -89,14 +79,22 @@ export type TransportSalesDeliveryType = (
|
|
|
89
79
|
stackingVehicleCostPrice?: string; // overrides the stacking rate from the delivery settings
|
|
90
80
|
};
|
|
91
81
|
|
|
92
|
-
export type
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
82
|
+
export type TransportSalesDeliveryType = (
|
|
83
|
+
| PortDeliverytype
|
|
84
|
+
| AddressDeliveryType
|
|
85
|
+
| TransportPickUpDeliveryType
|
|
86
|
+
) &
|
|
87
|
+
TransportDeliveryExtras;
|
|
88
|
+
|
|
89
|
+
export type TransportPurchaseDeliveryType = PurchaseDeliveryType & TransportDeliveryExtras;
|
|
90
|
+
|
|
91
|
+
/** @deprecated Use SalesDeliveryTypes from ./deliveries.js. */
|
|
92
|
+
export const TransportSalesDeliveryType = {
|
|
93
|
+
Address: SalesDeliveryTypes.ADDRESS,
|
|
94
|
+
Port: SalesDeliveryTypes.PORT,
|
|
95
|
+
PortAndShip: SalesDeliveryTypes.PORT_AND_SHIP,
|
|
96
|
+
PickUp: SalesDeliveryTypes.PICK_UP,
|
|
97
|
+
} as const;
|
|
100
98
|
|
|
101
99
|
export type Transport = {
|
|
102
100
|
id: string;
|
|
@@ -181,6 +179,8 @@ export enum TransportActions {
|
|
|
181
179
|
* server writes into the delivery it ends up with.
|
|
182
180
|
*/
|
|
183
181
|
export type TransportUpdate = {
|
|
182
|
+
/** Changes the purchase method and the purchase agreement together. */
|
|
183
|
+
type?: TransportPurchaseType;
|
|
184
184
|
delivery?: TransportSalesDeliveryType | TransportPurchaseDeliveryType;
|
|
185
185
|
notes?: string | null;
|
|
186
186
|
adminApproved?: boolean;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LocationValue } from '@bisondesk/commons-sdk/locations';
|
|
2
2
|
import { Organization } from './crm.js';
|
|
3
|
+
import { SalesDeliveryType } from './deliveries.js';
|
|
3
4
|
import { BaseEvent } from './internal-events.js';
|
|
4
5
|
import { Opportunity, VehicleSaleDealStatus, VehicleSaleLogisticsStatus } from './opportunities.js';
|
|
5
|
-
import {
|
|
6
|
+
import { Quote } from './quotes.js';
|
|
6
7
|
import { DataRecord } from './utils.js';
|
|
7
8
|
|
|
8
9
|
export enum VehicleSaleInfoActions {
|
|
@@ -31,7 +32,7 @@ export type VehicleSaleInfoBff = {
|
|
|
31
32
|
client?: Organization;
|
|
32
33
|
delivery?: {
|
|
33
34
|
address?: LocationValue;
|
|
34
|
-
type:
|
|
35
|
+
type: SalesDeliveryType['type'];
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DeliveryTypes } from '@bisondesk/core-sdk/types/quotes';
|
|
2
|
+
import { expectTypeOf } from 'vitest';
|
|
3
|
+
import {
|
|
4
|
+
AddressDeliveryType,
|
|
5
|
+
DropOffDeliveryType,
|
|
6
|
+
PickUpDeliveryType,
|
|
7
|
+
PurchaseDeliveryType,
|
|
8
|
+
PurchaseDeliveryTypes,
|
|
9
|
+
SalesDeliveryType,
|
|
10
|
+
SalesDeliveryTypes,
|
|
11
|
+
} from '../types/deliveries.js';
|
|
12
|
+
import { isAddressDelivery } from './deliveries.js';
|
|
13
|
+
|
|
14
|
+
test('purchase and sales contracts keep supplier drop-off and customer pick-up separate', () => {
|
|
15
|
+
expectTypeOf<DropOffDeliveryType>().not.toMatchTypeOf<SalesDeliveryType>();
|
|
16
|
+
expectTypeOf<PickUpDeliveryType>().not.toMatchTypeOf<PurchaseDeliveryType>();
|
|
17
|
+
expectTypeOf<AddressDeliveryType>().toMatchTypeOf<PurchaseDeliveryType>();
|
|
18
|
+
expectTypeOf<
|
|
19
|
+
AddressDeliveryType<PurchaseDeliveryTypes.ADDRESS>
|
|
20
|
+
>().toMatchTypeOf<PurchaseDeliveryType>();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('the previous quote export keeps its four sales methods', () => {
|
|
24
|
+
expect(DeliveryTypes).toEqual(SalesDeliveryTypes);
|
|
25
|
+
expect(Object.values(DeliveryTypes)).toEqual(['park', 'address', 'port', 'portAndShip']);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test.each([
|
|
29
|
+
SalesDeliveryTypes.ADDRESS,
|
|
30
|
+
PurchaseDeliveryTypes.ADDRESS,
|
|
31
|
+
] as const)('reads the address fields for %s', (type) => {
|
|
32
|
+
const delivery: AddressDeliveryType<SalesDeliveryTypes.ADDRESS | PurchaseDeliveryTypes.ADDRESS> =
|
|
33
|
+
{
|
|
34
|
+
type,
|
|
35
|
+
address: { country: 'be', city: 'Gent' },
|
|
36
|
+
distanceKm: '100',
|
|
37
|
+
agreedPrice: '0',
|
|
38
|
+
technicalControlNeeded: false,
|
|
39
|
+
};
|
|
40
|
+
expect(isAddressDelivery(delivery)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('a supplier drop-off has no collection address', () => {
|
|
44
|
+
expect(
|
|
45
|
+
isAddressDelivery({
|
|
46
|
+
type: PurchaseDeliveryTypes.DROP_OFF,
|
|
47
|
+
agreedPrice: '0',
|
|
48
|
+
}),
|
|
49
|
+
).toBe(false);
|
|
50
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AddressDeliveryType,
|
|
3
|
+
PurchaseDeliveryType,
|
|
4
|
+
PurchaseDeliveryTypes,
|
|
5
|
+
SalesDeliveryType,
|
|
6
|
+
SalesDeliveryTypes,
|
|
7
|
+
} from '../types/deliveries.js';
|
|
8
|
+
|
|
9
|
+
/** Purchase collection and sales delivery share the same stored address fields. */
|
|
10
|
+
export const isAddressDelivery = (
|
|
11
|
+
delivery?: PurchaseDeliveryType | SalesDeliveryType,
|
|
12
|
+
): delivery is AddressDeliveryType<PurchaseDeliveryTypes.ADDRESS | SalesDeliveryTypes.ADDRESS> =>
|
|
13
|
+
delivery?.type === PurchaseDeliveryTypes.ADDRESS || delivery?.type === SalesDeliveryTypes.ADDRESS;
|
package/src/utils/transports.ts
CHANGED
|
@@ -4,12 +4,10 @@ import { VehiclePurchase } from '../types/vehicles.js';
|
|
|
4
4
|
import { hasPurchaseArrived } from './vehicles.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* asks this question — what it costs, whose money moved, which papers it needs — is the same for
|
|
10
|
-
* both.
|
|
7
|
+
* Both purchase types bring a vehicle to our park: we collect a pickup, and the supplier brings
|
|
8
|
+
* a drop-off. They share the purchase payment and arrival rules.
|
|
11
9
|
*/
|
|
12
|
-
export const isPurchaseTransport = (transport: Transport): boolean =>
|
|
10
|
+
export const isPurchaseTransport = (transport: Pick<Transport, 'type'>): boolean =>
|
|
13
11
|
transport.type !== TransportType.SaleDelivery;
|
|
14
12
|
|
|
15
13
|
/**
|