@openmrs/esm-stock-management-app 3.0.1-pre.818 → 3.0.1-pre.827
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/dist/10.js +1 -0
- package/dist/10.js.map +1 -0
- package/dist/165.js +1 -1
- package/dist/165.js.map +1 -1
- package/dist/20.js +1 -1
- package/dist/20.js.map +1 -1
- package/dist/642.js +1 -0
- package/dist/642.js.map +1 -0
- package/dist/675.js +1 -0
- package/dist/675.js.map +1 -0
- package/dist/{880.js → 727.js} +1 -1
- package/dist/727.js.map +1 -0
- package/dist/780.js +1 -0
- package/dist/780.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 +129 -56
- package/dist/openmrs-esm-stock-management-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/index.ts +8 -0
- package/src/routes.json +14 -0
- package/src/stock-items/add-stock-item/add-stock-action-button.component.tsx +2 -3
- package/src/stock-items/add-stock-item/add-stock-item.component.tsx +29 -20
- package/src/stock-items/add-stock-item/add-stock-item.scss +22 -3
- package/src/stock-items/add-stock-item/add-stock-item.test.tsx +11 -11
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +9 -10
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.resource.tsx +1 -1
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +226 -214
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.resource.tsx +7 -2
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rule-button.component.tsx +6 -4
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +162 -166
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.scss +19 -11
- package/src/stock-items/add-stock-item/stock-item-rules/edit-stock-rule.component.tsx +8 -5
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-action.component.tsx +66 -3
- package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +82 -71
- package/src/stock-items/add-stock-item/transactions/transactions.resource.tsx +7 -1
- package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +2 -2
- package/src/stock-items/stock-item.utils.tsx +7 -50
- package/src/stock-items/stock-items-table.component.tsx +2 -2
- package/src/stock-items/stock-items-table.test.tsx +28 -23
- package/src/stock-items/stock-items.resource.ts +7 -5
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +1 -0
- package/dist/600.js +0 -1
- package/dist/600.js.map +0 -1
- package/dist/880.js.map +0 -1
@@ -1,8 +1,7 @@
|
|
1
1
|
import { Button } from '@carbon/react';
|
2
|
+
import { launchWorkspace } from '@openmrs/esm-framework';
|
2
3
|
import React, { useCallback } from 'react';
|
3
4
|
import { useTranslation } from 'react-i18next';
|
4
|
-
import { launchOverlay } from '../../../core/components/overlay/hook';
|
5
|
-
import StockRulesAddOrUpdate from './add-stock-rules.component';
|
6
5
|
|
7
6
|
interface AddStockRuleActionButtonProps {
|
8
7
|
stockItemUuid: string;
|
@@ -12,8 +11,11 @@ const AddStockRuleActionButton: React.FC<AddStockRuleActionButtonProps> = ({ sto
|
|
12
11
|
const { t } = useTranslation();
|
13
12
|
|
14
13
|
const handleClick = useCallback(() => {
|
15
|
-
|
16
|
-
|
14
|
+
launchWorkspace('stock-item-rules-form-workspace', {
|
15
|
+
workspaceTitle: t('addStockRule', 'Add Stock Rule'),
|
16
|
+
stockItemUuid,
|
17
|
+
});
|
18
|
+
}, [stockItemUuid, t]);
|
17
19
|
|
18
20
|
return (
|
19
21
|
<Button onClick={handleClick} size="md" kind="primary">
|
@@ -1,33 +1,30 @@
|
|
1
1
|
import {
|
2
|
-
ModalHeader,
|
3
|
-
ModalBody,
|
4
|
-
ModalFooter,
|
5
2
|
Button,
|
3
|
+
ButtonSet,
|
4
|
+
Checkbox,
|
5
|
+
CheckboxGroup,
|
6
6
|
Form,
|
7
|
+
FormGroup,
|
7
8
|
Select,
|
8
|
-
TextInput,
|
9
9
|
SelectItem,
|
10
|
-
|
11
|
-
Checkbox,
|
12
|
-
CheckboxGroup,
|
10
|
+
TextInput,
|
13
11
|
} from '@carbon/react';
|
14
|
-
import
|
15
|
-
import
|
16
|
-
import { useRoles, useStockTagLocations } from '../../../stock-lookups/stock-lookups.resource';
|
17
|
-
import { createOrUpdateStockRule } from './stock-rules.resource';
|
18
|
-
import { type StockRule } from '../../../core/api/types/stockItem/StockRule';
|
19
|
-
import { showSnackbar } from '@openmrs/esm-framework';
|
12
|
+
import { type DefaultWorkspaceProps, showSnackbar } from '@openmrs/esm-framework';
|
13
|
+
import React, { type ChangeEvent, useCallback, useEffect, useState } from 'react';
|
20
14
|
import { useTranslation } from 'react-i18next';
|
21
|
-
import { closeOverlay } from '../../../core/components/overlay/hook';
|
22
15
|
import { ResourceRepresentation } from '../../../core/api/api';
|
16
|
+
import { type StockRule } from '../../../core/api/types/stockItem/StockRule';
|
17
|
+
import { useRoles, useStockTagLocations } from '../../../stock-lookups/stock-lookups.resource';
|
23
18
|
import { type StockItemInventoryFilter, useStockItemPackagingUOMs } from '../../stock-items.resource';
|
19
|
+
import styles from './add-stock-rules.scss';
|
20
|
+
import { createOrUpdateStockRule } from './stock-rules.resource';
|
24
21
|
|
25
|
-
interface AddStockRuleProps {
|
22
|
+
interface AddStockRuleProps extends Partial<DefaultWorkspaceProps> {
|
26
23
|
model?: StockRule;
|
27
24
|
stockItemUuid?: string;
|
28
25
|
}
|
29
26
|
|
30
|
-
const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUuid }) => {
|
27
|
+
const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUuid, closeWorkspace }) => {
|
31
28
|
const { t } = useTranslation();
|
32
29
|
|
33
30
|
const [stockItemFilter, setStockItemFilter] = useState<StockItemInventoryFilter>({
|
@@ -99,7 +96,7 @@ const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUu
|
|
99
96
|
const selectedQuantityUnit = dispensingUnits?.results.find((x) => x.uuid === evt.target.value);
|
100
97
|
setFormModel({
|
101
98
|
...formModel,
|
102
|
-
stockItemPackagingUOMUuid: selectedQuantityUnit
|
99
|
+
stockItemPackagingUOMUuid: selectedQuantityUnit?.uuid,
|
103
100
|
});
|
104
101
|
};
|
105
102
|
|
@@ -142,7 +139,7 @@ const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUu
|
|
142
139
|
kind: 'success',
|
143
140
|
subtitle: t('stockRuleAddedSuccessfully', 'Stock Rule Added Successfully'),
|
144
141
|
});
|
145
|
-
|
142
|
+
closeWorkspace?.();
|
146
143
|
},
|
147
144
|
(error) => {
|
148
145
|
showSnackbar({
|
@@ -155,179 +152,178 @@ const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUu
|
|
155
152
|
)
|
156
153
|
.catch();
|
157
154
|
},
|
158
|
-
[formModel, model, t, stockItemUuid],
|
155
|
+
[formModel, model, t, stockItemUuid, closeWorkspace],
|
159
156
|
);
|
160
157
|
|
161
158
|
return (
|
162
|
-
<
|
163
|
-
<
|
164
|
-
<
|
165
|
-
|
166
|
-
<FormGroup>
|
167
|
-
<section className={styles.section}>
|
168
|
-
<section className={styles.section}>
|
169
|
-
<Select
|
170
|
-
name="location"
|
171
|
-
className="select-field"
|
172
|
-
labelText={t('location', 'Location')}
|
173
|
-
id="location"
|
174
|
-
value={formModel?.locationUuid ? formModel.locationUuid : ''}
|
175
|
-
onChange={onLocationChange}
|
176
|
-
>
|
177
|
-
<SelectItem disabled hidden value="" text={t('chooseLocation', 'Choose the location')} />
|
178
|
-
{stockLocations?.map((location) => {
|
179
|
-
return <SelectItem key={location.id} value={location.id} text={location.name} />;
|
180
|
-
})}
|
181
|
-
</Select>
|
182
|
-
</section>
|
183
|
-
|
184
|
-
<section className={styles.section}>
|
185
|
-
<TextInput
|
186
|
-
id="name"
|
187
|
-
type="text"
|
188
|
-
labelText={t('name', 'Rule Name')}
|
189
|
-
size="md"
|
190
|
-
onChange={onNameChanged}
|
191
|
-
value={model?.name}
|
192
|
-
placeholder="e.g Panado Alert"
|
193
|
-
/>
|
194
|
-
</section>
|
195
|
-
|
196
|
-
<section className={styles.section}>
|
197
|
-
<Select
|
198
|
-
name="quantityUnit"
|
199
|
-
className="select-field"
|
200
|
-
labelText={t('quantityUnit', 'Quantity Unit')}
|
201
|
-
id="quantityUnit"
|
202
|
-
value={formModel?.stockItemPackagingUOMUuid ? formModel.stockItemPackagingUOMUuid : ''}
|
203
|
-
onChange={onQuantityUnitChange}
|
204
|
-
>
|
205
|
-
<SelectItem disabled hidden value="" text={t('chooseQuantityUnit', 'Choose the Unit of Quantity')} />
|
206
|
-
{dispensingUnits?.results.map((stockItemPackagingUOMUuid) => {
|
207
|
-
return (
|
208
|
-
<SelectItem
|
209
|
-
key={stockItemPackagingUOMUuid.uuid}
|
210
|
-
value={stockItemPackagingUOMUuid.uuid}
|
211
|
-
text={stockItemPackagingUOMUuid.packagingUomName}
|
212
|
-
/>
|
213
|
-
);
|
214
|
-
})}
|
215
|
-
</Select>
|
216
|
-
</section>
|
217
|
-
|
218
|
-
<section className={styles.section}>
|
219
|
-
<TextInput
|
220
|
-
id="quantity"
|
221
|
-
type="number"
|
222
|
-
labelText={t('quantity', 'Quantity Threshold')}
|
223
|
-
size="md"
|
224
|
-
onChange={onQuantityChanged}
|
225
|
-
value={model?.quantity}
|
226
|
-
placeholder="e.g 30 Boxes"
|
227
|
-
/>
|
228
|
-
</section>
|
229
|
-
</section>
|
230
|
-
</FormGroup>
|
231
|
-
|
232
|
-
<FormGroup>
|
159
|
+
<Form onSubmit={onFormSubmit} className={styles.formContainer}>
|
160
|
+
<div>
|
161
|
+
<FormGroup>
|
162
|
+
<section className={styles.section}>
|
233
163
|
<section className={styles.section}>
|
234
164
|
<Select
|
235
|
-
name="
|
165
|
+
name="location"
|
236
166
|
className="select-field"
|
237
|
-
labelText={t('
|
238
|
-
id="
|
239
|
-
value={formModel?.
|
240
|
-
onChange={
|
167
|
+
labelText={t('location', 'Location')}
|
168
|
+
id="location"
|
169
|
+
value={formModel?.locationUuid ? formModel.locationUuid : ''}
|
170
|
+
onChange={onLocationChange}
|
241
171
|
>
|
242
|
-
<SelectItem disabled hidden value="" text={t('
|
243
|
-
{
|
244
|
-
return <SelectItem key={
|
172
|
+
<SelectItem disabled hidden value="" text={t('chooseLocation', 'Choose the location')} />
|
173
|
+
{stockLocations?.map((location) => {
|
174
|
+
return <SelectItem key={location.id} value={location.id} text={location.name} />;
|
245
175
|
})}
|
246
176
|
</Select>
|
247
177
|
</section>
|
178
|
+
|
179
|
+
<section className={styles.section}>
|
180
|
+
<TextInput
|
181
|
+
id="name"
|
182
|
+
type="text"
|
183
|
+
labelText={t('name', 'Rule Name')}
|
184
|
+
size="md"
|
185
|
+
onChange={onNameChanged}
|
186
|
+
value={model?.name}
|
187
|
+
placeholder="e.g Panado Alert"
|
188
|
+
/>
|
189
|
+
</section>
|
190
|
+
|
248
191
|
<section className={styles.section}>
|
249
192
|
<Select
|
250
|
-
name="
|
193
|
+
name="quantityUnit"
|
251
194
|
className="select-field"
|
252
|
-
labelText={t('
|
253
|
-
id="
|
254
|
-
value={formModel?.
|
255
|
-
onChange={
|
195
|
+
labelText={t('quantityUnit', 'Quantity Unit')}
|
196
|
+
id="quantityUnit"
|
197
|
+
value={formModel?.stockItemPackagingUOMUuid ? formModel.stockItemPackagingUOMUuid : ''}
|
198
|
+
onChange={onQuantityUnitChange}
|
256
199
|
>
|
257
|
-
<SelectItem disabled hidden value="" text={t('
|
258
|
-
{
|
259
|
-
return
|
200
|
+
<SelectItem disabled hidden value="" text={t('chooseQuantityUnit', 'Choose the Unit of Quantity')} />
|
201
|
+
{dispensingUnits?.results?.map((stockItemPackagingUOMUuid) => {
|
202
|
+
return (
|
203
|
+
<SelectItem
|
204
|
+
key={stockItemPackagingUOMUuid.uuid}
|
205
|
+
value={stockItemPackagingUOMUuid.uuid}
|
206
|
+
text={stockItemPackagingUOMUuid.packagingUomName}
|
207
|
+
/>
|
208
|
+
);
|
260
209
|
})}
|
261
210
|
</Select>
|
262
211
|
</section>
|
212
|
+
|
263
213
|
<section className={styles.section}>
|
264
214
|
<TextInput
|
265
|
-
id="
|
215
|
+
id="quantity"
|
266
216
|
type="number"
|
267
|
-
labelText={t('
|
217
|
+
labelText={t('quantity', 'Quantity Threshold')}
|
268
218
|
size="md"
|
269
|
-
onChange={
|
270
|
-
value={model?.
|
271
|
-
placeholder="e.g 30
|
272
|
-
/>
|
273
|
-
<TextInput
|
274
|
-
id="actionFrequency"
|
275
|
-
type="number"
|
276
|
-
labelText={t('actionFrequency', 'Notification Frequency (Minutes)')}
|
277
|
-
size="md"
|
278
|
-
onChange={onActionFrequencyChanged}
|
279
|
-
value={model?.actionFrequency}
|
280
|
-
placeholder="e.g 3600 Minutes"
|
219
|
+
onChange={onQuantityChanged}
|
220
|
+
value={model?.quantity}
|
221
|
+
placeholder="e.g 30 Boxes"
|
281
222
|
/>
|
282
223
|
</section>
|
283
|
-
</
|
224
|
+
</section>
|
225
|
+
</FormGroup>
|
284
226
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
</
|
315
|
-
</
|
227
|
+
<FormGroup>
|
228
|
+
<section className={styles.section}>
|
229
|
+
<Select
|
230
|
+
name="alertRole"
|
231
|
+
className="select-field"
|
232
|
+
labelText={t('alertRole', 'Alert Role')}
|
233
|
+
id="alertRole"
|
234
|
+
value={formModel?.alertRole ? formModel.alertRole : ''}
|
235
|
+
onChange={onAlertRoleChange}
|
236
|
+
>
|
237
|
+
<SelectItem disabled hidden value="" text={t('chooseAlertRole', 'Choose an Alert Role')} />
|
238
|
+
{rolesData?.results?.map((alertRole) => {
|
239
|
+
return <SelectItem key={alertRole.display} value={alertRole.display} text={alertRole.display} />;
|
240
|
+
})}
|
241
|
+
</Select>
|
242
|
+
</section>
|
243
|
+
<section className={styles.section}>
|
244
|
+
<Select
|
245
|
+
name="mailRole"
|
246
|
+
className="select-field"
|
247
|
+
labelText={t('mailRole', 'Mail Role')}
|
248
|
+
id="mailRole"
|
249
|
+
value={formModel?.mailRole ? formModel.mailRole : ''}
|
250
|
+
onChange={onMailRoleChange}
|
251
|
+
>
|
252
|
+
<SelectItem disabled hidden value="" text={t('chooseMailRole', 'Choose a Mail Role')} />
|
253
|
+
{rolesData?.results?.map((mailRole) => {
|
254
|
+
return <SelectItem key={mailRole.display} value={mailRole.display} text={mailRole.display} />;
|
255
|
+
})}
|
256
|
+
</Select>
|
257
|
+
</section>
|
258
|
+
<section className={styles.section}>
|
259
|
+
<TextInput
|
260
|
+
id="evaluationFrequency"
|
261
|
+
type="number"
|
262
|
+
labelText={t('evaluationFrequency', 'Frequency Check (Minutes)')}
|
263
|
+
size="md"
|
264
|
+
onChange={onEvaluationFrequencyChanged}
|
265
|
+
value={model?.evaluationFrequency}
|
266
|
+
placeholder="e.g 30 Minutes"
|
267
|
+
/>
|
268
|
+
<TextInput
|
269
|
+
id="actionFrequency"
|
270
|
+
type="number"
|
271
|
+
labelText={t('actionFrequency', 'Notification Frequency (Minutes)')}
|
272
|
+
size="md"
|
273
|
+
onChange={onActionFrequencyChanged}
|
274
|
+
value={model?.actionFrequency}
|
275
|
+
placeholder="e.g 3600 Minutes"
|
276
|
+
/>
|
277
|
+
</section>
|
278
|
+
</FormGroup>
|
279
|
+
|
280
|
+
<div
|
281
|
+
style={{
|
282
|
+
display: 'grid',
|
283
|
+
gridTemplateColumns: '1fr 1fr',
|
284
|
+
justifyContent: 'center',
|
285
|
+
}}
|
286
|
+
>
|
287
|
+
<FormGroup className="clear-margin-bottom">
|
288
|
+
<CheckboxGroup className={styles.checkboxGrid}>
|
289
|
+
<Checkbox
|
290
|
+
onChange={onEnabledChanged}
|
291
|
+
checked={formModel?.enabled}
|
292
|
+
labelText={`Enabled ?`}
|
293
|
+
value={model?.enabled}
|
294
|
+
id="chk-ruleEnabled"
|
295
|
+
/>
|
296
|
+
</CheckboxGroup>
|
297
|
+
</FormGroup>
|
298
|
+
<FormGroup className="clear-margin-bottom">
|
299
|
+
<CheckboxGroup className={styles.checkboxGrid}>
|
300
|
+
<Checkbox
|
301
|
+
onChange={onAppliesToChildrenChanged}
|
302
|
+
name="appliesToChildren"
|
303
|
+
checked={formModel?.enableDescendants}
|
304
|
+
value={model?.enableDescendants}
|
305
|
+
labelText={`Applies to child locations?`}
|
306
|
+
id="chk-ruleAppliesToChildren"
|
307
|
+
/>
|
308
|
+
</CheckboxGroup>
|
309
|
+
</FormGroup>
|
310
|
+
</div>
|
316
311
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
312
|
+
<div>
|
313
|
+
This stock rule will be evaluated by checking if the stock quantities have lowered to the threshold or below
|
314
|
+
and a notification will be sent to the personnel with the specified role in the given location. The
|
315
|
+
notification will only be sent once per specified notification frequency.
|
316
|
+
</div>
|
317
|
+
</div>
|
318
|
+
<ButtonSet className={styles.buttonSet}>
|
319
|
+
<Button kind="secondary" onClick={closeWorkspace} className={styles.button}>
|
320
|
+
{t('cancel', 'Cancel')}
|
321
|
+
</Button>
|
322
|
+
<Button type="submit" className={styles.button}>
|
323
|
+
{t('save', 'Save')}
|
324
|
+
</Button>
|
325
|
+
</ButtonSet>
|
326
|
+
</Form>
|
331
327
|
);
|
332
328
|
};
|
333
329
|
|
@@ -1,17 +1,25 @@
|
|
1
|
-
@use '@carbon/
|
2
|
-
@use '@carbon/
|
3
|
-
@use '@
|
1
|
+
@use '@carbon/type';
|
2
|
+
@use '@carbon/layout';
|
3
|
+
@use '@carbon/colors';
|
4
4
|
|
5
|
-
.
|
6
|
-
|
5
|
+
.formContainer {
|
6
|
+
display: flex;
|
7
|
+
flex-direction: column;
|
8
|
+
justify-content: space-between;
|
9
|
+
width: 100%;
|
10
|
+
height: 100%;
|
11
|
+
padding: layout.$spacing-03;
|
7
12
|
}
|
8
13
|
|
9
|
-
.
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
.button {
|
15
|
+
display: flex;
|
16
|
+
align-content: flex-start;
|
17
|
+
align-items: baseline;
|
18
|
+
min-width: 50%;
|
13
19
|
}
|
14
20
|
|
15
|
-
.
|
16
|
-
|
21
|
+
.buttonSet {
|
22
|
+
display: flex;
|
23
|
+
justify-content: space-between;
|
24
|
+
width: 100%;
|
17
25
|
}
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import React, { useCallback } from 'react';
|
2
1
|
import { Button } from '@carbon/react';
|
3
2
|
import { Edit } from '@carbon/react/icons';
|
3
|
+
import React, { useCallback } from 'react';
|
4
4
|
|
5
|
+
import { launchWorkspace } from '@openmrs/esm-framework';
|
5
6
|
import { useTranslation } from 'react-i18next';
|
6
|
-
import { launchOverlay } from '../../../core/components/overlay/hook';
|
7
|
-
import StockRulesAddOrUpdate from './add-stock-rules.component';
|
8
7
|
import { type StockRule } from '../../../core/api/types/stockItem/StockRule';
|
9
8
|
|
10
9
|
interface EditStockRulesActionMenuProps {
|
@@ -15,8 +14,12 @@ interface EditStockRulesActionMenuProps {
|
|
15
14
|
const EditStockRuleActionsMenu: React.FC<EditStockRulesActionMenuProps> = ({ data, stockItemUuid }) => {
|
16
15
|
const { t } = useTranslation();
|
17
16
|
const handleClick = useCallback(() => {
|
18
|
-
|
19
|
-
|
17
|
+
launchWorkspace('stock-item-rules-form-workspace', {
|
18
|
+
workspaceTitle: t('editStockRule', 'Edit Stock Rule'),
|
19
|
+
stockItemUuid,
|
20
|
+
model: data,
|
21
|
+
});
|
22
|
+
}, [data, t, stockItemUuid]);
|
20
23
|
|
21
24
|
return (
|
22
25
|
<Button
|
package/src/stock-items/add-stock-item/transactions/printout/transactions-print-action.component.tsx
CHANGED
@@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { Button, Stack, ComboButton, MenuItem } from '@carbon/react';
|
3
3
|
import { Printer } from '@carbon/react/icons';
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
|
-
import { useStockItem } from '../../../stock-items.resource';
|
5
|
+
import { useStockItem, useStockItemInventory } from '../../../stock-items.resource';
|
6
6
|
import { showModal, useConfig } from '@openmrs/esm-framework';
|
7
7
|
import { type ConfigObject } from '../../../../config-schema';
|
8
8
|
import styles from './printable-transaction.scss';
|
@@ -13,9 +13,10 @@ type Props = {
|
|
13
13
|
itemUuid: string;
|
14
14
|
columns: any;
|
15
15
|
data: any;
|
16
|
+
filter?: StockItemInventoryFilter;
|
16
17
|
};
|
17
18
|
|
18
|
-
const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid }) => {
|
19
|
+
const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid, filter }) => {
|
19
20
|
const { t } = useTranslation();
|
20
21
|
|
21
22
|
const { enablePrintButton } = useConfig<ConfigObject>();
|
@@ -27,8 +28,66 @@ const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid }) =
|
|
27
28
|
isPatientTransaction: 'true',
|
28
29
|
});
|
29
30
|
|
31
|
+
const [stockItemFilter, setStockItemFilter] = useState<StockItemInventoryFilter>({
|
32
|
+
startIndex: 0,
|
33
|
+
v: filter?.v || ResourceRepresentation.Default,
|
34
|
+
limit: 10,
|
35
|
+
q: filter?.q,
|
36
|
+
totalCount: true,
|
37
|
+
});
|
38
|
+
|
30
39
|
const { item: stockItem, isLoading: isStockItemLoading } = useStockItem(itemUuid);
|
31
40
|
const { items: stockCardData, isLoading: isStockCardLoading, error } = useStockItemTransactions(stockCardItemFilter);
|
41
|
+
const { items: inventoryBalance } = useStockItemInventory(stockItemFilter);
|
42
|
+
|
43
|
+
const [balances, setBalances] = useState<Record<string, { quantity: number; itemName: string }>>({});
|
44
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
45
|
+
|
46
|
+
useEffect(() => {
|
47
|
+
if (stockCardData?.results?.length) {
|
48
|
+
setCurrentIndex(0);
|
49
|
+
setBalances({});
|
50
|
+
}
|
51
|
+
}, [stockCardData?.results]);
|
52
|
+
|
53
|
+
useEffect(() => {
|
54
|
+
const currentItem = stockCardData?.results?.[currentIndex];
|
55
|
+
if (currentItem?.stockItemUuid) {
|
56
|
+
setStockItemFilter((prev) => ({
|
57
|
+
...prev,
|
58
|
+
stockItemUuid: currentItem.stockItemUuid,
|
59
|
+
}));
|
60
|
+
}
|
61
|
+
}, [currentIndex, stockCardData]);
|
62
|
+
|
63
|
+
useEffect(() => {
|
64
|
+
const currentItem = stockCardData?.results?.[currentIndex];
|
65
|
+
const stockItemUuid = currentItem?.stockItemUuid;
|
66
|
+
|
67
|
+
if (inventoryBalance?.total && stockItemUuid) {
|
68
|
+
setBalances((prev) => ({
|
69
|
+
...prev,
|
70
|
+
[stockItemUuid]: {
|
71
|
+
quantity: Number(inventoryBalance.total),
|
72
|
+
itemName: currentItem.packagingUomName ?? '',
|
73
|
+
},
|
74
|
+
}));
|
75
|
+
|
76
|
+
setCurrentIndex((prev) => prev + 1);
|
77
|
+
}
|
78
|
+
}, [inventoryBalance, currentIndex, stockCardData]);
|
79
|
+
|
80
|
+
const stockCardWithBalance = useMemo(() => {
|
81
|
+
return (
|
82
|
+
stockCardData?.results?.map((transaction) => {
|
83
|
+
const balance = balances[transaction.stockItemUuid];
|
84
|
+
return {
|
85
|
+
...transaction,
|
86
|
+
balance: `${balance?.quantity ?? ''} ${balance?.itemName ?? ''}`,
|
87
|
+
};
|
88
|
+
}) ?? []
|
89
|
+
);
|
90
|
+
}, [stockCardData?.results, balances]);
|
32
91
|
|
33
92
|
const stockCardHeaders = useMemo(
|
34
93
|
() => [
|
@@ -56,6 +115,10 @@ const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid }) =
|
|
56
115
|
key: 'transaction',
|
57
116
|
header: 'Transaction',
|
58
117
|
},
|
118
|
+
{
|
119
|
+
key: 'balance',
|
120
|
+
header: 'Balance',
|
121
|
+
},
|
59
122
|
{
|
60
123
|
key: 'totalout',
|
61
124
|
header: 'OUT',
|
@@ -82,7 +145,7 @@ const TransactionsPrintAction: React.FC<Props> = ({ columns, data, itemUuid }) =
|
|
82
145
|
onClose: () => dispose(),
|
83
146
|
title: stockItem.drugName || stockItem.conceptName || '',
|
84
147
|
columns: stockCardHeaders,
|
85
|
-
data:
|
148
|
+
data: stockCardWithBalance,
|
86
149
|
});
|
87
150
|
};
|
88
151
|
|