@openmrs/esm-stock-management-app 1.0.1-pre.716 → 1.0.1-pre.724

Sign up to get free protection for your applications and to get access to all the features.
@@ -134,10 +134,10 @@
134
134
  "initial": true,
135
135
  "entry": true,
136
136
  "recorded": false,
137
- "size": 5409050,
137
+ "size": 5412981,
138
138
  "sizes": {
139
139
  "consume-shared": 252,
140
- "javascript": 5387101,
140
+ "javascript": 5391032,
141
141
  "share-init": 252,
142
142
  "runtime": 21445
143
143
  },
@@ -154,7 +154,7 @@
154
154
  "auxiliaryFiles": [
155
155
  "main.js.map"
156
156
  ],
157
- "hash": "549717c7f94ac2f7",
157
+ "hash": "f071e74f33c1c1fb",
158
158
  "childrenByOrder": {}
159
159
  },
160
160
  {
@@ -348,9 +348,9 @@
348
348
  "initial": false,
349
349
  "entry": false,
350
350
  "recorded": false,
351
- "size": 16572,
351
+ "size": 16573,
352
352
  "sizes": {
353
- "javascript": 16572
353
+ "javascript": 16573
354
354
  },
355
355
  "names": [],
356
356
  "idHints": [],
@@ -364,7 +364,7 @@
364
364
  "auxiliaryFiles": [
365
365
  "606.js.map"
366
366
  ],
367
- "hash": "35104a430eb0ea12",
367
+ "hash": "4645f30c4d9bba07",
368
368
  "childrenByOrder": {}
369
369
  },
370
370
  {
@@ -607,9 +607,9 @@
607
607
  "initial": false,
608
608
  "entry": false,
609
609
  "recorded": false,
610
- "size": 1750178,
610
+ "size": 1754109,
611
611
  "sizes": {
612
- "javascript": 1749968,
612
+ "javascript": 1753899,
613
613
  "consume-shared": 210
614
614
  },
615
615
  "names": [],
@@ -623,7 +623,7 @@
623
623
  "auxiliaryFiles": [
624
624
  "973.js.map"
625
625
  ],
626
- "hash": "3c6bcfc1834a0d12",
626
+ "hash": "3f51c8b4b2de28f9",
627
627
  "childrenByOrder": {}
628
628
  }
