@flowselections/layout-maker 1.36.7 → 1.45.8
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/AfleverbriefBuilderPage.d.ts +10 -0
- package/dist-lib/components/AfleverbriefBuilderPage.d.ts.map +1 -0
- package/dist-lib/components/AfleverbriefBuilderPage.js +101 -0
- package/dist-lib/components/BlokOntwerperPage.d.ts.map +1 -1
- package/dist-lib/components/BlokOntwerperPage.js +8 -3
- package/dist-lib/components/ComputersLijst.d.ts.map +1 -1
- package/dist-lib/components/ComputersLijst.js +1 -1
- package/dist-lib/components/FustKolomVolgorde.d.ts +11 -0
- package/dist-lib/components/FustKolomVolgorde.d.ts.map +1 -0
- package/dist-lib/components/FustKolomVolgorde.js +52 -0
- package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
- package/dist-lib/components/LayoutsPage.js +10 -9
- package/dist-lib/components/PaginaDocument.d.ts +4 -1
- package/dist-lib/components/PaginaDocument.d.ts.map +1 -1
- package/dist-lib/components/PaginaDocument.js +10 -5
- package/dist-lib/components/PakbonBuilderPage.d.ts.map +1 -1
- package/dist-lib/components/PakbonBuilderPage.js +34 -14
- package/dist-lib/components/PakbonPreview.d.ts +4 -2
- package/dist-lib/components/PakbonPreview.d.ts.map +1 -1
- package/dist-lib/components/PakbonPreview.js +74 -24
- package/dist-lib/components/PakbonSectiesPanel.d.ts +5 -3
- package/dist-lib/components/PakbonSectiesPanel.d.ts.map +1 -1
- package/dist-lib/components/PakbonSectiesPanel.js +8 -5
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts +2 -1
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts.map +1 -1
- package/dist-lib/components/PdfMapToestemmingBanner.js +73 -14
- package/dist-lib/components/PdfVoorbeeld.d.ts +20 -0
- package/dist-lib/components/PdfVoorbeeld.d.ts.map +1 -0
- package/dist-lib/components/PdfVoorbeeld.js +95 -0
- package/dist-lib/components/PrintProgrammaUitleg.d.ts.map +1 -1
- package/dist-lib/components/PrintProgrammaUitleg.js +1 -1
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +81 -43
- package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekDetailPage.js +2 -2
- package/dist-lib/components/PrintplekWizard.d.ts.map +1 -1
- package/dist-lib/components/PrintplekWizard.js +6 -2
- package/dist-lib/components/ProductiebonBuilderPage.d.ts.map +1 -1
- package/dist-lib/components/ProductiebonBuilderPage.js +13 -7
- package/dist-lib/index.d.ts +16 -6
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +11 -5
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +3585 -1267
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +3585 -1267
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +25898 -0
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/moduleClient.js +29 -0
- package/dist-lib/integrations/supabase/types.d.ts +3607 -1265
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +1 -0
- package/dist-lib/lib/aiLayout.functions.d.ts +3585 -1267
- package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
- package/dist-lib/lib/code128.d.ts +5 -0
- package/dist-lib/lib/code128.d.ts.map +1 -0
- package/dist-lib/lib/code128.js +51 -0
- package/dist-lib/lib/documentVoorbeeld.functions.d.ts +23 -0
- package/dist-lib/lib/documentVoorbeeld.functions.d.ts.map +1 -0
- package/dist-lib/lib/documentVoorbeeld.functions.js +37 -0
- package/dist-lib/lib/fontMetrics.d.ts +15 -0
- package/dist-lib/lib/fontMetrics.d.ts.map +1 -0
- package/dist-lib/lib/fontMetrics.js +118 -0
- package/dist-lib/lib/htmlNaarPdf.server.d.ts +2 -2
- package/dist-lib/lib/htmlNaarPdf.server.d.ts.map +1 -1
- package/dist-lib/lib/htmlNaarPdf.server.js +2 -1
- package/dist-lib/lib/htmlPdf.server.d.ts +11 -0
- package/dist-lib/lib/htmlPdf.server.d.ts.map +1 -1
- package/dist-lib/lib/htmlPdf.server.js +170 -9
- package/dist-lib/lib/layoutPreview.d.ts.map +1 -1
- package/dist-lib/lib/layoutPreview.js +6 -3
- package/dist-lib/lib/orderData.server.d.ts.map +1 -1
- package/dist-lib/lib/orderData.server.js +49 -16
- package/dist-lib/lib/pakbonBarcodeVerzoek.d.ts +39 -0
- package/dist-lib/lib/pakbonBarcodeVerzoek.d.ts.map +1 -0
- package/dist-lib/lib/pakbonBarcodeVerzoek.js +80 -0
- package/dist-lib/lib/pakbonBuilder.d.ts +90 -5
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +455 -58
- package/dist-lib/lib/pakbonContent.d.ts +41 -0
- package/dist-lib/lib/pakbonContent.d.ts.map +1 -0
- package/dist-lib/lib/pakbonContent.js +668 -0
- package/dist-lib/lib/pakbonDocument.d.ts +199 -0
- package/dist-lib/lib/pakbonDocument.d.ts.map +1 -0
- package/dist-lib/lib/pakbonDocument.js +735 -0
- package/dist-lib/lib/pakbonHtml.d.ts +21 -2
- package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
- package/dist-lib/lib/pakbonHtml.js +144 -36
- package/dist-lib/lib/pakbonPresentation.d.ts +8 -0
- package/dist-lib/lib/pakbonPresentation.d.ts.map +1 -0
- package/dist-lib/lib/pakbonPresentation.js +31 -0
- package/dist-lib/lib/pakbonScan.d.ts +44 -0
- package/dist-lib/lib/pakbonScan.d.ts.map +1 -0
- package/dist-lib/lib/pakbonScan.js +87 -0
- package/dist-lib/lib/pdfJobSaver.d.ts +10 -6
- package/dist-lib/lib/pdfJobSaver.d.ts.map +1 -1
- package/dist-lib/lib/pdfJobSaver.js +302 -99
- package/dist-lib/lib/pdfMap.d.ts +37 -2
- package/dist-lib/lib/pdfMap.d.ts.map +1 -1
- package/dist-lib/lib/pdfMap.js +120 -7
- package/dist-lib/lib/pdfOpslagStatus.d.ts +23 -0
- package/dist-lib/lib/pdfOpslagStatus.d.ts.map +1 -0
- package/dist-lib/lib/pdfOpslagStatus.js +74 -0
- package/dist-lib/lib/printApi.d.ts +31 -0
- package/dist-lib/lib/printApi.d.ts.map +1 -1
- package/dist-lib/lib/printApi.js +62 -1
- package/dist-lib/lib/printQueue.server.d.ts +13 -0
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/printQueue.server.js +673 -96
- package/dist-lib/lib/printService.functions.d.ts +11840 -2568
- package/dist-lib/lib/printService.functions.d.ts.map +1 -1
- package/dist-lib/lib/profielHtml.d.ts.map +1 -1
- package/dist-lib/lib/profielHtml.js +8 -1
- package/dist-lib/lib/supabaseClient.d.ts +1 -3
- package/dist-lib/lib/supabaseClient.d.ts.map +1 -1
- package/dist-lib/lib/supabaseClient.js +4 -8
- package/dist-lib/lib/useDocumentData.d.ts +8 -0
- package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
- package/dist-lib/lib/useDocumentData.js +1 -1
- package/dist-lib/lib/voorbeeldPrint.d.ts +3 -0
- package/dist-lib/lib/voorbeeldPrint.d.ts.map +1 -1
- package/dist-lib/lib/voorbeeldPrint.js +65 -17
- package/package.json +9 -2
|
@@ -75,8 +75,134 @@ export const FUST_VELD_OPTIES = [
|
|
|
75
75
|
{ value: "locatie", label: "Locatie" },
|
|
76
76
|
{ value: "fustsoort", label: "Tray/fustsoort" },
|
|
77
77
|
{ value: "planten_per_fust", label: "Planten per fust" },
|
|
78
|
+
{ value: "fust_aantal", label: "Aantal fusten" },
|
|
78
79
|
{ value: "aantal", label: "Totaal planten" },
|
|
79
80
|
];
|
|
81
|
+
/**
|
|
82
|
+
* Alle velden die op een fustregel van de afleverbrief kunnen staan. De
|
|
83
|
+
* afleverbrief beschrijft één kar, dus kar- en laagnummer horen er ook bij.
|
|
84
|
+
*/
|
|
85
|
+
export const FUSTREGEL_VELD_OPTIES = [
|
|
86
|
+
{ value: "fustsoort", label: "Fustsoort" },
|
|
87
|
+
{ value: "fusthoogte", label: "Fusthoogte" },
|
|
88
|
+
{ value: "belading", label: "Belading" },
|
|
89
|
+
{ value: "karnummer", label: "Karnummer" },
|
|
90
|
+
{ value: "laagnummer", label: "Laag" },
|
|
91
|
+
{ value: "artikelnummer", label: "Artikelnummer" },
|
|
92
|
+
{ value: "artikelnaam", label: "Omschrijving" },
|
|
93
|
+
{ value: "potmaat", label: "Potmaat" },
|
|
94
|
+
{ value: "kleur", label: "Kleur" },
|
|
95
|
+
{ value: "productgroep", label: "Productgroep" },
|
|
96
|
+
{ value: "locatie", label: "Locatie" },
|
|
97
|
+
{ value: "planten_per_fust", label: "Planten per fust" },
|
|
98
|
+
{ value: "fust_aantal", label: "Aantal fusten" },
|
|
99
|
+
{ value: "aantal", label: "Totaal planten" },
|
|
100
|
+
{ value: "gewicht", label: "Gewicht" },
|
|
101
|
+
];
|
|
102
|
+
/** Labels van de fustregelvelden, gedeeld door scherm en afdruk. */
|
|
103
|
+
export const FUSTREGEL_LABELS = Object.fromEntries(FUSTREGEL_VELD_OPTIES.map((o) => [o.value, o.label]));
|
|
104
|
+
/** Velden die rechts uitgelijnd horen te staan. */
|
|
105
|
+
export const FUSTREGEL_RECHTS = new Set([
|
|
106
|
+
"planten_per_fust",
|
|
107
|
+
"fust_aantal",
|
|
108
|
+
"aantal",
|
|
109
|
+
"gewicht",
|
|
110
|
+
]);
|
|
111
|
+
const tekst = (waarde) => String(waarde ?? "").trim();
|
|
112
|
+
/**
|
|
113
|
+
* Zet de karren van een levering om naar losse fustregels. Met `comprimeren`
|
|
114
|
+
* komen identieke fusten (zelfde fustsoort, artikel, potmaat, kleur en aantal
|
|
115
|
+
* planten per fust) op één regel te staan; het aantal fusten wordt opgeteld.
|
|
116
|
+
* Zonder `comprimeren` krijgt elke losse fust een eigen regel.
|
|
117
|
+
*/
|
|
118
|
+
export function fustRegels(karren, opties = {}) {
|
|
119
|
+
const lijst = Array.isArray(karren) ? karren : [];
|
|
120
|
+
const regels = [];
|
|
121
|
+
for (const kar of lijst) {
|
|
122
|
+
const karnummer = tekst(kar?.karnummer ?? kar?.cart_label);
|
|
123
|
+
for (const laag of Array.isArray(kar?.lagen) ? kar.lagen : []) {
|
|
124
|
+
const fusten = Array.isArray(laag?.fusten) ? laag.fusten : [];
|
|
125
|
+
const fustInfo = (soort) => fusten.find((f) => tekst(f?.fusttype ?? f?.fustsoort).toLowerCase() === soort.toLowerCase());
|
|
126
|
+
for (const pr of Array.isArray(laag?.producten) ? laag.producten : []) {
|
|
127
|
+
const fustsoort = tekst(pr?.fustsoort) || "Onbekend";
|
|
128
|
+
const info = fustInfo(fustsoort);
|
|
129
|
+
regels.push({
|
|
130
|
+
fustsoort,
|
|
131
|
+
fusthoogte: tekst(info?.hoogte),
|
|
132
|
+
belading: tekst(pr?.belading ?? info?.belading ?? laag?.belading),
|
|
133
|
+
karnummer,
|
|
134
|
+
laagnummer: tekst(laag?.laagnummer),
|
|
135
|
+
artikelnummer: tekst(pr?.artikelnummer),
|
|
136
|
+
artikelnaam: tekst(pr?.artikelnaam),
|
|
137
|
+
potmaat: tekst(pr?.potmaat ?? laag?.potmaat),
|
|
138
|
+
kleur: tekst(pr?.kleur),
|
|
139
|
+
productgroep: tekst(pr?.productgroep),
|
|
140
|
+
locatie: tekst(pr?.locatie),
|
|
141
|
+
planten_per_fust: Number(pr?.planten_per_fust ?? 0) || 0,
|
|
142
|
+
fust_aantal: Number(pr?.fust_aantal ?? 0) || 0,
|
|
143
|
+
aantal: Number(pr?.aantal ?? 0) || 0,
|
|
144
|
+
gewicht: tekst(pr?.gewicht),
|
|
145
|
+
barcode: tekst(pr?.barcode ?? info?.barcode),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
let uit = regels;
|
|
151
|
+
if (opties.comprimeren !== false) {
|
|
152
|
+
const map = new Map();
|
|
153
|
+
for (const r of regels) {
|
|
154
|
+
const sleutel = [
|
|
155
|
+
r.fustsoort,
|
|
156
|
+
r.fusthoogte,
|
|
157
|
+
r.artikelnummer,
|
|
158
|
+
r.artikelnaam,
|
|
159
|
+
r.potmaat,
|
|
160
|
+
r.kleur,
|
|
161
|
+
r.planten_per_fust,
|
|
162
|
+
]
|
|
163
|
+
.join("|")
|
|
164
|
+
.toLowerCase();
|
|
165
|
+
const bestaand = map.get(sleutel);
|
|
166
|
+
if (bestaand) {
|
|
167
|
+
bestaand.fust_aantal += r.fust_aantal;
|
|
168
|
+
bestaand.aantal += r.aantal;
|
|
169
|
+
// Kar- en laagnummers van samengevoegde regels blijven zichtbaar.
|
|
170
|
+
const lagen = new Set([...bestaand.laagnummer.split(", "), r.laagnummer].filter(Boolean));
|
|
171
|
+
bestaand.laagnummer = [...lagen].join(", ");
|
|
172
|
+
if (!bestaand.locatie)
|
|
173
|
+
bestaand.locatie = r.locatie;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
map.set(sleutel, { ...r });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
uit = [...map.values()];
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Zonder samenvoegen krijgt elke losse fust een eigen regel, zodat de
|
|
183
|
+
// schakelaar zichtbaar effect heeft: 8 dezelfde fusten worden 8 regels
|
|
184
|
+
// van 1 fust in plaats van één regel met 8.
|
|
185
|
+
const los = [];
|
|
186
|
+
for (const r of regels) {
|
|
187
|
+
const n = r.fust_aantal;
|
|
188
|
+
if (n > 1 && n <= 500) {
|
|
189
|
+
const perFust = r.planten_per_fust > 0 ? r.planten_per_fust : Math.round(r.aantal / n);
|
|
190
|
+
for (let i = 0; i < n; i += 1) {
|
|
191
|
+
los.push({ ...r, fust_aantal: 1, aantal: perFust });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
los.push(r);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
uit = los;
|
|
199
|
+
}
|
|
200
|
+
const sortering = opties.sortering ?? "fustsoort";
|
|
201
|
+
if (sortering !== "eigen") {
|
|
202
|
+
uit = [...uit].sort((a, b) => String(a[sortering] ?? "").localeCompare(String(b[sortering] ?? ""), "nl", { numeric: true }));
|
|
203
|
+
}
|
|
204
|
+
return uit;
|
|
205
|
+
}
|
|
80
206
|
const groepering = {
|
|
81
207
|
key: "groepering",
|
|
82
208
|
label: "Groeperen op",
|
|
@@ -209,10 +335,56 @@ export const SECTIE_REGISTER = [
|
|
|
209
335
|
},
|
|
210
336
|
],
|
|
211
337
|
},
|
|
338
|
+
{
|
|
339
|
+
type: "fustregels",
|
|
340
|
+
label: "Fustregels",
|
|
341
|
+
omschrijving: "Alle fusten van deze kar als regels, met de fustgegevens en het aantal fusten per regel.",
|
|
342
|
+
opties: [
|
|
343
|
+
{
|
|
344
|
+
key: "velden",
|
|
345
|
+
label: "Zichtbare fustgegevens",
|
|
346
|
+
type: "meerkeuze",
|
|
347
|
+
standaard: [
|
|
348
|
+
"fustsoort",
|
|
349
|
+
"artikelnummer",
|
|
350
|
+
"artikelnaam",
|
|
351
|
+
"potmaat",
|
|
352
|
+
"planten_per_fust",
|
|
353
|
+
"fust_aantal",
|
|
354
|
+
"aantal",
|
|
355
|
+
],
|
|
356
|
+
opties: FUSTREGEL_VELD_OPTIES,
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
key: "comprimeren",
|
|
360
|
+
label: "Identieke fusten samenvoegen tot één regel",
|
|
361
|
+
type: "schakelaar",
|
|
362
|
+
standaard: true,
|
|
363
|
+
hint: "Twee dezelfde fusten op de kar komen dan op één regel te staan, met 2 bij het aantal fusten.",
|
|
364
|
+
},
|
|
365
|
+
{ key: "toonKoppen", label: "Kolomkoppen tonen", type: "schakelaar", standaard: true },
|
|
366
|
+
{ key: "zebra", label: "Om-en-om arcering", type: "schakelaar", standaard: false },
|
|
367
|
+
{ key: "randen", label: "Randen om cellen", type: "schakelaar", standaard: true },
|
|
368
|
+
{ key: "toonTotaal", label: "Totaalregel tonen", type: "schakelaar", standaard: true },
|
|
369
|
+
{
|
|
370
|
+
key: "sortering",
|
|
371
|
+
label: "Sorteren op",
|
|
372
|
+
type: "keuze",
|
|
373
|
+
standaard: "fustsoort",
|
|
374
|
+
opties: [
|
|
375
|
+
{ value: "eigen", label: "Eigen volgorde" },
|
|
376
|
+
{ value: "fustsoort", label: "Fustsoort" },
|
|
377
|
+
{ value: "artikelnummer", label: "Artikelnummer" },
|
|
378
|
+
{ value: "artikelnaam", label: "Omschrijving" },
|
|
379
|
+
{ value: "locatie", label: "Locatie" },
|
|
380
|
+
],
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
},
|
|
212
384
|
{
|
|
213
385
|
type: "pickmethode",
|
|
214
386
|
label: "Pickmethode",
|
|
215
|
-
omschrijving: "Bepaalt
|
|
387
|
+
omschrijving: "Bepaalt of orders per kar, per fust of op beide manieren worden gepickt.",
|
|
216
388
|
opties: [
|
|
217
389
|
{
|
|
218
390
|
key: "methode",
|
|
@@ -222,8 +394,9 @@ export const SECTIE_REGISTER = [
|
|
|
222
394
|
opties: [
|
|
223
395
|
{ value: "kar", label: "Order picken per kar" },
|
|
224
396
|
{ value: "fusten", label: "Order picken per fusten (zelf karindeling maken)" },
|
|
397
|
+
{ value: "beide", label: "Order picken per kar én per fusten (karren + verzamellijst)" },
|
|
225
398
|
],
|
|
226
|
-
hint: "Bij picken per fusten vervallen de blokken Karren, Lagen, Producten en Fusten
|
|
399
|
+
hint: "Bij picken per fusten vervallen de blokken Karren, Lagen, Producten en Fusten. Bij de gecombineerde keuze bepaalt de Engine per opdracht: full_cart toont de karindeling, partial_order alleen de te verzamelen fusten.",
|
|
227
400
|
},
|
|
228
401
|
{
|
|
229
402
|
key: "kop",
|
|
@@ -243,12 +416,21 @@ export const SECTIE_REGISTER = [
|
|
|
243
416
|
"locatie",
|
|
244
417
|
"fustsoort",
|
|
245
418
|
"planten_per_fust",
|
|
419
|
+
"fust_aantal",
|
|
246
420
|
"aantal",
|
|
247
421
|
],
|
|
248
422
|
opties: FUST_VELD_OPTIES,
|
|
249
423
|
},
|
|
250
424
|
{ key: "toonFusthoogte", label: "Fusthoogte en belading tonen", type: "schakelaar", standaard: true },
|
|
251
425
|
{ key: "toonTotaal", label: "Totaal aantal fusten tonen", type: "schakelaar", standaard: true },
|
|
426
|
+
{
|
|
427
|
+
key: "toonBarcode",
|
|
428
|
+
label: "Barcode voor afleverbrief tonen",
|
|
429
|
+
type: "schakelaar",
|
|
430
|
+
standaard: true,
|
|
431
|
+
hint: "De barcode wordt uitsluitend overgenomen uit de Engine-opdracht.",
|
|
432
|
+
},
|
|
433
|
+
{ key: "barcodeHoogte", label: "Barcodehoogte (mm)", type: "getal", standaard: 15 },
|
|
252
434
|
],
|
|
253
435
|
},
|
|
254
436
|
{
|
|
@@ -474,6 +656,13 @@ export const SECTIE_REGISTER = [
|
|
|
474
656
|
{ key: "label", label: "Bijschrift", type: "tekst", standaard: "Voor ontvangst getekend" },
|
|
475
657
|
{ key: "toonNaam", label: "Naamregel", type: "schakelaar", standaard: true },
|
|
476
658
|
{ key: "toonDatum", label: "Datumregel", type: "schakelaar", standaard: true },
|
|
659
|
+
{
|
|
660
|
+
key: "toonBarcode",
|
|
661
|
+
label: "Barcode onderaan tonen",
|
|
662
|
+
type: "schakelaar",
|
|
663
|
+
standaard: true,
|
|
664
|
+
hint: "De barcode wordt uitsluitend overgenomen uit de Engine-opdracht.",
|
|
665
|
+
},
|
|
477
666
|
],
|
|
478
667
|
},
|
|
479
668
|
{
|
|
@@ -498,9 +687,9 @@ export const SECTIE_REGISTER = [
|
|
|
498
687
|
{
|
|
499
688
|
type: "barcode",
|
|
500
689
|
label: "Barcode",
|
|
501
|
-
omschrijving: "
|
|
690
|
+
omschrijving: "Scanbare barcode. Bij Engine-pakbonnen komt de waarde uit de opdracht.",
|
|
502
691
|
opties: [
|
|
503
|
-
{ key: "waarde", label: "Inhoud", type: "tekst", standaard: "{{
|
|
692
|
+
{ key: "waarde", label: "Inhoud", type: "tekst", standaard: "{{barcode}}" },
|
|
504
693
|
{ key: "hoogte", label: "Hoogte (mm)", type: "getal", standaard: 15 },
|
|
505
694
|
],
|
|
506
695
|
},
|
|
@@ -555,28 +744,94 @@ export function standaardPakbonConfig() {
|
|
|
555
744
|
export function leesPakbonConfig(config) {
|
|
556
745
|
// Accepteert zowel de layout-config ({ pakbon: {...} }) als een kale
|
|
557
746
|
// PakbonConfig. Zonder deze tolerantie viel de afdruk terug op de
|
|
558
|
-
// standaardsecties en verdween o.a. het documentlogo.
|
|
747
|
+
// standaardsecties en verdween o.a. het documentlogo. De sleutel
|
|
748
|
+
// "afleverbrief" wordt meegelezen zodat de printpijplijn ook
|
|
749
|
+
// afleverbrief-layouts met hun eigen secties afdrukt.
|
|
559
750
|
const raw = config;
|
|
560
751
|
const c = Array.isArray(raw?.secties)
|
|
561
752
|
? raw
|
|
562
|
-
: raw?.pakbon;
|
|
753
|
+
: (raw?.pakbon ?? raw?.afleverbrief);
|
|
563
754
|
const secties = Array.isArray(c?.secties) ? c.secties : null;
|
|
564
755
|
const logo = c?.logo ?? null;
|
|
565
756
|
const basis = secties && secties.length ? { secties } : standaardPakbonConfig();
|
|
566
757
|
return { ...basis, secties: migreerPickmethode(basis.secties), logo };
|
|
567
758
|
}
|
|
759
|
+
/** Standaardindeling van een afleverbrief: geen kar-, laag- of fustblokken. */
|
|
760
|
+
export function standaardAfleverbriefConfig() {
|
|
761
|
+
return {
|
|
762
|
+
secties: [
|
|
763
|
+
"logo",
|
|
764
|
+
"bedrijfsgegevens",
|
|
765
|
+
"klantgegevens",
|
|
766
|
+
"afleveradres",
|
|
767
|
+
"orderinformatie",
|
|
768
|
+
"transportinformatie",
|
|
769
|
+
"fustregels",
|
|
770
|
+
"totalen",
|
|
771
|
+
"opmerkingen",
|
|
772
|
+
"handtekening",
|
|
773
|
+
].map(nieuweSectie),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Blokken die op een afleverbrief thuishoren. Een afleverbrief beschrijft
|
|
778
|
+
* altijd precies één kar, dus kar-, laag- en pickmethodeblokken vervallen.
|
|
779
|
+
*/
|
|
780
|
+
export const AFLEVERBRIEF_SECTIE_TYPES = [
|
|
781
|
+
"logo",
|
|
782
|
+
"bedrijfsgegevens",
|
|
783
|
+
"klantgegevens",
|
|
784
|
+
"afleveradres",
|
|
785
|
+
"factuuradres",
|
|
786
|
+
"orderinformatie",
|
|
787
|
+
"transportinformatie",
|
|
788
|
+
"fustregels",
|
|
789
|
+
"totalen",
|
|
790
|
+
"opmerkingen",
|
|
791
|
+
"handtekening",
|
|
792
|
+
"tekstblok",
|
|
793
|
+
"qrcode",
|
|
794
|
+
"barcode",
|
|
795
|
+
"afbeelding",
|
|
796
|
+
];
|
|
797
|
+
/** Leest de sectie-opbouw van een afleverbrief-layout. */
|
|
798
|
+
export function leesAfleverbriefConfig(config) {
|
|
799
|
+
// Eerst de eigen sleutel; oudere afleverbrief-layouts zijn per abuis via de
|
|
800
|
+
// pakbon-opbouw onder "pakbon" opgeslagen en worden hier meegelezen.
|
|
801
|
+
const raw = config;
|
|
802
|
+
const c = Array.isArray(raw?.secties)
|
|
803
|
+
? raw
|
|
804
|
+
: (raw?.afleverbrief ?? raw?.pakbon);
|
|
805
|
+
const secties = Array.isArray(c?.secties) ? c.secties : null;
|
|
806
|
+
const logo = c?.logo ?? null;
|
|
807
|
+
const basis = secties && secties.length ? { secties } : standaardAfleverbriefConfig();
|
|
808
|
+
return { ...basis, secties: basis.secties, logo };
|
|
809
|
+
}
|
|
568
810
|
/** Zet de oude karren-optie "pickmethode" om naar een eigen pickmethode-blok. */
|
|
569
811
|
function migreerPickmethode(secties) {
|
|
812
|
+
// Alleen relevant voor pakbonnen met een karren-blok; een afleverbrief
|
|
813
|
+
// krijgt nooit een pickmethode-kop.
|
|
570
814
|
if (secties.some((s) => s.type === "pickmethode"))
|
|
571
815
|
return secties;
|
|
816
|
+
if (!secties.some((s) => s.type === "karren"))
|
|
817
|
+
return secties;
|
|
572
818
|
const karIndex = secties.findIndex((s) => s.type === "karren");
|
|
573
819
|
const oud = karIndex >= 0 ? String(secties[karIndex].opties?.["pickmethode"] ?? "kar") : "kar";
|
|
574
820
|
const blok = nieuweSectie("pickmethode");
|
|
575
|
-
blok.opties["methode"] = oud === "fusten"
|
|
821
|
+
blok.opties["methode"] = oud === "fusten" || oud === "beide" ? oud : "kar";
|
|
576
822
|
const kopie = [...secties];
|
|
577
823
|
kopie.splice(karIndex >= 0 ? karIndex : kopie.length, 0, blok);
|
|
578
824
|
return kopie;
|
|
579
825
|
}
|
|
826
|
+
/** Normaliseert alleen de twee varianten uit het gedeelde Engine-contract. */
|
|
827
|
+
export function pakbonLayoutVariant(value) {
|
|
828
|
+
const variant = String(value ?? "").trim().toLowerCase();
|
|
829
|
+
if (variant === "full_cart")
|
|
830
|
+
return "full_cart";
|
|
831
|
+
if (variant === "partial_order")
|
|
832
|
+
return "partial_order";
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
580
835
|
/** Actieve pickmethode van een pakbonconfiguratie. */
|
|
581
836
|
export function pickMethode(secties) {
|
|
582
837
|
const lijst = Array.isArray(secties) ? secties : [];
|
|
@@ -584,13 +839,31 @@ export function pickMethode(secties) {
|
|
|
584
839
|
const waarde = blok
|
|
585
840
|
? String(blok.opties?.["methode"] ?? "kar")
|
|
586
841
|
: String(lijst.find((s) => s.type === "karren")?.opties?.["pickmethode"] ?? "kar");
|
|
587
|
-
|
|
842
|
+
if (waarde === "fusten")
|
|
843
|
+
return "fusten";
|
|
844
|
+
if (waarde === "beide")
|
|
845
|
+
return "beide";
|
|
846
|
+
return "kar";
|
|
588
847
|
}
|
|
589
848
|
const KAR_SECTIES = ["karren", "lagen", "producten", "fusten"];
|
|
590
849
|
/** Blokken die bij de gekozen pickmethode niet van toepassing zijn. */
|
|
591
850
|
export function sectieOnderdrukt(type, methode) {
|
|
592
851
|
return methode === "fusten" && KAR_SECTIES.includes(type);
|
|
593
852
|
}
|
|
853
|
+
/**
|
|
854
|
+
* Blokken die de Engine-variant weglaat. Zonder variant blijft de editor/het
|
|
855
|
+
* losse voorbeeld compleet; een echte Engine-opdracht wordt in de wachtrij
|
|
856
|
+
* geblokkeerd totdat de variant aanwezig is.
|
|
857
|
+
*/
|
|
858
|
+
export function sectieOnderdruktVoorVariant(type, methode, variant) {
|
|
859
|
+
if (sectieOnderdrukt(type, methode))
|
|
860
|
+
return true;
|
|
861
|
+
if (methode !== "beide" || !variant)
|
|
862
|
+
return false;
|
|
863
|
+
if (variant === "full_cart")
|
|
864
|
+
return type === "pickmethode";
|
|
865
|
+
return type === "pickmethode" ? false : [...KAR_SECTIES, "orderregels"].includes(type);
|
|
866
|
+
}
|
|
594
867
|
const p = (nr, naam, potmaat, aantal, locatie, groep, kleur) => ({
|
|
595
868
|
artikelnummer: nr,
|
|
596
869
|
artikelnaam: naam,
|
|
@@ -651,6 +924,7 @@ export const DEMO_ORDER = {
|
|
|
651
924
|
karren: [
|
|
652
925
|
{
|
|
653
926
|
karnummer: 5,
|
|
927
|
+
barcode: "VOORBEELD-KAR-05",
|
|
654
928
|
route: "Route Zuid",
|
|
655
929
|
chauffeur: "J. Bakker",
|
|
656
930
|
gewicht: "142 kg",
|
|
@@ -687,6 +961,7 @@ export const DEMO_ORDER = {
|
|
|
687
961
|
// ze samengevoegd tot één blok met "Deze kar 3× pakken".
|
|
688
962
|
...[6, 7, 8].map((nr) => ({
|
|
689
963
|
karnummer: nr,
|
|
964
|
+
barcode: `VOORBEELD-KAR-${String(nr).padStart(2, "0")}`,
|
|
690
965
|
route: "Route Zuid",
|
|
691
966
|
chauffeur: "J. Bakker",
|
|
692
967
|
gewicht: "118 kg",
|
|
@@ -813,8 +1088,10 @@ function laagVingerafdruk(l) {
|
|
|
813
1088
|
return [l.belading, l.potmaat, l.gewicht, l.opmerking, producten, fusten].join("#");
|
|
814
1089
|
}
|
|
815
1090
|
function karVingerafdruk(k) {
|
|
816
|
-
// karnummer bewust niet meegenomen: alleen de indeling telt
|
|
817
|
-
|
|
1091
|
+
// karnummer bewust niet meegenomen: alleen de indeling telt. Een kar met een
|
|
1092
|
+
// eigen barcode of cart_id van de Engine is wél uniek en wordt nooit gebundeld.
|
|
1093
|
+
const uniek = String(k.barcode ?? "") || String(k.cart_id ?? "") || String(k.cart_label ?? "");
|
|
1094
|
+
return [uniek, k.route, k.chauffeur, k.gewicht, k.gedeeld ? "gedeeld" : "", (k.lagen ?? []).map(laagVingerafdruk).join("~")].join("#");
|
|
818
1095
|
}
|
|
819
1096
|
/** Groepeert identieke karren. Bij `aan = false` blijft elke kar los. */
|
|
820
1097
|
export function groepeerIdentiekeKarren(karren, aan) {
|
|
@@ -862,69 +1139,189 @@ export function karBundelTekst(aantal) {
|
|
|
862
1139
|
export function laagBundelTekst(aantal) {
|
|
863
1140
|
return `Deze laag ${aantal}×`;
|
|
864
1141
|
}
|
|
1142
|
+
const fustSleutel = (waarde) => String(waarde ?? "")
|
|
1143
|
+
.trim()
|
|
1144
|
+
.replace(/\s+/g, " ")
|
|
1145
|
+
.toLowerCase();
|
|
865
1146
|
/**
|
|
866
1147
|
* Verzamellijst met alle fusten van een order, opgeteld per fusttype,
|
|
867
1148
|
* inclusief de producten die in dat fusttype gepickt moeten worden.
|
|
868
|
-
*
|
|
869
|
-
*
|
|
1149
|
+
* Een product hoort uitsluitend bij zijn eigen fustsoort — nooit bij alle
|
|
1150
|
+
* fustgroepen van de laag.
|
|
870
1151
|
*/
|
|
871
1152
|
export function fustVerzamellijst(karren) {
|
|
872
1153
|
const lijst = Array.isArray(karren) ? karren : [];
|
|
873
1154
|
const map = new Map();
|
|
1155
|
+
/** Expliciet door de Engine opgegeven fustaantallen per fusttype. */
|
|
1156
|
+
const opgegevenAantallen = new Map();
|
|
1157
|
+
const zoekGroep = (type, f) => {
|
|
1158
|
+
const sleutel = fustSleutel(type) || "onbekend";
|
|
1159
|
+
let groep = map.get(sleutel);
|
|
1160
|
+
if (!groep) {
|
|
1161
|
+
groep = {
|
|
1162
|
+
fusttype: String(type ?? "").trim() || "Onbekend",
|
|
1163
|
+
aantal: 0,
|
|
1164
|
+
hoogte: String(f?.["hoogte"] ?? ""),
|
|
1165
|
+
belading: String(f?.["belading"] ?? ""),
|
|
1166
|
+
producten: [],
|
|
1167
|
+
};
|
|
1168
|
+
map.set(sleutel, groep);
|
|
1169
|
+
}
|
|
1170
|
+
else if (f) {
|
|
1171
|
+
if (!groep.hoogte && f["hoogte"])
|
|
1172
|
+
groep.hoogte = String(f["hoogte"]);
|
|
1173
|
+
if (!groep.belading && f["belading"])
|
|
1174
|
+
groep.belading = String(f["belading"]);
|
|
1175
|
+
}
|
|
1176
|
+
return groep;
|
|
1177
|
+
};
|
|
874
1178
|
for (const kar of lijst) {
|
|
875
1179
|
for (const laag of Array.isArray(kar?.lagen) ? kar.lagen : []) {
|
|
876
1180
|
const producten = Array.isArray(laag?.producten) ? laag.producten : [];
|
|
877
|
-
// Zonder aparte fustlijst: fusten afleiden uit de producten, zodat een
|
|
878
|
-
// module die alleen orderregels aanlevert toch een verzamellijst krijgt.
|
|
879
1181
|
const opgegeven = Array.isArray(laag?.fusten) ? laag.fusten : [];
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
for (const pr of producten) {
|
|
883
|
-
const soort = String(pr?.fustsoort ?? "").trim() || "Onbekend";
|
|
884
|
-
const aantal = Number(pr?.fust_aantal ?? 0) || 0;
|
|
885
|
-
if (aantal > 0)
|
|
886
|
-
afgeleid.set(soort, (afgeleid.get(soort) ?? 0) + aantal);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
const fusten = opgegeven.length
|
|
890
|
-
? opgegeven
|
|
891
|
-
: Array.from(afgeleid.entries()).map(([fusttype, aantal]) => ({ fusttype, aantal }));
|
|
892
|
-
for (const f of fusten) {
|
|
1182
|
+
// Fustmetadata (hoogte/belading) en expliciete aantallen vastleggen.
|
|
1183
|
+
for (const f of opgegeven) {
|
|
893
1184
|
const type = String(f?.fusttype ?? f?.fustsoort ?? "Onbekend");
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1185
|
+
zoekGroep(type, f);
|
|
1186
|
+
const sleutel = fustSleutel(type) || "onbekend";
|
|
1187
|
+
opgegevenAantallen.set(sleutel, (opgegevenAantallen.get(sleutel) ?? 0) + (Number(f?.aantal ?? 0) || 0));
|
|
1188
|
+
}
|
|
1189
|
+
// Producten bij hun eigen fustsoort plaatsen.
|
|
1190
|
+
for (const pr of producten) {
|
|
1191
|
+
const type = String(pr?.fustsoort ?? "").trim() || "Onbekend";
|
|
1192
|
+
const groep = zoekGroep(type);
|
|
1193
|
+
const nr = String(pr?.artikelnummer ?? "");
|
|
1194
|
+
const naam = String(pr?.artikelnaam ?? "");
|
|
1195
|
+
const bestaand = groep.producten.find((x) => x.artikelnummer === nr && x.artikelnaam === naam);
|
|
1196
|
+
const aantal = Number(pr?.aantal ?? 0) || 0;
|
|
1197
|
+
const fustAantal = Number(pr?.fust_aantal ?? 0) || 0;
|
|
1198
|
+
if (bestaand) {
|
|
1199
|
+
bestaand.aantal += aantal;
|
|
1200
|
+
bestaand.fust_aantal += fustAantal;
|
|
904
1201
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
productgroep: String(pr?.productgroep ?? ""),
|
|
919
|
-
locatie: String(pr?.locatie ?? ""),
|
|
920
|
-
fustsoort: String(pr?.fustsoort ?? ""),
|
|
921
|
-
planten_per_fust: Number(pr?.planten_per_fust ?? 0),
|
|
922
|
-
aantal: Number(pr?.aantal ?? 0),
|
|
923
|
-
});
|
|
924
|
-
}
|
|
1202
|
+
else {
|
|
1203
|
+
groep.producten.push({
|
|
1204
|
+
artikelnummer: nr,
|
|
1205
|
+
artikelnaam: naam,
|
|
1206
|
+
potmaat: String(pr?.potmaat ?? ""),
|
|
1207
|
+
kleur: String(pr?.kleur ?? ""),
|
|
1208
|
+
productgroep: String(pr?.productgroep ?? ""),
|
|
1209
|
+
locatie: String(pr?.locatie ?? ""),
|
|
1210
|
+
fustsoort: String(pr?.fustsoort ?? ""),
|
|
1211
|
+
planten_per_fust: Number(pr?.planten_per_fust ?? 0) || 0,
|
|
1212
|
+
fust_aantal: fustAantal,
|
|
1213
|
+
aantal,
|
|
1214
|
+
});
|
|
925
1215
|
}
|
|
926
1216
|
}
|
|
927
1217
|
}
|
|
928
1218
|
}
|
|
929
|
-
|
|
1219
|
+
const groepen = [...map.entries()].map(([sleutel, groep]) => {
|
|
1220
|
+
const uitProducten = groep.producten.reduce((n, p) => n + p.fust_aantal, 0);
|
|
1221
|
+
const expliciet = opgegevenAantallen.get(sleutel) ?? 0;
|
|
1222
|
+
// Engine-opgave is leidend; anders tellen we de fusten van de producten op.
|
|
1223
|
+
groep.aantal = expliciet > 0 ? expliciet : uitProducten;
|
|
1224
|
+
return groep;
|
|
1225
|
+
});
|
|
1226
|
+
return groepen
|
|
1227
|
+
.filter((g) => g.producten.length > 0 || g.aantal > 0)
|
|
1228
|
+
.sort((a, b) => a.fusttype.localeCompare(b.fusttype));
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Voorbeeld van een deelkar (niet-volle kar): alleen een deel van de fusten,
|
|
1232
|
+
* zonder karindeling. Uitsluitend bedoeld voor het voorbeeld in de builder —
|
|
1233
|
+
* echte opdrachten krijgen hun gegevens van de Logistics Engine.
|
|
1234
|
+
*/
|
|
1235
|
+
export function deelkarVoorbeeldOrder(order = DEMO_ORDER) {
|
|
1236
|
+
const eerste = order.karren[0];
|
|
1237
|
+
const laag = eerste?.lagen?.[0];
|
|
1238
|
+
if (!eerste || !laag)
|
|
1239
|
+
return order;
|
|
1240
|
+
return {
|
|
1241
|
+
...order,
|
|
1242
|
+
karren: [
|
|
1243
|
+
{
|
|
1244
|
+
...eerste,
|
|
1245
|
+
gedeeld: true,
|
|
1246
|
+
barcode: "VOORBEELD-DEELKAR",
|
|
1247
|
+
lagen: [{ ...laag, producten: laag.producten.slice(0, 1), fusten: laag.fusten?.slice(0, 1) ?? [] }],
|
|
1248
|
+
},
|
|
1249
|
+
],
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
// --- restpakbon (deelkar) ---------------------------------------------------
|
|
1253
|
+
/** Restregels zoals de Logistics Engine ze meestuurt onder `cart.cart_items`. */
|
|
1254
|
+
export function deelkarRegels(order) {
|
|
1255
|
+
const o = (order && typeof order === "object" ? order : {});
|
|
1256
|
+
const cart = (o["cart"] && typeof o["cart"] === "object" ? o["cart"] : {});
|
|
1257
|
+
const lijst = cart["cart_items"] ?? cart["items"];
|
|
1258
|
+
return Array.isArray(lijst) ? lijst : [];
|
|
1259
|
+
}
|
|
1260
|
+
const tekstWaarde = (waarde) => waarde === undefined || waarde === null ? "" : String(waarde).trim();
|
|
1261
|
+
/**
|
|
1262
|
+
* Beperkt een order tot de restregels van één deelkar. Alleen wat de Engine
|
|
1263
|
+
* als `cart.cart_items` meestuurt komt op de restpakbon te staan; nooit de
|
|
1264
|
+
* volledige karinhoud. Wordt gedeeld door voorbeeld, PDF en print, zodat de
|
|
1265
|
+
* drie weergaven niet uiteen kunnen lopen.
|
|
1266
|
+
*/
|
|
1267
|
+
export function beperkTotDeelkar(order) {
|
|
1268
|
+
const regels = deelkarRegels(order);
|
|
1269
|
+
if (!regels.length)
|
|
1270
|
+
return order;
|
|
1271
|
+
const o = (order && typeof order === "object" ? order : {});
|
|
1272
|
+
const cart = (o["cart"] && typeof o["cart"] === "object" ? o["cart"] : {});
|
|
1273
|
+
const karren = Array.isArray(o["karren"]) ? o["karren"] : [];
|
|
1274
|
+
const cartId = tekstWaarde(cart["cart_id"]);
|
|
1275
|
+
const basisKar = (cartId ? karren.find((k) => tekstWaarde(k["cart_id"]) === cartId) : undefined) ??
|
|
1276
|
+
karren[0] ??
|
|
1277
|
+
{};
|
|
1278
|
+
const producten = regels.map((raw) => {
|
|
1279
|
+
const item = raw;
|
|
1280
|
+
return {
|
|
1281
|
+
artikelnummer: tekstWaarde(item["artikelnummer"] ?? item["artikelcode"]),
|
|
1282
|
+
artikelnaam: tekstWaarde(item["artikelnaam"] ?? item["product_name"] ?? item["omschrijving"]),
|
|
1283
|
+
potmaat: tekstWaarde(item["potmaat"]),
|
|
1284
|
+
aantal: Number(item["aantal"] ?? item["quantity"] ?? 0) || 0,
|
|
1285
|
+
belading: tekstWaarde(item["belading"]),
|
|
1286
|
+
barcode: tekstWaarde(item["barcode"]),
|
|
1287
|
+
opmerking: tekstWaarde(item["opmerking"]),
|
|
1288
|
+
locatie: tekstWaarde(item["locatie"]),
|
|
1289
|
+
gewicht: tekstWaarde(item["gewicht"]),
|
|
1290
|
+
productgroep: tekstWaarde(item["productgroep"]),
|
|
1291
|
+
kleur: tekstWaarde(item["kleur"]),
|
|
1292
|
+
fust_aantal: Number(item["fust_aantal"] ?? item["aantal_fusten"] ?? 0) || 0,
|
|
1293
|
+
fustsoort: tekstWaarde(item["fustsoort"] ?? item["fusttype"]),
|
|
1294
|
+
planten_per_fust: Number(item["planten_per_fust"] ?? 0) || 0,
|
|
1295
|
+
};
|
|
1296
|
+
});
|
|
1297
|
+
// Fusten per soort optellen uit dezelfde restregels, zodat de verzamellijst
|
|
1298
|
+
// en de totalen nooit meer tonen dan er nog verzameld moet worden.
|
|
1299
|
+
const fustMap = new Map();
|
|
1300
|
+
for (const pr of producten) {
|
|
1301
|
+
const sleutel = pr.fustsoort.toLowerCase() || "onbekend";
|
|
1302
|
+
const bestaand = fustMap.get(sleutel);
|
|
1303
|
+
if (bestaand)
|
|
1304
|
+
bestaand.aantal += pr.fust_aantal;
|
|
1305
|
+
else
|
|
1306
|
+
fustMap.set(sleutel, {
|
|
1307
|
+
fusttype: pr.fustsoort || "Onbekend",
|
|
1308
|
+
aantal: pr.fust_aantal,
|
|
1309
|
+
hoogte: "",
|
|
1310
|
+
belading: pr.belading,
|
|
1311
|
+
barcode: "",
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
const laag = {
|
|
1315
|
+
laagnummer: 1,
|
|
1316
|
+
belading: "",
|
|
1317
|
+
potmaat: "",
|
|
1318
|
+
gewicht: "",
|
|
1319
|
+
opmerking: "",
|
|
1320
|
+
producten,
|
|
1321
|
+
fusten: [...fustMap.values()].filter((f) => f.aantal > 0),
|
|
1322
|
+
};
|
|
1323
|
+
return {
|
|
1324
|
+
...o,
|
|
1325
|
+
karren: [{ ...basisKar, lagen: [laag] }],
|
|
1326
|
+
};
|
|
930
1327
|
}
|