@flowselections/floriday-verkoop-module 1.0.94 → 1.0.98

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 (174) hide show
  1. package/dist-lib/components/verkoop/AnalyticsCards.d.ts +1 -1
  2. package/dist-lib/components/verkoop/AnalyticsCards.d.ts.map +1 -1
  3. package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts +1 -1
  4. package/dist-lib/components/verkoop/CartAssignmentWizard.d.ts.map +1 -1
  5. package/dist-lib/components/verkoop/CartLayersDialog.d.ts +1 -1
  6. package/dist-lib/components/verkoop/CartLayersDialog.d.ts.map +1 -1
  7. package/dist-lib/components/verkoop/CreateOrderPage.d.ts +1 -1
  8. package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -1
  9. package/dist-lib/components/verkoop/CreateOrderPage.js +82 -43
  10. package/dist-lib/components/verkoop/DiagnoseConnectionDialog.d.ts +1 -1
  11. package/dist-lib/components/verkoop/DiagnoseConnectionDialog.d.ts.map +1 -1
  12. package/dist-lib/components/verkoop/EditLocalOrderDialog.d.ts +1 -1
  13. package/dist-lib/components/verkoop/EditLocalOrderDialog.d.ts.map +1 -1
  14. package/dist-lib/components/verkoop/EngineBufferCard.d.ts +1 -1
  15. package/dist-lib/components/verkoop/EngineBufferCard.d.ts.map +1 -1
  16. package/dist-lib/components/verkoop/FloridayStageLine.d.ts +2 -2
  17. package/dist-lib/components/verkoop/FloridayStageLine.d.ts.map +1 -1
  18. package/dist-lib/components/verkoop/InvoiceTimingSettings.d.ts +1 -1
  19. package/dist-lib/components/verkoop/InvoiceTimingSettings.d.ts.map +1 -1
  20. package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts +1 -1
  21. package/dist-lib/components/verkoop/OrderAfleverbrievenCard.d.ts.map +1 -1
  22. package/dist-lib/components/verkoop/OrderCarrierPicker.d.ts +1 -1
  23. package/dist-lib/components/verkoop/OrderCarrierPicker.d.ts.map +1 -1
  24. package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts +1 -1
  25. package/dist-lib/components/verkoop/OrderControlStatusCard.d.ts.map +1 -1
  26. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts +1 -1
  27. package/dist-lib/components/verkoop/OrderKarindelingCard.d.ts.map +1 -1
  28. package/dist-lib/components/verkoop/OrderKarindelingCard.js +1 -1
  29. package/dist-lib/components/verkoop/OrderLinePackingCard.d.ts +1 -1
  30. package/dist-lib/components/verkoop/OrderLinePackingCard.d.ts.map +1 -1
  31. package/dist-lib/components/verkoop/OrderPickupMomentPicker.d.ts +1 -1
  32. package/dist-lib/components/verkoop/OrderPickupMomentPicker.d.ts.map +1 -1
  33. package/dist-lib/components/verkoop/OrderPickupMomentPicker.js +2 -1
  34. package/dist-lib/components/verkoop/OrderShipmentsCard.d.ts +1 -1
  35. package/dist-lib/components/verkoop/OrderShipmentsCard.d.ts.map +1 -1
  36. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts +1 -1
  37. package/dist-lib/components/verkoop/PlanCoverageBadge.d.ts.map +1 -1
  38. package/dist-lib/components/verkoop/PlanCoverageBadge.js +7 -5
  39. package/dist-lib/components/verkoop/ProductDimensionsSettings.d.ts +1 -1
  40. package/dist-lib/components/verkoop/ProductDimensionsSettings.d.ts.map +1 -1
  41. package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts +1 -1
  42. package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -1
  43. package/dist-lib/components/verkoop/SalesOrderDetailPage.js +6 -6
  44. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts +1 -1
  45. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  46. package/dist-lib/components/verkoop/SalesOrderDetailView.js +2 -1
  47. package/dist-lib/components/verkoop/SalesOrdersFilterPanel.d.ts +1 -1
  48. package/dist-lib/components/verkoop/SalesOrdersFilterPanel.d.ts.map +1 -1
  49. package/dist-lib/components/verkoop/SalesOrdersFilters.d.ts +1 -1
  50. package/dist-lib/components/verkoop/SalesOrdersFilters.d.ts.map +1 -1
  51. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts +2 -1
  52. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  53. package/dist-lib/components/verkoop/SearchableSelect.d.ts +1 -1
  54. package/dist-lib/components/verkoop/SearchableSelect.d.ts.map +1 -1
  55. package/dist-lib/components/verkoop/StockConsumptionAlertsBanner.d.ts +1 -1
  56. package/dist-lib/components/verkoop/StockConsumptionAlertsBanner.d.ts.map +1 -1
  57. package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts +1 -1
  58. package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
  59. package/dist-lib/components/verkoop/WeekCalendar.d.ts +1 -1
  60. package/dist-lib/components/verkoop/WeekCalendar.d.ts.map +1 -1
  61. package/dist-lib/integrations/supabase/client.js +1 -1
  62. package/dist-lib/integrations/supabase/client.server.js +1 -1
  63. package/dist-lib/integrations/supabase/types.d.ts +253 -0
  64. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  65. package/dist-lib/lib/carrier-availability.d.ts +0 -28
  66. package/dist-lib/lib/carrier-availability.d.ts.map +1 -1
  67. package/dist-lib/lib/carrier-availability.js +3 -141
  68. package/dist-lib/lib/cart-replan.functions.d.ts +5 -0
  69. package/dist-lib/lib/cart-replan.functions.d.ts.map +1 -1
  70. package/dist-lib/lib/cart-replan.functions.js +25 -1
  71. package/dist-lib/lib/create-order.functions.d.ts +5 -0
  72. package/dist-lib/lib/create-order.functions.d.ts.map +1 -1
  73. package/dist-lib/lib/create-order.functions.js +81 -54
  74. package/dist-lib/lib/departure-preview.check.d.ts +2 -0
  75. package/dist-lib/lib/departure-preview.check.d.ts.map +1 -0
  76. package/dist-lib/lib/departure-preview.check.js +37 -0
  77. package/dist-lib/lib/departure-preview.d.ts +47 -0
  78. package/dist-lib/lib/departure-preview.d.ts.map +1 -0
  79. package/dist-lib/lib/departure-preview.functions.d.ts +13 -0
  80. package/dist-lib/lib/departure-preview.functions.d.ts.map +1 -0
  81. package/dist-lib/lib/departure-preview.functions.js +17 -0
  82. package/dist-lib/lib/departure-preview.js +70 -0
  83. package/dist-lib/lib/departure-preview.server.d.ts +10 -0
  84. package/dist-lib/lib/departure-preview.server.d.ts.map +1 -0
  85. package/dist-lib/lib/departure-preview.server.js +29 -0
  86. package/dist-lib/lib/floriday-external-fulfillment.check.d.ts +2 -0
  87. package/dist-lib/lib/floriday-external-fulfillment.check.d.ts.map +1 -0
  88. package/dist-lib/lib/floriday-external-fulfillment.check.js +21 -0
  89. package/dist-lib/lib/floriday-external-fulfillment.d.ts +19 -0
  90. package/dist-lib/lib/floriday-external-fulfillment.d.ts.map +1 -0
  91. package/dist-lib/lib/floriday-external-fulfillment.js +24 -0
  92. package/dist-lib/lib/floriday-external-fulfillment.server.d.ts +5 -0
  93. package/dist-lib/lib/floriday-external-fulfillment.server.d.ts.map +1 -0
  94. package/dist-lib/lib/floriday-external-fulfillment.server.js +110 -0
  95. package/dist-lib/lib/floriday-fulfillment-status.server.d.ts +2 -0
  96. package/dist-lib/lib/floriday-fulfillment-status.server.d.ts.map +1 -1
  97. package/dist-lib/lib/floriday-fulfillment-status.server.js +3 -0
  98. package/dist-lib/lib/floriday-line-key.check.d.ts +2 -0
  99. package/dist-lib/lib/floriday-line-key.check.d.ts.map +1 -0
  100. package/dist-lib/lib/floriday-line-key.check.js +31 -0
  101. package/dist-lib/lib/floriday-line-key.d.ts +12 -0
  102. package/dist-lib/lib/floriday-line-key.d.ts.map +1 -0
  103. package/dist-lib/lib/floriday-line-key.js +20 -0
  104. package/dist-lib/lib/floriday-mirror.functions.d.ts.map +1 -1
  105. package/dist-lib/lib/floriday-mirror.functions.js +38 -2
  106. package/dist-lib/lib/logistics-engine.functions.d.ts +1 -1
  107. package/dist-lib/lib/order-cart-count.server.d.ts +8 -0
  108. package/dist-lib/lib/order-cart-count.server.d.ts.map +1 -0
  109. package/dist-lib/lib/order-cart-count.server.js +69 -0
  110. package/dist-lib/lib/order-departure.server.d.ts +1 -0
  111. package/dist-lib/lib/order-departure.server.d.ts.map +1 -1
  112. package/dist-lib/lib/order-departure.server.js +16 -4
  113. package/dist-lib/lib/order-pickup.functions.d.ts +4 -0
  114. package/dist-lib/lib/order-pickup.functions.d.ts.map +1 -1
  115. package/dist-lib/lib/order-pickup.functions.js +7 -0
  116. package/dist-lib/lib/plan-coverage.d.ts +13 -1
  117. package/dist-lib/lib/plan-coverage.d.ts.map +1 -1
  118. package/dist-lib/lib/plan-coverage.js +20 -1
  119. package/dist-lib/lib/salesorders-list.server.d.ts.map +1 -1
  120. package/dist-lib/lib/salesorders-list.server.js +6 -6
  121. package/dist-lib/lib/salesorders-mapping.d.ts +5 -0
  122. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  123. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  124. package/dist-lib/lib/salesorders.functions.js +6 -0
  125. package/dist-lib/lib/tradeitems.functions.d.ts +1117 -12
  126. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  127. package/dist-lib/lib/useBufferEvents.d.ts +2 -2
  128. package/dist-lib/lib/useBufferEvents.d.ts.map +1 -1
  129. package/dist-lib/lib/useLocalSalesOrderDetailQuery.d.ts +2 -2
  130. package/dist-lib/lib/useLocalSalesOrderDetailQuery.d.ts.map +1 -1
  131. package/dist-lib/lib/useSalesOrderDetailQuery.d.ts +1 -1
  132. package/dist-lib/lib/useSalesOrderDetailQuery.d.ts.map +1 -1
  133. package/dist-lib/lib/useSalesOrdersQuery.d.ts +1 -1
  134. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
  135. package/package.json +1 -1
  136. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.d.ts +0 -9
  137. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.d.ts.map +0 -1
  138. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.js +0 -26
  139. package/dist-lib/components/karindeling/AfmetingenTab.d.ts +0 -6
  140. package/dist-lib/components/karindeling/AfmetingenTab.d.ts.map +0 -1
  141. package/dist-lib/components/karindeling/AfmetingenTab.js +0 -128
  142. package/dist-lib/components/karindeling/KarindelingPage.d.ts +0 -2
  143. package/dist-lib/components/karindeling/KarindelingPage.d.ts.map +0 -1
  144. package/dist-lib/components/karindeling/KarindelingPage.js +0 -102
  145. package/dist-lib/components/ui/dropdown-menu.d.ts +0 -9
  146. package/dist-lib/components/ui/dropdown-menu.d.ts.map +0 -1
  147. package/dist-lib/components/ui/dropdown-menu.js +0 -14
  148. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.d.ts +0 -4
  149. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.d.ts.map +0 -1
  150. package/dist-lib/components/verkoop/AutoFulfillmentStatusCard.js +0 -95
  151. package/dist-lib/components/verkoop/CreateOrderDialog.d.ts +0 -5
  152. package/dist-lib/components/verkoop/CreateOrderDialog.d.ts.map +0 -1
  153. package/dist-lib/components/verkoop/CreateOrderDialog.js +0 -33
  154. package/dist-lib/lib/cron/mirror-floriday-orders.d.ts +0 -4
  155. package/dist-lib/lib/cron/mirror-floriday-orders.d.ts.map +0 -1
  156. package/dist-lib/lib/cron/mirror-floriday-orders.js +0 -23
  157. package/dist-lib/lib/cron/push-order-statuses.d.ts +0 -4
  158. package/dist-lib/lib/cron/push-order-statuses.d.ts.map +0 -1
  159. package/dist-lib/lib/cron/push-order-statuses.js +0 -23
  160. package/dist-lib/lib/floriday/floriday.server.d.ts +0 -14
  161. package/dist-lib/lib/floriday/floriday.server.d.ts.map +0 -1
  162. package/dist-lib/lib/floriday/floriday.server.js +0 -92
  163. package/dist-lib/lib/floriday/sales-orders.functions.d.ts +0 -4736
  164. package/dist-lib/lib/floriday/sales-orders.functions.d.ts.map +0 -1
  165. package/dist-lib/lib/floriday/sales-orders.functions.js +0 -193
  166. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts +0 -77581
  167. package/dist-lib/lib/floriday-auto-fulfillment.functions.d.ts.map +0 -1
  168. package/dist-lib/lib/floriday-auto-fulfillment.functions.js +0 -65
  169. package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts +0 -21
  170. package/dist-lib/lib/floriday-auto-fulfillment.server.d.ts.map +0 -1
  171. package/dist-lib/lib/floriday-auto-fulfillment.server.js +0 -352
  172. package/dist-lib/lib/floriday-status-sync.server.d.ts +0 -14
  173. package/dist-lib/lib/floriday-status-sync.server.d.ts.map +0 -1
  174. package/dist-lib/lib/floriday-status-sync.server.js +0 -130
