@openmrs/esm-stock-management-app 1.0.1-pre.783 → 1.0.1-pre.788

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 (128) 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/922.js +1 -0
  13. package/dist/922.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/config-schema.ts +6 -0
  22. package/src/core/utils/utils.ts +29 -0
  23. package/src/index.ts +4 -0
  24. package/src/routes.json +9 -0
  25. package/src/stock-items/add-stock-item/transactions/printout/transactions-stockcard-printout.component.tsx +8 -12
  26. package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +8 -12
  27. package/src/stock-items/stock-items.resource.ts +5 -5
  28. package/src/stock-lookups/stock-lookups.resource.ts +2 -2
  29. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-items-table.scss +34 -0
  30. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-items-table.tsx +111 -0
  31. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-operation-expanded-row.component.tsx +87 -0
  32. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-operation-expanded-row.scss +31 -0
  33. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-operations-status.tsx +45 -0
  34. package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +41 -16
  35. package/src/stock-operations/stock-operation-reference.component.tsx +64 -0
  36. package/src/stock-operations/stock-operation-status/stock-operation-status-row.tsx +77 -0
  37. package/src/stock-operations/stock-operation-status/stock-operation-status.scss +32 -0
  38. package/src/stock-operations/stock-operation-status/stock-operation-status.tsx +45 -0
  39. package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +30 -29
  40. package/src/stock-operations/stock-operation.utils.tsx +16 -79
  41. package/src/stock-operations/stock-operations-dialog/stock-operations-issue-stock-button.component.tsx +27 -39
  42. package/src/stock-operations/stock-operations-dialog/stock-operations-print-button.component.tsx +51 -59
  43. package/src/stock-operations/{stock-item-selector/stock-item-selector.resource.tsx → stock-operations-forms/hooks/useFilterableStockItems.ts} +4 -4
  44. package/src/stock-operations/stock-operations-forms/hooks/useFilteredOperationTypesByRoles.ts +30 -0
  45. package/src/stock-operations/stock-operations-forms/hooks/useOperationTypePermisions.ts +29 -0
  46. package/src/stock-operations/stock-operations-forms/hooks/useParties.ts +73 -0
  47. package/src/stock-operations/{users-selector/users-selector.resource.tsx → stock-operations-forms/hooks/useSearchUser.ts} +9 -7
  48. package/src/stock-operations/{batch-no-selector/batch-no-selector.resource.tsx → stock-operations-forms/hooks/useStockItemBatchNumbers.ts} +3 -3
  49. package/src/stock-operations/stock-operations-forms/hooks/useStockOperationLinks.ts +20 -0
  50. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +72 -0
  51. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +90 -0
  52. 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
  53. package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +157 -0
  54. package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +53 -0
  55. package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +79 -0
  56. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +59 -0
  57. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +216 -0
  58. package/src/stock-operations/{batch-no-selector → stock-operations-forms/input-components}/unique-batch-no-entry-input.component.tsx +12 -7
  59. package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +110 -0
  60. package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +111 -0
  61. package/src/stock-operations/stock-operations-forms/step1.test.tsx +303 -0
  62. package/src/stock-operations/stock-operations-forms/step2.test.tsx +254 -0
  63. package/src/stock-operations/stock-operations-forms/step3.test.tsx +223 -0
  64. package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +241 -0
  65. package/src/stock-operations/stock-operations-forms/steps/quantity-uom-cell.component.tsx +33 -0
  66. package/src/stock-operations/stock-operations-forms/steps/received-items.component.tsx +110 -0
  67. package/src/stock-operations/stock-operations-forms/steps/stock-availability-cell.component.tsx +51 -0
  68. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-batch-no-cell.component.tsx +40 -0
  69. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-cell.component.tsx +50 -0
  70. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-expiry-cell.component.tsx +41 -0
  71. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +281 -0
  72. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.scc.scss +64 -0
  73. package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +243 -0
  74. package/src/stock-operations/stock-operations-forms/stock-issue-form-initializer-with-related-requisition-operation.component.tsx +55 -0
  75. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +41 -0
  76. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +211 -0
  77. package/src/stock-operations/stock-operations-forms/stock-operation-form-header.component.tsx +166 -0
  78. package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +205 -0
  79. package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +111 -0
  80. package/src/stock-operations/stock-operations-forms/stock-operation-related-link.component.tsx +45 -0
  81. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +41 -0
  82. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +52 -0
  83. package/src/stock-operations/stock-operations-forms/stock-operations-form-utils.ts +32 -0
  84. package/src/stock-operations/stock-operations-table.component.tsx +57 -92
  85. package/src/stock-operations/stock-operations.resource.ts +16 -13
  86. package/src/stock-operations/validation-schema.ts +72 -14
  87. package/dist/766.js +0 -2
  88. package/dist/766.js.map +0 -1
  89. package/dist/822.js +0 -1
  90. package/dist/822.js.map +0 -1
  91. package/src/stock-operations/add-stock-operation/add-stock-operation.component.tsx +0 -349
  92. package/src/stock-operations/add-stock-operation/add-stock-operation.resource.tsx +0 -27
  93. package/src/stock-operations/add-stock-operation/add-stock-operation.scss +0 -60
  94. package/src/stock-operations/add-stock-operation/add-stock-operation.test.tsx +0 -192
  95. package/src/stock-operations/add-stock-operation/add-stock-operation.utils.tsx +0 -152
  96. package/src/stock-operations/add-stock-operation/add-stock-utils.ts +0 -103
  97. package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +0 -439
  98. package/src/stock-operations/add-stock-operation/base-operation-details.scss +0 -30
  99. package/src/stock-operations/add-stock-operation/received-items.component.tsx +0 -93
  100. package/src/stock-operations/add-stock-operation/stock-item-search/stock-item-search.component.tsx +0 -70
  101. package/src/stock-operations/add-stock-operation/stock-items-addition-row.component.tsx +0 -357
  102. package/src/stock-operations/add-stock-operation/stock-items-addition-row.resource.tsx +0 -0
  103. package/src/stock-operations/add-stock-operation/stock-items-addition-row.scss +0 -12
  104. package/src/stock-operations/add-stock-operation/stock-items-addition-row.test.tsx +0 -10
  105. package/src/stock-operations/add-stock-operation/stock-items-addition.component.scss +0 -17
  106. package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +0 -254
  107. package/src/stock-operations/add-stock-operation/stock-operation-context/useStockOperationContext.tsx +0 -16
  108. package/src/stock-operations/add-stock-operation/stock-operation-reference.component.tsx +0 -39
  109. package/src/stock-operations/add-stock-operation/stock-operation-related-link.component.tsx +0 -38
  110. package/src/stock-operations/add-stock-operation/stock-operation-status.component.tsx +0 -170
  111. package/src/stock-operations/add-stock-operation/stock-operation-submission.component.tsx +0 -189
  112. package/src/stock-operations/add-stock-operation/stock-operation-submission.test.tsx +0 -138
  113. package/src/stock-operations/add-stock-operation/types.ts +0 -55
  114. package/src/stock-operations/add-stock-operation/validationSchema.ts +0 -54
  115. package/src/stock-operations/batch-no-selector/batch-no-selector.component.tsx +0 -114
  116. package/src/stock-operations/batch-no-selector/batch-no-selector.scss +0 -0
  117. package/src/stock-operations/batch-no-selector/batch-no-selector.test.tsx +0 -101
  118. package/src/stock-operations/party-selector/party-selector.component.tsx +0 -59
  119. package/src/stock-operations/qty-uom-selector/qty-uom-selector.component.tsx +0 -65
  120. package/src/stock-operations/qty-uom-selector/qty-uom-selector.resource.tsx +0 -0
  121. package/src/stock-operations/qty-uom-selector/qty-uom-selector.scss +0 -0
  122. package/src/stock-operations/qty-uom-selector/qty-uom-selector.test.tsx +0 -10
  123. package/src/stock-operations/stock-item-selector/stock-item-selector.component.tsx +0 -69
  124. package/src/stock-operations/stock-item-selector/stock-item-selector.scss +0 -0
  125. package/src/stock-operations/stock-item-selector/stock-item-selector.test.tsx +0 -10
  126. package/src/stock-operations/stock-operation-reason-selector/stock-operation-reason-selector.component.tsx +0 -62
  127. package/src/stock-operations/users-selector/users-selector.component.tsx +0 -75
  128. /package/dist/{766.js.LICENSE.txt → 493.js.LICENSE.txt} +0 -0
