@openmrs/esm-stock-management-app 1.0.1-pre.575 → 1.0.1-pre.586
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/769.js +1 -1
- package/dist/769.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +6 -6
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/config-schema.ts +1 -1
- package/src/core/api/types/stockItem/StockItemInventory.ts +1 -0
- package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +5 -0
- package/src/stock-operations/add-stock-operation/add-stock-operation.component.tsx +7 -5
- package/src/stock-operations/add-stock-operation/add-stock-operation.utils.tsx +23 -27
- package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +350 -223
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.component.tsx +151 -25
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +2 -0
- package/src/stock-operations/batch-no-selector/batch-no-selector.component.tsx +8 -4
- package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +26 -51
- package/src/stock-operations/party-selector/party-selector.component.tsx +35 -30
- package/src/stock-operations/stock-item-selector/stock-item-selector.component.tsx +1 -1
- package/src/stock-operations/stock-operation.utils.tsx +2 -13
- package/src/stock-operations/stock-operations-table.component.tsx +29 -20
- package/src/stock-operations/stock-operations.resource.ts +1 -1
@@ -12,6 +12,7 @@ import {
|
|
12
12
|
} from "@carbon/react";
|
13
13
|
import { TrashCan } from "@carbon/react/icons";
|
14
14
|
import { StockOperationItemFormData } from "../validation-schema";
|
15
|
+
import QtyUomSelector from "../qty-uom-selector/qty-uom-selector.component";
|
15
16
|
import StockItemSelector from "../stock-item-selector/stock-item-selector.component";
|
16
17
|
import {
|
17
18
|
Control,
|
@@ -33,8 +34,11 @@ import { StockItemPackagingUOMDTO } from "../../core/api/types/stockItem/StockIt
|
|
33
34
|
import { StockItemInventory } from "../../core/api/types/stockItem/StockItemInventory";
|
34
35
|
import { StockOperationItemDTO } from "../../core/api/types/stockOperation/StockOperationItemDTO";
|
35
36
|
import { StockItemDTO } from "../../core/api/types/stockItem/StockItem";
|
36
|
-
import QtyUomSelector from "../qty-uom-selector/qty-uom-selector.component";
|
37
37
|
import BatchNoSelector from "../batch-no-selector/batch-no-selector.component";
|
38
|
+
import {
|
39
|
+
getStockItemInventory,
|
40
|
+
StockItemInventoryFilter,
|
41
|
+
} from "../stock-operations.resource";
|
38
42
|
|
39
43
|
import styles from "./stock-items-addition-row.scss";
|
40
44
|
|
@@ -46,6 +50,8 @@ interface StockItemsAdditionRowProps {
|
|
46
50
|
requiresBatchUuid?: boolean;
|
47
51
|
canUpdateBatchInformation?: boolean;
|
48
52
|
canCapturePurchasePrice?: boolean;
|
53
|
+
stockOperationUuid?: string;
|
54
|
+
locationUuid?: string;
|
49
55
|
batchNos?: {
|
50
56
|
[key: string]: StockBatchDTO[];
|
51
57
|
};
|
@@ -86,19 +92,26 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
86
92
|
requiresBatchUuid,
|
87
93
|
canUpdateBatchInformation,
|
88
94
|
canCapturePurchasePrice,
|
89
|
-
batchBalance,
|
90
95
|
control,
|
91
96
|
setValue,
|
92
97
|
errors,
|
93
98
|
remove,
|
94
99
|
fields,
|
100
|
+
stockOperationUuid,
|
101
|
+
locationUuid,
|
95
102
|
}) => {
|
96
103
|
const [stockItemUuid, setStockItemUuid] = useState<
|
97
104
|
string | null | undefined
|
98
105
|
>();
|
99
|
-
|
100
|
-
|
101
|
-
|
106
|
+
|
107
|
+
const [batchBalances, setBatchBalances] = useState<{ [key: number]: any }>(
|
108
|
+
{}
|
109
|
+
);
|
110
|
+
const [stockItemExpiries, setStockItemExpiries] = useState<{
|
111
|
+
[key: number]: Date | null | undefined;
|
112
|
+
}>({});
|
113
|
+
|
114
|
+
const [qtyInputErrors, setQtyErrors] = useState({});
|
102
115
|
|
103
116
|
const handleStockItemChange = (index: number, data?: StockItemDTO) => {
|
104
117
|
if (!data) return;
|
@@ -125,16 +138,99 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
125
138
|
item.stockItemPackagingUOMName = null;
|
126
139
|
|
127
140
|
item.stockBatchUuid = null;
|
128
|
-
|
129
|
-
|
130
|
-
}
|
141
|
+
|
142
|
+
setValue(`stockItems.${index}.stockItemUuid`, item?.stockItemUuid);
|
143
|
+
setValue(`stockItems.${index}.stockItemName`, item?.stockItemName);
|
144
|
+
}
|
145
|
+
};
|
146
|
+
|
147
|
+
const handleFetchBatchBalance = ({
|
148
|
+
stockItemUuid,
|
149
|
+
stockBatchUuid,
|
150
|
+
index,
|
151
|
+
excludeExpired = true,
|
152
|
+
}) => {
|
153
|
+
const filters: StockItemInventoryFilter = {
|
154
|
+
stockBatchUuid,
|
155
|
+
stockItemUuid,
|
156
|
+
stockOperationUuid,
|
157
|
+
excludeExpired,
|
158
|
+
locationUuid,
|
159
|
+
groupBy: "LocationStockItemBatchNo",
|
160
|
+
};
|
161
|
+
if (stockBatchUuid) {
|
162
|
+
getStockItemInventory(filters)
|
163
|
+
.then(({ data }) => data)
|
164
|
+
.then((res: any) => {
|
165
|
+
if ((res as any).error) {
|
166
|
+
return;
|
167
|
+
}
|
168
|
+
const inventory: StockItemInventory = (
|
169
|
+
res?.results as StockItemInventory[]
|
170
|
+
)?.[0];
|
171
|
+
|
172
|
+
const newBatchBalance = inventory
|
173
|
+
? {
|
174
|
+
quantity: inventory.quantity,
|
175
|
+
quantityUoM: inventory.quantityUoM,
|
176
|
+
quantityUoMUuid: inventory.quantityUoMUuid,
|
177
|
+
}
|
178
|
+
: { quantity: 0, quantityUoM: null };
|
179
|
+
|
180
|
+
setBatchBalances((prevBalances) => ({
|
181
|
+
...prevBalances,
|
182
|
+
[index]: newBatchBalance,
|
183
|
+
}));
|
184
|
+
|
185
|
+
setValue(
|
186
|
+
`stockItems.${index}.stockItemPackagingUOMUuid`,
|
187
|
+
inventory.quantityUoMUuid
|
188
|
+
);
|
189
|
+
|
190
|
+
setValue(
|
191
|
+
`stockItems.${index}.stockItemPackagingUOMName`,
|
192
|
+
inventory.quantityUoM
|
193
|
+
);
|
194
|
+
})
|
195
|
+
.catch((error: any) => {
|
196
|
+
if ((error as any).error) {
|
197
|
+
return;
|
198
|
+
}
|
199
|
+
return;
|
200
|
+
});
|
201
|
+
} else {
|
202
|
+
setBatchBalances((prevBalances) => ({
|
203
|
+
...prevBalances,
|
204
|
+
[index]: null,
|
205
|
+
}));
|
131
206
|
}
|
132
207
|
};
|
133
208
|
|
209
|
+
const handleInputChange = (e: any, index: number) => {
|
210
|
+
const inputValue = e?.target?.value;
|
211
|
+
const maxQuantity = Number(batchBalances[index]?.quantity);
|
212
|
+
|
213
|
+
if (inputValue > maxQuantity) {
|
214
|
+
setQtyErrors((prevErrors) => ({
|
215
|
+
...prevErrors,
|
216
|
+
[`stockItems.${index}.quantity`]: `Quantity cannot exceed ${maxQuantity}`,
|
217
|
+
}));
|
218
|
+
} else {
|
219
|
+
setQtyErrors((prevErrors) => {
|
220
|
+
const newErrors = { ...prevErrors };
|
221
|
+
delete newErrors[`stockItems.${index}.quantity`];
|
222
|
+
return newErrors;
|
223
|
+
});
|
224
|
+
}
|
225
|
+
setValue(`stockItems.${index}.quantity`, inputValue);
|
226
|
+
};
|
227
|
+
|
134
228
|
return (
|
135
229
|
<>
|
136
230
|
{fields?.map((row, index) => {
|
137
231
|
const stockItemId = `stockItems.${index}.stockItemUuid`;
|
232
|
+
const currentBatchBalance = batchBalances[index];
|
233
|
+
const currentStockItemExpiry = stockItemExpiries[index];
|
138
234
|
return (
|
139
235
|
<TableRow
|
140
236
|
className={isDesktop ? styles.desktopRow : styles.tabletRow}
|
@@ -198,11 +294,27 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
198
294
|
`stockItems.${index}.batchNo`,
|
199
295
|
item?.batchNo ?? ""
|
200
296
|
);
|
297
|
+
|
201
298
|
setValue(
|
202
299
|
`stockItems.${index}.expiration`,
|
203
300
|
item?.expiration
|
204
301
|
);
|
205
|
-
|
302
|
+
|
303
|
+
setValue(
|
304
|
+
`stockItems.${index}.hasExpiration`,
|
305
|
+
item?.expiration ? true : false
|
306
|
+
);
|
307
|
+
|
308
|
+
setStockItemExpiries((prevExpiries) => ({
|
309
|
+
...prevExpiries,
|
310
|
+
[index]: item?.expiration ?? null,
|
311
|
+
}));
|
312
|
+
|
313
|
+
handleFetchBatchBalance({
|
314
|
+
stockItemUuid: row?.stockItemUuid,
|
315
|
+
stockBatchUuid: item?.uuid,
|
316
|
+
index,
|
317
|
+
});
|
206
318
|
}}
|
207
319
|
placeholder={"Filter..."}
|
208
320
|
invalid={!!errors?.stockItems?.[index]?.stockBatchUuid}
|
@@ -243,7 +355,9 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
243
355
|
id={`expiration-input-${row.uuid}`}
|
244
356
|
name="operationDate"
|
245
357
|
placeholder={DATE_PICKER_FORMAT}
|
246
|
-
defaultValue={formatForDatePicker(
|
358
|
+
defaultValue={formatForDatePicker(
|
359
|
+
currentStockItemExpiry || row?.expiration
|
360
|
+
)}
|
247
361
|
invalid={!!errors?.stockItems?.[index]?.expiration}
|
248
362
|
/>
|
249
363
|
</DatePicker>
|
@@ -254,7 +368,7 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
254
368
|
) &&
|
255
369
|
!canEdit) ||
|
256
370
|
requiresBatchUuid) &&
|
257
|
-
formatForDatePicker(row.expiration)}
|
371
|
+
formatForDatePicker(currentStockItemExpiry || row.expiration)}
|
258
372
|
</TableCell>
|
259
373
|
)}
|
260
374
|
<TableCell>
|
@@ -263,33 +377,38 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
263
377
|
className="small-placeholder-text"
|
264
378
|
size="sm"
|
265
379
|
id={`qty-${row?.uuid}`}
|
380
|
+
min={1}
|
381
|
+
max={Number(currentBatchBalance?.quantity)}
|
266
382
|
hideSteppers={true}
|
267
383
|
allowEmpty={true}
|
268
|
-
onChange={(e: any) =>
|
269
|
-
setValue(`stockItems.${index}.quantity`, e?.target?.value)
|
270
|
-
}
|
384
|
+
onChange={(e: any) => handleInputChange(e, index)}
|
271
385
|
value={row?.quantity ?? ""}
|
272
|
-
invalidText={
|
386
|
+
invalidText={
|
387
|
+
errors?.stockItems?.[index]?.quantity?.message ||
|
388
|
+
qtyInputErrors[`stockItems.${index}.quantity`]
|
389
|
+
}
|
273
390
|
placeholder={
|
274
391
|
requiresBatchUuid &&
|
275
392
|
!requiresActualBatchInformation &&
|
276
|
-
|
393
|
+
currentBatchBalance
|
277
394
|
? `Bal: ${
|
278
|
-
|
279
|
-
|
280
|
-
]?.quantity?.toLocaleString() ?? ""
|
281
|
-
} ${
|
282
|
-
batchBalance[row?.stockBatchUuid]?.quantityUoM ?? ""
|
283
|
-
}`
|
395
|
+
currentBatchBalance?.quantity?.toLocaleString() ?? ""
|
396
|
+
} ${currentBatchBalance?.quantityUoM ?? ""}`
|
284
397
|
: ""
|
285
398
|
}
|
286
|
-
invalid={
|
399
|
+
invalid={
|
400
|
+
!!errors?.stockItems?.[index]?.quantity ||
|
401
|
+
!!qtyInputErrors[`stockItems.${index}.quantity`]
|
402
|
+
}
|
287
403
|
/>
|
288
404
|
)}
|
289
405
|
{!canEdit && row?.quantity?.toLocaleString()}
|
290
406
|
</TableCell>
|
407
|
+
{/* Qty UoM Cell (Non-editable) */}
|
291
408
|
<TableCell>
|
292
|
-
{canEdit &&
|
409
|
+
{canEdit &&
|
410
|
+
row?.uuid.startsWith("new-item") &&
|
411
|
+
!currentBatchBalance?.quantityUoM ? (
|
293
412
|
<QtyUomSelector
|
294
413
|
stockItemUuid={row.stockItemUuid}
|
295
414
|
onStockPackageChanged={(selectedItem) => {
|
@@ -306,10 +425,15 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
306
425
|
controllerName={`stockItems.${index}.stockItemPackagingUOMUuid`}
|
307
426
|
name={`stockItems.${index}.stockItemPackagingUOMUuid`}
|
308
427
|
/>
|
428
|
+
) : currentBatchBalance?.quantityUoM ? (
|
429
|
+
currentBatchBalance.quantityUoM
|
430
|
+
) : (
|
431
|
+
row?.stockItemPackagingUOMName
|
309
432
|
)}
|
433
|
+
|
310
434
|
{!canEdit && row?.stockItemPackagingUOMName}
|
311
435
|
</TableCell>
|
312
|
-
{canCapturePurchasePrice
|
436
|
+
{canCapturePurchasePrice ? (
|
313
437
|
<TableCell>
|
314
438
|
{canEdit && (
|
315
439
|
<NumberInput
|
@@ -330,6 +454,8 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
|
|
330
454
|
)}
|
331
455
|
{!canEdit && row?.purchasePrice?.toLocaleString()}
|
332
456
|
</TableCell>
|
457
|
+
) : (
|
458
|
+
setValue(`stockItems.${index}.purchasePrice`, null)
|
333
459
|
)}
|
334
460
|
{canEdit && (
|
335
461
|
<TableCell>
|
@@ -241,6 +241,8 @@ const StockItemsAddition: React.FC<StockItemsAdditionProps> = ({
|
|
241
241
|
{ uuid: `new-item-1`, id: `new-item-1` },
|
242
242
|
]
|
243
243
|
}
|
244
|
+
stockOperationUuid={model.uuid ?? ""}
|
245
|
+
locationUuid={model.atLocationUuid ?? ""}
|
244
246
|
batchBalance={batchBalance}
|
245
247
|
batchNos={batchNos}
|
246
248
|
control={control}
|
@@ -59,12 +59,16 @@ const BatchNoSelector = <T,>(props: BatchNoSelectorProps<T>) => {
|
|
59
59
|
return item;
|
60
60
|
});
|
61
61
|
|
62
|
+
const filteredBatches = stockItemBatchesInfo?.filter(
|
63
|
+
(s) => s.quantity !== undefined && s.quantity !== 0
|
64
|
+
);
|
65
|
+
|
62
66
|
useEffect(() => {
|
63
67
|
if (
|
64
68
|
!isLoading &&
|
65
69
|
stockItemBatchNos &&
|
66
70
|
props.selectedItem &&
|
67
|
-
stockItemBatchNos.length === 0
|
71
|
+
(stockItemBatchNos.length === 0 || filteredBatches.length === 0)
|
68
72
|
) {
|
69
73
|
setValidationMessage(
|
70
74
|
"No stock batch numbers defined. Do a initial/receipt stock operation first."
|
@@ -72,7 +76,7 @@ const BatchNoSelector = <T,>(props: BatchNoSelectorProps<T>) => {
|
|
72
76
|
} else {
|
73
77
|
setValidationMessage(null);
|
74
78
|
}
|
75
|
-
}, [isLoading, stockItemBatchNos, props.selectedItem]);
|
79
|
+
}, [isLoading, stockItemBatchNos, props.selectedItem, filteredBatches]);
|
76
80
|
|
77
81
|
if (isLoading) return <InlineLoading status="active" />;
|
78
82
|
|
@@ -90,7 +94,7 @@ const BatchNoSelector = <T,>(props: BatchNoSelectorProps<T>) => {
|
|
90
94
|
controllerName={props.controllerName}
|
91
95
|
id={props.name}
|
92
96
|
size={"sm"}
|
93
|
-
items={
|
97
|
+
items={filteredBatches || []}
|
94
98
|
onChange={(data: { selectedItem?: StockBatchDTO }) => {
|
95
99
|
setSelectedItem(data.selectedItem || null);
|
96
100
|
props.onBatchNoChanged?.(data.selectedItem);
|
@@ -98,7 +102,7 @@ const BatchNoSelector = <T,>(props: BatchNoSelectorProps<T>) => {
|
|
98
102
|
}}
|
99
103
|
initialSelectedItem={initialSelectedItem}
|
100
104
|
itemToString={(s: StockBatchDTO) =>
|
101
|
-
s?.batchNo ? `${s?.batchNo}
|
105
|
+
s?.batchNo ? `${s?.batchNo}` : ""
|
102
106
|
}
|
103
107
|
placeholder={props.placeholder}
|
104
108
|
invalid={props.invalid}
|
package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx
CHANGED
@@ -1,68 +1,43 @@
|
|
1
|
-
import React
|
1
|
+
import React from "react";
|
2
2
|
import { Button } from "@carbon/react";
|
3
|
+
import { Edit } from "@carbon/react/icons";
|
3
4
|
import { useTranslation } from "react-i18next";
|
4
5
|
import { StockOperationDTO } from "../../core/api/types/stockOperation/StockOperationDTO";
|
5
|
-
import { launchAddOrEditDialog } from "../stock-operation.utils";
|
6
6
|
import { StockOperationType } from "../../core/api/types/stockOperation/StockOperationType";
|
7
|
-
import {
|
7
|
+
import { launchAddOrEditDialog } from "../stock-operation.utils";
|
8
|
+
|
8
9
|
interface EditStockOperationActionMenuProps {
|
9
|
-
|
10
|
-
operationNumber?: string;
|
11
|
-
model?: StockOperationDTO;
|
10
|
+
model: StockOperationDTO;
|
12
11
|
operations: StockOperationType[];
|
12
|
+
operationUuid: string;
|
13
|
+
operationNumber: string;
|
14
|
+
onEdit: (operation: StockOperationDTO) => void;
|
15
|
+
showIcon?: boolean;
|
16
|
+
showprops?: boolean;
|
13
17
|
}
|
18
|
+
|
14
19
|
const EditStockOperationActionMenu: React.FC<
|
15
20
|
EditStockOperationActionMenuProps
|
16
|
-
> = ({
|
21
|
+
> = ({ model, operations, showIcon = true, showprops = true }) => {
|
17
22
|
const { t } = useTranslation();
|
18
|
-
const [operation, setOperation] = useState<StockOperationDTO | null>(null);
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
);
|
26
|
-
}
|
27
|
-
const type: StockOperationType = {
|
28
|
-
uuid: "",
|
29
|
-
name: "",
|
30
|
-
description: "",
|
31
|
-
operationType: "",
|
32
|
-
hasSource: false,
|
33
|
-
sourceType: "Location",
|
34
|
-
hasDestination: false,
|
35
|
-
destinationType: "Location",
|
36
|
-
hasRecipient: false,
|
37
|
-
recipientRequired: false,
|
38
|
-
availableWhenReserved: false,
|
39
|
-
allowExpiredBatchNumbers: false,
|
40
|
-
stockOperationTypeLocationScopes: [],
|
41
|
-
creator: undefined,
|
42
|
-
dateCreated: undefined,
|
43
|
-
changedBy: undefined,
|
44
|
-
dateChanged: undefined,
|
45
|
-
dateVoided: undefined,
|
46
|
-
voidedBy: undefined,
|
47
|
-
voidReason: "",
|
48
|
-
voided: false,
|
24
|
+
const handleEdit = () => {
|
25
|
+
const operation = operations.find(
|
26
|
+
(op) => op.uuid === model.operationTypeUuid
|
27
|
+
);
|
28
|
+
launchAddOrEditDialog(t, model, true, operation, operations, false);
|
49
29
|
};
|
50
30
|
|
51
31
|
return (
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
}}
|
62
|
-
>
|
63
|
-
{operationNumber ? operationNumber : `${model?.operationNumber}`}
|
64
|
-
</Button>
|
65
|
-
</>
|
32
|
+
<Button
|
33
|
+
kind="ghost"
|
34
|
+
size="sm"
|
35
|
+
onClick={handleEdit}
|
36
|
+
iconDescription={t("editStockOperation", "Edit Stock Operation")}
|
37
|
+
renderIcon={showIcon ? Edit : undefined}
|
38
|
+
>
|
39
|
+
{showprops && model.operationNumber}
|
40
|
+
</Button>
|
66
41
|
);
|
67
42
|
};
|
68
43
|
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import React, { ReactNode } from "react";
|
2
|
-
import { Concept } from "../../core/api/types/concept/Concept";
|
1
|
+
import React, { ReactNode, useEffect } from "react";
|
3
2
|
import { Control, Controller, FieldValues } from "react-hook-form";
|
4
3
|
import { Party } from "../../core/api/types/Party";
|
5
4
|
import { ComboBox } from "@carbon/react";
|
@@ -7,12 +6,12 @@ import { ComboBox } from "@carbon/react";
|
|
7
6
|
interface PartySelectorProps<T> {
|
8
7
|
partyUuid?: string;
|
9
8
|
parties: Party[];
|
10
|
-
onPartyChange?: (
|
9
|
+
onPartyChange?: (party: Party) => void;
|
11
10
|
title?: string;
|
12
11
|
placeholder?: string;
|
13
12
|
invalid?: boolean;
|
14
13
|
invalidText?: ReactNode;
|
15
|
-
|
14
|
+
filterFunction?: (party: Party) => boolean;
|
16
15
|
|
17
16
|
// Control
|
18
17
|
controllerName: string;
|
@@ -25,32 +24,38 @@ const PartySelector = <T,>(props: PartySelectorProps<T>) => {
|
|
25
24
|
<Controller
|
26
25
|
name={props.controllerName}
|
27
26
|
control={props.control}
|
28
|
-
render={({ field: { onChange, ref } }) =>
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
props.
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
props.parties
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
27
|
+
render={({ field: { onChange, value, ref } }) => {
|
28
|
+
const selectedParty = props.parties.find(
|
29
|
+
(p) => p.uuid === props.partyUuid
|
30
|
+
);
|
31
|
+
|
32
|
+
if (selectedParty && !value) {
|
33
|
+
onChange(selectedParty.uuid);
|
34
|
+
}
|
35
|
+
return (
|
36
|
+
<ComboBox
|
37
|
+
titleText={props.title}
|
38
|
+
name={props.name}
|
39
|
+
id={props.name}
|
40
|
+
size={"md"}
|
41
|
+
items={props.parties}
|
42
|
+
onChange={(data: { selectedItem: Party }) => {
|
43
|
+
props.onPartyChange?.(data.selectedItem);
|
44
|
+
onChange(data.selectedItem?.uuid);
|
45
|
+
}}
|
46
|
+
initialSelectedItem={selectedParty}
|
47
|
+
selectedItem={props.parties.find((p) => p.uuid === value)}
|
48
|
+
itemToString={(item?: Party) =>
|
49
|
+
item && item?.name ? `${item?.name}` : ""
|
50
|
+
}
|
51
|
+
shouldFilterItem={() => true}
|
52
|
+
placeholder={props.placeholder}
|
53
|
+
ref={ref}
|
54
|
+
invalid={props.invalid}
|
55
|
+
invalidText={props.invalidText}
|
56
|
+
/>
|
57
|
+
);
|
58
|
+
}}
|
54
59
|
/>
|
55
60
|
);
|
56
61
|
};
|
@@ -68,7 +68,7 @@ const StockItemSelector = <T,>(props: StockItemSelectorProps<T>) => {
|
|
68
68
|
};
|
69
69
|
|
70
70
|
function stockItemName(item: StockItemDTO): string {
|
71
|
-
return item
|
71
|
+
return item?.drugName || item?.conceptName;
|
72
72
|
}
|
73
73
|
|
74
74
|
export default StockItemSelector;
|
@@ -25,10 +25,7 @@ export const addOrEditStockOperation = async (
|
|
25
25
|
t: TFunction,
|
26
26
|
stockOperation: StockOperationDTO,
|
27
27
|
isEditing: boolean,
|
28
|
-
operation?: StockOperationType
|
29
|
-
operations?: StockOperationType[],
|
30
|
-
canPrint?: boolean,
|
31
|
-
printEnabled?: boolean
|
28
|
+
operation?: StockOperationType
|
32
29
|
) => {
|
33
30
|
const payload = stockOperation;
|
34
31
|
try {
|
@@ -98,15 +95,7 @@ export const launchAddOrEditDialog = (
|
|
98
95
|
<AddStockOperation
|
99
96
|
model={stockOperation}
|
100
97
|
onSave={(stockOperation) =>
|
101
|
-
addOrEditStockOperation(
|
102
|
-
t,
|
103
|
-
stockOperation,
|
104
|
-
isEditing,
|
105
|
-
operation,
|
106
|
-
operations,
|
107
|
-
canPrint,
|
108
|
-
printEnabled
|
109
|
-
)
|
98
|
+
addOrEditStockOperation(t, stockOperation, isEditing, operation)
|
110
99
|
}
|
111
100
|
isEditing={isEditing}
|
112
101
|
operation={operation}
|
@@ -130,7 +130,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
130
130
|
selectedStatus.length ||
|
131
131
|
selectedOperations.length;
|
132
132
|
|
133
|
-
|
133
|
+
const [operations, setOperations] = useState<StockOperationType[]>([]);
|
134
134
|
|
135
135
|
const handleOnFilterChange = useCallback((selectedItems, filterType) => {
|
136
136
|
if (filterType === StockFilters.SOURCES) {
|
@@ -157,6 +157,17 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
157
157
|
}
|
158
158
|
};
|
159
159
|
|
160
|
+
const handleEditClick = (stockOperation, isEditing) => {
|
161
|
+
launchAddOrEditDialog(
|
162
|
+
t,
|
163
|
+
stockOperation,
|
164
|
+
isEditing,
|
165
|
+
operation,
|
166
|
+
operations,
|
167
|
+
false
|
168
|
+
);
|
169
|
+
};
|
170
|
+
|
160
171
|
const tableRows = useMemo(() => {
|
161
172
|
return items?.map((stockOperation, index) => ({
|
162
173
|
...stockOperation,
|
@@ -165,8 +176,13 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
165
176
|
operationTypeName: `${stockOperation?.operationTypeName}`,
|
166
177
|
operationNumber: (
|
167
178
|
<EditStockOperationActionMenu
|
168
|
-
model={
|
179
|
+
model={stockOperation}
|
169
180
|
operations={operations}
|
181
|
+
operationUuid={operation.uuid}
|
182
|
+
operationNumber={""}
|
183
|
+
onEdit={() => handleEditClick(stockOperation, true)}
|
184
|
+
showIcon={false}
|
185
|
+
showprops={true}
|
170
186
|
/>
|
171
187
|
),
|
172
188
|
status: `${stockOperation?.status}`,
|
@@ -297,25 +313,18 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
297
313
|
</div>
|
298
314
|
),
|
299
315
|
actions: (
|
300
|
-
<
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
operations,
|
310
|
-
false
|
311
|
-
);
|
312
|
-
}}
|
313
|
-
iconDescription={t("editStockItem", "Edit Stock Item")}
|
314
|
-
renderIcon={(props) => <Edit size={16} {...props} />}
|
315
|
-
></Button>
|
316
|
+
<EditStockOperationActionMenu
|
317
|
+
model={stockOperation}
|
318
|
+
operations={operations}
|
319
|
+
operationUuid={operation.uuid}
|
320
|
+
operationNumber={""}
|
321
|
+
onEdit={() => handleEditClick(stockOperation, true)}
|
322
|
+
showIcon={true}
|
323
|
+
showprops={false}
|
324
|
+
/>
|
316
325
|
),
|
317
326
|
}));
|
318
|
-
}, [items,
|
327
|
+
}, [items, operations, t]);
|
319
328
|
|
320
329
|
if (isLoading && !filterApplied) {
|
321
330
|
return (
|
@@ -417,7 +426,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
417
426
|
);
|
418
427
|
}}
|
419
428
|
onOperationLoaded={(ops) => {
|
420
|
-
|
429
|
+
setOperations(ops);
|
421
430
|
}}
|
422
431
|
/>
|
423
432
|
</TableToolbarContent>
|
@@ -210,7 +210,7 @@ export function getStockOperationItemsCost(filter: StockOperationFilter) {
|
|
210
210
|
export function getStockItemInventory(filter: StockItemInventoryFilter) {
|
211
211
|
const apiUrl = `${restBaseUrl}/stockmanagement/stockiteminventory${toQueryParams(
|
212
212
|
filter
|
213
|
-
)}`;
|
213
|
+
)}&v=default`;
|
214
214
|
const abortController = new AbortController();
|
215
215
|
return openmrsFetch(apiUrl, {
|
216
216
|
method: "GET",
|