@flowselections/floriday-voorraad 1.0.28 → 1.0.29
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/dist-lib/components/voorraad/ArtikelWizard.d.ts +2 -1
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +555 -316
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts +2 -1
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +3 -3
- package/dist-lib/components/voorraad/FustenPage.d.ts +2 -0
- package/dist-lib/components/voorraad/FustenPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/FustenPage.js +97 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.d.ts +2 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/LogistiekTakenCard.js +54 -0
- package/dist-lib/components/voorraad/PublicatiesPage.d.ts +2 -0
- package/dist-lib/components/voorraad/PublicatiesPage.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublicatiesPage.js +60 -0
- package/dist-lib/components/voorraad/PublishProgressCard.d.ts +12 -0
- package/dist-lib/components/voorraad/PublishProgressCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublishProgressCard.js +30 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.d.ts +10 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/PublishReadinessCard.js +12 -0
- package/dist-lib/components/voorraad/StockSyncStatus.d.ts +2 -0
- package/dist-lib/components/voorraad/StockSyncStatus.d.ts.map +1 -0
- package/dist-lib/components/voorraad/StockSyncStatus.js +23 -0
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +5 -1
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +1 -1
- package/dist-lib/hooks/useFusten.d.ts +17 -0
- package/dist-lib/hooks/useFusten.d.ts.map +1 -0
- package/dist-lib/hooks/useFusten.js +81 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts +14 -4
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
- package/dist-lib/hooks/useLocalTradeItems.js +83 -5
- package/dist-lib/hooks/useLogisticsTasks.d.ts +13 -0
- package/dist-lib/hooks/useLogisticsTasks.d.ts.map +1 -0
- package/dist-lib/hooks/useLogisticsTasks.js +155 -0
- package/dist-lib/hooks/usePublishJob.d.ts +13 -0
- package/dist-lib/hooks/usePublishJob.d.ts.map +1 -0
- package/dist-lib/hooks/usePublishJob.js +67 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.d.ts +2 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.d.ts.map +1 -0
- package/dist-lib/hooks/useRegisterModuleBaseUrl.js +31 -0
- package/dist-lib/hooks/useStockSyncHealth.d.ts +8 -0
- package/dist-lib/hooks/useStockSyncHealth.d.ts.map +1 -0
- package/dist-lib/hooks/useStockSyncHealth.js +42 -0
- package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -1
- package/dist-lib/hooks/useTradeItemStock.js +37 -1
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +5 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +1849 -50
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +1849 -50
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +1849 -50
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +1870 -41
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/floricode-required-features.functions.d.ts +1849 -50
- package/dist-lib/lib/floricode-required-features.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.d.ts +1 -1
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +1 -2
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts +1849 -50
- package/dist-lib/lib/floriday-customer-offer.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-customer-offer.functions.js +14 -19
- package/dist-lib/lib/floriday-env.functions.d.ts +35712 -0
- package/dist-lib/lib/floriday-env.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-env.functions.js +16 -0
- package/dist-lib/lib/floriday-env.server.d.ts +12 -0
- package/dist-lib/lib/floriday-env.server.d.ts.map +1 -1
- package/dist-lib/lib/floriday-env.server.js +15 -2
- package/dist-lib/lib/floriday-gateway.functions.d.ts +26934 -82
- package/dist-lib/lib/floriday-gateway.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-gateway.functions.js +12 -3
- package/dist-lib/lib/floriday-readiness.server.d.ts +11 -0
- package/dist-lib/lib/floriday-readiness.server.d.ts.map +1 -0
- package/dist-lib/lib/floriday-readiness.server.js +43 -0
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts +3698 -100
- package/dist-lib/lib/floriday-vbn-required.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-warehouse.functions.d.ts +5442 -45
- package/dist-lib/lib/floriday-warehouse.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-warehouse.functions.js +3 -0
- package/dist-lib/lib/floriday-writes.functions.d.ts +3698 -100
- package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
- package/dist-lib/lib/fusten.d.ts +87 -0
- package/dist-lib/lib/fusten.d.ts.map +1 -0
- package/dist-lib/lib/fusten.js +389 -0
- package/dist-lib/lib/logistics-engine.d.ts +63 -0
- package/dist-lib/lib/logistics-engine.d.ts.map +1 -0
- package/dist-lib/lib/logistics-engine.js +57 -0
- package/dist-lib/lib/logistics-events.d.ts +18 -0
- package/dist-lib/lib/logistics-events.d.ts.map +1 -0
- package/dist-lib/lib/logistics-events.js +61 -0
- package/dist-lib/lib/module-runtime-config.functions.d.ts +14 -0
- package/dist-lib/lib/module-runtime-config.functions.d.ts.map +1 -0
- package/dist-lib/lib/module-runtime-config.functions.js +107 -0
- package/dist-lib/lib/publish-errors.d.ts +37 -0
- package/dist-lib/lib/publish-errors.d.ts.map +1 -0
- package/dist-lib/lib/publish-errors.js +183 -0
- package/dist-lib/lib/publish-pipeline.d.ts +91 -0
- package/dist-lib/lib/publish-pipeline.d.ts.map +1 -0
- package/dist-lib/lib/publish-pipeline.js +212 -0
- package/dist-lib/lib/publish-readiness.d.ts +42 -0
- package/dist-lib/lib/publish-readiness.d.ts.map +1 -0
- package/dist-lib/lib/publish-readiness.js +102 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLocalTradeItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useLocalTradeItems.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAwB,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGvG;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAwED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;;;;EA0B9D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA4BrF;AAED,MAAM,WAAW,SAAS;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC;CACpC;AAED
|
|
1
|
+
{"version":3,"file":"useLocalTradeItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useLocalTradeItems.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAwB,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGvG;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAwED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;;;;EA0B9D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA4BrF;AAED,MAAM,WAAW,SAAS;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC;CACpC;AAED,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,KAAK,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAWjF;AAqBD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqGlB;AAED,wEAAwE;AACxE,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAGD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhF;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
|
|
@@ -110,10 +110,38 @@ export async function getLocalTradeItem(id) {
|
|
|
110
110
|
source: "product",
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
+
export function readLocalSyncStatus(customFields) {
|
|
114
|
+
const cf = asRecord(customFields);
|
|
115
|
+
const raw = cf.floriday_sync;
|
|
116
|
+
if (!raw || typeof raw !== "object")
|
|
117
|
+
return null;
|
|
118
|
+
const s = raw;
|
|
119
|
+
return {
|
|
120
|
+
dirty: Boolean(s.dirty),
|
|
121
|
+
last_attempt_at: s.last_attempt_at ?? null,
|
|
122
|
+
last_error: s.last_error ?? null,
|
|
123
|
+
last_synced_at: s.last_synced_at ?? null,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
113
126
|
/**
|
|
114
127
|
* Slaat Floriday-velden op in `products.custom_fields.floriday_payload`. Als `id` ontbreekt maken we een
|
|
115
128
|
* nieuw product aan (met minimale ERP-velden uit de payload). Nooit een concept-rij.
|
|
129
|
+
*
|
|
130
|
+
* `sync` legt vast of de gegevens al door Floriday zijn bevestigd. Zolang `dirty` waar is,
|
|
131
|
+
* is de lokale payload leidend bij het opnieuw openen van het artikel.
|
|
116
132
|
*/
|
|
133
|
+
/** Nieuw fusttype in een belading meteen in de fustenvoorraad registreren. */
|
|
134
|
+
function scheduleFustSync(connectionId) {
|
|
135
|
+
void (async () => {
|
|
136
|
+
try {
|
|
137
|
+
const { syncFustTypes } = await import("../lib/fusten");
|
|
138
|
+
await syncFustTypes(connectionId);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Fustenvoorraad is secundair; nooit het opslaan blokkeren.
|
|
142
|
+
}
|
|
143
|
+
})();
|
|
144
|
+
}
|
|
117
145
|
export async function upsertLocalTradeItem(params) {
|
|
118
146
|
const userRes = await supabase.auth.getUser();
|
|
119
147
|
const userId = userRes.data.user?.id;
|
|
@@ -123,13 +151,35 @@ export async function upsertLocalTradeItem(params) {
|
|
|
123
151
|
const linkedProductId = typeof payload.linkedProductId === "string" && payload.linkedProductId
|
|
124
152
|
? String(payload.linkedProductId)
|
|
125
153
|
: null;
|
|
126
|
-
|
|
154
|
+
let targetId = params.id && params.id.length > 0 ? params.id : linkedProductId;
|
|
155
|
+
// Bestaat er al een lokale rij voor dit Floriday-artikel? Dan daarop schrijven
|
|
156
|
+
// in plaats van een duplicaat aanmaken.
|
|
157
|
+
const floridayTradeItemId = params.floridayTradeItemId ?? params.meta?.floridayId ?? null;
|
|
158
|
+
if (!targetId && floridayTradeItemId) {
|
|
159
|
+
const { data: byFloriday } = await supabase
|
|
160
|
+
.from("products")
|
|
161
|
+
.select("id")
|
|
162
|
+
.eq("floriday_trade_item_id", floridayTradeItemId)
|
|
163
|
+
.maybeSingle();
|
|
164
|
+
targetId = byFloriday?.id ?? null;
|
|
165
|
+
}
|
|
166
|
+
const syncPatch = params.sync
|
|
167
|
+
? {
|
|
168
|
+
dirty: params.sync.dirty,
|
|
169
|
+
last_attempt_at: params.sync.last_attempt_at ?? new Date().toISOString(),
|
|
170
|
+
last_error: params.sync.last_error ?? null,
|
|
171
|
+
last_synced_at: params.sync.last_synced_at ?? null,
|
|
172
|
+
}
|
|
173
|
+
: null;
|
|
127
174
|
const productPatch = {
|
|
128
175
|
updated_at: new Date().toISOString(),
|
|
129
176
|
};
|
|
130
177
|
if (params.meta?.floridayId !== undefined) {
|
|
131
178
|
productPatch.floriday_trade_item_id = params.meta.floridayId;
|
|
132
179
|
}
|
|
180
|
+
else if (floridayTradeItemId) {
|
|
181
|
+
productPatch.floriday_trade_item_id = floridayTradeItemId;
|
|
182
|
+
}
|
|
133
183
|
if (payload.name)
|
|
134
184
|
productPatch.product = payload.name;
|
|
135
185
|
if (payload.articleCode)
|
|
@@ -152,8 +202,9 @@ export async function upsertLocalTradeItem(params) {
|
|
|
152
202
|
articleCode: payload.articleCode || currentCustomFields.articleCode,
|
|
153
203
|
floriday_id: params.meta?.floridayId !== undefined
|
|
154
204
|
? params.meta.floridayId
|
|
155
|
-
: currentCustomFields.floriday_id,
|
|
205
|
+
: (currentCustomFields.floriday_id ?? floridayTradeItemId ?? null),
|
|
156
206
|
floriday_payload: payload,
|
|
207
|
+
...(syncPatch ? { floriday_sync: syncPatch } : {}),
|
|
157
208
|
};
|
|
158
209
|
const { error } = await supabase
|
|
159
210
|
.from("products")
|
|
@@ -161,6 +212,7 @@ export async function upsertLocalTradeItem(params) {
|
|
|
161
212
|
.eq("id", targetId);
|
|
162
213
|
if (error)
|
|
163
214
|
throw new Error(error.message);
|
|
215
|
+
scheduleFustSync(params.connectionId ?? null);
|
|
164
216
|
return targetId;
|
|
165
217
|
}
|
|
166
218
|
const generatedId = crypto.randomUUID();
|
|
@@ -175,19 +227,45 @@ export async function upsertLocalTradeItem(params) {
|
|
|
175
227
|
barcode: payload.gtin || null,
|
|
176
228
|
image_url: firstImageUrl || null,
|
|
177
229
|
product_type: "levend",
|
|
178
|
-
trade_item_key: `product:${generatedId}`,
|
|
179
|
-
floriday_trade_item_id: params.meta?.floridayId ?? null,
|
|
230
|
+
trade_item_key: floridayTradeItemId ?? `product:${generatedId}`,
|
|
231
|
+
floriday_trade_item_id: params.meta?.floridayId ?? floridayTradeItemId ?? null,
|
|
180
232
|
custom_fields: {
|
|
181
233
|
articleCode: payload.articleCode || null,
|
|
182
|
-
floriday_id: params.meta?.floridayId ?? null,
|
|
234
|
+
floriday_id: params.meta?.floridayId ?? floridayTradeItemId ?? null,
|
|
183
235
|
floriday_payload: payload,
|
|
236
|
+
...(syncPatch ? { floriday_sync: syncPatch } : {}),
|
|
184
237
|
},
|
|
185
238
|
};
|
|
186
239
|
const { error } = await supabase.from("products").insert(insertRow);
|
|
187
240
|
if (error)
|
|
188
241
|
throw new Error(error.message);
|
|
242
|
+
scheduleFustSync(params.connectionId ?? null);
|
|
189
243
|
return generatedId;
|
|
190
244
|
}
|
|
245
|
+
/** Zet alleen de sync-status bij, zonder de payload te herschrijven. */
|
|
246
|
+
export async function markLocalSyncStatus(productRowId, status) {
|
|
247
|
+
const { data } = await supabase
|
|
248
|
+
.from("products")
|
|
249
|
+
.select("custom_fields")
|
|
250
|
+
.eq("id", productRowId)
|
|
251
|
+
.maybeSingle();
|
|
252
|
+
const current = asRecord(data?.custom_fields);
|
|
253
|
+
const next = {
|
|
254
|
+
...current,
|
|
255
|
+
floriday_sync: {
|
|
256
|
+
dirty: status.dirty,
|
|
257
|
+
last_attempt_at: status.last_attempt_at ?? new Date().toISOString(),
|
|
258
|
+
last_error: status.last_error ?? null,
|
|
259
|
+
last_synced_at: status.last_synced_at ?? null,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
const { error } = await supabase
|
|
263
|
+
.from("products")
|
|
264
|
+
.update({ custom_fields: next })
|
|
265
|
+
.eq("id", productRowId);
|
|
266
|
+
if (error)
|
|
267
|
+
throw new Error(error.message);
|
|
268
|
+
}
|
|
191
269
|
/**
|
|
192
270
|
* Legacy API. Alleen meta-velden die vandaag nog op `products` bestaan (`floriday_trade_item_id`
|
|
193
271
|
* en `custom_fields.floriday_id`) worden gepersisteerd; overige velden worden stilzwijgend genegeerd
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type LogisticsTaskRow, type TaskExecutionResult } from "../lib/logistics-engine";
|
|
2
|
+
export declare function useLogisticsTasks(statuses?: string[]): {
|
|
3
|
+
tasks: LogisticsTaskRow[];
|
|
4
|
+
loading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
refetch: () => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Voert één `stock.reserve` taak uit. De Engine bepaalt WAT er gereserveerd
|
|
10
|
+
* wordt; deze module rekent niets zelf uit.
|
|
11
|
+
*/
|
|
12
|
+
export declare function runStockReserveTask(task: LogisticsTaskRow, connectionId: string | null): Promise<TaskExecutionResult>;
|
|
13
|
+
//# sourceMappingURL=useLogisticsTasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLogisticsTasks.d.ts","sourceRoot":"","sources":["../../src/hooks/useLogisticsTasks.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAKjC,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAM,EAAyB;;;;;EAuD1E;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAoG9B"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taken van de Logistics Engine voor deze module, rechtstreeks uit de
|
|
3
|
+
* gedeelde Supabase-database (public.logistics_tasks).
|
|
4
|
+
*
|
|
5
|
+
* De Engine plant; wij tonen, voeren `stock.reserve` uit en melden af.
|
|
6
|
+
* In schaduwmodus wordt alleen vergeleken en NIETS geschreven aan voorraad;
|
|
7
|
+
* de taak wordt dan ook niet afgemeld.
|
|
8
|
+
*/
|
|
9
|
+
import { useCallback, useEffect, useState } from "react";
|
|
10
|
+
import { supabase } from "../integrations/supabase/client";
|
|
11
|
+
import { OWNER_MODULE, describeLoadCarriers, parseStockReservePlan, } from "../lib/logistics-engine";
|
|
12
|
+
const TASK_COLUMNS = "id,order_ref,buffer_ref,task_type,sequence,depends_on,planned_start,planned_end,due_at,status,shadow,payload,result,rule_version";
|
|
13
|
+
export function useLogisticsTasks(statuses = ["planned", "ready"]) {
|
|
14
|
+
const key = statuses.join(",");
|
|
15
|
+
const [tasks, setTasks] = useState([]);
|
|
16
|
+
const [loading, setLoading] = useState(true);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const refetch = useCallback(async () => {
|
|
19
|
+
const { data, error } = await supabase
|
|
20
|
+
.from("logistics_tasks")
|
|
21
|
+
.select(TASK_COLUMNS)
|
|
22
|
+
.eq("owner_module", OWNER_MODULE)
|
|
23
|
+
.in("status", key.split(","))
|
|
24
|
+
.order("planned_start", { ascending: true });
|
|
25
|
+
if (error) {
|
|
26
|
+
setError(error.message);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setError(null);
|
|
30
|
+
setTasks((data ?? []));
|
|
31
|
+
}, [key]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
let cancelled = false;
|
|
34
|
+
setLoading(true);
|
|
35
|
+
(async () => {
|
|
36
|
+
await refetch();
|
|
37
|
+
if (!cancelled)
|
|
38
|
+
setLoading(false);
|
|
39
|
+
})();
|
|
40
|
+
return () => {
|
|
41
|
+
cancelled = true;
|
|
42
|
+
};
|
|
43
|
+
}, [refetch]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const channel = supabase
|
|
46
|
+
.channel(`logistics-tasks-${OWNER_MODULE}`)
|
|
47
|
+
.on("postgres_changes", {
|
|
48
|
+
event: "*",
|
|
49
|
+
schema: "public",
|
|
50
|
+
table: "logistics_tasks",
|
|
51
|
+
filter: `owner_module=eq.${OWNER_MODULE}`,
|
|
52
|
+
}, () => {
|
|
53
|
+
refetch();
|
|
54
|
+
})
|
|
55
|
+
.subscribe();
|
|
56
|
+
return () => {
|
|
57
|
+
supabase.removeChannel(channel);
|
|
58
|
+
};
|
|
59
|
+
}, [refetch]);
|
|
60
|
+
return { tasks, loading, error, refetch };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Voert één `stock.reserve` taak uit. De Engine bepaalt WAT er gereserveerd
|
|
64
|
+
* wordt; deze module rekent niets zelf uit.
|
|
65
|
+
*/
|
|
66
|
+
export async function runStockReserveTask(task, connectionId) {
|
|
67
|
+
const plan = parseStockReservePlan(task.payload);
|
|
68
|
+
const shadow = task.shadow;
|
|
69
|
+
if (plan.lines.length === 0) {
|
|
70
|
+
return {
|
|
71
|
+
taskId: task.id,
|
|
72
|
+
applied: false,
|
|
73
|
+
shadow,
|
|
74
|
+
diff: [],
|
|
75
|
+
message: `Taak zonder regels (${describeLoadCarriers(plan.loadCarriers)}).`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const keys = plan.lines.map((l) => l.tradeItemKey);
|
|
79
|
+
let query = supabase
|
|
80
|
+
.from("trade_item_stock")
|
|
81
|
+
.select("trade_item_key,physical_stock,reserved_stock,connection_id")
|
|
82
|
+
.in("trade_item_key", keys);
|
|
83
|
+
if (connectionId)
|
|
84
|
+
query = query.eq("connection_id", connectionId);
|
|
85
|
+
const { data: rows, error: readError } = await query;
|
|
86
|
+
if (readError)
|
|
87
|
+
throw new Error(`voorraad lezen: ${readError.message}`);
|
|
88
|
+
const stock = (rows ?? []);
|
|
89
|
+
const diff = plan.lines.map((line) => {
|
|
90
|
+
const row = stock.find((r) => r.trade_item_key === line.tradeItemKey);
|
|
91
|
+
const currentReserved = row?.reserved_stock ?? 0;
|
|
92
|
+
return {
|
|
93
|
+
tradeItemKey: line.tradeItemKey,
|
|
94
|
+
currentReserved,
|
|
95
|
+
engineReserved: line.quantity,
|
|
96
|
+
delta: line.quantity - currentReserved,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
if (shadow) {
|
|
100
|
+
return {
|
|
101
|
+
taskId: task.id,
|
|
102
|
+
applied: false,
|
|
103
|
+
shadow: true,
|
|
104
|
+
diff,
|
|
105
|
+
message: `Schaduwmodus: ${diff.length} regel(s) vergeleken, niets geschreven (${describeLoadCarriers(plan.loadCarriers)}).`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
await supabase
|
|
109
|
+
.from("logistics_tasks")
|
|
110
|
+
.update({ status: "in_progress", started_at: new Date().toISOString() })
|
|
111
|
+
.eq("id", task.id);
|
|
112
|
+
try {
|
|
113
|
+
for (const line of plan.lines) {
|
|
114
|
+
const row = stock.find((r) => r.trade_item_key === line.tradeItemKey);
|
|
115
|
+
if (!row)
|
|
116
|
+
throw new Error(`Geen voorraadrij voor ${line.tradeItemKey}`);
|
|
117
|
+
const { error } = await supabase
|
|
118
|
+
.from("trade_item_stock")
|
|
119
|
+
.update({ reserved_stock: line.quantity })
|
|
120
|
+
.eq("connection_id", row.connection_id)
|
|
121
|
+
.eq("trade_item_key", line.tradeItemKey);
|
|
122
|
+
if (error) {
|
|
123
|
+
throw new Error(`reservering ${line.tradeItemKey}: ${error.message}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
const message = e?.message ?? String(e);
|
|
129
|
+
await supabase
|
|
130
|
+
.from("logistics_tasks")
|
|
131
|
+
.update({
|
|
132
|
+
status: "failed",
|
|
133
|
+
result: { message, diff },
|
|
134
|
+
completed_at: new Date().toISOString(),
|
|
135
|
+
})
|
|
136
|
+
.eq("id", task.id);
|
|
137
|
+
throw new Error(message);
|
|
138
|
+
}
|
|
139
|
+
const result = {
|
|
140
|
+
taskId: task.id,
|
|
141
|
+
applied: true,
|
|
142
|
+
shadow: false,
|
|
143
|
+
diff,
|
|
144
|
+
message: `${plan.lines.length} regel(s) gereserveerd (${describeLoadCarriers(plan.loadCarriers)}).`,
|
|
145
|
+
};
|
|
146
|
+
await supabase
|
|
147
|
+
.from("logistics_tasks")
|
|
148
|
+
.update({
|
|
149
|
+
status: "done",
|
|
150
|
+
result: result,
|
|
151
|
+
completed_at: new Date().toISOString(),
|
|
152
|
+
})
|
|
153
|
+
.eq("id", task.id);
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PublishJobRow, type PublishStepRow } from "../lib/publish-pipeline";
|
|
2
|
+
export declare function usePublishJob(jobId: string | null): {
|
|
3
|
+
job: PublishJobRow | null;
|
|
4
|
+
steps: PublishStepRow[];
|
|
5
|
+
loading: boolean;
|
|
6
|
+
reload: () => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
export declare function usePublishJobs(limit?: number): {
|
|
9
|
+
jobs: PublishJobRow[];
|
|
10
|
+
loading: boolean;
|
|
11
|
+
reload: () => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=usePublishJob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePublishJob.d.ts","sourceRoot":"","sources":["../../src/hooks/usePublishJob.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;;;;;EAqDjD;AAED,wBAAgB,cAAc,CAAC,KAAK,SAAK;;;;EAoBxC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Volgt een lopende publicatie live: opdracht + deelstappen.
|
|
3
|
+
*/
|
|
4
|
+
import { useEffect, useState, useCallback } from "react";
|
|
5
|
+
import { supabase } from "../integrations/supabase/client";
|
|
6
|
+
import { loadPublishJob, } from "../lib/publish-pipeline";
|
|
7
|
+
export function usePublishJob(jobId) {
|
|
8
|
+
const [job, setJob] = useState(null);
|
|
9
|
+
const [steps, setSteps] = useState([]);
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const reload = useCallback(async () => {
|
|
12
|
+
if (!jobId) {
|
|
13
|
+
setJob(null);
|
|
14
|
+
setSteps([]);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
setLoading(true);
|
|
18
|
+
const res = await loadPublishJob(jobId);
|
|
19
|
+
setJob(res.job);
|
|
20
|
+
setSteps(res.steps);
|
|
21
|
+
setLoading(false);
|
|
22
|
+
}, [jobId]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
void reload();
|
|
25
|
+
}, [reload]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!jobId)
|
|
28
|
+
return;
|
|
29
|
+
const channel = supabase
|
|
30
|
+
.channel(`publish-job-${jobId}`)
|
|
31
|
+
.on("postgres_changes", {
|
|
32
|
+
event: "*",
|
|
33
|
+
schema: "public",
|
|
34
|
+
table: "voorraad_publish_steps",
|
|
35
|
+
filter: `job_id=eq.${jobId}`,
|
|
36
|
+
}, () => void reload())
|
|
37
|
+
.on("postgres_changes", {
|
|
38
|
+
event: "*",
|
|
39
|
+
schema: "public",
|
|
40
|
+
table: "voorraad_publish_jobs",
|
|
41
|
+
filter: `id=eq.${jobId}`,
|
|
42
|
+
}, () => void reload())
|
|
43
|
+
.subscribe();
|
|
44
|
+
return () => {
|
|
45
|
+
void supabase.removeChannel(channel);
|
|
46
|
+
};
|
|
47
|
+
}, [jobId, reload]);
|
|
48
|
+
return { job, steps, loading, reload };
|
|
49
|
+
}
|
|
50
|
+
export function usePublishJobs(limit = 50) {
|
|
51
|
+
const [jobs, setJobs] = useState([]);
|
|
52
|
+
const [loading, setLoading] = useState(true);
|
|
53
|
+
const reload = useCallback(async () => {
|
|
54
|
+
setLoading(true);
|
|
55
|
+
const { data } = await supabase
|
|
56
|
+
.from("voorraad_publish_jobs")
|
|
57
|
+
.select("*")
|
|
58
|
+
.order("created_at", { ascending: false })
|
|
59
|
+
.limit(limit);
|
|
60
|
+
setJobs((data ?? []));
|
|
61
|
+
setLoading(false);
|
|
62
|
+
}, [limit]);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
void reload();
|
|
65
|
+
}, [reload]);
|
|
66
|
+
return { jobs, loading, reload };
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRegisterModuleBaseUrl.d.ts","sourceRoot":"","sources":["../../src/hooks/useRegisterModuleBaseUrl.ts"],"names":[],"mappings":"AAUA,wBAAgB,wBAAwB,SA0BvC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registreert eenmalig per sessie de basis-URL van de shell waarin deze
|
|
3
|
+
* module draait, zodat de Postgres-cron de voorraadsync-hooks kan aanroepen
|
|
4
|
+
* zonder hardgecodeerde host.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useRef } from "react";
|
|
7
|
+
import { registerModuleBaseUrl } from "../lib/module-runtime-config.functions";
|
|
8
|
+
let alreadyRegistered = false;
|
|
9
|
+
export function useRegisterModuleBaseUrl() {
|
|
10
|
+
const started = useRef(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (alreadyRegistered || started.current)
|
|
13
|
+
return;
|
|
14
|
+
started.current = true;
|
|
15
|
+
alreadyRegistered = true;
|
|
16
|
+
registerModuleBaseUrl()
|
|
17
|
+
.then((res) => {
|
|
18
|
+
if (res?.ok) {
|
|
19
|
+
console.info(`[voorraad] basis-URL geregistreerd: ${res.baseUrl}${res.changed ? " (bijgewerkt)" : ""}`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
alreadyRegistered = false;
|
|
23
|
+
console.warn(`[voorraad] basis-URL niet geregistreerd: ${res?.reason ?? "onbekende reden"}`);
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
.catch((e) => {
|
|
27
|
+
alreadyRegistered = false;
|
|
28
|
+
console.warn("[voorraad] kon basis-URL niet registreren:", e?.message ?? e);
|
|
29
|
+
});
|
|
30
|
+
}, []);
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface StockSyncHealth {
|
|
2
|
+
failed: number;
|
|
3
|
+
pending: number;
|
|
4
|
+
stalePending: number;
|
|
5
|
+
oldestPendingAt: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function useStockSyncHealth(): import("@tanstack/react-query").UseQueryResult<NoInfer<StockSyncHealth>, Error>;
|
|
8
|
+
//# sourceMappingURL=useStockSyncHealth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStockSyncHealth.d.ts","sourceRoot":"","sources":["../../src/hooks/useStockSyncHealth.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,kBAAkB,oFAmCjC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gezondheid van de voorraad-push-wachtrij richting Floriday.
|
|
3
|
+
* Signaleert vastgelopen (`failed`) of te lang wachtende (`pending`) regels.
|
|
4
|
+
*/
|
|
5
|
+
import { useQuery } from "@tanstack/react-query";
|
|
6
|
+
import { supabase } from "../integrations/supabase/client";
|
|
7
|
+
const STALE_MINUTES = 10;
|
|
8
|
+
export function useStockSyncHealth() {
|
|
9
|
+
return useQuery({
|
|
10
|
+
queryKey: ["stock-sync-health"],
|
|
11
|
+
refetchInterval: 60000,
|
|
12
|
+
queryFn: async () => {
|
|
13
|
+
const { data, error } = await supabase
|
|
14
|
+
.from("floriday_continuous_stock_queue")
|
|
15
|
+
.select("status, created_at")
|
|
16
|
+
.in("status", ["pending", "failed"])
|
|
17
|
+
.limit(1000);
|
|
18
|
+
if (error)
|
|
19
|
+
throw error;
|
|
20
|
+
const rows = (data ?? []);
|
|
21
|
+
const cutoff = Date.now() - STALE_MINUTES * 60000;
|
|
22
|
+
let failed = 0;
|
|
23
|
+
let pending = 0;
|
|
24
|
+
let stalePending = 0;
|
|
25
|
+
let oldestPendingAt = null;
|
|
26
|
+
for (const r of rows) {
|
|
27
|
+
if (r.status === "failed") {
|
|
28
|
+
failed++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
pending++;
|
|
32
|
+
const ts = Date.parse(r.created_at);
|
|
33
|
+
if (Number.isFinite(ts) && ts < cutoff)
|
|
34
|
+
stalePending++;
|
|
35
|
+
if (!oldestPendingAt || r.created_at < oldestPendingAt) {
|
|
36
|
+
oldestPendingAt = r.created_at;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { failed, pending, stalePending, oldestPendingAt };
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTradeItemStock.d.ts","sourceRoot":"","sources":["../../src/hooks/useTradeItemStock.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,GAAG,IAAI,CAKhB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,EAAE,CAMX;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;;;mBA4ElB,iBAAiB;
|
|
1
|
+
{"version":3,"file":"useTradeItemStock.d.ts","sourceRoot":"","sources":["../../src/hooks/useTradeItemStock.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,GAAG,IAAI,CAKhB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,EAAE,CAMX;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;;;mBA4ElB,iBAAiB;EAmEnC;AAED,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAUzC"}
|
|
@@ -120,8 +120,44 @@ export function useTradeItemStock(connectionId, keyOrKeys) {
|
|
|
120
120
|
}, { onConflict: "connection_id,trade_item_key" });
|
|
121
121
|
if (error)
|
|
122
122
|
throw new Error(error.message);
|
|
123
|
+
const previousPhysical = row?.physical_stock ?? 0;
|
|
123
124
|
setRow(values);
|
|
124
|
-
|
|
125
|
+
// Verkoop = daling van de fysieke voorraad. Het bijbehorende aantal
|
|
126
|
+
// fusten wordt automatisch van de fustenvoorraad afgeschreven op basis
|
|
127
|
+
// van de primaire belading van dit artikel.
|
|
128
|
+
const sold = previousPhysical - values.physical_stock;
|
|
129
|
+
if (sold > 0) {
|
|
130
|
+
void (async () => {
|
|
131
|
+
try {
|
|
132
|
+
const { registerSaleFustUsage } = await import("../lib/fusten");
|
|
133
|
+
await registerSaleFustUsage({
|
|
134
|
+
connectionId,
|
|
135
|
+
tradeItemKey: primaryKey,
|
|
136
|
+
piecesSold: sold,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// Fustenvoorraad is secundair; nooit de voorraadmutatie blokkeren.
|
|
141
|
+
}
|
|
142
|
+
})();
|
|
143
|
+
}
|
|
144
|
+
// Relevante voorraadwijziging melden zodat de Logistics Engine kan
|
|
145
|
+
// herplannen: rij in logistics_events met dezelfde order_ref als de
|
|
146
|
+
// openstaande Engine-taak. Fire-and-forget, nooit blokkerend.
|
|
147
|
+
void (async () => {
|
|
148
|
+
try {
|
|
149
|
+
const { emitStockChangedEvent } = await import("../lib/logistics-events");
|
|
150
|
+
await emitStockChangedEvent({
|
|
151
|
+
tradeItemKey: primaryKey,
|
|
152
|
+
physicalStock: values.physical_stock,
|
|
153
|
+
reservedStock: values.reserved_stock,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// Engine-tabel niet bereikbaar; voorraad is lokaal wel opgeslagen.
|
|
158
|
+
}
|
|
159
|
+
})();
|
|
160
|
+
}, [connectionId, primaryKey, row]);
|
|
125
161
|
return { row: row ?? EMPTY, loading, save };
|
|
126
162
|
}
|
|
127
163
|
export async function fetchStockMap(connectionId) {
|
package/dist-lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAIxF,eAAO,MAAM,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAIxF,eAAO,MAAM,sBAAsB,EAAE,UAcpC,CAAC"}
|
package/dist-lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ============================================================================
|
|
2
2
|
// src/index.ts — MODULE CONTRACT (Voorraad)
|
|
3
3
|
// ============================================================================
|
|
4
|
-
import { Package } from "lucide-react";
|
|
4
|
+
import { Boxes, Package } from "lucide-react";
|
|
5
5
|
export * from './_core-safelist';
|
|
6
6
|
export { VoorraadPage } from './components/voorraad/VoorraadPage';
|
|
7
7
|
export { NieuwArtikelPage } from './components/voorraad/NieuwArtikelPage';
|
|
@@ -20,6 +20,10 @@ export const floridayVoorraadModule = {
|
|
|
20
20
|
label: "Voorraad",
|
|
21
21
|
href: "/voorraad",
|
|
22
22
|
icon: Package,
|
|
23
|
+
children: [
|
|
24
|
+
{ label: "Producten", href: "/voorraad", icon: Package },
|
|
25
|
+
{ label: "Fusten", href: "/voorraad/fusten", icon: Boxes },
|
|
26
|
+
],
|
|
23
27
|
},
|
|
24
28
|
settingsCards: [{ component: VoorraadVeldenCard, order: 50 }],
|
|
25
29
|
};
|