@@ -15,35 +15,7 @@ export type CarrierAvailability = {
15
15
  delivery_weekdays?: number[] | null;
16
16
  pickup_moments?: PickupMoment[] | null;
17
17
  };
18
- export type EarliestDelivery = {
19
- /** Leverdatum als YYYY-MM-DD. */
20
- deliveryISO: string;
21
- /** Ophaal-/aanmelddag als YYYY-MM-DD. */
22
- pickupISO: string;
23
- /** Uiterste aanmeldmoment dat hierbij hoort (ISO-datum + tijd), indien bekend. */
24
- signupDeadlineISO: string | null;
25
- signupTime: string | null;
26
- /** Aanlevertijd van het gekozen moment, bv. "20:00". */
27
- deliveryTime: string | null;
28
- };
29
18
  export declare function toISODate(d: Date): string;
30
19
  /** "20:00:00" / "20:00" -> "20:00"; leeg -> null. */
31
20
  export declare function normalizeTime(t: string | null | undefined): string | null;
32
- /**
33
- * Eerst mogelijke leverdatum.
34
- *
35
- * - Een ophaaldag telt alleen mee als het bijbehorende aanmeldmoment nog niet
36
- * verstreken is (aanmelddeadline = ophaaldag − signup_days op signup_time).
37
- * - Ophaaldag moet in pickup_weekdays vallen, leverdag in delivery_weekdays.
38
- * - `pickDays` (interne orderpicktijd) is de minimale voorlooptijd tot de ophaaldag.
39
- */
40
- export declare function computeEarliestDelivery(carrier: CarrierAvailability | null | undefined, pickDays: number, now?: Date, horizonDays?: number): EarliestDelivery;
41
- /** "Nu" in Europe/Amsterdam als lokale Date — voor servercode die in UTC draait. */
42
- export declare function nowInAmsterdam(base?: Date): Date;
43
- /**
44
- * Aanlevertijd die hoort bij een (al vastgelegde) leverdatum van een order.
45
- * Kiest het aanmeldmoment dat op die datum uitkomt; bij meerdere momenten het
46
- * moment dat het laatst nog haalbaar was op het referentiemoment (besteltijd).
47
- */
48
- export declare function resolveDeliveryTimeForDate(carrier: CarrierAvailability | null | undefined, deliveryISO: string, reference?: Date): string | null;
49
21
  //# sourceMappingURL=carrier-availability.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"carrier-availability.d.ts","sourceRoot":"","sources":["../../src/lib/carrier-availability.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wDAAwD;IACxD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAEzC;AAoBD,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzE;AAuBD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAC/C,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,IAAiB,EACtB,WAAW,SAAK,GACf,gBAAgB,CA0DlB;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,IAAI,GAAE,IAAiB,GAAG,IAAI,CAQ5D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAC/C,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,IAAiB,GAC3B,MAAM,GAAG,IAAI,CAiBf"}
