@openmrs/esm-stock-management-app 1.0.1-pre.361 → 1.0.1-pre.366

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,47 @@
1
+ import React, { useEffect, useMemo, useState } from "react";
1
2
  import {
2
3
  Button,
3
- Form,
4
- ModalBody,
5
- ModalFooter,
6
- ModalHeader,
7
4
  InlineLoading,
8
5
  ComboBox,
6
+ DatePickerInput,
7
+ DatePicker,
8
+ Select,
9
+ SelectItem,
10
+ RadioButtonGroup,
11
+ RadioButton,
12
+ Form,
13
+ Checkbox,
14
+ NumberInput,
9
15
  } from "@carbon/react";
10
- import React from "react";
11
16
  import styles from "./create-stock-report.scss";
12
17
  import { useTranslation } from "react-i18next";
13
18
  import { closeOverlay } from "../../core/components/overlay/hook";
14
19
  import { useReportTypes } from "../stock-reports.resource";
15
-
20
+ import {
21
+ DATE_PICKER_CONTROL_FORMAT,
22
+ DATE_PICKER_FORMAT,
23
+ formatForDatePicker,
24
+ today,
25
+ } from "../../constants";
26
+ import { Controller, useForm } from "react-hook-form";
27
+ import { zodResolver } from "@hookform/resolvers/zod";
28
+ import { StockReportSchema, reportSchema } from "../report-validation-schema";
29
+ import {
30
+ useConcept,
31
+ useStockTagLocations,
32
+ } from "../../stock-lookups/stock-lookups.resource";
33
+ import { ConfigObject, showSnackbar, useConfig } from "@openmrs/esm-framework";
34
+ import { Concept } from "../../core/api/types/concept/Concept";
35
+ import { createBatchJob } from "../../stock-batch/stock-batch.resource";
36
+ import {
37
+ ReportParameter,
38
+ getParamDefaultLimit,
39
+ getReportEndDateLabel,
40
+ getReportLimitLabel,
41
+ getReportStartDateLabel,
42
+ } from "../ReportType";
43
+ import { formatDisplayDate } from "../../core/utils/datetimeUtils";
44
+ import { BatchJobTypeReport } from "../../core/api/types/BatchJob";
16
45
  interface CreateReportProps {
17
46
  model?: ReportModel;
18
47
  }
@@ -33,11 +62,161 @@ export interface ReportModel {
33
62
  stockSource?: string;
34
63
  stockSourceDestinationUuid?: string;
35
64
  stockSourceDestination?: string;
65
+ inventoryGroupBy?: string;
66
+ inventoryGroupByName?: string;
67
+ maxReorderLevelRatio?: number;
68
+ stockItemUuid?: string;
69
+ stockItemName?: string;
70
+ patientUuid?: string;
71
+ patientName?: string;
72
+ limit?: number | null;
73
+ mostLeastMoving?: string;
74
+ mostLeastMovingName?: string;
75
+ fullFillment?: string[];
36
76
  }
