@bisondesk/core-sdk 1.0.655 → 1.0.657

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.
Files changed (105) hide show
  1. package/lib/types/deliveries.d.ts +74 -0
  2. package/lib/types/deliveries.d.ts.map +1 -0
  3. package/lib/types/deliveries.js +24 -0
  4. package/lib/types/deliveries.js.map +1 -0
  5. package/lib/types/quotes.d.ts +5 -65
  6. package/lib/types/quotes.d.ts.map +1 -1
  7. package/lib/types/quotes.js +1 -18
  8. package/lib/types/quotes.js.map +1 -1
  9. package/lib/types/transports.d.ts +10 -15
  10. package/lib/types/transports.d.ts.map +1 -1
  11. package/lib/types/transports.js +5 -5
  12. package/lib/types/transports.js.map +1 -1
  13. package/lib/types/vehicle-sales.d.ts +3 -2
  14. package/lib/types/vehicle-sales.d.ts.map +1 -1
  15. package/lib/types/vehicle-sales.js.map +1 -1
  16. package/lib/utils/deliveries.d.ts +3 -0
  17. package/lib/utils/deliveries.d.ts.map +1 -0
  18. package/lib/utils/deliveries.js +3 -0
  19. package/lib/utils/deliveries.js.map +1 -0
  20. package/lib/utils/deliveries.test.d.ts +2 -0
  21. package/lib/utils/deliveries.test.d.ts.map +1 -0
  22. package/lib/utils/deliveries.test.js +34 -0
  23. package/lib/utils/deliveries.test.js.map +1 -0
  24. package/lib/utils/transports.d.ts +1 -1
  25. package/lib/utils/transports.d.ts.map +1 -1
  26. package/lib/utils/transports.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/types/deliveries.ts +92 -0
  29. package/src/types/quotes.ts +17 -73
  30. package/src/types/transports.ts +24 -24
  31. package/src/types/vehicle-sales.ts +3 -2
  32. package/src/utils/deliveries.test.ts +50 -0
  33. package/src/utils/deliveries.ts +13 -0
  34. package/src/utils/transports.ts +3 -5
  35. package/tsconfig.tsbuildinfo +1 -1
  36. package/src/types/activities.js +0 -13
  37. package/src/types/activities.js.map +0 -1
  38. package/src/types/comparables.js +0 -2
  39. package/src/types/comparables.js.map +0 -1
  40. package/src/types/crm.js +0 -58
  41. package/src/types/crm.js.map +0 -1
  42. package/src/types/dashboard.js +0 -2
  43. package/src/types/dashboard.js.map +0 -1
  44. package/src/types/definitions.js +0 -2
  45. package/src/types/definitions.js.map +0 -1
  46. package/src/types/fields.js +0 -2
  47. package/src/types/fields.js.map +0 -1
  48. package/src/types/insights.js +0 -2
  49. package/src/types/insights.js.map +0 -1
  50. package/src/types/interests.js +0 -6
  51. package/src/types/interests.js.map +0 -1
  52. package/src/types/internal-events.js +0 -18
  53. package/src/types/internal-events.js.map +0 -1
  54. package/src/types/internet-opportunities.js +0 -2
  55. package/src/types/internet-opportunities.js.map +0 -1
  56. package/src/types/internet-vehicles.js +0 -2
  57. package/src/types/internet-vehicles.js.map +0 -1
  58. package/src/types/leasing-administration.js +0 -2
  59. package/src/types/leasing-administration.js.map +0 -1
  60. package/src/types/leasing-debtors.js +0 -2
  61. package/src/types/leasing-debtors.js.map +0 -1
  62. package/src/types/leasing-search.js +0 -2
  63. package/src/types/leasing-search.js.map +0 -1
  64. package/src/types/leasing-settings.js +0 -7
  65. package/src/types/leasing-settings.js.map +0 -1
  66. package/src/types/leasing.js +0 -38
  67. package/src/types/leasing.js.map +0 -1
  68. package/src/types/marketing.js +0 -35
  69. package/src/types/marketing.js.map +0 -1
  70. package/src/types/offers.js +0 -56
  71. package/src/types/opportunities.js +0 -107
  72. package/src/types/opportunities.js.map +0 -1
  73. package/src/types/payments.js +0 -7
  74. package/src/types/picklists.js +0 -2
  75. package/src/types/picklists.js.map +0 -1
  76. package/src/types/quotes.js +0 -42
  77. package/src/types/recently-viewed.js +0 -2
  78. package/src/types/recently-viewed.js.map +0 -1
  79. package/src/types/reservations.js +0 -5
  80. package/src/types/reservations.js.map +0 -1
  81. package/src/types/roi-ratings.js +0 -5
  82. package/src/types/roi-ratings.js.map +0 -1
  83. package/src/types/saved-filters.js +0 -9
  84. package/src/types/saved-filters.js.map +0 -1
  85. package/src/types/search.js +0 -2
  86. package/src/types/search.js.map +0 -1
  87. package/src/types/settings.js +0 -2
  88. package/src/types/settings.js.map +0 -1
  89. package/src/types/templates.js +0 -2
  90. package/src/types/templates.js.map +0 -1
  91. package/src/types/tenants.js +0 -21
  92. package/src/types/tenants.js.map +0 -1
  93. package/src/types/user-performance.js +0 -7
  94. package/src/types/user-performance.js.map +0 -1
  95. package/src/types/utils.js +0 -2
  96. package/src/types/validation.js +0 -2
  97. package/src/types/validation.js.map +0 -1
  98. package/src/types/vehicle-sales.js +0 -6
  99. package/src/types/vehicle-sales.js.map +0 -1
  100. package/src/types/vehicles.js +0 -98
  101. package/src/types/vehicles.js.map +0 -1
  102. package/src/utils/leasing.js +0 -6
  103. package/src/utils/leasing.js.map +0 -1
  104. package/src/utils/opportunities.js +0 -48
  105. package/src/utils/opportunities.js.map +0 -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;AASvD,eAAO,MAAM,mBAAmB,cAAe,SAAS,KAAG,OACZ,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