629
629
  ]
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.24.0"},"extensions":[{"name":"stock-nav-menu","slot":"stock-sidebar-slot","component":"stockNavMenu","online":true,"offline":true},{"name":"overview-db-link","slot":"stock-page-dashboard-slot","component":"stockOverviewLink","meta":{"name":"overview","slot":"overview-dashboard-slot","title":"overview"},"order":0,"online":true,"offline":true},{"name":"stock-overview-db","slot":"overview-dashboard-slot","component":"stockOverview"},{"name":"operations-db-link","slot":"stock-page-dashboard-slot","component":"stockOperationsLink","meta":{"name":"operations","slot":"operations-dashboard-slot","title":"operations"},"order":2,"online":true,"offline":true},{"name":"stock-operations-db","slot":"operations-dashboard-slot","component":"stockOperations"},{"name":"items-db-link","slot":"stock-page-dashboard-slot","component":"stockItemsLink","meta":{"name":"items","slot":"items-dashboard-slot","title":"items"},"order":1,"online":true,"offline":true},{"name":"stock-items-db","slot":"items-dashboard-slot","component":"stockItems"},{"name":"user-scopes-db-link","slot":"stock-page-dashboard-slot","component":"stockUserScopesLink","meta":{"name":"user-scopes","slot":"user-scopes-dashboard-slot","title":"user-scopes"},"order":3,"online":true,"offline":true},{"name":"stock-user-scopes-db","slot":"user-scopes-dashboard-slot","component":"stockUserScopes"},{"name":"sources-db-link","slot":"stock-page-dashboard-slot","component":"stockSourcesLink","meta":{"name":"sources","slot":"sources-dashboard-slot","title":"Sources"},"order":2,"online":true,"offline":true},{"name":"stock-sources-db","slot":"sources-dashboard-slot","component":"stockSources"},{"name":"locations-db-link","slot":"stock-page-dashboard-slot","component":"stockLocationsLink","meta":{"name":"locations","slot":"locations-dashboard-slot","title":"Locations"},"order":4,"online":true,"offline":true},{"name":"stock-locations-db","slot":"locations-dashboard-slot","component":"stockLocations"},{"name":"reports-db-link","slot":"stock-page-dashboard-slot","component":"stockReportsLink","meta":{"name":"reports","slot":"reports-dashboard-slot","title":"Reports"},"order":5,"online":true,"offline":true},{"name":"stock-reports-db","slot":"reports-dashboard-slot","component":"stockReports"},{"name":"settings-db-link","slot":"stock-page-dashboard-slot","component":"stockSettingsLink","meta":{"name":"settings","slot":"settings-dashboard-slot","title":"Settings"},"order":6,"online":true,"offline":true},{"name":"stock-settings-db","slot":"settings-dashboard-slot","component":"stockSettings"},{"name":"stock-management-admin-card-link","slot":"system-admin-page-card-link-slot","component":"stockManagementAdminCardLink"},{"name":"stock-management-app-menu-item","component":"stockManagementAppMenuItem","slot":"app-menu-item-slot","meta":{"name":" Stock Management"}},{"name":"delete-packaging-unit-button","component":"deletePackagingUnitButton"}],"modals":[{"name":"delete-stock-modal","component":"deleteStockModal"},{"name":"delete-stock-user-scope-modal","component":"deleteUserScopeModal"},{"name":"delete-stock-rule-modal","component":"deleteStockRuleModal"},{"name":"delete-packaging-unit-modal","component":"deletePackagingUnitModal"},{"name":"import-bulk-stock-items","component":"importBulkStockItemsModal"},{"name":"stock-operation-dialog","component":"stockOperationModal"}],"pages":[{"component":"root","route":"stock-management"}],"version":"1.0.1-pre.716"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.24.0"},"extensions":[{"name":"stock-nav-menu","slot":"stock-sidebar-slot","component":"stockNavMenu","online":true,"offline":true},{"name":"overview-db-link","slot":"stock-page-dashboard-slot","component":"stockOverviewLink","meta":{"name":"overview","slot":"overview-dashboard-slot","title":"overview"},"order":0,"online":true,"offline":true},{"name":"stock-overview-db","slot":"overview-dashboard-slot","component":"stockOverview"},{"name":"operations-db-link","slot":"stock-page-dashboard-slot","component":"stockOperationsLink","meta":{"name":"operations","slot":"operations-dashboard-slot","title":"operations"},"order":2,"online":true,"offline":true},{"name":"stock-operations-db","slot":"operations-dashboard-slot","component":"stockOperations"},{"name":"items-db-link","slot":"stock-page-dashboard-slot","component":"stockItemsLink","meta":{"name":"items","slot":"items-dashboard-slot","title":"items"},"order":1,"online":true,"offline":true},{"name":"stock-items-db","slot":"items-dashboard-slot","component":"stockItems"},{"name":"user-scopes-db-link","slot":"stock-page-dashboard-slot","component":"stockUserScopesLink","meta":{"name":"user-scopes","slot":"user-scopes-dashboard-slot","title":"user-scopes"},"order":3,"online":true,"offline":true},{"name":"stock-user-scopes-db","slot":"user-scopes-dashboard-slot","component":"stockUserScopes"},{"name":"sources-db-link","slot":"stock-page-dashboard-slot","component":"stockSourcesLink","meta":{"name":"sources","slot":"sources-dashboard-slot","title":"Sources"},"order":2,"online":true,"offline":true},{"name":"stock-sources-db","slot":"sources-dashboard-slot","component":"stockSources"},{"name":"locations-db-link","slot":"stock-page-dashboard-slot","component":"stockLocationsLink","meta":{"name":"locations","slot":"locations-dashboard-slot","title":"Locations"},"order":4,"online":true,"offline":true},{"name":"stock-locations-db","slot":"locations-dashboard-slot","component":"stockLocations"},{"name":"reports-db-link","slot":"stock-page-dashboard-slot","component":"stockReportsLink","meta":{"name":"reports","slot":"reports-dashboard-slot","title":"Reports"},"order":5,"online":true,"offline":true},{"name":"stock-reports-db","slot":"reports-dashboard-slot","component":"stockReports"},{"name":"settings-db-link","slot":"stock-page-dashboard-slot","component":"stockSettingsLink","meta":{"name":"settings","slot":"settings-dashboard-slot","title":"Settings"},"order":6,"online":true,"offline":true},{"name":"stock-settings-db","slot":"settings-dashboard-slot","component":"stockSettings"},{"name":"stock-management-admin-card-link","slot":"system-admin-page-card-link-slot","component":"stockManagementAdminCardLink"},{"name":"stock-management-app-menu-item","component":"stockManagementAppMenuItem","slot":"app-menu-item-slot","meta":{"name":" Stock Management"}},{"name":"delete-packaging-unit-button","component":"deletePackagingUnitButton"}],"modals":[{"name":"delete-stock-modal","component":"deleteStockModal"},{"name":"delete-stock-user-scope-modal","component":"deleteUserScopeModal"},{"name":"delete-stock-rule-modal","component":"deleteStockRuleModal"},{"name":"delete-packaging-unit-modal","component":"deletePackagingUnitModal"},{"name":"import-bulk-stock-items","component":"importBulkStockItemsModal"},{"name":"stock-operation-dialog","component":"stockOperationModal"}],"pages":[{"component":"root","route":"stock-management"}],"version":"1.0.1-pre.724"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-stock-management-app",
3
- "version": "1.0.1-pre.716",
3
+ "version": "1.0.1-pre.724",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Stock management microfrontend for OpenMRS 3.x",
6
6
  "browser": "dist/openmrs-esm-stock-management-app.js",