@@ -1,93 +1,30 @@
1
+ import { showModal } from '@openmrs/esm-framework';
1
2
  import React from 'react';
2
- import { closeOverlay, launchOverlay } from '../core/components/overlay/hook';
3
- import { FetchResponse, restBaseUrl, showModal, showSnackbar } from '@openmrs/esm-framework';
4
3
  import { TFunction } from 'react-i18next';
5
- import { StockOperationDTO } from '../core/api/types/stockOperation/StockOperationDTO';
6
- import { createStockOperation, updateStockOperation } from './stock-operations.resource';
7
- import AddStockOperation from './add-stock-operation/add-stock-operation.component';
8
- import { OperationType, StockOperationType } from '../core/api/types/stockOperation/StockOperationType';
9
4
  import { useLocation } from 'react-router-dom';
10
- import { extractErrorMessagesFromResponse } from '../constants';
11
- import { handleMutate } from '../utils';
12
-
13
- export const addOrEditStockOperation = async (
14
- t: TFunction,
15
- stockOperation: StockOperationDTO,
16
- isEditing: boolean,
17
- operation?: StockOperationType,
18
- ) => {
19
- const payload = stockOperation;
20
- try {
21
- if (operation.operationType === 'requisition') {
22
- delete payload.destinationName;
23
- }
24
- if (operation.operationType === OperationType.STOCK_ISSUE_OPERATION_TYPE) {
25
- const stockIssueOpsTypeUuid = '66666666-6666-6666-6666-666666666666';
26
- delete payload.completedDate;
27
- delete payload.completedBy;
28
- delete payload.completedByFamilyName;
29
- delete payload.completedByGivenName;
30
- delete payload.operationTypeUuid;
31
- delete payload.permission;
32
- delete payload.locked;
33
-
34
- payload['operationTypeUuid'] = stockIssueOpsTypeUuid;
35
- }
36
- const response: FetchResponse<StockOperationDTO> = await (isEditing ? updateStockOperation : createStockOperation)(
37
- payload,
38
- );
39
-
40
- if (response?.data) {
41
- handleMutate(`${restBaseUrl}/stockmanagement/stockoperation`);
42
- showSnackbar({
43
- isLowContrast: true,
44
- title: isEditing
45
- ? t('editStockOperation', 'Edit stock operation')
46
- : t('addStockOperation', 'Add stock operation'),
47
- kind: 'success',
48
- subtitle: isEditing
49
- ? t('stockOperationEdited', 'Stock operation edited successfully')
50
- : t('stockOperationAdded', 'Stock operation added successfully'),
51
- });
52
-
53
- closeOverlay();
54
- }
55
- } catch (error) {
56
- const errorMessages = extractErrorMessagesFromResponse(error);
57
- showSnackbar({
58
- subtitle: errorMessages.join(', '),
59
- title: t('errorSavingForm', 'Error on saving form'),
60
- kind: 'error',
61
- isLowContrast: true,
62
- });
63
- }
64
- };
5
+ import { StockOperationDTO } from '../core/api/types/stockOperation/StockOperationDTO';
6
+ import { StockOperationType } from '../core/api/types/stockOperation/StockOperationType';
7
+ import { launchOverlay } from '../core/components/overlay/hook';
8
+ import StockOperationForm from './stock-operations-forms/stock-operation-form.component';
65
9
 