1
+ {"version":3,"file":"carrier-availability.d.ts","sourceRoot":"","sources":["../../src/lib/carrier-availability.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;CACxC,CAAC;AAEF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAEzC;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzE"}
@@ -1,26 +1,9 @@
1
- // Bepaalt de eerst mogelijke leverdatum op basis van de aanmeldmomenten
2
- // (pickup_moments) van de vervoerder. Zuiver rekenwerk, gedeeld door de UI
3
- // (CreateOrderPage) en de server-validatie (createManualOrder), zodat beide
4
- // exact hetzelfde antwoord geven.
1
+ // Gegevens van de vervoerder (pickup_moments). Hier wordt niets berekend:
2
+ // ophaalmomenten, werkdagen, tijdzone en de eerst haalbare leverdatum komen
3
+ // van de Logistiek Engine (logistics_departure_preview / logistics_order_departure).
5
4
  export function toISODate(d) {
6
5
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
7
6
  }
8
- function addDays(d, n) {
9
- const c = new Date(d.getTime());
10
- c.setDate(c.getDate() + n);
11
- return c;
12
- }
13
- /** ISO-weekdag: maandag = 1 … zondag = 7. */
14
- function isoWeekday(d) {
15
- return d.getDay() === 0 ? 7 : d.getDay();
16
- }
17
- function parseTime(t, fallback) {
18
- const s = (t ?? fallback) || fallback;
19
- const m = /^(\d{1,2}):(\d{2})/.exec(String(s));
20
- if (!m)
21
- return [23, 59];
22
- return [Number(m[1]), Number(m[2])];
23
- }
24
7
  /** "20:00:00" / "20:00" -> "20:00"; leeg -> null. */
25
8
  export function normalizeTime(t) {
26
9
  const m = /^(\d{1,2}):(\d{2})/.exec(String(t ?? "").trim());
@@ -28,124 +11,3 @@ export function normalizeTime(t) {
28
11
  return null;
29
12
  return `${String(Number(m[1])).padStart(2, "0")}:${m[2]}`;
30
13
  }
31
- function allowsWeekday(list, d) {
32
- if (!Array.isArray(list) || list.length === 0)
33
- return true;
34
- return list.map(Number).includes(isoWeekday(d));
35
- }
36
- function momentsOf(carrier) {
37
- const raw = Array.isArray(carrier.pickup_moments) ? carrier.pickup_moments : [];
38
- if (raw.length > 0)
39
- return raw;
40
- // Terugval op de losse signup_time-velden.
41
- const times = [carrier.signup_time_1, carrier.signup_time_2].filter(Boolean);
42
- if (times.length > 0) {
43
- return times.map((t) => ({
44
- signup_time: t,
45
- signup_days: carrier.signup_days_before_delivery ?? 0,
46
- delivery_days: carrier.delivery_days ?? 0,
47
- }));
48
- }
49
- // Geen aanmeldmomenten bekend: één moment zonder deadline.
50
- return [{ signup_time: null, signup_days: carrier.signup_days_before_delivery ?? 0, delivery_days: carrier.delivery_days ?? 0 }];
51
- }
52
- /**
53
- * Eerst mogelijke leverdatum.
54
- *
55
- * - Een ophaaldag telt alleen mee als het bijbehorende aanmeldmoment nog niet
56
- * verstreken is (aanmelddeadline = ophaaldag − signup_days op signup_time).
57
- * - Ophaaldag moet in pickup_weekdays vallen, leverdag in delivery_weekdays.
58
- * - `pickDays` (interne orderpicktijd) is de minimale voorlooptijd tot de ophaaldag.
59
- */
60
- export function computeEarliestDelivery(carrier, pickDays, now = new Date(), horizonDays = 90) {
61
- const lead = Math.max(0, Number(pickDays) || 0);
62
- const today = new Date(now.getTime());
63
- today.setHours(0, 0, 0, 0);
64
- const carrierDeliveryDays = Math.max(0, Number(carrier?.delivery_days ?? 0) || 0);
65
- if (!carrier) {
66
- const d = addDays(today, lead);
67
- return { deliveryISO: toISODate(d), pickupISO: toISODate(d), signupDeadlineISO: null, signupTime: null, deliveryTime: null };
68
- }
69
- const moments = momentsOf(carrier);
70
- let best = null;
71
- for (let i = lead; i <= horizonDays; i++) {
72
- const pickupDate = addDays(today, i);
73
- if (!allowsWeekday(carrier.pickup_weekdays, pickupDate))
74
- continue;
75
- for (const m of moments) {
76
- const signupDays = Math.max(0, Number(m.signup_days ?? carrier.signup_days_before_delivery ?? 0) || 0);
77
- const signupDate = addDays(pickupDate, -signupDays);
78
- let deadlineISO = null;
79
- if (m.signup_time) {
80
- const [hh, mm] = parseTime(m.signup_time, "23:59");
81
- const deadline = new Date(signupDate.getTime());
82
- deadline.setHours(hh, mm, 0, 0);
83
- if (deadline.getTime() <= now.getTime())
84
- continue; // aanmeldmoment verstreken
85
- deadlineISO = `${toISODate(signupDate)}T${String(hh).padStart(2, "0")}:${String(mm).padStart(2, "0")}`;
86
- }
87
- else if (signupDate.getTime() < today.getTime()) {
88
- continue;
89
- }
90
- const deliveryDays = Math.max(0, Number(m.delivery_days ?? carrierDeliveryDays) || 0);
91
- const deliveryDate = addDays(pickupDate, deliveryDays);
92
- if (!allowsWeekday(carrier.delivery_weekdays, deliveryDate))
93
- continue;
94
- const candidate = {
95
- deliveryISO: toISODate(deliveryDate),
96
- pickupISO: toISODate(pickupDate),
97
- signupDeadlineISO: deadlineISO,
98
- signupTime: m.signup_time ?? null,
99
- deliveryTime: normalizeTime(m.delivery_time),
100
- };
101
- if (!best ||
102
- candidate.deliveryISO < best.deliveryISO ||
103
- (candidate.deliveryISO === best.deliveryISO &&
104
- (candidate.deliveryTime ?? "99:99") < (best.deliveryTime ?? "99:99"))) {
105
- best = candidate;
106
- }
107
- }
108
- if (best)
109
- break; // eerste geldige ophaaldag bepaalt de vroegste levering
110
- }
111
- if (best)
112
- return best;
113
- const fallback = addDays(today, lead + carrierDeliveryDays);
114
- return { deliveryISO: toISODate(fallback), pickupISO: toISODate(fallback), signupDeadlineISO: null, signupTime: null, deliveryTime: null };
115
- }
116
- /** "Nu" in Europe/Amsterdam als lokale Date — voor servercode die in UTC draait. */
117
- export function nowInAmsterdam(base = new Date()) {
118
- const parts = new Intl.DateTimeFormat("en-US", {
119
- timeZone: "Europe/Amsterdam",
120
- year: "numeric", month: "2-digit", day: "2-digit",
121
- hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false,
122
- }).formatToParts(base);
123
- const get = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
124
- return new Date(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"), 0);
125
- }
126
- /**
127
- * Aanlevertijd die hoort bij een (al vastgelegde) leverdatum van een order.
128
- * Kiest het aanmeldmoment dat op die datum uitkomt; bij meerdere momenten het
129
- * moment dat het laatst nog haalbaar was op het referentiemoment (besteltijd).
130
- */
131
- export function resolveDeliveryTimeForDate(carrier, deliveryISO, reference = new Date()) {
132
- if (!carrier || !deliveryISO)
133
- return null;
134
- const moments = momentsOf(carrier);
135
- const candidates = [];
136
- for (const m of moments) {
137
- const time = normalizeTime(m.delivery_time);
138
- if (!time)
139
- continue;
140
- candidates.push({ time, signup: normalizeTime(m.signup_time) });
141
- }
142
- if (candidates.length === 0)
143
- return null;
144
- if (candidates.length === 1)
145
- return candidates[0].time;
146
- const refTime = `${String(reference.getHours()).padStart(2, "0")}:${String(reference.getMinutes()).padStart(2, "0")}`;
147
- const sorted = [...candidates].sort((a, b) => a.time.localeCompare(b.time));
148
- // Eerste moment waarvan het aanmeldmoment op de besteltijd nog niet verstreken is.
149
- const still = sorted.find((c) => !c.signup || c.signup > refTime);
150
- return (still ?? sorted[sorted.length - 1]).time;
151
- }
@@ -79,6 +79,11 @@ export declare const getOrderPlanCoverage: import("@tanstack/start-client-core")
79
79
  }, Promise<{
80
80
  orderId: string;
81
81
  coverage: import("./plan-coverage.js").PlanCoverage;
82
+ externalEvent: {
83
+ status: string | null;
84
+ error: string | null;
85
+ sendError: string | null;
86
+ } | null;
82
87
  }>>;
83
88
  export declare const replanBufferForOrder: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
84
89
  supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
@@ -1 +1 @@
1
- {"version":3,"file":"cart-replan.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cart-replan.functions.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,eAAe,GAAG,sBAAsB,CAAC;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM;QAYrD,OAAO;cACD,MAAM,GAAG,IAAI;cACb,MAAM,EAAE;kBACJ,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAlBnB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,OAAO,CAAC;IACV,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC,CA+YD;AA4BD,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM;QAzBxD,OAAO;aACF,MAAM;kBACD,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAoBnB;AAED,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;QA/B3B,OAAO;aACF,MAAM;kBACD,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GA6BhB,CAAC;AAML,wBAAsB,oBAAoB,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC;IAC/D,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE,CAAC,CAED;AAMD,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;;;GAU7B,CAAC;AAEL,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;QAle3B,OAAO;cACD,MAAM,GAAG,IAAI;cACb,MAAM,EAAE;kBACJ,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAgehB,CAAC"}
1
+ {"version":3,"file":"cart-replan.functions.d.ts","sourceRoot":"","sources":["../../src/lib/cart-replan.functions.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,eAAe,GAAG,sBAAsB,CAAC;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM;QAYrD,OAAO;cACD,MAAM,GAAG,IAAI;cACb,MAAM,EAAE;kBACJ,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAlBnB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,OAAO,CAAC;IACV,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC,CA+YD;AA4BD,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM;QAzBxD,OAAO;aACF,MAAM;kBACD,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAoBnB;AAED,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;QA/B3B,OAAO;aACF,MAAM;kBACD,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GA6BhB,CAAC;AAML,wBAAsB,oBAAoB,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC;IAC/D,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE,CAAC,CAED;AAMD,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;;;;gBAUA,MAAM,GAAG,IAAI;eAAS,MAAM,GAAG,IAAI;mBAAa,MAAM,GAAG,IAAI;;GAsB1F,CAAC;AAEL,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;QAxf3B,OAAO;cACD,MAAM,GAAG,IAAI;cACb,MAAM,EAAE;kBACJ,MAAM;yBACC,MAAM;yBACN,OAAO;cAClB,MAAM,EAAE;kBACJ,WAAW,EAAE;cACjB,QAAQ;GAsfhB,CAAC"}
@@ -393,7 +393,31 @@ export const getOrderPlanCoverage = createServerFn({ method: "GET" })
393
393
  const { unknownCoverage } = await import("./plan-coverage.js");
394
394
  const cov = (await loadPlanCoverage(context.supabase, [dbOrderId])).get(dbOrderId) ??
395
395
  unknownCoverage("Geen antwoord van de Engine");
396
- return { orderId: dbOrderId, coverage: cov };
396
+ // Uitkomst van de melding "Afgehandeld in Floriday" (alleen lezen).
397
+ let externalEvent = null;
398
+ try {
399
+ const { data: o } = await context.supabase.from("orders")
400
+ .select("custom_fields")
401
+ .eq("id", dbOrderId)
402
+ .maybeSingle();
403
+ const cf = (o?.custom_fields ?? {});
404
+ const evId = typeof cf.floriday_external_engine_event_id === "string" ? cf.floriday_external_engine_event_id : null;
405
+ const sendError = typeof cf.floriday_external_engine_error === "string" ? cf.floriday_external_engine_error : null;
406
+ if (evId) {
407
+ const { data: ev } = await context.supabase.from("logistics_events")
408
+ .select("status, error")
409
+ .eq("id", evId)
410
+ .maybeSingle();
411
+ externalEvent = { status: ev?.status ?? null, error: ev?.error ?? null, sendError };
412
+ }
413
+ else if (sendError) {
414
+ externalEvent = { status: null, error: null, sendError };
415
+ }
416
+ }
417
+ catch {
418
+ externalEvent = null;
419
+ }
420
+ return { orderId: dbOrderId, coverage: cov, externalEvent };
397
421
  });
398
422
  export const replanBufferForOrder = createServerFn({ method: "POST" })
399
423
  .middleware([requireSupabaseAuth])
@@ -146,6 +146,10 @@ export declare const createManualOrder: import("@tanstack/start-client-core").Op
146
146
  isReservation?: boolean | undefined;
147
147
  loadCarrierType?: string | null | undefined;
148
148
  notes?: string | null | undefined;
149
+ momentKey?: string | null | undefined;
150
+ acceptLateSignup?: boolean | undefined;
151
+ acceptedByName?: string | null | undefined;
152
+ source?: "manual" | "mailbox" | undefined;
149
153
  }, Promise<{
150
154
  ok: true;
151
155
  orderId: string;
@@ -219,6 +223,7 @@ export declare const updateLocalOrder: import("@tanstack/start-client-core").Opt
219
223
  }, undefined, undefined, undefined>], (input: unknown) => {
220
224
  orderId: string;
221
225
  deliveryDate?: string | undefined;
226
+ acceptLateSignup?: boolean | undefined;
222
227
  items?: {
223
228
  itemId: string;
224
229
  quantity: number;
@@ -1 +1 @@
1
- {"version":3,"file":"create-order.functions.d.ts","sourceRoot":"","sources":["../../src/lib/create-order.functions.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,2BAA2B;;;;;;GA+CpC,CAAC;AAIL,eAAO,MAAM,2BAA2B;;;;0CAElB,OAAO;;;;GAoDzB,CAAC;AAWL,eAAO,MAAM,0BAA0B;;;;;;YA+D7B,MAAM;iBACD,MAAM;sBACD,MAAM,GAAG,IAAI;cACrB,MAAM;oBACA,MAAM,GAAG,IAAI;0BACP,MAAM;0BACN,MAAM;yBACP,MAAM;wBACP,MAAM;wBACN,MAAM;yBACL,MAAM;kBACb,OAAO;gBACT,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS;;GA6RpD,CAAC;AAGL,eAAO,MAAM,kCAAkC;;;;0CAEzB,OAAO;;;;;;;;;;;;;;;;;;;;;;GAkDzB,CAAC;AAKL,eAAO,MAAM,qBAAqB;;;;;;YAoBI,MAAM;;;GAIxC,CAAC;AAGL,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;GAWnC,CAAC;AASL,eAAO,MAAM,8BAA8B;;;;8CAEjB,OAAO;;;;GAU7B,CAAC;AASL,eAAO,MAAM,mBAAmB;;;;;;;;0BAgBuB,MAAM;0BAAoB,MAAM;yBAAmB,MAAM;;;GA8C5G,CAAC;AAGL,eAAO,MAAM,kBAAkB;;;;;;GAU3B,CAAC;AA2CL,eAAO,MAAM,iBAAiB;;;;8CAEJ,OAAO;;;;;;;;;;;;;;;;;;;;;;;aA0OY,MAAM;GAE/C,CAAC;AAKL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;;GAY7B,CAAC;AAQL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;GAoG7B,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;8CAER,OAAO;;;;GAyB7B,CAAC;AAyCL,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;aA0JG,MAAM;iBACQ,MAAM,GAAG,IAAI;kBACX,MAAM;;YAEnB,MAAM,GAAG,IAAI;;;;YAkB7B,MAAM;mBACS,MAAM,GAAG,IAAI;qBACT,MAAM;;cAErB,MAAM,GAAG,IAAI;;;;;;GAQpC,CAAC;AAIL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;;;;;;;;;;;;;;;GAoN7B,CAAC;AAKL,eAAO,MAAM,kBAAkB;;;;8CAEL,OAAO;;;;;;;;WAUM,MAAM;YAAU,MAAM,GAAG,IAAI;WAahE,CAAC"}
1
+ {"version":3,"file":"create-order.functions.d.ts","sourceRoot":"","sources":["../../src/lib/create-order.functions.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,2BAA2B;;;;;;GA+CpC,CAAC;AAIL,eAAO,MAAM,2BAA2B;;;;0CAElB,OAAO;;;;GAoDzB,CAAC;AAWL,eAAO,MAAM,0BAA0B;;;;;;YA+D7B,MAAM;iBACD,MAAM;sBACD,MAAM,GAAG,IAAI;cACrB,MAAM;oBACA,MAAM,GAAG,IAAI;0BACP,MAAM;0BACN,MAAM;yBACP,MAAM;wBACP,MAAM;wBACN,MAAM;yBACL,MAAM;kBACb,OAAO;gBACT,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS;;GA6RpD,CAAC;AAGL,eAAO,MAAM,kCAAkC;;;;0CAEzB,OAAO;;;;;;;;;;;;;;;;;;;;;;GAkDzB,CAAC;AAKL,eAAO,MAAM,qBAAqB;;;;;;YAoBI,MAAM;;;GAIxC,CAAC;AAGL,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;GAWnC,CAAC;AASL,eAAO,MAAM,8BAA8B;;;;8CAEjB,OAAO;;;;GAU7B,CAAC;AASL,eAAO,MAAM,mBAAmB;;;;;;;;0BAgBuB,MAAM;0BAAoB,MAAM;yBAAmB,MAAM;;;GA8C5G,CAAC;AAGL,eAAO,MAAM,kBAAkB;;;;;;GAU3B,CAAC;AA0CL,eAAO,MAAM,iBAAiB;;;;8CAEJ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;aA0OY,MAAM;GAE/C,CAAC;AAKL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;;GAY7B,CAAC;AAQL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;GAoG7B,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;8CAER,OAAO;;;;GAyB7B,CAAC;AA0CL,eAAO,MAAM,oBAAoB;;;;8CAEP,OAAO;;;aA0JG,MAAM;iBACQ,MAAM,GAAG,IAAI;kBACX,MAAM;;YAEnB,MAAM,GAAG,IAAI;;;;YAkB7B,MAAM;mBACS,MAAM,GAAG,IAAI;qBACT,MAAM;;cAErB,MAAM,GAAG,IAAI;;;;;;GAQpC,CAAC;AAIL,eAAO,MAAM,gBAAgB;;;;8CAEH,OAAO;;;;;;;;;;;;;;;;;;;;;GAmO7B,CAAC;AAKL,eAAO,MAAM,kBAAkB;;;;8CAEL,OAAO;;;;;;;;WAUM,MAAM;YAAU,MAAM,GAAG,IAAI;WAahE,CAAC"}
@@ -658,15 +658,14 @@ const CreateManualOrderInput = z.object({
658
658
  loadCarrierType: z.string().max(50).nullable().optional(),
659
659
  notes: z.string().max(2000).nullable().optional(),
660
660
  lines: z.array(LineInput).min(1),
661
+ // Gekozen ophaalmoment (momentKey uit de Engine-voorbeeldversie).
662
+ momentKey: z.string().max(64).nullable().optional(),
663
+ // Bewust aanmaken na de aanmeldtijd (spoedorder). Zonder dit wordt een
664
+ // niet-haalbare leverdatum geweigerd.
665
+ acceptLateSignup: z.boolean().optional(),
666
+ acceptedByName: z.string().max(255).nullable().optional(),
667
+ source: z.enum(["manual", "mailbox"]).optional(),
661
668
  });
662
- function addCalendarDays(base, n) {
663
- const x = new Date(base);
664
- x.setDate(x.getDate() + n);
665
- return x;
666
- }
667
- function toISODate(d) {
668
- return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
669
- }
670
669
  export const createManualOrder = createServerFn({ method: "POST" })
671
670
  .middleware([requireSupabaseAuth])
672
671
  .inputValidator((input) => CreateManualOrderInput.parse(input))
@@ -677,45 +676,52 @@ export const createManualOrder = createServerFn({ method: "POST" })
677
676
  const { assertOrderAllowed } = await import("./logistics-stock.server.js");
678
677
  await assertOrderAllowed(context.supabase, data.lines.map((l) => ({ productId: l.product_id, quantity: Number(l.quantity) })));
679
678
  }
680
- // Validatie eerst mogelijke leverdatum — o.b.v. de aanmeldmomenten van de
681
- // vervoerder (pickup_moments), niet enkel kalenderdagen. Een reservering
682
- // heeft nog geen vervoerder en dus geen leverdatumvalidatie.
683
- if (!data.isReservation && !data.carrierId) {
684
- throw new Error("Selecteer een vervoerder");
685
- }
686
679
  // Ladingdrager: zonder keuze de standaard van de Engine; geen eigen controle.
687
680
  const { resolveLoadCarrierType } = await import("./load-carriers.server.js");
688
681
  const loadCarrierType = await resolveLoadCarrierType(context.supabase, data.loadCarrierType);
689
- const c = data.carrierId
690
- ? (await context.supabase
691
- .from("carriers")
692
- .select("delivery_days, signup_time_1, signup_time_2, signup_days_before_delivery, pickup_weekdays, delivery_weekdays, pickup_moments")
693
- .eq("id", data.carrierId)
694
- .maybeSingle()).data
695
- : null;
696
- const carrierDeliveryDays = Math.max(0, Number(c?.delivery_days ?? 0));
697
- const { data: settings } = await context.supabase
698
- .from("afhandeling_settings")
699
- .select("pick_days_before_transport")
700
- .order("updated_at", { ascending: false })
701
- .limit(1).maybeSingle();
702
- const pickDays = Math.max(0, Number(settings?.pick_days_before_transport ?? 0));
703
- const { computeEarliestDelivery, nowInAmsterdam, resolveDeliveryTimeForDate } = await import("./carrier-availability.js");
704
- const nowLocal = nowInAmsterdam();
705
- const earliest = computeEarliestDelivery(c, pickDays, nowLocal);
706
- // Aanlevertijd van het aanmeldmoment dat bij deze leverdatum hoort (bv. 20:00).
707
- const deliveryTime = data.isReservation
708
- ? null
709
- : (data.deliveryDate === earliest.deliveryISO
710
- ? earliest.deliveryTime
711
- : resolveDeliveryTimeForDate(c, data.deliveryDate ?? "", nowLocal));
712
- const earliestISO = earliest.deliveryISO;
682
+ // Ophaalmoment en haalbaarheid komen alleen van de Logistiek Engine
683
+ // (logistics_departure_preview). Geen eigen berekening of terugval.
684
+ let carrierId = data.isReservation ? null : (data.carrierId ?? null);
685
+ let momentKey = null;
686
+ let deliveryTime = null;
687
+ let lateSignup = null;
713
688
  if (!data.isReservation) {
714
689
  if (!data.deliveryDate)
715
690
  throw new Error("Leverdatum ontbreekt.");
716
- if (data.deliveryDate < earliestISO) {
717
- throw new Error(`Leverdatum (${data.deliveryDate}) ligt voor de eerst mogelijke datum (${earliestISO}). Het eerstvolgende aanmeldmoment van de vervoerder is ${earliest.signupDeadlineISO ?? "onbekend"} (orderpicktijd ${pickDays}d, levertijd ${carrierDeliveryDays}d).`);
691
+ const { loadDeparturePreview, deliveryTimeForMoment } = await import("./departure-preview.server.js");
692
+ const { decidePreview } = await import("./departure-preview.js");
693
+ const preview = await loadDeparturePreview(context.supabase, {
694
+ carrierId,
695
+ deliveryLocation: data.deliveryLocationId,
696
+ deliveryDate: data.deliveryDate.slice(0, 10),
697
+ momentKey: data.momentKey ?? null,
698
+ });
699
+ const d = decidePreview(preview);
700
+ if (d.kind === "blocked")
701
+ throw new Error(d.reason);
702
+ if (d.kind === "late") {
703
+ if (!data.acceptLateSignup) {
704
+ throw new Error(d.firstDate
705
+ ? `${d.reason} De eerste haalbare leverdatum is ${d.firstDate}.`
706
+ : d.reason);
707
+ }
708
+ const by = context.claims?.email ?? null;
709
+ lateSignup = {
710
+ by_user_id: context.userId ?? null,
711
+ by_email: by,
712
+ by_name: data.acceptedByName ?? by,
713
+ at: new Date().toISOString(),
714
+ delivery_date: data.deliveryDate.slice(0, 10),
715
+ signup_deadline: preview?.chosen?.signupDeadline ?? null,
716
+ reason: d.reason,
717
+ source: data.source ?? "manual",
718
+ };
718
719
  }
720
+ carrierId = preview?.carrierId ?? carrierId;
721
+ if (!carrierId)
722
+ throw new Error("Er is geen vervoerder bekend voor deze afleverlocatie. Kies een vervoerder.");
723
+ momentKey = d.momentKey;
724
+ deliveryTime = await deliveryTimeForMoment(context.supabase, carrierId, momentKey);
719
725
  }
720
726
  const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
721
727
  // Zorg dat elk product_id (= identiteit uit de voorraadmodule) een rij
@@ -829,8 +835,10 @@ export const createManualOrder = createServerFn({ method: "POST" })
829
835
  source: "manual",
830
836
  delivery_location: data.deliveryLocationId,
831
837
  pickup_location: data.pickupLocationId,
832
- carrier: data.isReservation ? null : (data.carrierId ?? null),
838
+ carrier: carrierId,
833
839
  delivery_time: deliveryTime,
840
+ pickup_moment: momentKey,
841
+ ...(lateSignup ? { late_signup_override: lateSignup } : {}),
834
842
  is_reservation: !!data.isReservation,
835
843
  load_carrier_type: loadCarrierType,
836
844
  },
@@ -1036,6 +1044,7 @@ export const deleteMailboxProposal = createServerFn({ method: "POST" })
1036
1044
  const UpdateLocalOrderInput = z.object({
1037
1045
  orderId: z.string().uuid(),
1038
1046
  deliveryDate: z.string().min(1).max(50).optional(),
1047
+ acceptLateSignup: z.boolean().optional(),
1039
1048
  items: z
1040
1049
  .array(z.object({
1041
1050
  itemId: z.string().uuid(),
@@ -1255,7 +1264,7 @@ export const updateLocalOrder = createServerFn({ method: "POST" })
1255
1264
  const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
1256
1265
  const { data: order, error: oErr } = await supabaseAdmin
1257
1266
  .from("orders")
1258
- .select("id, custom_fields, order_source, is_reservation, plan_locked_at")
1267
+ .select("id, custom_fields, order_source, is_reservation, plan_locked_at, delivery_date")
1259
1268
  .eq("id", data.orderId)
1260
1269
  .maybeSingle();
1261
1270
  if (oErr)
@@ -1378,23 +1387,41 @@ export const updateLocalOrder = createServerFn({ method: "POST" })
1378
1387
  }
1379
1388
  // Leverdatum bijwerken (alleen als niet-reservering).
1380
1389
  if (data.deliveryDate && !order.is_reservation) {
1381
- // Aanlevertijd meeverversen op basis van de aanmeldmomenten van de vervoerder.
1390
+ // Haalbaarheid en moment alleen via de Engine; geen eigen berekening.
1382
1391
  let newDeliveryTime = cf?.delivery_time ?? null;
1383
- if (cf?.carrier) {
1384
- const { data: carrierRow } = await supabaseAdmin
1385
- .from("carriers")
1386
- .select("delivery_days, signup_time_1, signup_time_2, signup_days_before_delivery, pickup_weekdays, delivery_weekdays, pickup_moments")
1387
- .eq("id", cf.carrier)
1388
- .maybeSingle();
1389
- const { resolveDeliveryTimeForDate, nowInAmsterdam } = await import("./carrier-availability.js");
1390
- newDeliveryTime =
1391
- resolveDeliveryTimeForDate(carrierRow, data.deliveryDate, nowInAmsterdam()) ??
1392
- newDeliveryTime;
1392
+ let newMoment = cf?.pickup_moment ?? null;
1393
+ let lateOverride = cf?.late_signup_override ?? null;
1394
+ const newDate = String(data.deliveryDate).slice(0, 10);
1395
+ if (newDate !== String(order.delivery_date ?? "").slice(0, 10) && cf?.delivery_location) {
1396
+ const { loadDeparturePreview, deliveryTimeForMoment } = await import("./departure-preview.server.js");
1397
+ const { decidePreview } = await import("./departure-preview.js");
1398
+ const preview = await loadDeparturePreview(context.supabase, {
1399
+ carrierId: cf?.carrier ?? null,
1400
+ deliveryLocation: String(cf.delivery_location),
1401
+ deliveryDate: newDate,
1402
+ momentKey: null,
1403
+ });
1404
+ const d = decidePreview(preview);
1405
+ if (d.kind === "blocked")
1406
+ throw new Error(d.reason);
1407
+ if (d.kind === "late") {
1408
+ if (!data.acceptLateSignup) {
1409
+ throw new Error(d.firstDate ? `${d.reason} De eerste haalbare leverdatum is ${d.firstDate}.` : d.reason);
1410
+ }
1411
+ const by = context.claims?.email ?? null;
1412
+ lateOverride = {
1413
+ by_user_id: context.userId ?? null, by_email: by, by_name: by,
1414
+ at: new Date().toISOString(), delivery_date: newDate,
1415
+ signup_deadline: preview?.chosen?.signupDeadline ?? null, reason: d.reason, source: "manual",
1416
+ };
1417
+ }
1418
+ newMoment = d.momentKey;
1419
+ newDeliveryTime = await deliveryTimeForMoment(context.supabase, cf?.carrier ?? null, newMoment);
1393
1420
  }
1394
1421
  const { error: uErr } = await supabaseAdmin.from("orders")
1395
1422
  .update({
1396
1423
  delivery_date: data.deliveryDate,
1397
- custom_fields: { ...(cf ?? {}), delivery_time: newDeliveryTime },
1424
+ custom_fields: { ...(cf ?? {}), delivery_time: newDeliveryTime, pickup_moment: newMoment, ...(lateOverride ? { late_signup_override: lateOverride } : {}) },
1398
1425
  updated_at: new Date().toISOString(),
1399
1426
  })
1400
1427
  .eq("id", data.orderId);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=departure-preview.check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"departure-preview.check.d.ts","sourceRoot":"","sources":["../../src/lib/departure-preview.check.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ // Controle voorbeeld-ophaalmoment. Draai: bun src/lib/departure-preview.check.ts
2
+ import { decidePreview, normalizePreview } from "./departure-preview.js";
3
+ import { LIST_CHUNK } from "./order-departure.server.js";
4
+ let failed = 0;
5
+ function check(name, got, want) {
6
+ const ok = got === want;
7
+ if (!ok)
8
+ failed++;
9
+ console.log(`${ok ? "OK " : "FOUT"} ${name}: ${got}${ok ? "" : ` (verwacht ${want})`}`);
10
+ }
11
+ const good = decidePreview(normalizePreview({
12
+ ok: true, carrierId: "c", deliveryDateFeasible: true,
13
+ moments: [{ momentKey: "1@15:00|1@13:00", departureAt: "2026-10-20T13:00:00Z", signupDeadline: "2026-10-20T11:00:00Z", feasible: true },
14
+ { momentKey: "1@09:00|1@07:00", departureAt: "2026-10-20T07:00:00Z", signupDeadline: "2026-10-20T05:00:00Z", feasible: false }],
15
+ chosen: { momentKey: "1@15:00|1@13:00", departureAt: "2026-10-20T13:00:00Z", signupDeadline: "2026-10-20T11:00:00Z" },
16
+ }));
17
+ check("haalbaar: soort", good.kind, "ok");
18
+ check("haalbaar: tekst", good.kind === "ok" ? good.text : null, "ophalen di 20 okt 15:00 · aanmelden di 20 okt 13:00");
19
+ check("niet-haalbaar moment blijft zichtbaar", normalizePreview({ ok: true, moments: [{ momentKey: "x", feasible: false }] })?.moments[0].feasible, false);
20
+ const late = decidePreview(normalizePreview({
21
+ ok: true, deliveryDateFeasible: false, reason: "Aanmelden kan tot di 20-10 13:00.",
22
+ firstFeasibleDeliveryDate: "2026-10-22", firstFeasibleReason: "Eerstvolgende aanmelding do 13:00",
23
+ chosen: { momentKey: "k", departureAt: "2026-10-20T13:00:00Z" },
24
+ }));
25
+ check("te laat: soort (toch aanmaken mogelijk)", late.kind, "late");
26
+ check("te laat: reden", late.kind === "late" ? late.reason : null, "Aanmelden kan tot di 20-10 13:00.");
27
+ check("te laat: eerste datum", late.kind === "late" ? late.firstDate : null, "2026-10-22");
28
+ const bad = decidePreview(normalizePreview({ ok: false, reason: "Geen vervoerder bekend", chosen: { departureAt: "2026-10-20T13:00:00Z" } }));
29
+ check("ok=false: geblokkeerd", bad.kind, "blocked");
30
+ check("ok=false: alleen reden", bad.kind === "blocked" ? bad.reason : null, "Geen vervoerder bekend");
31
+ check("geen antwoord: geblokkeerd", decidePreview(null).kind, "blocked");
32
+ check("lijst in delen van 1000", LIST_CHUNK, 1000);
33
+ if (failed) {
34
+ console.error(`${failed} controle(s) mislukt`);
35
+ process.exit(1);
36
+ }
37
+ console.log("Alle controles geslaagd");
@@ -0,0 +1,47 @@
1
+ export interface PreviewMoment {
2
+ momentKey: string;
3
+ departureAt: string | null;
4
+ signupDeadline: string | null;
5
+ feasible: boolean;
6
+ }
7
+ export interface DeparturePreview {
8
+ ok: boolean;
9
+ reason: string | null;
10
+ carrierId: string | null;
11
+ moments: PreviewMoment[];
12
+ chosen: {
13
+ momentKey: string | null;
14
+ departureAt: string | null;
15
+ signupDeadline: string | null;
16
+ } | null;
17
+ deliveryDateFeasible: boolean;
18
+ deliveryDateReason: string | null;
19
+ firstFeasibleDeliveryDate: string | null;
20
+ firstFeasibleReason: string | null;
21
+ }
22
+ export declare function normalizePreview(raw: unknown): DeparturePreview | null;
23
+ export declare const PREVIEW_UNKNOWN = "Het ophaalmoment is nu niet bekend. Probeer het over een minuut opnieuw.";
24
+ export type PreviewDecision = {
25
+ kind: "ok";
26
+ momentKey: string | null;
27
+ text: string | null;
28
+ } | {
29
+ kind: "late";
30
+ reason: string;
31
+ firstDate: string | null;
32
+ firstReason: string | null;
33
+ momentKey: string | null;
34
+ text: string | null;
35
+ } | {
36
+ kind: "blocked";
37
+ reason: string;
38
+ };
39
+ /**
40
+ * Wat je ziet / of je mag aanmaken.
41
+ * - ok = false of geen antwoord: geblokkeerd, alleen de reden.
42
+ * - leverdatum niet haalbaar: "te laat" — alleen aanmaken na bewuste keuze.
43
+ */
44
+ export declare function decidePreview(p: DeparturePreview | null): PreviewDecision;
45
+ export declare function momentLabel(m: PreviewMoment): string;
46
+ export declare const LATE_CONFIRM = "Deze order komt na de aanmeldtijd. De vervoerder krijgt hem als te laat aangemeld. Doorgaan?";
47
+ //# sourceMappingURL=departure-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"departure-preview.d.ts","sourceRoot":"","sources":["../../src/lib/departure-preview.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACvG,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CA2BtE;AAED,eAAO,MAAM,eAAe,6EAA6E,CAAC;AAE1G,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACrI;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AASxC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,eAAe,CAgBzE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAEpD;AAED,eAAO,MAAM,YAAY,iGACuE,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const getDeparturePreview: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
2
+ supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
3
+ userId: string;
4
+ claims: import("@supabase/auth-js").User;
5
+ }, undefined, undefined, undefined>], (input: unknown) => {
6
+ carrierId: string | null;
7
+ deliveryLocation: string;
8
+ deliveryDate: string;
9
+ momentKey?: string | null | undefined;
10
+ }, Promise<{
11
+ preview: import("./departure-preview.js").DeparturePreview | null;
12
+ }>>;
13
+ //# sourceMappingURL=departure-preview.functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"departure-preview.functions.d.ts","sourceRoot":"","sources":["../../src/lib/departure-preview.functions.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB;;;;8CAEN,OAAO;;;;;;;GAa7B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { createServerFn } from "@tanstack/react-start";
2
+ import { z } from "zod";
3
+ import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
4
+ export const getDeparturePreview = createServerFn({ method: "GET" })
5
+ .middleware([requireSupabaseAuth])
6
+ .inputValidator((input) => z
7
+ .object({
8
+ carrierId: z.string().uuid().nullable(),
9
+ deliveryLocation: z.string().min(1).max(100),
10
+ deliveryDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
11
+ momentKey: z.string().max(64).nullable().optional(),
12
+ })
13
+ .parse(input))
14
+ .handler(async ({ data, context }) => {
15
+ const { loadDeparturePreview } = await import("./departure-preview.server.js");
16
+ return { preview: await loadDeparturePreview(context.supabase, data) };
17
+ });