@openmrs/esm-stock-management-app 1.0.1-pre.330 → 1.0.1-pre.334

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from "react";
1
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
2
2
  import { useStockOperationPages } from "./stock-operations-table.resource";
3
3
  import { ResourceRepresentation } from "../core/api/api";
4
4
  import {
@@ -26,6 +26,8 @@ import {
26
26
  StructuredListBody,
27
27
  OverflowMenu,
28
28
  OverflowMenuItem,
29
+ DatePickerInput,
30
+ DatePicker,
29
31
  } from "@carbon/react";
30
32
  import { ArrowRight } from "@carbon/react/icons";
31
33
  import { formatDisplayDate } from "../core/utils/datetimeUtils";
@@ -36,7 +38,7 @@ import {
36
38
  StockOperationStatusRejected,
37
39
  StockOperationStatusReturned,
38
40
  } from "../core/api/types/stockOperation/StockOperationStatus";
39
- import { isDesktop, showModal } from "@openmrs/esm-framework";
41
+ import { isDesktop, showModal, useConfig } from "@openmrs/esm-framework";
40
42
  import StockOperationTypesSelector from "./stock-operation-types-selector/stock-operation-types-selector.component";
41
43
  import { launchAddOrEditDialog } from "./stock-operation.utils";
42
44
  import { initialStockOperationValue } from "../core/utils/utils";
@@ -44,6 +46,12 @@ import { StockOperationType } from "../core/api/types/stockOperation/StockOperat
44
46
  import { useTranslation } from "react-i18next";
45
47
  import EditStockOperationActionMenu from "./edit-stock-operation/edit-stock-operation-action-menu.component";
46
48
  import { handleMutate } from "./swr-revalidation";
49
+ import StockOperationsFilters from "./stock-operations-filters.component";
50
+ import {
51
+ DATE_PICKER_CONTROL_FORMAT,
52
+ DATE_PICKER_FORMAT,
53
+ StockFilters,
54
+ } from "../constants";
47
55
 
48
56
  interface StockOperationsTableProps {
49
57
  status?: string;
@@ -93,6 +101,15 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
93
101
  totalCount: true,
94
102
  });
95
103
 
104
+ const [filteredItems, setFilteredItems] = useState(items);
105
+ const [selectedFromDate, setSelectedFromDate] = useState(null);
106
+ const [selectedToDate, setSelectedToDate] = useState(null);
107
+ const [selectedSources, setSelectedSources] = useState<string[]>([]);
108
+ const [selectedStatus, setSelectedStatus] = useState<string[]>([]);
109
+ const [selectedOperations, setSelectedOperations] = useState<string[]>([]);
110
+
111
+ const config = useConfig();
112
+
96
113
  let operations: StockOperationType[] | null | undefined;
97
114
  const handleOnComplete = () => {
98
115
  const dispose = showModal("stock-operation-dialog", {
@@ -103,15 +120,89 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
103
120
  });
104
121
  handleMutate("ws/rest/v1/stockmanagement/stockoperation");
105
122
  };