+ {"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;AAQnD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAoB,EAAW,EAAE,CACnE,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 * Which side of the trade the transport serves. Both purchase types answer yes: a pick-up we drive\n * and a drop-off the supplier drives differ only in who is behind the wheel, and every rule that\n * asks this question what it costs, whose money moved, which papers it needs — is the same for\n * both.\n */\nexport const isPurchaseTransport = (transport: Transport): 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"]}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bisondesk/core-sdk",
3
- "version": "1.0.655",
3
+ "version": "1.0.657",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "author": "TheTruckCompany",
@@ -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
+ };
@@ -1,5 +1,6 @@
1
- import { AttachmentValue, LocationValue } from '@bisondesk/commons-sdk/types';
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?: PickUpDeliveryType | AddressDeliveryType | PortDeliverytype;
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';
@@ -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
- } from './quotes.js';
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
- export type TransportSalesDeliveryType = (
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 TransportPurchaseDeliveryType = AddressDeliveryType & {
93
- cleaningNeeded?: boolean;
94
- driver?: string;
95
- transportCompany?: string;
96
- date?: string; // Pick-up (purchase) | Delivery (OPP) (leaves parking)
97
- adminCost?: string; // user-entered administrative cost summed into totalCostExclVat
98
- stackingVehicleCostPrice?: string; // overrides the stacking rate from the delivery settings
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 { DeliveryTypes, Quote } from './quotes.js';
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: DeliveryTypes;
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;
@@ -4,12 +4,10 @@ import { VehiclePurchase } from '../types/vehicles.js';
4
4
  import { hasPurchaseArrived } from './vehicles.js';
5
5
 
6
6
  /**
7
- * Which side of the trade the transport serves. Both purchase types answer yes: a pick-up we drive
8
- * and a drop-off the supplier drives differ only in who is behind the wheel, and every rule that
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
  /**