37
77
  const CreateReport: React.FC<CreateReportProps> = ({ model }) => {
38
78
  const { t } = useTranslation();
79
+ const { stockItemCategoryUUID } = useConfig<ConfigObject>();
39
80
 
40
81
  const { reportTypes, isLoading } = useReportTypes();
82
+ const { stockLocations } = useStockTagLocations();
83
+ const { items, isLoading: isLoadingStockItemCategories } = useConcept(
84
+ stockItemCategoryUUID
85
+ );
86
+ const [displayDate, setDisplayDate] = useState<boolean>(false);
87
+ const [displayStartDate, setDisplayStartDate] = useState<boolean>(false);
88
+ const [displayEndDate, setDisplayEndDate] = useState<boolean>(false);
89
+ const [displayStockItemCategory, setDisplayStockItemCategory] =
90
+ useState<boolean>(false);
91
+ const [displayLocation, setDisplayLocation] = useState<boolean>(false);
92
+ const [displayChildLocations, setDisplayChildLocations] =
93
+ useState<boolean>(false);
94
+ const [displayStockSource, setDisplayStockSource] = useState<boolean>(false);
95
+ const [displayStockSourceDestination, setDisplayStockSourceDestination] =
96
+ useState<boolean>(false);
97
+ const [displayInventoryGroupBy, setDisplayInventoryGroupBy] =
98
+ useState<boolean>(false);
99
+ const [displayMaxReorderLevelRatio, setDisplayMaxReorderLevelRatio] =
100
+ useState<boolean>(false);
101
+ const [displayPatient, setDisplayPatient] = useState<boolean>(false);
102
+ const [displayStockItem, setDisplayStockItem] = useState<boolean>(false);
103
+ const [displayLimit, setDisplayLimit] = useState<boolean>(false);
104
+ const [displayMostLeastMoving, setDisplayMostLeastMoving] =
105
+ useState<boolean>(false);
106
+ const [displayFulfillment, setDisplayFulfillment] = useState<boolean>(false);
107
+ const [selectedReportName, setSelectedReportName] = useState<string>("");
108
+
109
+ const handleReportNameChange = (name: string) => {
110
+ setSelectedReportName(name);
111
+ };
112
+ useEffect(() => {
113
+ let hasResetParameters = false;
114
+ if (selectedReportName) {
115
+ const reportType = (reportTypes as any)?.find(
116
+ (p) => p.name === selectedReportName
117
+ );
118
+ if (reportType) {
119
+ setDisplayDate(
120
+ reportType.parameters?.some((p) => p === ReportParameter.Date)
121
+ );
122
+ setDisplayStartDate(
123
+ reportType.parameters?.some((p) => p === ReportParameter.StartDate)
124
+ );
125
+ setDisplayEndDate(
126
+ reportType.parameters?.some((p) => p === ReportParameter.EndDate)
127
+ );
128
+ setDisplayStockItemCategory(
129
+ reportType.parameters?.some(
130
+ (p) => p === ReportParameter.StockItemCategory
131
+ )
132
+ );
133
+ setDisplayLocation(
134
+ reportType.parameters?.some((p) => p === ReportParameter.Location)
135
+ );
136
+ setDisplayChildLocations(
137
+ reportType.parameters?.some(
138
+ (p) => p === ReportParameter.ChildLocations
139
+ )
140
+ );
141
+ setDisplayStockSource(
142
+ reportType.parameters?.some((p) => p === ReportParameter.StockSource)
143
+ );
144
+ setDisplayStockSourceDestination(
145
+ reportType.parameters?.some(
146
+ (p) => p === ReportParameter.StockSourceDestination
147
+ )
148
+ );
149
+ setDisplayInventoryGroupBy(
150
+ reportType.parameters?.some(
151
+ (p) => p === ReportParameter.InventoryGroupBy
152
+ )
153
+ );
154
+ setDisplayMaxReorderLevelRatio(
155
+ reportType.parameters?.some(
156
+ (p) => p === ReportParameter.MaxReorderLevelRatio
157
+ )
158
+ );
159
+ setDisplayStockItem(
160
+ reportType.parameters?.some((p) => p === ReportParameter.StockItem)
161
+ );
162
+ setDisplayPatient(
163
+ reportType.parameters?.some((p) => p === ReportParameter.Patient)
164
+ );
165
+ setDisplayLimit(
166
+ reportType.parameters?.some((p) => p === ReportParameter.Limit)
167
+ );
168
+ setDisplayMostLeastMoving(
169
+ reportType.parameters?.some(
170
+ (p) => p === ReportParameter.MostLeastMoving
171
+ )
172
+ );
173
+ setDisplayFulfillment(
174
+ reportType.parameters?.some((p) => p === ReportParameter.Fullfillment)
175
+ );
176
+ hasResetParameters = true;
177
+ }
178
+ }
179
+ if (!hasResetParameters) {
180
+ setDisplayDate(false);
181
+ setDisplayStartDate(false);
182
+ setDisplayEndDate(false);
183
+ setDisplayStockItemCategory(false);
184
+ setDisplayLocation(false);
185
+ setDisplayChildLocations(false);
186
+ setDisplayStockSource(false);
187
+ setDisplayStockSourceDestination(false);
188
+ setDisplayInventoryGroupBy(false);
189
+ setDisplayMaxReorderLevelRatio(false);
190
+ setDisplayStockItem(false);
191
+ setDisplayPatient(false);
192
+ setDisplayLimit(false);
193
+ setDisplayMostLeastMoving(false);
194
+ setDisplayFulfillment(false);
195
+ }
196
+ }, [selectedReportName, reportTypes]);
197
+
198
+ const stockItemCategories = useMemo(() => {
199
+ return [
200
+ {
201
+ display: "All Categories",
202
+ name: "All Categories",
203
+ uuid: "",
204
+ } as any as Concept,
205
+ ...((items && items?.answers?.length > 0
206
+ ? items?.answers
207
+ : items?.setMembers) ?? []),
208
+ ];
209
+ }, [items]);
210
+ const {
211
+ handleSubmit,
212
+ control,
213
+ formState: { errors, defaultValues, isDirty },
214
+ setValue,
215
+ } = useForm<StockReportSchema>({
216
+ mode: "all",
217
+ resolver: zodResolver(reportSchema),
218
+ });
219
+
41
220
  if (isLoading) {
42
221
  return (
43
222
  <InlineLoading
@@ -48,36 +227,461 @@ const CreateReport: React.FC<CreateReportProps> = ({ model }) => {
48
227
  );
49
228
  }
50
229
 
230
+ const onSubmit = async (report: StockReportSchema) => {
231
+ const reportSystemName = (reportTypes as any).find(
232
+ (reportType) => reportType.name === report.reportName
233
+ )?.systemName;
234
+
235
+ let hideSplash = true;
236
+ try {
237
+ const newLine = "\r\n";
238
+ let parameters = `param.report=${reportSystemName}${newLine}`;
239
+ if (displayFulfillment) {
240
+ parameters += getReportParameter(
241
+ ReportParameter.Fullfillment,
242
+ (report.fullFillment ?? ["All"]).join(","),
243
+ (report.fullFillment ?? ["All"]).join(", "),
244
+ t("stockmanagement.report.edit.fullfillment"),
245
+ newLine
246
+ );
247
+ }
248
+ if (displayPatient) {
249
+ parameters += getReportParameter(
250
+ ReportParameter.Patient,
251
+ report.patientUuid ?? "",
252
+ report.patientName?.trim() ?? "All Patients",
253
+ t("Patients"),
254
+ newLine
255
+ );
256
+ }
257
+ if (displayStockItem) {
258
+ parameters += getReportParameter(
259
+ ReportParameter.StockItem,
260
+ report.stockItemUuid ?? "",
261
+ report.stockItemName?.trim() ?? "All Stock Items",
262
+ t("Stock Item"),
263
+ newLine
264
+ );
265
+ }
266
+ if (displayStockItemCategory) {
267
+ parameters += getReportParameter(
268
+ ReportParameter.StockItemCategory,
269
+ report.stockItemCategoryConceptUuid ?? "",
270
+ report.stockItemCategory?.trim() ?? "All Categories",
271
+ t("Stock Item Category"),
272
+ newLine
273
+ );
274
+ }
275
+ if (displayInventoryGroupBy) {
276
+ parameters += getReportParameter(
277
+ ReportParameter.InventoryGroupBy,
278
+ report.inventoryGroupBy ?? "LocationStockItemBatchNo",
279
+ report.inventoryGroupByName?.trim() ?? "Stock Item Batch Number",
280
+ t("stockmanagement.report.edit.inventorygroupby"),
281
+ newLine
282
+ );
283
+ }
284
+ if (displayLocation) {
285
+ parameters += getReportParameter(
286
+ ReportParameter.Location,
287
+ report.location,
288
+ report.location?.trim() ?? "",
289
+ t("Location"),
290
+ newLine
291
+ );
292
+ if (displayChildLocations) {
293
+ parameters += getReportParameter(
294
+ ReportParameter.ChildLocations,
295
+ report.childLocations ? "true" : "false",
296
+ report.childLocations ? "Yes" : "No",
297
+ t("Include Child Locations"),
298
+ newLine
299
+ );
300
+ }
301
+ }
302
+ if (displayMaxReorderLevelRatio) {
303
+ parameters += getReportParameter(
304
+ ReportParameter.MaxReorderLevelRatio,
305
+ (report.maxReorderLevelRatio ?? 0).toString(),
306
+ (report.maxReorderLevelRatio ?? 0).toString() + "%",
307
+ t("stockmanagement.report.edit.maxreorderlevelratio"),
308
+ newLine
309
+ );
310
+ }
311
+ if (displayStockSource) {
312
+ parameters += getReportParameter(
313
+ ReportParameter.StockSource,
314
+ report.stockSourceUuid ?? "",
315
+ report.stockSource?.trim() ?? "All Sources",
316
+ t("stockmanagement.report.edit.stocksource"),
317
+ newLine
318
+ );
319
+ }
320
+ if (displayStockSourceDestination) {
321
+ parameters += getReportParameter(
322
+ ReportParameter.StockSourceDestination,
323
+ report.stockSourceDestinationUuid ?? "",
324
+ report.stockSourceDestination?.trim() ?? "All Destinations",
325
+ t("stockmanagement.report.edit.stocksourcedestination"),
326
+ newLine
327
+ );
328
+ }
329
+ if (displayMostLeastMoving) {
330
+ parameters += getReportParameter(
331
+ ReportParameter.MostLeastMoving,
332
+ report.mostLeastMoving ?? "MostMoving",
333
+ report.mostLeastMovingName?.trim() ?? "Most Moving",
334
+ t("stockmanagement.report.edit.mostleastmoving"),
335
+ newLine
336
+ );
337
+ }
338
+ if (displayLimit) {
339
+ parameters += getReportParameter(
340
+ ReportParameter.Limit,
341
+ (
342
+ report.limit ??
343
+ getParamDefaultLimit(report.reportSystemName) ??
344
+ 20
345
+ ).toString(),
346
+ (
347
+ report.limit ??
348
+ getParamDefaultLimit(report.reportSystemName) ??
349
+ 20
350
+ ).toString(),
351
+ t(getReportLimitLabel(report.reportSystemName)),
352
+ newLine
353
+ );
354
+ }
355
+ if (displayDate) {
356
+ parameters += getReportParameter(
357
+ ReportParameter.Date,
358
+ JSON.stringify(report.date).replaceAll('"', ""),
359
+ formatDisplayDate(report.date) ?? "",
360
+ t("stockmanagement.report.edit.date"),
361
+ newLine
362
+ );
363
+ }
364
+ if (displayStartDate) {
365
+ parameters += getReportParameter(
366
+ ReportParameter.StartDate,
367
+ JSON.stringify(report.startDate).replaceAll('"', ""),
368
+ formatDisplayDate(report.startDate) ?? "",
369
+ t(getReportStartDateLabel(report.reportSystemName)),
370
+ newLine
371
+ );
372
+ }
373
+ if (displayEndDate) {
374
+ parameters += getReportParameter(
375
+ ReportParameter.EndDate,
376
+ JSON.stringify(report.endDate).replaceAll('"', ""),
377
+ formatDisplayDate(report.endDate) ?? "",
378
+ t(getReportEndDateLabel(report.reportSystemName)),
379
+ newLine
380
+ );
381
+ }
382
+ const newItem = {
383
+ batchJobType: BatchJobTypeReport,
384
+ description: report.reportName,
385
+ parameters: parameters,
386
+ };
387
+ await createBatchJob(newItem)
388
+ .then((response) => {
389
+ closeOverlay();
390
+ if (response.status === 201) {
391
+ showSnackbar({
392
+ title: t("batchJob", "Batch Job"),
393
+ subtitle: t("BatchJobSuccess", "Batch job created successfully"),
394
+ kind: "success",
395
+ });
396
+ } else {
397
+ showSnackbar({
398
+ title: t("BatchJobErrorTitle", "Batch job"),
399
+ subtitle: t("batchJobErrorMessage", "Error creating batch job"),
400
+ kind: "error",
401
+ });
402
+ }
403
+ })
404
+ .catch((error) => {
405
+ showSnackbar({
406
+ title: t("BatchJobErrorTitle", "Batch job"),
407
+ subtitle: t("batchJobErrorMessage", "Error creating batch job"),
408
+ kind: "error",
409
+ });
410
+ });
411
+ hideSplash = false;
412
+ } finally {
413
+ if (hideSplash) {
414
+ // setShowSplash(false);
415
+ }
416
+ }
417
+ };
418
+ const onError = (error: any) => {
419
+ console.error(error);
420
+ };
421
+ const getReportParameter = (
422
+ name: string,
423
+ value: string,
424
+ valueDescription: string,
425
+ description: string,
426
+ newLine: string
427
+ ): string => {
428
+ return `param.${name}.value=${value}${newLine}param.${name}.value.desc=${valueDescription}${newLine}param.${name}.description=${description}${newLine}`;
429
+ };
430
+
51
431
  return (
52
- <div>
53
- <Form>
54
- <ModalHeader />
55
- <ModalBody>
56
- <section className={styles.section}>
57
- <div>
58
- <>
59
- <span className={styles.subTitle}>{t("report", "Report")}</span>
432
+ <Form onSubmit={handleSubmit(onSubmit, onError)}>
433
+ <div className={styles.reportContainer}>
434
+ <>
435
+ <span>{t("reportName", "Report")}</span>
436
+ <Controller
437
+ control={control}
438
+ name="reportName"
439
+ render={({ field: { onChange } }) => (
440
+ <ComboBox
441
+ id="report"
442
+ size="md"
443
+ labelText={t("reportName", "Report")}
444
+ items={reportTypes}
445
+ itemToString={(item) => `${item?.name ?? item?.name ?? ""}`}
446
+ placeholder="Filter..."
447
+ onChange={({ selectedItem }) => {
448
+ onChange(selectedItem.name);
449
+ handleReportNameChange(selectedItem.name);
450
+ }}
451
+ />
452
+ )}
453
+ />
454
+ </>
455
+
456
+ {displayStockItemCategory && (
457
+ <>
458
+ <span>{t("stockItemCategory", "Stock Item Category")}</span>
459
+ <Controller
460
+ control={control}
461
+ name="stockReportItemCategory"
462
+ render={({ field: { onChange } }) => (
60
463
  <ComboBox
61
- id="report"
464
+ id="stockReportItem"
62
465
  size="md"
63
- labelText={t("reportName", "Report")}
64
- items={reportTypes ?? []}
65
- itemToString={(item) => `${item?.name ?? item?.name ?? ""}`}
466
+ labelText={t("stockItemCategory", "Stock Item Category")}
467
+ items={stockItemCategories}
468
+ onChange={({ selectedItem }) => {
469
+ onChange(selectedItem.uuid);
470
+ }}
471
+ itemToString={(item) =>
472
+ item && item?.display ? `${item?.display}` : ""
473
+ }
66
474
  placeholder="Filter..."
67
475
  />
68
- </>
69
- </div>
70
- </section>
71
- <br />
72
- </ModalBody>
73
- <ModalFooter>
74
- <Button kind="secondary" onClick={closeOverlay}>
75
- {t("cancel", "Cancel")}
76
- </Button>
77
- <Button type="submit">{t("continue", "Continue")}</Button>
78
- </ModalFooter>
79
- </Form>
80
- </div>
476
+ )}
477
+ />
478
+ </>
479
+ )}
480
+ {displayStartDate && (
481
+ <Controller
482
+ control={control}
483
+ name="startDate"
484
+ render={({ field: { onChange, value } }) => (
485
+ <DatePicker
486
+ datePickerType="single"
487
+ maxDate={formatForDatePicker(today())}
488
+ locale="en"
489
+ dateFormat={DATE_PICKER_CONTROL_FORMAT}
490
+ onChange={onChange}
491
+ value={value}
492
+ >
493
+ <DatePickerInput
494
+ id="startDate"
495
+ name="startDate"
496
+ placeholder={DATE_PICKER_FORMAT}
497
+ labelText={t("startDate", "Start Date")}
498
+ defaultValue=""
499
+ invalid={errors?.startDate?.message}
500
+ invalidText={errors?.startDate?.message}
501
+ />
502
+ </DatePicker>
503
+ )}
504
+ />
505
+ )}
506
+ {displayEndDate && (
507
+ <Controller
508
+ control={control}
509
+ name="endDate"
510
+ render={({ field: { onChange, value } }) => (
511
+ <DatePicker
512
+ datePickerType="single"
513
+ maxDate={formatForDatePicker(today())}
514
+ locale="en"
515
+ dateFormat={DATE_PICKER_CONTROL_FORMAT}
516
+ onChange={onChange}
517
+ value={value}
518
+ >
519
+ <DatePickerInput
520
+ id="endDate"
521
+ name="endDate"
522
+ placeholder={DATE_PICKER_FORMAT}
523
+ labelText={t("endDate", "End Date")}
524
+ defaultValue=""
525
+ invalid={errors?.endDate?.message}
526
+ invalidText={errors?.endDate?.message}
527
+ />
528
+ </DatePicker>
529
+ )}
530
+ />
531
+ )}
532
+ {displayLocation && (
533
+ <Select
534
+ name="location"
535
+ className="select-field"
536
+ labelText={t("location", "Location")}
537
+ id="location"
538
+ onChange={(e) => setValue("location", e.target.value)}
539
+ defaultValue=""
540
+ >
541
+ <SelectItem
542
+ disabled
543
+ hidden
544
+ value=""
545
+ text={t("Choose a location")}
546
+ />
547
+ {(stockLocations ?? [])?.map((loc) => {
548
+ return <SelectItem key={loc.id} value={loc.id} text={loc.name} />;
549
+ })}
550
+ </Select>
551
+ )}
552
+ {displayChildLocations && (
553
+ <Controller
554
+ control={control}
555
+ name="childLocations"
556
+ render={({ field: { onChange, value } }) => (
557
+ <Checkbox
558
+ id="childLocations"
559
+ onChange={onChange}
560
+ value={value}
561
+ labelText={t(
562
+ "IncludeChildLocations",
563
+ "Include Child Locations"
564
+ )}
565
+ />
566
+ )}
567
+ />
568
+ )}
569
+ {displayMostLeastMoving && (
570
+ <Controller
571
+ control={control}
572
+ name="mostLeastMoving"
573
+ render={({ field: { onChange, value } }) => (
574
+ <RadioButtonGroup
575
+ name="mostLeastMoving"
576
+ legendText={t("rank", "Rank")}
577
+ onChange={onChange}
578
+ value={value}
579
+ >
580
+ <RadioButton
581
+ value="MostMoving"
582
+ id="mostLeastMovingMost"
583
+ labelText={t("mostMoving", "Most Moving")}
584
+ />
585
+ <RadioButton
586
+ value="LeastMoving"
587
+ id="mostLeastMovingLeast"
588
+ labelText={t("LeastMoving", "Least Moving")}
589
+ />
590
+ </RadioButtonGroup>
591
+ )}
592
+ />
593
+ )}
594
+ {displayLimit && (
595
+ <Controller
596
+ control={control}
597
+ name="limit"
598
+ render={({ field: { onChange, value } }) => (
599
+ <NumberInput
600
+ id="limitTop"
601
+ allowEmpty={true}
602
+ value={value}
603
+ onchange={onChange}
604
+ label={t("limit", "Limit")}
605
+ defaultValue={20}
606
+ />
607
+ )}
608
+ />
609
+ )}
610
+ {displayFulfillment && (
611
+ <div style={{ display: "flex", flexDirection: "row", gap: "0 1rem" }}>
612
+ <Controller
613
+ control={control}
614
+ name="fullFillment"
615
+ render={({ field: { onChange, value } }) => (
616
+ <>
617
+ <Checkbox
618
+ id="allFulfillment"
619
+ checked={value?.includes("All")}
620
+ onChange={(event) => {
621
+ const isChecked = event.target.checked;
622
+ if (isChecked) {
623
+ onChange(["All"]);
624
+ } else {
625
+ onChange(value.filter((item) => item !== "All"));
626
+ }
627
+ }}
628
+ labelText={t("all", "All")}
629
+ />
630
+ <Checkbox
631
+ id="fullFulfillment"
632
+ checked={value?.includes("Full")}
633
+ onChange={(event) => {
634
+ const isChecked = event.target.checked;
635
+ onChange(
636
+ isChecked
637
+ ? [...value.filter((item) => item !== "All"), "Full"]
638
+ : value.filter((item) => item !== "Full")
639
+ );
640
+ }}
641
+ labelText={t("fullFulfillment", "Full Fulfillment")}
642
+ />
643
+ <Checkbox
644
+ id="partialFulfillment"
645
+ checked={value?.includes("Partial")}
646
+ onChange={(event) => {
647
+ const isChecked = event.target.checked;
648
+ onChange(
649
+ isChecked
650
+ ? [
651
+ ...value.filter((item) => item !== "All"),
652
+ "Partial",
653
+ ]
654
+ : value.filter((item) => item !== "Partial")
655
+ );
656
+ }}
657
+ labelText={t("partialFulfillment", "Partial Fulfillment")}
658
+ />
659
+ <Checkbox
660
+ id="noneFulfillment"
661
+ checked={value?.includes("None")}
662
+ onChange={(event) => {
663
+ const isChecked = event.target.checked;
664
+ onChange(
665
+ isChecked
666
+ ? [...value.filter((item) => item !== "All"), "None"]
667
+ : value.filter((item) => item !== "None")
668
+ );
669
+ }}
670
+ labelText={t("noneFulfillment", "Non Fulfillment")}
671
+ />
672
+ </>
673
+ )}
674
+ />
675
+ </div>
676
+ )}
677
+ </div>
678
+ <div className={styles.reportButton}>
679
+ <Button kind="secondary" onClick={closeOverlay}>
680
+ {t("cancel", "Cancel")}
681
+ </Button>
682
+ <Button type="submit">{t("continue", "Continue")}</Button>
683
+ </div>
684
+ </Form>
81
685
  );
82
686
  };
83
687