123
+
124
+ useEffect(() => {
125
+ filterItems();
126
+ }, [
127
+ selectedFromDate,
128
+ selectedToDate,
129
+ selectedSources,
130
+ selectedStatus,
131
+ selectedOperations,
132
+ currentPage,
133
+ currentPageSize,
134
+ ]);
135
+
136
+ const handleOnFilterChange = useCallback((selectedItems, filterType) => {
137
+ if (filterType === StockFilters.SOURCES) {
138
+ setSelectedSources(selectedItems);
139
+ } else if (filterType === StockFilters.OPERATION) {
140
+ setSelectedOperations(selectedItems);
141
+ } else {
142
+ setSelectedStatus(selectedItems);
143
+ }
144
+ }, []);
145
+
146
+ const handleDateFilterChange = ([startDate, endDate]) => {
147
+ if (startDate) {
148
+ setSelectedFromDate(startDate);
149
+ if (selectedToDate && startDate && selectedToDate < startDate) {
150
+ setSelectedToDate(startDate);
151
+ }
152
+ }
153
+ if (endDate) {
154
+ setSelectedToDate(endDate);
155
+ if (selectedFromDate && endDate && selectedFromDate > endDate) {
156
+ setSelectedFromDate(endDate);
157
+ }
158
+ }
159
+ };
160
+
161
+ const filterItems = () => {
162
+ let filtered = items;
163
+
164
+ if (selectedSources.length > 0) {
165
+ filtered = filtered.filter((row) =>
166
+ selectedSources.includes(row.sourceName)
167
+ );
168
+ }
169
+ if (selectedOperations.length > 0) {
170
+ filtered = filtered.filter((row) =>
171
+ selectedOperations.includes(row.operationTypeName)
172
+ );
173
+ }
174
+ if (selectedStatus.length > 0) {
175
+ filtered = filtered.filter((row) => selectedStatus.includes(row.status));
176
+ }
177
+ if (selectedFromDate && selectedToDate) {
178
+ filtered = filtered.filter((row) => {
179
+ const itemDate = new Date(row.operationDate);
180
+ return itemDate >= selectedFromDate && itemDate <= selectedToDate;
181
+ });
182
+ } else if (selectedFromDate) {
183
+ filtered = filtered.filter((row) => {
184
+ const itemDate = new Date(row.operationDate);
185
+ return itemDate >= selectedFromDate;
186
+ });
187
+ } else if (selectedToDate) {
188
+ filtered = filtered.filter((row) => {
189
+ const itemDate = new Date(row.operationDate);
190
+ return itemDate <= selectedToDate;
191
+ });
192
+ }
193
+
194
+ setFilteredItems(filtered);
195
+ };
196
+
106
197
  const tableRows = useMemo(() => {
107
- return items?.map((stockOperation, index) => ({
198
+ return filteredItems?.map((stockOperation, index) => ({
108
199
  ...stockOperation,
109
200
  id: stockOperation?.uuid,
110
201
  key: `key-${stockOperation?.uuid}`,
111
202
  operationTypeName: `${stockOperation?.operationTypeName}`,
112
203
  operationNumber: (
113
204
  <EditStockOperationActionMenu
114
- model={items[index]}
205
+ model={filteredItems[index]}
115
206
  operations={operations}
116
207
  />
117
208
  ),
@@ -244,7 +335,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
244
335
  itemText="Edit"
245
336
  onClick={() => {
246
337
  launchAddOrEditDialog(
247
- items[index],
338
+ filteredItems[index],
248
339
  true,
249
340
  operation,
250
341
  operations,
@@ -255,7 +346,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
255
346
  </OverflowMenu>
256
347
  ),
257
348
  }));
258
- }, [handleOnComplete, items, operation, operations]);
349
+ }, [handleOnComplete, filteredItems, operation, operations]);
259
350
 
260
351
  if (isLoading) {
261
352
  return (
@@ -305,6 +396,37 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
305
396
  placeholder="Filter Table"
306
397
  size="sm"
307
398
  />
399
+ <div className={styles.filterContainer}>
400
+ <DatePicker
401
+ className={styles.dateAlign}
402
+ datePickerType="range"
403
+ dateFormat={DATE_PICKER_CONTROL_FORMAT}
404
+ value={[selectedFromDate, selectedToDate]}
405
+ onChange={([startDate, endDate]) => {
406
+ handleDateFilterChange([startDate, endDate]);
407
+ }}
408
+ >
409
+ <DatePickerInput placeholder={DATE_PICKER_FORMAT} />
410
+ <DatePickerInput placeholder={DATE_PICKER_FORMAT} />
411
+ </DatePicker>
412
+
413
+ <StockOperationsFilters
414
+ conceptUuid={config.stockSourceTypeUUID}
415
+ filterName={StockFilters.SOURCES}
416
+ onFilterChange={handleOnFilterChange}
417
+ />
418
+
419
+ <StockOperationsFilters
420
+ filterName={StockFilters.STATUS}
421
+ onFilterChange={handleOnFilterChange}
422
+ />
423
+
424
+ <StockOperationsFilters
425
+ filterName={StockFilters.OPERATION}
426
+ onFilterChange={handleOnFilterChange}
427
+ />
428
+ </div>
429
+
308
430
  <StockOperationTypesSelector
309
431
  onOperationTypeSelected={(operation) => {
310
432
  launchAddOrEditDialog(
@@ -383,39 +505,47 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
383
505
  <StructuredListBody>
384
506
  <StructuredListRow>
385
507
  <StructuredListCell noWrap>
386
- {items[index]?.dateCreated
387
- ? formatDisplayDate(items[index]?.dateCreated)
508
+ {filteredItems[index]?.dateCreated
509
+ ? formatDisplayDate(
510
+ filteredItems[index]?.dateCreated
511
+ )
388
512
  : ""}
389
513
  &nbsp;
390
- {items[index]?.dateCreated ? "By" : ""}
514
+ {filteredItems[index]?.dateCreated ? "By" : ""}
391
515
  &nbsp;
392
- {items[index]?.dateCreated
393
- ? items[index]?.creatorFamilyName
516
+ {filteredItems[index]?.dateCreated
517
+ ? filteredItems[index]?.creatorFamilyName
394
518
  : ""}
395
519
  </StructuredListCell>
396
520
  <StructuredListCell>
397
- {items[index]?.completedDate
521
+ {filteredItems[index]?.completedDate
398
522
  ? formatDisplayDate(
399
- items[index]?.completedDate
523
+ filteredItems[index]?.completedDate
400
524
  )
401
525
  : ""}
402
526
  &nbsp;
403
- {items[index]?.completedDate ? "By" : ""}
527
+ {filteredItems[index]?.completedDate
528
+ ? "By"
529
+ : ""}
404
530
  &nbsp;
405
- {items[index]?.completedDate
406
- ? items[index]?.creatorFamilyName
531
+ {filteredItems[index]?.completedDate
532
+ ? filteredItems[index]?.creatorFamilyName
407
533
  : ""}
408
534
  </StructuredListCell>
409
535
  <StructuredListCell>
410
- {items[index]?.stockOperationItems
411
- ? items[index].stockOperationItems?.map(
536
+ {filteredItems[index]?.stockOperationItems
537
+ ? filteredItems[
538
+ index
539
+ ].stockOperationItems?.map(
412
540
  (item) => item.batchNo
413
541
  )[0]
414
542
  : ""}
415
543
  </StructuredListCell>
416
544
  <StructuredListCell>
417
- {items[index]?.stockOperationItems
418
- ? items[index].stockOperationItems?.map(
545
+ {filteredItems[index]?.stockOperationItems
546
+ ? filteredItems[
547
+ index
548
+ ].stockOperationItems?.map(
419
549
  (item) => item.quantity
420
550
  )[0]
421
551
  : ""}
@@ -423,55 +553,61 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
423
553
  </StructuredListRow>
424
554
  <StructuredListRow>
425
555
  <StructuredListCell noWrap>
426
- {items[index]?.stockOperationItems.map(
556
+ {filteredItems[index]?.stockOperationItems.map(
427
557
  (item) => item.quantity
428
558
  )[1]
429
- ? formatDisplayDate(items[index]?.dateCreated)
559
+ ? formatDisplayDate(
560
+ filteredItems[index]?.dateCreated
561
+ )
430
562
  : ""}
431
563
  &nbsp;
432
- {items[index]?.stockOperationItems.map(
564
+ {filteredItems[index]?.stockOperationItems.map(
433
565
  (item) => item.quantity
434
566
  )[1]
435
567
  ? "By"
436
568
  : ""}
437
569
  &nbsp;
438
- {items[index]?.stockOperationItems.map(
570
+ {filteredItems[index]?.stockOperationItems.map(
439
571
  (item) => item.quantity
440
572
  )[1]
441
- ? items[index]?.creatorFamilyName
573
+ ? filteredItems[index]?.creatorFamilyName
442
574
  : ""}
443
575
  </StructuredListCell>
444
576
  <StructuredListCell>
445
- {items[index]?.stockOperationItems.map(
577
+ {filteredItems[index]?.stockOperationItems.map(
446
578
  (item) => item.quantity
447
579
  )[1]
448
580
  ? formatDisplayDate(
449
- items[index]?.completedDate
581
+ filteredItems[index]?.completedDate
450
582
  )
451
583
  : ""}
452
584
  &nbsp;
453
- {items[index]?.stockOperationItems.map(
585
+ {filteredItems[index]?.stockOperationItems.map(
454
586
  (item) => item.quantity
455
- )[1] && items[index]?.completedDate
587
+ )[1] && filteredItems[index]?.completedDate
456
588
  ? "By"
457
589
  : ""}
458
590
  &nbsp;
459
- {items[index]?.stockOperationItems.map(
591
+ {filteredItems[index]?.stockOperationItems.map(
460
592
  (item) => item.quantity
461
- )[1] && items[index]?.completedDate
593
+ )[1] && filteredItems[index]?.completedDate
462
594
  ? items[index]?.creatorFamilyName
463
595
  : ""}
464
596
  </StructuredListCell>
465
597
  <StructuredListCell>
466
- {items[index]?.stockOperationItems
467
- ? items[index].stockOperationItems?.map(
598
+ {filteredItems[index]?.stockOperationItems
599
+ ? filteredItems[
600
+ index
601
+ ].stockOperationItems?.map(
468
602
  (item) => item.batchNo
469
603
  )[1]
470
604
  : ""}
471
605
  </StructuredListCell>
472
606
  <StructuredListCell>
473
- {items[index]?.stockOperationItems
474
- ? items[index].stockOperationItems?.map(
607
+ {filteredItems[index]?.stockOperationItems
608
+ ? filteredItems[
609
+ index
610
+ ].stockOperationItems?.map(
475
611
  (item) => item.quantity
476
612
  )[1]
477
613
  : ""}