66
- export const launchAddOrEditDialog = (
10
+ export const launchStockoperationAddOrEditDialog = (
67
11
  t: TFunction,
68
- stockOperation: StockOperationDTO,
69
- isEditing: boolean,
70
- operation?: StockOperationType,
71
- operations?: StockOperationType[],
72
- canPrint?: boolean,
12
+ operationType: StockOperationType,
13
+ stockOperation?: StockOperationDTO,
14
+ stockRequisitionUuid?: string, // Only suplied on stock issue (when overlay is launched for stock issue)
73
15
  ) => {
74
- const printEnabled = canPrint !== undefined ? canPrint : stockOperation?.status === 'COMPLETED';
75
-
76
16
  launchOverlay(
77
- isEditing
17
+ stockOperation
78
18
  ? t('editOperationTitle', 'Edit {{operationType}}', {
79
19
  operationType: stockOperation?.operationTypeName,
80
20
  })
81
21
  : t('newOperationTitle', 'New: {{operationName}}', {
82
- operationName: operation?.name,
22
+ operationName: operationType?.name,
83
23
  }),
84
- <AddStockOperation
85
- model={stockOperation}
86
- onSave={(stockOperation) => addOrEditStockOperation(t, stockOperation, isEditing, operation)}
87
- isEditing={isEditing}
88
- operation={operation}
89
- canEdit={isEditing ? (stockOperation?.status === 'NEW' ? true : false) : true}
90
- canPrint={printEnabled}
24
+ <StockOperationForm
25
+ stockOperationType={operationType}
26
+ stockOperation={stockOperation}
27
+ stockRequisitionUuid={stockRequisitionUuid}
91
28
  />,
92
29
  );
93
30
  };
@@ -100,7 +37,7 @@ export function getStockOperationUniqueId() {
100
37
  return `${new Date().getTime()}-${Math.random().toString(36).substring(2, 16)}`;
101
38
  }
102
39
 
103
- export const showActionDialogButton = async (title: string, requireReason: boolean, operation: StockOperationDTO) => {
40
+ export const showActionDialogButton = (title: string, requireReason: boolean, operation: StockOperationDTO) => {
104
41
  const dispose = showModal('stock-operation-dialog', {
105
42
  title: title,
106
43
  operation: operation,
@@ -1,60 +1,48 @@
1
- import React from 'react';
1
+ import React, { useEffect, useMemo } from 'react';
2
2
 
3
- import { Button } from '@carbon/react';
4
- import { useTranslation } from 'react-i18next';
3
+ import { Button, InlineLoading } from '@carbon/react';
5
4
  import { DeliveryTruck } from '@carbon/react/icons';
5
+ import { useTranslation } from 'react-i18next';
6
6
  import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
7
- import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
8
- import { launchAddOrEditDialog } from '../stock-operation.utils';
7
+ import { OperationType } from '../../core/api/types/stockOperation/StockOperationType';
8
+ import { useStockOperationTypes } from '../../stock-lookups/stock-lookups.resource';
9
+ import { launchStockoperationAddOrEditDialog } from '../stock-operation.utils';
10
+ import { showSnackbar } from '@openmrs/esm-framework';
9
11
 
10
12
  interface StockOperationIssueStockButtonProps {
11
13
  operation: StockOperationDTO;
12
- operations: StockOperationType[];
13
14
  }
14
15
 
15
- const StockOperationIssueStockButton: React.FC<StockOperationIssueStockButtonProps> = ({ operation, operations }) => {
16
+ const StockOperationIssueStockButton: React.FC<StockOperationIssueStockButtonProps> = ({ operation }) => {
16
17
  const { t } = useTranslation();
17
- const type: StockOperationType = {
18
- uuid: '',
19
- name: 'Stock Issue',
20
- description: '',
21
- operationType: 'stockissue',
22
- hasSource: false,
23
- sourceType: 'Location',
24
- hasDestination: false,
25
- destinationType: 'Location',
26
- hasRecipient: false,
27
- recipientRequired: false,
28
- availableWhenReserved: false,
29
- allowExpiredBatchNumbers: false,
30
- stockOperationTypeLocationScopes: [],
31
- creator: undefined,
32
- dateCreated: undefined,
33
- changedBy: undefined,
34
- dateChanged: undefined,
35
- dateVoided: undefined,
36
- voidedBy: undefined,
37
- voidReason: '',
38
- voided: false,
39
- };
18
+ const { error, isLoading, types } = useStockOperationTypes();
19
+ const stockIssueOperationType = useMemo(
20
+ () => types?.results?.find((type) => type.operationType === OperationType.STOCK_ISSUE_OPERATION_TYPE),
21
+ [types],
22
+ );
40
23
 
41
- const modifiedOperation = addRequisitionStockOperation(operation);
42
24
  const handleButtonClick = () => {
43
- launchAddOrEditDialog(t, modifiedOperation, false, type, operations, false);
25
+ launchStockoperationAddOrEditDialog(t, stockIssueOperationType, undefined, operation.uuid);
44
26
  };
45
27
 
28
+ useEffect(() => {
29
+ if (error) {
30
+ showSnackbar({
31
+ kind: 'error',
32
+ title: t('stockOperationError', 'Error loading stock operation types'),
33
+ subtitle: error?.message,
34
+ });
35
+ }
36
+ }, [error, t]);
37
+
38
+ if (isLoading)
39
+ return <InlineLoading description="" iconDescription={t('loadingOperationTypes', 'Loading operation types')} />;
40
+
46
41
  return (
47
42
  <Button onClick={handleButtonClick} kind="tertiary" renderIcon={(props) => <DeliveryTruck size={16} {...props} />}>
48
43
  {t('issueStock', 'Issue Stock ')}
49
44
  </Button>
50
45
  );
51
46
  };
52
- function addRequisitionStockOperation(stockOperation) {
53
- const { uuid } = stockOperation;
54
- return {
55
- ...stockOperation,
56
- requisitionStockOperationUuid: uuid,
57
- };
58
- }
59
47
 
60
48
  export default StockOperationIssueStockButton;
@@ -1,50 +1,50 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
 
3
3
  import { Button } from '@carbon/react';
4
- import { useTranslation } from 'react-i18next';
5
4
  import { Printer } from '@carbon/react/icons';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { StockItemInventory } from '../../core/api/types/stockItem/StockItemInventory';
6
7
  import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
7
8
  import { StockOperationItemCost } from '../../core/api/types/stockOperation/StockOperationItemCost';
8
- import { StockItemInventory } from '../../core/api/types/stockItem/StockItemInventory';
9
9
 
10
- import { StockItemInventoryFilter } from '../../stock-items/stock-items.resource';
10
+ import { InlineLoading } from '@carbon/react';
11
+ import { showSnackbar } from '@openmrs/esm-framework';
12
+ import { extractErrorMessagesFromResponse } from '../../constants';
11
13
  import { ResourceRepresentation } from '../../core/api/api';
12
- import { BuildStockOperationData } from '../stock-print-reports/StockOperationReport';
14
+ import { OperationType } from '../../core/api/types/stockOperation/StockOperationType';
15
+ import { StockItemInventoryFilter } from '../../stock-items/stock-items.resource';
16
+ import {
17
+ getStockItemInventory,
18
+ getStockOperation,
19
+ getStockOperationItemsCost,
20
+ useStockOperationAndItems,
21
+ } from '../stock-operations.resource';
13
22
  import { PrintGoodsReceivedNoteStockOperation } from '../stock-print-reports/GoodsReceivedNote';
14
- import { PrintTransferOutStockOperation } from '../stock-print-reports/StockTransferDocument';
15
23
  import { PrintRequisitionStockOperation } from '../stock-print-reports/RequisitionDocument';
16
- import { getStockItemInventory, getStockOperation, getStockOperationItemsCost } from '../stock-operations.resource';
24
+ import { BuildStockOperationData } from '../stock-print-reports/StockOperationReport';
25
+ import { PrintTransferOutStockOperation } from '../stock-print-reports/StockTransferDocument';
17
26
 
18
27
  interface StockOperationCancelButtonProps {
19
28
  operation: StockOperationDTO;
20
29
  }
21
30
 
22
- const StockOperationPrintButton: React.FC<StockOperationCancelButtonProps> = ({ operation }) => {
31
+ const StockOperationPrintButton: React.FC<StockOperationCancelButtonProps> = ({ operation: _operation }) => {
23
32
  const { t } = useTranslation();
24
-
33
+ const { isLoading, items: operation, error } = useStockOperationAndItems(_operation.uuid);
34
+ const [loading, setLoading] = useState(false);
25
35
  const onPrintStockOperation = async () => {
36
+ setLoading(true);
26
37
  try {
27
38
  let parentOperation: StockOperationDTO | null | undefined;
28
39
  let itemsCost: StockOperationItemCost[] | null | undefined = null;
29
40
  let itemInventory: StockItemInventory[] | null | undefined = null;
30
41
 
31
42
  if (operation.requisitionStockOperationUuid) {
32
- // get stock operation
33
- getStockOperation(operation.requisitionStockOperationUuid)
34
- .then((payload: any) => {
35
- if ((payload as any).error) {
36
- return;
37
- }
38
- parentOperation = payload;
39
- })
40
- .catch((error: any) => {
41
- if ((error as any).error) {
42
- return;
43
- }
44
- return;
45
- });
43
+ // get related requisition stock operation
44
+ const response = await getStockOperation(operation.requisitionStockOperationUuid);
45
+ parentOperation = response.data;
46
46
  if (!parentOperation) {
47
- return null;
47
+ return;
48
48
  }
49
49
  }
50
50
 
@@ -59,19 +59,8 @@ const StockOperationPrintButton: React.FC<StockOperationCancelButtonProps> = ({
59
59
  if (operation?.uuid) {
60
60
  inventoryFilter.stockOperationUuid = operation.uuid;
61
61
  }
62
- getStockOperationItemsCost(inventoryFilter)
63
- .then((payload: any) => {
64
- if ((payload as any).error) {
65
- return;
66
- }
67
- itemsCost = payload?.results;
68
- })
69
- .catch((error: any) => {
70
- if ((error as any).error) {
71
- return;
72
- }
73
- return;
74
- });
62
+ const res = await getStockOperationItemsCost(inventoryFilter);
63
+ itemsCost = res.data?.results;
75
64
  }
76
65
  }
77
66
  const enableBalance = true;
@@ -88,35 +77,22 @@ const StockOperationPrintButton: React.FC<StockOperationCancelButtonProps> = ({
88
77
  inventoryFilter.groupBy = 'LocationStockItem';
89
78
  inventoryFilter.includeStockItemName = 'true';
90
79
 
91
- inventoryFilter.date = JSON.stringify(parentOperation?.dateCreated ?? operation?.dateCreated);
92
-
80
+ inventoryFilter.date = (parentOperation?.dateCreated ?? operation?.dateCreated) as any;
93
81
  // get stock item inventory
94
- getStockItemInventory(inventoryFilter)
95
- .then((payload: any) => {
96
- if ((payload as any).error) {
97
- return;
98
- }
99
- itemInventory = payload?.results;
100
- })
101
- .catch((error: any) => {
102
- if ((error as any).error) {
103
- return;
104
- }
105
- return;
106
- });
82
+ const res = await getStockItemInventory(inventoryFilter);
83
+ itemInventory = res.data?.results;
107
84
  }
108
-
109
85
  const data = await BuildStockOperationData(
110
86
  operation,
111
- operation.stockOperationItems,
87
+ operation.stockOperationItems ?? _operation?.stockOperationItems ?? [],
112
88
  parentOperation,
113
89
  itemsCost,
114
90
  itemInventory,
115
91
  );
116
92
  if (data) {
117
- if (operation?.operationType === 'receipt') {
93
+ if (operation?.operationType === OperationType.RECEIPT_OPERATION_TYPE) {
118
94
  await PrintGoodsReceivedNoteStockOperation(data);
119
- } else if (operation?.operationType === 'transferout') {
95
+ } else if (operation?.operationType === OperationType.TRANSFER_OUT_OPERATION_TYPE) {
120
96
  await PrintTransferOutStockOperation(data);
121
97
  } else {
122
98
  await PrintRequisitionStockOperation(data);
@@ -124,14 +100,30 @@ const StockOperationPrintButton: React.FC<StockOperationCancelButtonProps> = ({
124
100
  } else {
125
101
  console.info(data);
126
102
  }
127
- } catch (e) {
103
+ } catch (e: any) {
128
104
  console.info(e);
105
+ showSnackbar({
106
+ kind: 'error',
107
+ title: t('errorPrintingStockOperation', 'Error printing stock operation'),
108
+ subtitle: extractErrorMessagesFromResponse(e).join(', '),
109
+ });
110
+ } finally {
111
+ setLoading(false);
129
112
  }
130
113
  };
131
114
 
132
115
  return (
133
- <Button onClick={onPrintStockOperation} kind="tertiary" renderIcon={(props) => <Printer size={16} {...props} />}>
134
- {t('print', 'Print')}
116
+ <Button
117
+ onClick={onPrintStockOperation}
118
+ kind="tertiary"
119
+ disabled={isLoading || loading}
120
+ renderIcon={(props) => <Printer size={16} {...props} />}
121
+ >
122
+ {loading || isLoading ? (
123
+ <InlineLoading description={t('loading', 'Loading') + '...'} iconDescription={t('loading', 'Loading')} />
124
+ ) : (
125
+ t('print', 'Print')
126
+ )}
135
127
  </Button>
136
128
  );
137
129
  };
@@ -1,9 +1,9 @@
1
- import { UserFilterCriteria } from '../../stock-lookups/stock-lookups.resource';
2
1
  import { useEffect, useState } from 'react';
3
- import { ResourceRepresentation } from '../../core/api/api';
4
- import { StockItemFilter, useStockItems as useStockItemsData } from '../../stock-items/stock-items.resource';
2
+ import { StockItemFilter, useStockItems as useStockItemsData } from '../../../stock-items/stock-items.resource';
3
+ import { UserFilterCriteria } from '../../../stock-lookups/stock-lookups.resource';
4
+ import { ResourceRepresentation } from '../../../core/api/api';
5
5
 
6
- export function useStockItems(filter?: StockItemFilter) {
6
+ export function useFilterableStockItems(filter?: StockItemFilter) {
7
7
  const [conceptFilter, setConceptFilter] = useState<UserFilterCriteria>(
8
8
  filter || {
9
9
  v: ResourceRepresentation.Default,
@@ -0,0 +1,30 @@
1
+ import { useMemo } from 'react';
2
+ import { useStockOperationTypes, useUserRoles } from '../../../stock-lookups/stock-lookups.resource';
3
+
4
+ const useFilteredOperationTypesByRoles = () => {
5
+ const {
6
+ types: { results },
7
+ isLoading: isStockOperationTypesLoading,
8
+ error: stockOperationTypesError,
9
+ } = useStockOperationTypes();
10
+
11
+ const { userRoles, isLoading: isUserRolesLoading, error: userRolesError } = useUserRoles();
12
+
13
+ const operationTypes = useMemo(() => {
14
+ const applicablePrivilegeScopes = userRoles?.operationTypes?.map((p) => p.operationTypeUuid) || [];
15
+ const uniqueApplicablePrivilegeScopes = [...new Set(applicablePrivilegeScopes)];
16
+
17
+ return results?.filter((p) => uniqueApplicablePrivilegeScopes.includes(p.uuid)) || [];
18
+ }, [results, userRoles]);
19
+
20
+ const isLoading = isStockOperationTypesLoading || isUserRolesLoading;
21
+ const error = stockOperationTypesError || userRolesError;
22
+
23
+ return {
24
+ operationTypes,
25
+ isLoading,
26
+ error,
27
+ };
28
+ };
29
+
30
+ export default useFilteredOperationTypesByRoles;
@@ -0,0 +1,29 @@
1
+ import {
2
+ operationFromString,
3
+ StockOperationType,
4
+ StockOperationTypeCanCapturePurchasePrice,
5
+ StockOperationTypeHasPrint,
6
+ StockOperationTypeIsNegativeQtyAllowed,
7
+ StockOperationTypeIsQuantityOptional,
8
+ StockOperationTypeRequiresActualBatchInformation,
9
+ StockOperationTypeRequiresBatchUuid,
10
+ StockOperationTypeRequiresDispatchAcknowledgement,
11
+ StockOperationTypeRequiresStockAdjustmentReason,
12
+ } from '../../../core/api/types/stockOperation/StockOperationType';
13
+
14
+ const useOperationTypePermisions = (stockoperationType: StockOperationType) => {
15
+ const opType = operationFromString(stockoperationType.operationType);
16
+ return {
17
+ isNegativeQuantityAllowed: StockOperationTypeIsNegativeQtyAllowed(opType),
18
+ requiresBatchUuid: StockOperationTypeRequiresBatchUuid(opType),
19
+ requiresActualBatchInfo: StockOperationTypeRequiresActualBatchInformation(opType),
20
+ isQuantityOptional: StockOperationTypeIsQuantityOptional(opType),
21
+ canCaptureQuantityPrice: StockOperationTypeCanCapturePurchasePrice(opType),
22
+ requiresStockAdjustmentReason: StockOperationTypeRequiresStockAdjustmentReason(opType),
23
+ requiresDispatchAcknowledgement: StockOperationTypeRequiresDispatchAcknowledgement(opType),
24
+ allowExpiredBatchNumbers: stockoperationType?.allowExpiredBatchNumbers ?? false,
25
+ allowPrinting: StockOperationTypeHasPrint(opType),
26
+ };
27
+ };
28
+
29
+ export default useOperationTypePermisions;
@@ -0,0 +1,73 @@
1
+ import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+ import React, { useCallback, useMemo } from 'react';
3
+ import useSWR from 'swr';
4
+ import { Party } from '../../../core/api/types/Party';
5
+ import { LocationTypeLocation, LocationTypeOther } from '../../../core/api/types/stockOperation/LocationType';
6
+ import { StockOperationType } from '../../../core/api/types/stockOperation/StockOperationType';
7
+
8
+ const useParties = (stockOperationType: StockOperationType) => {
9
+ const apiUrl = `${restBaseUrl}/stockmanagement/party?v=default`;
10
+ const { data, isLoading, mutate, error } = useSWR<FetchResponse<{ results: Array<Party> }>>(apiUrl, openmrsFetch);
11
+ const sourceTags = useMemo(() => {
12
+ return (
13
+ stockOperationType?.stockOperationTypeLocationScopes
14
+ ?.filter((p) => stockOperationType?.hasSource && p.isSource)
15
+ .map((p) => p.locationTag) ?? []
16
+ );
17
+ }, [stockOperationType]);
18
+
19
+ const destinationTags = useMemo(() => {
20
+ return (
21
+ stockOperationType?.stockOperationTypeLocationScopes
22
+ ?.filter((p) => stockOperationType?.hasDestination && p.isDestination)
23
+ .map((p) => p.locationTag) ?? []
24
+ );
25
+ }, [stockOperationType]);
26
+
27
+ const sourcePartiesFilter = useCallback(
28
+ (p: Party) => {
29
+ return (
30
+ (p.locationUuid &&
31
+ stockOperationType?.sourceType === LocationTypeLocation &&
32
+ (sourceTags.length === 0 || (p.tags && sourceTags.some((x) => p.tags.includes(x))))) ||
33
+ (p.stockSourceUuid && stockOperationType?.sourceType === LocationTypeOther)
34
+ );
35
+ },
36
+ [stockOperationType, sourceTags],
37
+ );
38
+
39
+ const destinationPartiesFilter = useCallback(
40
+ (p: Party) => {
41
+ return (
42
+ (p.locationUuid &&
43
+ stockOperationType?.destinationType === LocationTypeLocation &&
44
+ (destinationTags.length === 0 || (p.tags && destinationTags.some((x) => p.tags.includes(x))))) ||
45
+ (p.stockSourceUuid && stockOperationType?.destinationType === LocationTypeOther)
46
+ );
47
+ },
48
+ [stockOperationType, destinationTags],
49
+ );
50
+
51
+ const sourceParties = useMemo(() => {
52
+ return data?.data?.results?.filter(sourcePartiesFilter) ?? [];
53
+ }, [data, sourcePartiesFilter]);
54
+
55
+ const destinationParties = useMemo(() => {
56
+ return data?.data?.results?.filter(destinationPartiesFilter) ?? [];
57
+ }, [data, destinationPartiesFilter]);
58
+
59
+ return {
60
+ parties: data?.data?.results ?? [],
61
+ isLoading,
62
+ mutate,
63
+ sourceParties,
64
+ destinationParties,
65
+ sourcePartiesFilter,
66
+ destinationPartiesFilter,
67
+ error,
68
+ sourceTags,
69
+ destinationTags,
70
+ };
71
+ };
72
+
73
+ export default useParties;
@@ -1,8 +1,8 @@
1
- import { ConceptFilterCriteria, UserFilterCriteria, useUsers } from '../../stock-lookups/stock-lookups.resource';
2
- import { useEffect, useState } from 'react';
3
- import { ResourceRepresentation } from '../../core/api/api';
1
+ import React, { useEffect, useState } from 'react';
2
+ import { ConceptFilterCriteria, UserFilterCriteria, useUsers } from '../../../stock-lookups/stock-lookups.resource';
3
+ import { ResourceRepresentation } from '../../../core/api/api';
4
4
 
5
- export function useUsersHook(filter?: ConceptFilterCriteria) {
5
+ const useSearchUser = (filter?: ConceptFilterCriteria) => {
6
6
  const [conceptFilter, setConceptFilter] = useState<UserFilterCriteria>(
7
7
  filter || {
8
8
  v: ResourceRepresentation.Default,
@@ -20,12 +20,12 @@ export function useUsersHook(filter?: ConceptFilterCriteria) {
20
20
 
21
21
  // Drug filter type
22
22
  const [limit, setLimit] = useState(filter?.limit || 10);
23
- const [representation, setRepresentation] = useState(filter?.v || ResourceRepresentation.Default);
23
+ const [representation, setRepresentation] = useState<string>(filter?.v || ResourceRepresentation.Default);
24
24
 
25
25
  useEffect(() => {
26
26
  setConceptFilter({
27
27
  startIndex: 0,
28
- v: representation,
28
+ v: representation as ResourceRepresentation,
29
29
  limit: limit,
30
30
  q: searchString,
31
31
  });
@@ -38,4 +38,6 @@ export function useUsersHook(filter?: ConceptFilterCriteria) {
38
38
  setSearchString,
39
39
  isLoading,
40
40
  };
41
- }
41
+ };
42
+
43
+ export default useSearchUser;
@@ -1,8 +1,8 @@
1
- import { StockBatchFilter, useStockBatches } from '../../stock-items/stock-items.resource';
2
1
  import { useEffect, useState } from 'react';
3
- import { ResourceRepresentation } from '../../core/api/api';
2
+ import { ResourceRepresentation } from '../../../core/api/api';
3
+ import { StockBatchFilter, useStockBatches } from '../../../stock-items/stock-items.resource';
4
4
 
5
- export function useStockItemBatchNos(stockItemUuid: string) {
5
+ export function useStockItemBatchNumbers(stockItemUuid: string) {
6
6
  const [conceptFilter, setConceptFilter] = useState<StockBatchFilter>({
7
7
  v: ResourceRepresentation.Default,
8
8
  limit: 10,
@@ -0,0 +1,20 @@
1
+ import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
3
+ import { StockOperationLinkDTO } from '../../../core/api/types/stockOperation/StockOperationLinkDTO';
4
+
5
+ const useStockOperationLinks = (stockOperationUuid?: string) => {
6
+ const apiUrl = `${restBaseUrl}/stockmanagement/stockoperationlink?v=default&q=${stockOperationUuid}`;
7
+ const { data, error, isLoading, mutate } = useSWR<
8
+ FetchResponse<{
9
+ results: Array<StockOperationLinkDTO>;
10
+ }>
11
+ >(stockOperationUuid ? apiUrl : null, openmrsFetch);
12
+ return {
13
+ error,
14
+ isLoading,
15
+ mutate,
16
+ operationLinks: data?.data?.results ?? [],
17
+ };
18
+ };
19
+
20
+ export default useStockOperationLinks;