@openmrs/esm-stock-management-app 1.0.1-pre.783 → 1.0.1-pre.785
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/__mocks__/index.ts +1 -0
- package/__mocks__/operation-type.mock.ts +532 -0
- package/dist/155.js +1 -0
- package/dist/155.js.map +1 -0
- package/dist/172.js +1 -1
- package/dist/20.js +1 -1
- package/dist/290.js +1 -1
- package/dist/493.js +2 -0
- package/dist/493.js.map +1 -0
- package/dist/606.js +1 -1
- package/dist/627.js +1 -1
- package/dist/914.js +1 -0
- package/dist/914.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-stock-management-app.js +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +75 -51
- package/dist/openmrs-esm-stock-management-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/core/utils/utils.ts +29 -0
- package/src/index.ts +4 -0
- package/src/routes.json +9 -0
- package/src/stock-items/add-stock-item/transactions/printout/transactions-stockcard-printout.component.tsx +8 -12
- package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +8 -12
- package/src/stock-items/stock-items.resource.ts +5 -5
- package/src/stock-lookups/stock-lookups.resource.ts +2 -2
- package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +41 -16
- package/src/stock-operations/{add-stock-operation/received-items.component.tsx → received-items.component.tsx} +1 -1
- package/src/stock-operations/stock-operation-reference.component.tsx +64 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status-row.tsx +77 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status.scss +32 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status.tsx +45 -0
- package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +30 -29
- package/src/stock-operations/stock-operation.utils.tsx +16 -79
- package/src/stock-operations/stock-operations-dialog/stock-operations-issue-stock-button.component.tsx +27 -39
- package/src/stock-operations/stock-operations-dialog/stock-operations-print-button.component.tsx +51 -59
- package/src/stock-operations/{stock-item-selector/stock-item-selector.resource.tsx → stock-operations-forms/hooks/useFilterableStockItems.ts} +4 -4
- package/src/stock-operations/stock-operations-forms/hooks/useFilteredOperationTypesByRoles.ts +30 -0
- package/src/stock-operations/stock-operations-forms/hooks/useOperationTypePermisions.ts +29 -0
- package/src/stock-operations/stock-operations-forms/hooks/useParties.ts +73 -0
- package/src/stock-operations/{users-selector/users-selector.resource.tsx → stock-operations-forms/hooks/useSearchUser.ts} +9 -7
- package/src/stock-operations/{batch-no-selector/batch-no-selector.resource.tsx → stock-operations-forms/hooks/useStockItemBatchNumbers.ts} +3 -3
- package/src/stock-operations/stock-operations-forms/hooks/useStockOperationLinks.ts +20 -0
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +72 -0
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +90 -0
- package/src/stock-operations/{add-stock-operation/stock-item-search/stock-item-search.scss → stock-operations-forms/input-components/input-components-styles.scss} +2 -2
- package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +157 -0
- package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +53 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +56 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +59 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +216 -0
- package/src/stock-operations/{batch-no-selector → stock-operations-forms/input-components}/unique-batch-no-entry-input.component.tsx +12 -7
- package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +110 -0
- package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +111 -0
- package/src/stock-operations/stock-operations-forms/step1.test.tsx +303 -0
- package/src/stock-operations/stock-operations-forms/step2.test.tsx +250 -0
- package/src/stock-operations/stock-operations-forms/step3.test.tsx +223 -0
- package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +241 -0
- package/src/stock-operations/stock-operations-forms/steps/quantity-uom-cell.component.tsx +33 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-availability-cell.component.tsx +51 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-batch-no-cell.component.tsx +40 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-cell.component.tsx +38 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-expiry-cell.component.tsx +41 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +281 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.scc.scss +64 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +236 -0
- package/src/stock-operations/stock-operations-forms/stock-issue-form-initializer-with-related-requisition-operation.component.tsx +55 -0
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +41 -0
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +197 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form-header.component.tsx +166 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +200 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +111 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-related-link.component.tsx +45 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +41 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +52 -0
- package/src/stock-operations/stock-operations-forms/stock-operations-form-utils.ts +32 -0
- package/src/stock-operations/stock-operations-table.component.tsx +20 -56
- package/src/stock-operations/stock-operations.resource.ts +16 -13
- package/src/stock-operations/validation-schema.ts +72 -14
- package/dist/766.js +0 -2
- package/dist/766.js.map +0 -1
- package/dist/822.js +0 -1
- package/dist/822.js.map +0 -1
- package/src/stock-operations/add-stock-operation/add-stock-operation.component.tsx +0 -349
- package/src/stock-operations/add-stock-operation/add-stock-operation.resource.tsx +0 -27
- package/src/stock-operations/add-stock-operation/add-stock-operation.scss +0 -60
- package/src/stock-operations/add-stock-operation/add-stock-operation.test.tsx +0 -192
- package/src/stock-operations/add-stock-operation/add-stock-operation.utils.tsx +0 -152
- package/src/stock-operations/add-stock-operation/add-stock-utils.ts +0 -103
- package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +0 -439
- package/src/stock-operations/add-stock-operation/base-operation-details.scss +0 -30
- package/src/stock-operations/add-stock-operation/stock-item-search/stock-item-search.component.tsx +0 -70
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.component.tsx +0 -357
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.resource.tsx +0 -0
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.scss +0 -12
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.test.tsx +0 -10
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.scss +0 -17
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +0 -254
- package/src/stock-operations/add-stock-operation/stock-operation-context/useStockOperationContext.tsx +0 -16
- package/src/stock-operations/add-stock-operation/stock-operation-reference.component.tsx +0 -39
- package/src/stock-operations/add-stock-operation/stock-operation-related-link.component.tsx +0 -38
- package/src/stock-operations/add-stock-operation/stock-operation-status.component.tsx +0 -170
- package/src/stock-operations/add-stock-operation/stock-operation-submission.component.tsx +0 -189
- package/src/stock-operations/add-stock-operation/stock-operation-submission.test.tsx +0 -138
- package/src/stock-operations/add-stock-operation/types.ts +0 -55
- package/src/stock-operations/add-stock-operation/validationSchema.ts +0 -54
- package/src/stock-operations/batch-no-selector/batch-no-selector.component.tsx +0 -114
- package/src/stock-operations/batch-no-selector/batch-no-selector.scss +0 -0
- package/src/stock-operations/batch-no-selector/batch-no-selector.test.tsx +0 -101
- package/src/stock-operations/party-selector/party-selector.component.tsx +0 -59
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.component.tsx +0 -65
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.resource.tsx +0 -0
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.scss +0 -0
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.test.tsx +0 -10
- package/src/stock-operations/stock-item-selector/stock-item-selector.component.tsx +0 -69
- package/src/stock-operations/stock-item-selector/stock-item-selector.scss +0 -0
- package/src/stock-operations/stock-item-selector/stock-item-selector.test.tsx +0 -10
- package/src/stock-operations/stock-operation-reason-selector/stock-operation-reason-selector.component.tsx +0 -62
- package/src/stock-operations/users-selector/users-selector.component.tsx +0 -75
- /package/dist/{766.js.LICENSE.txt → 493.js.LICENSE.txt} +0 -0
@@ -1,349 +0,0 @@
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
2
|
-
import { useTranslation } from 'react-i18next';
|
3
|
-
import { TabItem } from '../../core/components/tabs/types';
|
4
|
-
import VerticalTabs from '../../core/components/tabs/vertical-tabs.component';
|
5
|
-
import BaseOperationDetails from './base-operation-details.component';
|
6
|
-
import StockItemsAddition from './stock-items-addition.component';
|
7
|
-
import StockOperationSubmission from './stock-operation-submission.component';
|
8
|
-
import ReceivedItems from './received-items.component';
|
9
|
-
import { AddStockOperationProps } from './types';
|
10
|
-
import { useInitializeStockOperations } from './add-stock-operation.resource';
|
11
|
-
import { AccordionSkeleton } from '@carbon/react';
|
12
|
-
import { closeOverlay } from '../../core/components/overlay/hook';
|
13
|
-
import { addOrEditStockOperation, showActionDialogButton } from '../stock-operation.utils';
|
14
|
-
import StockOperationApprovalButton from '../stock-operations-dialog/stock-operations-approve-button.component';
|
15
|
-
import StockOperationRejectButton from '../stock-operations-dialog/stock-operations-reject-button.component';
|
16
|
-
import StockOperationReturnButton from '../stock-operations-dialog/stock-operations-return-button.component';
|
17
|
-
import StockOperationCancelButton from '../stock-operations-dialog/stock-operations-cancel-button.component';
|
18
|
-
import StockOperationPrintButton from '../stock-operations-dialog/stock-operations-print-button.component';
|
19
|
-
import StockOperationApproveDispatchButton from '../stock-operations-dialog/stock-operations-approve-dispatch-button.component';
|
20
|
-
import StockOperationCompleteDispatchButton from '../stock-operations-dialog/stock-operations-completed-dispatch-button.component';
|
21
|
-
import StockOperationIssueStockButton from '../stock-operations-dialog/stock-operations-issue-stock-button.component';
|
22
|
-
import { StockOperation } from './stock-operation-context/useStockOperationContext';
|
23
|
-
import { showSnackbar } from '@openmrs/esm-framework';
|
24
|
-
import {
|
25
|
-
OperationType,
|
26
|
-
StockOperationTypeIsStockIssue,
|
27
|
-
StockOperationType,
|
28
|
-
StockOperationTypeCanBeRelatedToRequisition,
|
29
|
-
operationFromString,
|
30
|
-
StockOperationTypeRequiresDispatchAcknowledgement,
|
31
|
-
} from '../../core/api/types/stockOperation/StockOperationType';
|
32
|
-
import { getStockOperationLinks, operationStatusColor } from '../stock-operations.resource';
|
33
|
-
import styles from './add-stock-operation.scss';
|
34
|
-
import { useStockOperationTypes } from '../../stock-lookups/stock-lookups.resource';
|
35
|
-
import { StockOperationLinkDTO } from '../../core/api/types/stockOperation/StockOperationLinkDTO';
|
36
|
-
import StockOperationStatus from './stock-operation-status.component';
|
37
|
-
import StockOperationRelatedLink from './stock-operation-related-link.component';
|
38
|
-
|
39
|
-
const AddStockOperation: React.FC<AddStockOperationProps> = (props) => {
|
40
|
-
const { t } = useTranslation();
|
41
|
-
const { isEditing, canEdit, canPrint } = props;
|
42
|
-
const { isLoading, error, result } = useInitializeStockOperations(props);
|
43
|
-
const [operationLinks, setOperationLinks] = useState<StockOperationLinkDTO[]>();
|
44
|
-
const [manageStockItems, setManageStockItems] = useState(props?.isEditing);
|
45
|
-
const { types } = useStockOperationTypes();
|
46
|
-
const [requisition, setRequisition] = useState(props?.model?.uuid);
|
47
|
-
const [manageSubmitOrComplete, setManageSubmitOrComplete] = useState(props?.isEditing);
|
48
|
-
|
49
|
-
const [requiresDispatchAcknowledgement, setRequiresDispatchAcknowledgement] = useState(false);
|
50
|
-
|
51
|
-
const currentStockOperationType = types?.results?.find((p) => p.operationType === props?.model?.operationType);
|
52
|
-
|
53
|
-
useEffect(() => {
|
54
|
-
if (
|
55
|
-
currentStockOperationType?.operationType === OperationType.REQUISITION_OPERATION_TYPE ||
|
56
|
-
props?.model?.operationType === OperationType.REQUISITION_OPERATION_TYPE
|
57
|
-
) {
|
58
|
-
setRequisition(props?.model?.uuid);
|
59
|
-
}
|
60
|
-
}, [currentStockOperationType, props?.model?.operationType, props?.model?.uuid]);
|
61
|
-
|
62
|
-
useEffect(() => {
|
63
|
-
if (
|
64
|
-
isEditing ||
|
65
|
-
StockOperationTypeCanBeRelatedToRequisition(operationFromString(currentStockOperationType?.name.toLowerCase())) ||
|
66
|
-
OperationType.REQUISITION_OPERATION_TYPE === currentStockOperationType?.operationType
|
67
|
-
) {
|
68
|
-
getStockOperationLinks(requisition).then((resp) => {
|
69
|
-
setOperationLinks(resp.data?.results);
|
70
|
-
});
|
71
|
-
}
|
72
|
-
}, [currentStockOperationType, requisition, props.model?.uuid, isEditing]);
|
73
|
-
|
74
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
75
|
-
const [canDisplayReceivedItems, setCanDisplayReceivedItems] = useState(false);
|
76
|
-
|
77
|
-
useEffect(() => {
|
78
|
-
const validOperationType = Object.values(OperationType).includes(props.model.operationType as OperationType)
|
79
|
-
? (props.model.operationType as OperationType)
|
80
|
-
: OperationType.RETURN_OPERATION_TYPE;
|
81
|
-
|
82
|
-
setRequiresDispatchAcknowledgement(StockOperationTypeRequiresDispatchAcknowledgement(validOperationType));
|
83
|
-
}, [props.model.operationType]);
|
84
|
-
|
85
|
-
useEffect(() => {
|
86
|
-
setCanDisplayReceivedItems(props?.model?.permission?.canDisplayReceivedItems ?? false);
|
87
|
-
}, [props?.model?.permission]);
|
88
|
-
|
89
|
-
if (isLoading) return <AccordionSkeleton />;
|
90
|
-
if (error) {
|
91
|
-
closeOverlay();
|
92
|
-
showSnackbar({
|
93
|
-
kind: 'error',
|
94
|
-
title: t('error', 'Error'),
|
95
|
-
subtitle: t('errorLoadingStockOperation', 'Error loading stock item'),
|
96
|
-
timeoutInMs: 5000,
|
97
|
-
isLowContrast: true,
|
98
|
-
});
|
99
|
-
return;
|
100
|
-
}
|
101
|
-
|
102
|
-
let operations: StockOperationType[] | null | undefined;
|
103
|
-
const status = props?.model?.status;
|
104
|
-
|
105
|
-
const tabs: TabItem[] = [
|
106
|
-
{
|
107
|
-
name: isEditing ? `${props?.operation?.name} Details` : `${props?.operation?.name} Details`,
|
108
|
-
component: (
|
109
|
-
<BaseOperationDetails
|
110
|
-
{...props}
|
111
|
-
isEditing={props?.operation?.name === 'Stock Issue' ? !isEditing : isEditing}
|
112
|
-
setup={result}
|
113
|
-
canEdit={canEdit}
|
114
|
-
model={isEditing ? props?.model : props?.operation?.name === 'Stock Issue' ? props?.model : result?.dto}
|
115
|
-
onSave={async () => {
|
116
|
-
setManageStockItems(true);
|
117
|
-
setSelectedIndex(1);
|
118
|
-
}}
|
119
|
-
operation={props?.operation}
|
120
|
-
/>
|
121
|
-
),
|
122
|
-
},
|
123
|
-
{
|
124
|
-
name: t('stockItems', 'Stock Items'),
|
125
|
-
component: (
|
126
|
-
<StockItemsAddition
|
127
|
-
{...props}
|
128
|
-
isEditing={isEditing}
|
129
|
-
setup={result}
|
130
|
-
canEdit={canEdit}
|
131
|
-
model={isEditing ? props?.model : props?.operation?.name === 'Stock Issue' ? props?.model : result?.dto} // check if type is stockIssue and pass requisition data
|
132
|
-
onSave={async () => {
|
133
|
-
setManageSubmitOrComplete(true);
|
134
|
-
setSelectedIndex(2);
|
135
|
-
}}
|
136
|
-
/>
|
137
|
-
),
|
138
|
-
disabled: !(isEditing || manageStockItems),
|
139
|
-
},
|
140
|
-
{
|
141
|
-
name: result?.requiresDispatchAcknowledgement ? 'Submit/Dispatch' : 'Submit/Complete',
|
142
|
-
component: (
|
143
|
-
<StockOperationSubmission
|
144
|
-
{...props}
|
145
|
-
isEditing={isEditing}
|
146
|
-
setup={result}
|
147
|
-
canEdit={canEdit}
|
148
|
-
locked={false}
|
149
|
-
model={isEditing ? props?.model : props?.operation?.name === 'Stock Issue' ? props?.model : result?.dto}
|
150
|
-
requiresDispatchAcknowledgement={
|
151
|
-
isEditing
|
152
|
-
? props?.model?.operationType === 'return' || props?.model?.operationType === 'issuestock'
|
153
|
-
: result.requiresDispatchAcknowledgement
|
154
|
-
}
|
155
|
-
actions={{
|
156
|
-
onGoBack: () => {
|
157
|
-
setSelectedIndex(1);
|
158
|
-
},
|
159
|
-
onSave: async (model) => {
|
160
|
-
// TODO: Update
|
161
|
-
await addOrEditStockOperation(t, model, props.isEditing, props.operation);
|
162
|
-
},
|
163
|
-
|
164
|
-
onComplete: async () => {
|
165
|
-
await showActionDialogButton('Complete', false, props?.model);
|
166
|
-
},
|
167
|
-
onSubmit: async () => {
|
168
|
-
await showActionDialogButton('Submit', false, props?.model);
|
169
|
-
},
|
170
|
-
onDispatch: async () => {
|
171
|
-
await showActionDialogButton('Dispatch', false, props?.model);
|
172
|
-
},
|
173
|
-
}}
|
174
|
-
/>
|
175
|
-
),
|
176
|
-
disabled: !(props.isEditing || manageSubmitOrComplete),
|
177
|
-
},
|
178
|
-
].concat(
|
179
|
-
StockOperationTypeIsStockIssue(props?.model?.operationType as OperationType) || canDisplayReceivedItems
|
180
|
-
? status === 'DISPATCHED' || status === 'COMPLETED'
|
181
|
-
? [
|
182
|
-
{
|
183
|
-
name: t('receivedItems', 'Received Items'),
|
184
|
-
component: <ReceivedItems model={props?.model} />,
|
185
|
-
},
|
186
|
-
]
|
187
|
-
: []
|
188
|
-
: [],
|
189
|
-
);
|
190
|
-
|
191
|
-
return (
|
192
|
-
<>
|
193
|
-
{!isEditing && props.operation.name === 'Stock Issue' ? (
|
194
|
-
<></>
|
195
|
-
) : (
|
196
|
-
<div className={styles.statusBody}>
|
197
|
-
<div style={{ margin: '10px' }}>
|
198
|
-
{isEditing && (
|
199
|
-
<div className={styles.statusLabel}>
|
200
|
-
<span className={styles.textHeading}>{t('status', 'Status ')}:</span>
|
201
|
-
<span
|
202
|
-
style={{
|
203
|
-
marginLeft: '2px',
|
204
|
-
color: `${operationStatusColor(props?.model?.status)}`,
|
205
|
-
}}
|
206
|
-
>
|
207
|
-
{props?.model?.status}
|
208
|
-
</span>
|
209
|
-
</div>
|
210
|
-
)}
|
211
|
-
<StockOperationStatus model={props?.model} />
|
212
|
-
</div>
|
213
|
-
|
214
|
-
{((!props?.model?.permission?.canEdit &&
|
215
|
-
(props?.model?.permission?.canApprove || props?.model?.permission?.canReceiveItems)) ||
|
216
|
-
props?.model?.permission?.canEdit ||
|
217
|
-
canPrint ||
|
218
|
-
props?.model?.permission?.isRequisitionAndCanIssueStock) && (
|
219
|
-
<div
|
220
|
-
style={{
|
221
|
-
margin: '10px',
|
222
|
-
display: 'flex',
|
223
|
-
flexDirection: 'row',
|
224
|
-
}}
|
225
|
-
>
|
226
|
-
<>
|
227
|
-
{!props?.model?.permission?.canEdit && props?.model?.permission?.canApprove && (
|
228
|
-
<>
|
229
|
-
{!requiresDispatchAcknowledgement && (
|
230
|
-
<div style={{ margin: '2px' }}>
|
231
|
-
<StockOperationApprovalButton operation={props?.model} />
|
232
|
-
</div>
|
233
|
-
)}
|
234
|
-
|
235
|
-
{requiresDispatchAcknowledgement && (
|
236
|
-
<div style={{ margin: '2px' }}>
|
237
|
-
<StockOperationApproveDispatchButton operation={props?.model} />
|
238
|
-
</div>
|
239
|
-
)}
|
240
|
-
|
241
|
-
<div style={{ margin: '2px' }}>
|
242
|
-
<StockOperationRejectButton operation={props?.model} />
|
243
|
-
</div>
|
244
|
-
<div style={{ margin: '2px' }}>
|
245
|
-
<StockOperationReturnButton operation={props?.model} />
|
246
|
-
</div>
|
247
|
-
<div style={{ margin: '2px' }}>
|
248
|
-
<StockOperationCancelButton operation={props?.model} />
|
249
|
-
</div>
|
250
|
-
</>
|
251
|
-
)}
|
252
|
-
|
253
|
-
{!props?.model?.permission?.canEdit && props?.model?.permission?.canReceiveItems && (
|
254
|
-
<>
|
255
|
-
<div style={{ margin: '2px' }}>
|
256
|
-
<StockOperationCompleteDispatchButton operation={props?.model} reason={false} />
|
257
|
-
</div>
|
258
|
-
<div style={{ margin: '2px' }}>
|
259
|
-
<StockOperationReturnButton operation={props?.model} />
|
260
|
-
</div>
|
261
|
-
</>
|
262
|
-
)}
|
263
|
-
|
264
|
-
{props?.model?.permission?.canEdit && (
|
265
|
-
<div style={{ margin: '2px' }}>
|
266
|
-
<StockOperationCancelButton operation={props?.model} />
|
267
|
-
</div>
|
268
|
-
)}
|
269
|
-
|
270
|
-
{props?.model?.permission?.isRequisitionAndCanIssueStock && (
|
271
|
-
<div style={{ margin: '2px' }}>
|
272
|
-
<StockOperationIssueStockButton operation={props?.model} operations={operations} />
|
273
|
-
</div>
|
274
|
-
)}
|
275
|
-
{(props?.model?.permission?.isRequisitionAndCanIssueStock ||
|
276
|
-
props?.model?.operationType === OperationType.STOCK_ISSUE_OPERATION_TYPE ||
|
277
|
-
props?.model?.operationType === OperationType.REQUISITION_OPERATION_TYPE ||
|
278
|
-
props?.model?.operationType === OperationType.RECEIPT_OPERATION_TYPE ||
|
279
|
-
props?.model?.operationType === OperationType.TRANSFER_OUT_OPERATION_TYPE) && (
|
280
|
-
<div style={{ margin: '2px' }}>
|
281
|
-
<StockOperationPrintButton operation={props?.model} />
|
282
|
-
</div>
|
283
|
-
)}
|
284
|
-
</>
|
285
|
-
</div>
|
286
|
-
)}
|
287
|
-
</div>
|
288
|
-
)}
|
289
|
-
{operationLinks && operationLinks?.length > 0 && (
|
290
|
-
<div style={{ margin: '10px' }}>
|
291
|
-
<h6 style={{ color: '#24a148' }}>Related Transactions:</h6>
|
292
|
-
{operationLinks.map(
|
293
|
-
(item) =>
|
294
|
-
(props?.model?.uuid === item?.parentUuid || currentStockOperationType?.uuid === item?.parentUuid) && (
|
295
|
-
<>
|
296
|
-
<span>{item?.childOperationTypeName}</span>
|
297
|
-
<span className={item?.childVoided ? 'voided' : ''}>
|
298
|
-
<span> </span>
|
299
|
-
{item?.childVoided && item?.childOperationNumber}
|
300
|
-
{!item?.childVoided && (
|
301
|
-
<span className={styles.relatedLink}>
|
302
|
-
<StockOperationRelatedLink
|
303
|
-
operationTypes={types.results}
|
304
|
-
operationUuid={item?.childUuid}
|
305
|
-
operationNumber={item?.childOperationNumber}
|
306
|
-
/>
|
307
|
-
</span>
|
308
|
-
)}
|
309
|
-
</span>
|
310
|
-
<span> </span>
|
311
|
-
<span>[{item?.childStatus}]</span>
|
312
|
-
</>
|
313
|
-
),
|
314
|
-
)}
|
315
|
-
<span> </span>
|
316
|
-
{operationLinks.map(
|
317
|
-
(item) =>
|
318
|
-
(props.model?.uuid === item?.childUuid || currentStockOperationType.uuid === item?.childUuid) && (
|
319
|
-
<>
|
320
|
-
<span>{item?.parentOperationTypeName}</span>
|
321
|
-
<span className={item?.parentVoided ? 'voided' : ''}>
|
322
|
-
<span> </span>
|
323
|
-
{item?.parentVoided && item?.parentOperationNumber}
|
324
|
-
{!item?.parentVoided && (
|
325
|
-
<span className={styles.relatedLink}>
|
326
|
-
<StockOperationRelatedLink
|
327
|
-
operationTypes={types.results}
|
328
|
-
operationUuid={item?.parentUuid}
|
329
|
-
operationNumber={item?.parentOperationNumber}
|
330
|
-
/>
|
331
|
-
</span>
|
332
|
-
)}
|
333
|
-
</span>
|
334
|
-
<span> </span>
|
335
|
-
<span>[{item?.parentStatus}]</span>
|
336
|
-
</>
|
337
|
-
),
|
338
|
-
)}
|
339
|
-
</div>
|
340
|
-
)}
|
341
|
-
|
342
|
-
<StockOperation>
|
343
|
-
<VerticalTabs tabs={tabs} selectedIndex={selectedIndex} onChange={setSelectedIndex} />
|
344
|
-
</StockOperation>
|
345
|
-
</>
|
346
|
-
);
|
347
|
-
};
|
348
|
-
|
349
|
-
export default AddStockOperation;
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { useEffect, useState } from 'react';
|
2
|
-
import { initializeNewStockOperation } from './add-stock-operation.utils';
|
3
|
-
import { AddStockOperationProps, InitializeResult } from './types';
|
4
|
-
|
5
|
-
export const useInitializeStockOperations = (props: AddStockOperationProps) => {
|
6
|
-
const [isLoading, setIsLoading] = useState(true);
|
7
|
-
const [error, setError] = useState(false);
|
8
|
-
const [result, setResult] = useState<InitializeResult>();
|
9
|
-
|
10
|
-
useEffect(() => {
|
11
|
-
setIsLoading(true);
|
12
|
-
initializeNewStockOperation(props.operation, props.model, props.operations)
|
13
|
-
.then((data) => {
|
14
|
-
setResult(data);
|
15
|
-
setIsLoading(false);
|
16
|
-
})
|
17
|
-
.catch(() => {
|
18
|
-
setError(true);
|
19
|
-
});
|
20
|
-
}, [props.model, props.operation, props.operations]);
|
21
|
-
|
22
|
-
return {
|
23
|
-
isLoading,
|
24
|
-
error,
|
25
|
-
result,
|
26
|
-
};
|
27
|
-
};
|
@@ -1,60 +0,0 @@
|
|
1
|
-
@use '@carbon/layout';
|
2
|
-
@use '@carbon/type';
|
3
|
-
@use '~@openmrs/esm-styleguide/src/vars' as *;
|
4
|
-
|
5
|
-
.sectionTitle {
|
6
|
-
@include type.type-style('heading-compact-02');
|
7
|
-
color: $text-02;
|
8
|
-
margin-bottom: layout.$spacing-04;
|
9
|
-
}
|
10
|
-
|
11
|
-
.modalBody {
|
12
|
-
padding-bottom: layout.$spacing-05;
|
13
|
-
}
|
14
|
-
|
15
|
-
.actionsContainer {
|
16
|
-
display: flex;
|
17
|
-
justify-content: space-between;
|
18
|
-
margin: 5px;
|
19
|
-
}
|
20
|
-
|
21
|
-
.statusContainer {
|
22
|
-
display: flex;
|
23
|
-
margin-top: 4px;
|
24
|
-
gap: 1rem;
|
25
|
-
}
|
26
|
-
|
27
|
-
.textHeading {
|
28
|
-
font-weight: bold;
|
29
|
-
}
|
30
|
-
|
31
|
-
.statusDescriptions {
|
32
|
-
margin-top: 4px;
|
33
|
-
|
34
|
-
.text {
|
35
|
-
margin-right: 4px;
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
.actionButtons {
|
40
|
-
margin: 10px;
|
41
|
-
display: flex;
|
42
|
-
flex-direction: row;
|
43
|
-
}
|
44
|
-
|
45
|
-
.statusLabel {
|
46
|
-
display: flex;
|
47
|
-
flex-direction: row;
|
48
|
-
margin-left: 10px;
|
49
|
-
}
|
50
|
-
|
51
|
-
.statusBody {
|
52
|
-
display: flex;
|
53
|
-
justify-content: space-between;
|
54
|
-
margin: 5px;
|
55
|
-
}
|
56
|
-
|
57
|
-
.relatedLink {
|
58
|
-
margin-left: 2px;
|
59
|
-
color: #0f62fe;
|
60
|
-
}
|
@@ -1,192 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { render, waitFor, screen, fireEvent } from '@testing-library/react';
|
3
|
-
import { showSnackbar } from '@openmrs/esm-framework';
|
4
|
-
import AddStockOperation from './add-stock-operation.component';
|
5
|
-
import { useInitializeStockOperations } from './add-stock-operation.resource';
|
6
|
-
import { useStockOperationTypes } from '../../stock-lookups/stock-lookups.resource';
|
7
|
-
import { getStockOperationLinks } from '../stock-operations.resource';
|
8
|
-
import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
|
9
|
-
import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
10
|
-
import { InitializeResult } from './types';
|
11
|
-
import { useStockOperations } from '../stock-operations.resource';
|
12
|
-
import { closeOverlay } from '../../core/components/overlay/hook';
|
13
|
-
|
14
|
-
jest.mock('react-i18next', () => ({
|
15
|
-
useTranslation: jest.fn().mockReturnValue({ t: (key) => key }),
|
16
|
-
}));
|
17
|
-
|
18
|
-
jest.mock('@openmrs/esm-framework', () => ({
|
19
|
-
ActionMenu: jest.fn(() => null),
|
20
|
-
showSnackbar: jest.fn(),
|
21
|
-
useDebounce: jest.fn((x) => x),
|
22
|
-
getGlobalStore: jest.fn(() => ({
|
23
|
-
getState: jest.fn(),
|
24
|
-
subscribe: jest.fn(),
|
25
|
-
setState: jest.fn(),
|
26
|
-
})),
|
27
|
-
parseDate: jest.fn((date) => new Date(date)),
|
28
|
-
showNotification: jest.fn(),
|
29
|
-
usePagination: jest.fn(() => ({ currentPage: 1, setPage: jest.fn() })),
|
30
|
-
useSession: jest.fn(() => ({ user: { display: 'Test User' } })),
|
31
|
-
}));
|
32
|
-
|
33
|
-
jest.mock('./add-stock-operation.resource', () => ({
|
34
|
-
useInitializeStockOperations: jest.fn(),
|
35
|
-
}));
|
36
|
-
|
37
|
-
jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
|
38
|
-
useStockOperationTypes: jest.fn(),
|
39
|
-
useUsers: jest.fn().mockReturnValue({ items: { results: [] }, isLoading: false }),
|
40
|
-
}));
|
41
|
-
|
42
|
-
jest.mock('../stock-operations.resource', () => ({
|
43
|
-
operationStatusColor: jest.fn(() => 'some-color'),
|
44
|
-
getStockOperationLinks: jest.fn(),
|
45
|
-
useStockOperations: jest.fn().mockReturnValue({
|
46
|
-
items: { results: [] },
|
47
|
-
isLoading: false,
|
48
|
-
error: null,
|
49
|
-
}),
|
50
|
-
}));
|
51
|
-
|
52
|
-
jest.mock('../../core/components/overlay/hook', () => ({
|
53
|
-
closeOverlay: jest.fn(),
|
54
|
-
}));
|
55
|
-
|
56
|
-
jest.mock('../../stock-items/stock-items.resource', () => ({
|
57
|
-
useStockItems: jest.fn().mockReturnValue({
|
58
|
-
isLoading: false,
|
59
|
-
error: null,
|
60
|
-
items: {
|
61
|
-
results: [{ uuid: 'mock-uuid', packagingUomName: 'Mock Unit', factor: 1 }],
|
62
|
-
},
|
63
|
-
}),
|
64
|
-
useStockItem: jest.fn(),
|
65
|
-
}));
|
66
|
-
|
67
|
-
const mockOnGoBack = jest.fn();
|
68
|
-
const mockOnSave = jest.fn();
|
69
|
-
const mockOnComplete = jest.fn();
|
70
|
-
const mockOnSubmit = jest.fn();
|
71
|
-
const mockOnDispatch = jest.fn();
|
72
|
-
|
73
|
-
const mockProps = {
|
74
|
-
stockOperations: { results: [] },
|
75
|
-
uuid: 'some-mock-uuid',
|
76
|
-
isEditing: false,
|
77
|
-
canPrint: false,
|
78
|
-
canEdit: true,
|
79
|
-
locked: false,
|
80
|
-
model: {
|
81
|
-
approvalRequired: null,
|
82
|
-
uuid: 'mock-uuid',
|
83
|
-
operationType: 'mock-operation-type',
|
84
|
-
status: 'COMPLETED',
|
85
|
-
dateCreated: '2023-01-01',
|
86
|
-
creatorFamilyName: 'Doe',
|
87
|
-
creatorGivenName: 'John',
|
88
|
-
} as unknown as StockOperationDTO,
|
89
|
-
operation: {
|
90
|
-
name: 'Stock Issue',
|
91
|
-
description: 'Issuing stock',
|
92
|
-
operationType: 'stockissue',
|
93
|
-
hasSource: true,
|
94
|
-
sourceType: {},
|
95
|
-
hasDestination: true,
|
96
|
-
destinationType: {},
|
97
|
-
hasRecipient: false,
|
98
|
-
recipientRequired: false,
|
99
|
-
availableWhenReserved: false,
|
100
|
-
allowExpiredBatchNumbers: false,
|
101
|
-
stockOperationTypeLocationScopes: [],
|
102
|
-
} as StockOperationType,
|
103
|
-
setup: {
|
104
|
-
isNegativeQuantityAllowed: false,
|
105
|
-
requiresBatchUuid: false,
|
106
|
-
requiresActualBatchInfo: false,
|
107
|
-
isQuantityOptional: false,
|
108
|
-
} as InitializeResult,
|
109
|
-
actions: {
|
110
|
-
onGoBack: mockOnGoBack,
|
111
|
-
onSave: mockOnSave,
|
112
|
-
onComplete: mockOnComplete,
|
113
|
-
onSubmit: mockOnSubmit,
|
114
|
-
onDispatch: mockOnDispatch,
|
115
|
-
},
|
116
|
-
dto: {
|
117
|
-
results: [],
|
118
|
-
},
|
119
|
-
};
|
120
|
-
|
121
|
-
describe('AddStockOperation', () => {
|
122
|
-
beforeEach(() => {
|
123
|
-
(useInitializeStockOperations as jest.Mock).mockReturnValue({
|
124
|
-
isLoading: true,
|
125
|
-
error: null,
|
126
|
-
item: {},
|
127
|
-
result: {
|
128
|
-
uuid: 'some-valid-uuid-value',
|
129
|
-
},
|
130
|
-
});
|
131
|
-
const mockStockOperationTypes = { results: [] };
|
132
|
-
(useStockOperationTypes as jest.Mock).mockReturnValue(mockStockOperationTypes);
|
133
|
-
(getStockOperationLinks as jest.Mock).mockResolvedValue({ data: { results: [] } });
|
134
|
-
(useStockOperations as jest.Mock).mockReturnValue({ items: { results: [] }, isLoading: false, error: null });
|
135
|
-
});
|
136
|
-
|
137
|
-
it('displays error state correctly', async () => {
|
138
|
-
(useInitializeStockOperations as jest.Mock).mockReturnValue({
|
139
|
-
isLoading: false,
|
140
|
-
error: true,
|
141
|
-
result: null,
|
142
|
-
});
|
143
|
-
const { result } = useInitializeStockOperations(mockProps);
|
144
|
-
if (!result) {
|
145
|
-
return null;
|
146
|
-
}
|
147
|
-
render(<AddStockOperation {...mockProps} />);
|
148
|
-
expect(showSnackbar).toHaveBeenCalledWith(
|
149
|
-
expect.objectContaining({
|
150
|
-
kind: 'error',
|
151
|
-
title: 'error',
|
152
|
-
}),
|
153
|
-
);
|
154
|
-
});
|
155
|
-
|
156
|
-
it('displays loading state correctly', async () => {
|
157
|
-
(useInitializeStockOperations as jest.Mock).mockReturnValue({
|
158
|
-
isLoading: true,
|
159
|
-
error: null,
|
160
|
-
result: null,
|
161
|
-
});
|
162
|
-
render(<AddStockOperation {...mockProps} />);
|
163
|
-
expect(showSnackbar).not.toHaveBeenCalled();
|
164
|
-
});
|
165
|
-
|
166
|
-
it('displays error state and shows snackbar', () => {
|
167
|
-
(useInitializeStockOperations as jest.Mock).mockReturnValue({ isLoading: false, error: true, result: null });
|
168
|
-
render(<AddStockOperation {...mockProps} />);
|
169
|
-
expect(showSnackbar).toHaveBeenCalledWith(expect.objectContaining({ kind: 'error' }));
|
170
|
-
});
|
171
|
-
|
172
|
-
it('calls external utilities correctly', async () => {
|
173
|
-
(useInitializeStockOperations as jest.Mock).mockReturnValue({
|
174
|
-
isLoading: false,
|
175
|
-
error: true,
|
176
|
-
result: null,
|
177
|
-
});
|
178
|
-
|
179
|
-
render(<AddStockOperation {...mockProps} />);
|
180
|
-
await waitFor(() => {
|
181
|
-
expect(closeOverlay).toHaveBeenCalled();
|
182
|
-
});
|
183
|
-
await waitFor(() => {
|
184
|
-
expect(showSnackbar).toHaveBeenCalledWith(
|
185
|
-
expect.objectContaining({
|
186
|
-
kind: 'error',
|
187
|
-
title: 'error',
|
188
|
-
}),
|
189
|
-
);
|
190
|
-
});
|
191
|
-
});
|
192
|
-
});
|