@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.
Files changed (121) hide show
  1. package/__mocks__/index.ts +1 -0
  2. package/__mocks__/operation-type.mock.ts +532 -0
  3. package/dist/155.js +1 -0
  4. package/dist/155.js.map +1 -0
  5. package/dist/172.js +1 -1
  6. package/dist/20.js +1 -1
  7. package/dist/290.js +1 -1
  8. package/dist/493.js +2 -0
  9. package/dist/493.js.map +1 -0
  10. package/dist/606.js +1 -1
  11. package/dist/627.js +1 -1
  12. package/dist/914.js +1 -0
  13. package/dist/914.js.map +1 -0
  14. package/dist/main.js +1 -1
  15. package/dist/main.js.map +1 -1
  16. package/dist/openmrs-esm-stock-management-app.js +1 -1
  17. package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +75 -51
  18. package/dist/openmrs-esm-stock-management-app.js.map +1 -1
  19. package/dist/routes.json +1 -1
  20. package/package.json +1 -1
  21. package/src/core/utils/utils.ts +29 -0
  22. package/src/index.ts +4 -0
  23. package/src/routes.json +9 -0
  24. package/src/stock-items/add-stock-item/transactions/printout/transactions-stockcard-printout.component.tsx +8 -12
  25. package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +8 -12
  26. package/src/stock-items/stock-items.resource.ts +5 -5
  27. package/src/stock-lookups/stock-lookups.resource.ts +2 -2
  28. package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +41 -16
  29. package/src/stock-operations/{add-stock-operation/received-items.component.tsx → received-items.component.tsx} +1 -1
  30. package/src/stock-operations/stock-operation-reference.component.tsx +64 -0
  31. package/src/stock-operations/stock-operation-status/stock-operation-status-row.tsx +77 -0
  32. package/src/stock-operations/stock-operation-status/stock-operation-status.scss +32 -0
  33. package/src/stock-operations/stock-operation-status/stock-operation-status.tsx +45 -0
  34. package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +30 -29
  35. package/src/stock-operations/stock-operation.utils.tsx +16 -79
  36. package/src/stock-operations/stock-operations-dialog/stock-operations-issue-stock-button.component.tsx +27 -39
  37. package/src/stock-operations/stock-operations-dialog/stock-operations-print-button.component.tsx +51 -59
  38. package/src/stock-operations/{stock-item-selector/stock-item-selector.resource.tsx → stock-operations-forms/hooks/useFilterableStockItems.ts} +4 -4
  39. package/src/stock-operations/stock-operations-forms/hooks/useFilteredOperationTypesByRoles.ts +30 -0
  40. package/src/stock-operations/stock-operations-forms/hooks/useOperationTypePermisions.ts +29 -0
  41. package/src/stock-operations/stock-operations-forms/hooks/useParties.ts +73 -0
  42. package/src/stock-operations/{users-selector/users-selector.resource.tsx → stock-operations-forms/hooks/useSearchUser.ts} +9 -7
  43. package/src/stock-operations/{batch-no-selector/batch-no-selector.resource.tsx → stock-operations-forms/hooks/useStockItemBatchNumbers.ts} +3 -3
  44. package/src/stock-operations/stock-operations-forms/hooks/useStockOperationLinks.ts +20 -0
  45. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +72 -0
  46. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +90 -0
  47. 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
  48. package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +157 -0
  49. package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +53 -0
  50. package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +56 -0
  51. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +59 -0
  52. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +216 -0
  53. package/src/stock-operations/{batch-no-selector → stock-operations-forms/input-components}/unique-batch-no-entry-input.component.tsx +12 -7
  54. package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +110 -0
  55. package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +111 -0
  56. package/src/stock-operations/stock-operations-forms/step1.test.tsx +303 -0
  57. package/src/stock-operations/stock-operations-forms/step2.test.tsx +250 -0
  58. package/src/stock-operations/stock-operations-forms/step3.test.tsx +223 -0
  59. package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +241 -0
  60. package/src/stock-operations/stock-operations-forms/steps/quantity-uom-cell.component.tsx +33 -0
  61. package/src/stock-operations/stock-operations-forms/steps/stock-availability-cell.component.tsx +51 -0
  62. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-batch-no-cell.component.tsx +40 -0
  63. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-cell.component.tsx +38 -0
  64. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-expiry-cell.component.tsx +41 -0
  65. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +281 -0
  66. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.scc.scss +64 -0
  67. package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +236 -0
  68. package/src/stock-operations/stock-operations-forms/stock-issue-form-initializer-with-related-requisition-operation.component.tsx +55 -0
  69. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +41 -0
  70. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +197 -0
  71. package/src/stock-operations/stock-operations-forms/stock-operation-form-header.component.tsx +166 -0
  72. package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +200 -0
  73. package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +111 -0
  74. package/src/stock-operations/stock-operations-forms/stock-operation-related-link.component.tsx +45 -0
  75. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +41 -0
  76. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +52 -0
  77. package/src/stock-operations/stock-operations-forms/stock-operations-form-utils.ts +32 -0
  78. package/src/stock-operations/stock-operations-table.component.tsx +20 -56
  79. package/src/stock-operations/stock-operations.resource.ts +16 -13
  80. package/src/stock-operations/validation-schema.ts +72 -14
  81. package/dist/766.js +0 -2
  82. package/dist/766.js.map +0 -1
  83. package/dist/822.js +0 -1
  84. package/dist/822.js.map +0 -1
  85. package/src/stock-operations/add-stock-operation/add-stock-operation.component.tsx +0 -349
  86. package/src/stock-operations/add-stock-operation/add-stock-operation.resource.tsx +0 -27
  87. package/src/stock-operations/add-stock-operation/add-stock-operation.scss +0 -60
  88. package/src/stock-operations/add-stock-operation/add-stock-operation.test.tsx +0 -192
  89. package/src/stock-operations/add-stock-operation/add-stock-operation.utils.tsx +0 -152
  90. package/src/stock-operations/add-stock-operation/add-stock-utils.ts +0 -103
  91. package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +0 -439
  92. package/src/stock-operations/add-stock-operation/base-operation-details.scss +0 -30
  93. package/src/stock-operations/add-stock-operation/stock-item-search/stock-item-search.component.tsx +0 -70
  94. package/src/stock-operations/add-stock-operation/stock-items-addition-row.component.tsx +0 -357
  95. package/src/stock-operations/add-stock-operation/stock-items-addition-row.resource.tsx +0 -0
  96. package/src/stock-operations/add-stock-operation/stock-items-addition-row.scss +0 -12
  97. package/src/stock-operations/add-stock-operation/stock-items-addition-row.test.tsx +0 -10
  98. package/src/stock-operations/add-stock-operation/stock-items-addition.component.scss +0 -17
  99. package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +0 -254
  100. package/src/stock-operations/add-stock-operation/stock-operation-context/useStockOperationContext.tsx +0 -16
  101. package/src/stock-operations/add-stock-operation/stock-operation-reference.component.tsx +0 -39
  102. package/src/stock-operations/add-stock-operation/stock-operation-related-link.component.tsx +0 -38
  103. package/src/stock-operations/add-stock-operation/stock-operation-status.component.tsx +0 -170
  104. package/src/stock-operations/add-stock-operation/stock-operation-submission.component.tsx +0 -189
  105. package/src/stock-operations/add-stock-operation/stock-operation-submission.test.tsx +0 -138
  106. package/src/stock-operations/add-stock-operation/types.ts +0 -55
  107. package/src/stock-operations/add-stock-operation/validationSchema.ts +0 -54
  108. package/src/stock-operations/batch-no-selector/batch-no-selector.component.tsx +0 -114
  109. package/src/stock-operations/batch-no-selector/batch-no-selector.scss +0 -0
  110. package/src/stock-operations/batch-no-selector/batch-no-selector.test.tsx +0 -101
  111. package/src/stock-operations/party-selector/party-selector.component.tsx +0 -59
  112. package/src/stock-operations/qty-uom-selector/qty-uom-selector.component.tsx +0 -65
  113. package/src/stock-operations/qty-uom-selector/qty-uom-selector.resource.tsx +0 -0
  114. package/src/stock-operations/qty-uom-selector/qty-uom-selector.scss +0 -0
  115. package/src/stock-operations/qty-uom-selector/qty-uom-selector.test.tsx +0 -10
  116. package/src/stock-operations/stock-item-selector/stock-item-selector.component.tsx +0 -69
  117. package/src/stock-operations/stock-item-selector/stock-item-selector.scss +0 -0
  118. package/src/stock-operations/stock-item-selector/stock-item-selector.test.tsx +0 -10
  119. package/src/stock-operations/stock-operation-reason-selector/stock-operation-reason-selector.component.tsx +0 -62
  120. package/src/stock-operations/users-selector/users-selector.component.tsx +0 -75
  121. /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
- });