@@ -48,16 +48,16 @@ const AddStockOperation: React.FC<AddStockOperationProps> = (props) => {
48
48
 
49
49
  const [requiresDispatchAcknowledgement, setRequiresDispatchAcknowledgement] = useState(false);
50
50
 
51
- const currentStockOperationType = types?.results?.find((p) => p.operationType === props.model?.operationType);
51
+ const currentStockOperationType = types?.results?.find((p) => p.operationType === props?.model?.operationType);
52
52
 
53
53
  useEffect(() => {
54
54
  if (
55
55
  currentStockOperationType?.operationType === OperationType.REQUISITION_OPERATION_TYPE ||
56
- props.model?.operationType === OperationType.REQUISITION_OPERATION_TYPE
56
+ props?.model?.operationType === OperationType.REQUISITION_OPERATION_TYPE
57
57
  ) {
58
- setRequisition(props.model?.uuid);
58
+ setRequisition(props?.model?.uuid);
59
59
  }
60
- }, [currentStockOperationType, props.model?.operationType, props.model?.uuid]);
60
+ }, [currentStockOperationType, props?.model?.operationType, props?.model?.uuid]);
61
61
 
62
62
  useEffect(() => {
63
63
  if (
@@ -110,8 +110,8 @@ const AddStockOperation: React.FC<AddStockOperationProps> = (props) => {
110
110
  {...props}
111
111
  isEditing={props?.operation?.name === 'Stock Issue' ? !isEditing : isEditing}
112
112
  setup={result}
113
- canEdit={props?.operation?.name === 'Stock Issue' ? !canEdit : canEdit}
114
- model={isEditing ? props?.model : props?.operation?.name === 'Stock Issue' ? props?.model : result?.dto} // check if type is stockIssue and pass requisition data
113
+ canEdit={canEdit}
114
+ model={isEditing ? props?.model : props?.operation?.name === 'Stock Issue' ? props?.model : result?.dto}
115
115
  onSave={async () => {
116
116
  setManageStockItems(true);
117
117
  setSelectedIndex(1);
@@ -291,7 +291,7 @@ const AddStockOperation: React.FC<AddStockOperationProps> = (props) => {
291
291
  <h6 style={{ color: '#24a148' }}>Related Transactions:</h6>
292
292
  {operationLinks.map(
293
293
  (item) =>
294
- (props.model?.uuid === item?.parentUuid || currentStockOperationType.uuid === item?.parentUuid) && (
294
+ (props?.model?.uuid === item?.parentUuid || currentStockOperationType?.uuid === item?.parentUuid) && (
295
295
  <>
296
296
  <span>{item?.childOperationTypeName}</span>
297
297
  <span className={item?.childVoided ? 'voided' : ''}>
@@ -91,8 +91,6 @@ const BaseOperationDetails: React.FC<BaseOperationDetailsProps> = ({
91
91
  setIsSaving(false);
92
92
  }
93
93
  };
94
-
95
- const isCompleteStatus = model?.status === 'COMPLETED';
96
94
  const sourceTags =
97
95
  operation?.stockOperationTypeLocationScopes
98
96
  ?.filter((p) => operation?.hasSource && p.isSource)
@@ -125,7 +123,7 @@ const BaseOperationDetails: React.FC<BaseOperationDetailsProps> = ({
125
123
  return (
126
124
  <div style={{ margin: '10px' }}>
127
125
  <form className={`${styles.formContainer} ${styles.verticalForm}`}>
128
- {isCompleteStatus ? (
126
+ {!canEdit || operationType === 'stockissue' ? (
129
127
  <>
130
128
  {model?.operationDate && (
131
129
  <TextInput
@@ -146,7 +144,7 @@ const BaseOperationDetails: React.FC<BaseOperationDetailsProps> = ({
146
144
  {model?.atLocationName && (
147
145
  <TextInput
148
146
  id="sourceLbl"
149
- value={model.atLocationName}
147
+ value={operationType === 'stockissue' ? issueStockOperation.sourceName : model?.sourceName ?? ''}
150
148
  readOnly={true}
151
149
  labelText={t('source', 'Source')}
152
150
  />
@@ -154,7 +152,9 @@ const BaseOperationDetails: React.FC<BaseOperationDetailsProps> = ({
154
152
  {model?.destinationName && (
155
153
  <TextInput
156
154
  id="destinationLbl"
157
- value={model.destinationName}
155
+ value={
156
+ operationType === 'stockissue' ? issueStockOperation.destinationName : model?.destinationName ?? ''
157
+ }
158
158
  readOnly={true}
159
159
  labelText={t('destination', 'Destination')}
160
160
  />
@@ -173,6 +173,20 @@ const BaseOperationDetails: React.FC<BaseOperationDetailsProps> = ({
173
173
  {model?.remarks && (
174
174
  <TextInput id="remarksLbl" value={model.remarks} readOnly={true} labelText={t('remarks', 'Remarks')} />
175
175
  )}
176
+ {operationType === 'stockissue' && (
177
+ <div style={{ display: 'flex', flexDirection: 'row-reverse' }}>
178
+ <Button
179
+ name="save"
180
+ type="button"
181
+ className="submitButton"
182
+ onClick={handleSubmit(handleSave)}
183
+ kind="primary"
184
+ renderIcon={ArrowRight}
185
+ >
186
+ {isSaving ? <InlineLoading /> : t('next', 'Next')}
187
+ </Button>
188
+ </div>
189
+ )}
176
190
  </>
177
191
  ) : (
178
192
  <>
@@ -1,4 +1,4 @@
1
- import React, { ChangeEvent, useState } from 'react';
1
+ import React, { ChangeEvent, useMemo, useState } from 'react';
2
2
  import { isDesktop } from '@openmrs/esm-framework';
3
3
  import { Button, DatePicker, DatePickerInput, Link, NumberInput, TableCell, TableRow, TextInput } from '@carbon/react';
4
4
  import { TrashCan } from '@carbon/react/icons';
@@ -27,6 +27,7 @@ import QtyUomSelector from '../qty-uom-selector/qty-uom-selector.component';
27
27
  import BatchNoSelector from '../batch-no-selector/batch-no-selector.component';
28
28
 
29
29
  import styles from './stock-items-addition-row.scss';
30
+ import { useStockItemBatchInformationHook } from '../../stock-items/add-stock-item/batch-information/batch-information.resource';
30
31
 
31
32
  interface StockItemsAdditionRowProps {
32
33
  canEdit?: boolean;
@@ -117,6 +118,36 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
117
118
  const isStockItem = (obj: any): obj is StockItemDTO => {
118
119
  return typeof obj === 'object' && obj !== null && 'drugName' in obj;
119
120
  };
121
+
122
+ const StockAvailability: React.FC<{ stockItemUuid: string }> = ({ stockItemUuid }) => {
123
+ const { items } = useStockItemBatchInformationHook({
124
+ stockItemUuid: stockItemUuid,
125
+ includeBatchNo: true,
126
+ });
127
+
128
+ const totalQuantity = useMemo(() => {
129
+ if (!items?.length) return 0;
130
+ return items.reduce((total, batch) => {
131
+ return total + (Number(batch.quantity) || 0);
132
+ }, 0);
133
+ }, [items]);
134
+ const commonUOM = useMemo(() => {
135
+ if (!items?.length) return '';
136
+ return items[0]?.quantityUoM || '';
137
+ }, [items]);
138
+
139
+ return (
140
+ <div className={styles.availability}>
141
+ {totalQuantity > 0 ? (
142
+ <span>
143
+ Available: {totalQuantity.toLocaleString()} {commonUOM}
144
+ </span>
145
+ ) : (
146
+ <span className={styles.outOfStock}>Out of Stock</span>
147
+ )}
148
+ </div>
149
+ );
150
+ };
120
151
  return (
121
152
  <>
122
153
  {fields?.map((row, index) => {
@@ -134,6 +165,11 @@ const StockItemsAdditionRow: React.FC<StockItemsAdditionRowProps> = ({
134
165
  </Link>
135
166
  )}
136
167
  </TableCell>
168
+ <TableCell>
169
+ <div className={styles.cellContent}>
170
+ {row?.stockItemUuid && <StockAvailability stockItemUuid={row.stockItemUuid} />}
171
+ </div>
172
+ </TableCell>
137
173
  {showQuantityRequested && (
138
174
  <TableCell>
139
175
  <div className={styles.cellContent}>
@@ -0,0 +1,12 @@
1
+ .availability {
2
+ font-size: 0.875rem;
3
+
4
+ .outOfStock {
5
+ color: #da1e28;
6
+ }
7
+ }
8
+ .cellContent {
9
+ display: flex;
10
+ align-items: center;
11
+ gap: 0.5rem;
12
+ }
@@ -107,6 +107,11 @@ const StockItemsAddition: React.FC<StockItemsAdditionProps> = ({
107
107
  header: t('item', 'Item'),
108
108
  styles: { width: '40% !important' },
109
109
  },
110
+ {
111
+ key: 'itemDetails',
112
+ header: t('itemDetails', 'Item Details'),
113
+ styles: { width: '20% !important' },
114
+ },
110
115
  ...(showQuantityRequested
111
116
  ? [
112
117
  {
@@ -15,10 +15,11 @@ const StockOperationReference = (props: StockOperationReferenceProps) => {
15
15
  const { types } = useStockOperationTypes();
16
16
 
17
17
  let model: StockOperationDTO;
18
-
19
- getStockOperation(props?.operationUuid).then((resp) => {
20
- model = resp.data;
21
- });
18
+ if (props?.operationUuid) {
19
+ getStockOperation(props?.operationUuid).then((resp) => {
20
+ model = resp?.data;
21
+ });
22
+ }
22
23
 
23
24
  const handleEdit = () => {
24
25
  const operation = types.results?.find((op) => op?.uuid === model?.operationTypeUuid);
@@ -49,7 +49,6 @@ const StockOperationSubmission: React.FC<StockOperationSubmissionProps> = ({
49
49
  name="rbgApprovelRequired"
50
50
  legendText={t('doesThisTransactionRequireApproval', 'Does the transaction require approval ?')}
51
51
  onChange={handleRadioButtonChange}
52
- defaultSelected={model?.approvalRequired === null ? false : approvalRequired}
53
52
  >
54
53
  <RadioButton value={true} id="rbgApprovelRequired-true" labelText={t('yes', 'Yes')} />
55
54
  <RadioButton value={false} id="rbgApprovelRequired-false" labelText={t('no', 'No')} />
@@ -115,7 +114,6 @@ const StockOperationSubmission: React.FC<StockOperationSubmissionProps> = ({
115
114
  }}
116
115
  renderIcon={Departure}
117
116
  >
118
- {t('dispatch', 'Dispatch')}
119
117
  {isSaving ? (
120
118
  <InlineLoading description={t('dispatching', 'Dispatching')} />
121
119
  ) : (
@@ -30,6 +30,7 @@ export const addOrEditStockOperation = async (
30
30
  delete payload.operationTypeUuid;
31
31
  delete payload.permission;
32
32
  delete payload.locked;
33
+
33
34
  payload['operationTypeUuid'] = stockIssueOpsTypeUuid;
34
35
  }
35
36
  const response: FetchResponse<StockOperationDTO> = await (isEditing ? updateStockOperation : createStockOperation)(
@@ -43,7 +43,7 @@ const StockOperationDialog: React.FC<StockOperationDialogProps> = ({ title, requ
43
43
  case 'complete':
44
44
  actionName = 'COMPLETE';
45
45
  break;
46
- case 'completedispatch':
46
+ case 'complete dispatch':
47
47
  actionName = 'COMPLETE';
48
48
  break;
49
49
  case 'cancel':
@@ -8,7 +8,6 @@ export function useStockOperationPages(filter: StockOperationFilter) {
8
8
 
9
9
  const pageSizes = [10, 20, 30, 40, 50];
10
10
  const [currentPageSize, setPageSize] = useState(10);
11
- console.log(items.results);
12
11
 
13
12
  const { goTo, results: paginatedItems, currentPage } = usePagination(items.results, currentPageSize);
14
13
 
@@ -58,18 +58,23 @@ export function getStockOperationLinks(filter: string) {
58
58
  }
59
59
 
60
60
  // getStockOperation
61
- export function useStockOperation(id: string) {
62
- const apiUrl = `${restBaseUrl}/stockmanagement/stockoperation/${id}`;
63
- const { data, error, isLoading } = useSWR<{ data: StockOperationDTO }, Error>(apiUrl, openmrsFetch);
61
+
62
+ export function useStockOperation(id: string | null) {
63
+ const apiUrl = id ? `${restBaseUrl}/stockmanagement/stockoperation/${id}` : null;
64
+ const { data, error, isLoading } = useSWR<{ data: StockOperationDTO }, Error>(apiUrl, apiUrl ? openmrsFetch : null);
64
65
  return {
65
- items: data.data ? data.data : {},
66
+ items: data?.data || {},
66
67
  isLoading,
67
68
  error,
68
69
  };
69
- } // getStockOperation
70
+ }
71
+
72
+ // getStockOperation
70
73
  export function getStockOperation(id: string): Promise<FetchResponse<StockOperationDTO>> {
74
+ if (!id) {
75
+ return;
76
+ }
71
77
  const apiUrl = `${restBaseUrl}/stockmanagement/stockoperation/${id}?v=full`;
72
-
73
78
  return openmrsFetch(apiUrl);
74
79
  }
75
80