Skip to content

Commit

Permalink
improvement(Aggregate consumption)
Browse files Browse the repository at this point in the history
- Improved commit message
- Fixed the error on the migrate file
- Restrict the detailed consumption option only if the number of outage days is defined and if the quantity consumed or lost are also defined
- Correction of the display problem on the aggregated stock consumption receipt
- Improved error messages for invalid stock consumption
- Removed fast insert mode
- Use of a template for the description of aggregated stock consumption`
  • Loading branch information
lomamech authored and jniles committed Mar 3, 2021
1 parent a93d0ca commit 66152aa
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 31 deletions.
1 change: 1 addition & 0 deletions client/src/i18n/en/stock.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"EXPIRATION" : "Expiration",
"EXPIRATION_RISK" : "Expiration Risk",
"EXIT" : "Stock Exit",
"EXIT_AGGREGATE_CONSUMPTION" : "Aggregate consumption for the depot: {{depot}} in the period: {{period}} by the user: {{user}}",
"EXIT_DEPOT" : "Distribution to a depot",
"EXIT_PATIENT" : "Distribution to a patient",
"EXIT_PATIENT_ADVANCED" : "Distribution to the patient {{patient}} from depot {{depot}}",
Expand Down
1 change: 0 additions & 1 deletion client/src/i18n/fr/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@
"EXIT_REPORT_DESCRIPTION" : "Ce rapport affiche les sorties de stock qui ont eu lieu dans different dépôts",
"INCLUDE_AGGREGATE_CONSUMPTION": "Inclure les consommations agrégées",
"INCLUDE_INFORMATION" : "Information à inclure",
"INCLUDE_INFORMATION" : "Information à inclure",
"INCLUDE_PATIENT_EXIT" : "Inclure les distributions vers les patients",
"INCLUDE_SERVICE_EXIT" : "Inclure les distributions vers les services",
"INCLUDE_GROUPED_SERVICE_EXIT" : "Inclure les distributions groupées par services",
Expand Down
1 change: 1 addition & 0 deletions client/src/i18n/fr/stock.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"EXPIRATION_RISK" : "Risque d'expiration",
"EXPIRATION" : "Expiration",
"EXIT" : "Sortie de stock",
"EXIT_AGGREGATE_CONSUMPTION" : "Consommation agrégée pour le Dépôt: {{depot}} à la Période: {{period}} par l'utilisateur: {{user}}",
"EXIT_DEPOT" : "Transfert vers un dépôt",
"EXIT_PATIENT" : "Distribution vers un patient",
"EXIT_PATIENT_ADVANCED" : "Distribution vers le patient {{patient}} à partir du dépôt {{depot}}",
Expand Down
2 changes: 1 addition & 1 deletion client/src/js/services/receipts/ReceiptModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ function ReceiptModal(Modal, Receipts, Invoice, Cash, Voucher) {
* @param {boolean} notifyCreated
*/
function stockAggregateConsumptionReceipt(documentUuid, notifyCreated) {
const opts = { title : 'STOCK.FLUX.AGGREGATE_CONSUMPTION', notifyCreated, renderer : Receipts.renderer };
const opts = { title : 'STOCK.RECEIPT.AGGREGATE_CONSUMPTION', notifyCreated, renderer : Receipts.renderer };
const promise = Receipts.stockAggregateConsumptionReceipt(documentUuid, { renderer : opts.renderer });
return ReceiptFactory(promise, opts);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
name="description"
ng-model="StockCtrl.movement.description"
translate-attr="{ placeholder : 'FORM.PLACEHOLDERS.DESCRIPTION' }"
ng-maxlength="StockCtrl.maxLength"
required>
ng-maxlength="StockCtrl.maxLength">
</textarea>
<div class="help-block" ng-messages="StockForm.description.$error" ng-show="StockForm.$submitted">
<div ng-messages-include="modules/templates/messages.tmpl.html"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ angular.module('bhima.controllers')

// dependencies injections
StockAggregatedConsumptionController.$inject = [
'NotifyService', 'SessionService', 'util',
'NotifyService', 'SessionService', 'util', '$translate',
'bhConstants', 'ReceiptModal', 'StockFormService', 'StockService',
'uiGridConstants', 'GridGroupingService', 'StockModalService',
];
Expand All @@ -15,7 +15,7 @@ StockAggregatedConsumptionController.$inject = [
* This module exists to Aggregated Consumption
*/
function StockAggregatedConsumptionController(
Notify, Session, util, bhConstants, ReceiptModal, StockForm,
Notify, Session, util, $translate, bhConstants, ReceiptModal, StockForm,
Stock, uiGridConstants, Grouping, StockModal,
) {
const vm = this;
Expand All @@ -35,6 +35,7 @@ function StockAggregatedConsumptionController(
};

vm.onSelectPeriod = (period) => {
vm.movement.hrLabel = period.hrLabel;
vm.movement.date = period.end_date;
vm.movement.start_date = period.start_date;
vm.currentDate = new Date();
Expand Down Expand Up @@ -136,7 +137,6 @@ function StockAggregatedConsumptionController(
enableFiltering : false,
}, {
field : 'consumption',
width : 150,
displayName : 'TABLE.COLUMNS.CONSUMPTION',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/aggregated_consumption/templates/lot_aggregate.tmpl.html',
Expand Down Expand Up @@ -243,6 +243,14 @@ function StockAggregatedConsumptionController(
// ================================= Submit ================================
function submit(form) {
// check stock validity
const i18nKeys = {
depot : vm.depot.text,
period : vm.movement.hrLabel,
user : Session.user.display_name,
};

const formatedDescription = $translate.instant('STOCK.EXIT_AGGREGATE_CONSUMPTION', i18nKeys);

const isValid = vm.Stock.validate();
const isValidConsumption = checkValidation(vm.Stock.store.data);

Expand All @@ -255,7 +263,8 @@ function StockAggregatedConsumptionController(
const movement = {
depot_uuid : vm.depot.uuid,
date : vm.movement.date,
description : vm.movement.description,
description : vm.movement.description
? formatedDescription.concat(' : ', vm.movement.description) : formatedDescription,
is_exit : 0,
flux_id : AGGREGATED_CONSUMPTION,
user_id : Session.user.id,
Expand All @@ -269,6 +278,7 @@ function StockAggregatedConsumptionController(
return row;
});

// Here we filter the products that were either consumed or lost
movement.lots = lots.filter(lot => {
return ((lot.quantity_consumed > 0 || lot.quantity_lost > 0)
&& (lot.old_quantity >= (lot.quantity_consumed + lot.quantity_lost)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@
</div>

<div style="margin-bottom: 5px;">
<div class="checkbox">
<label>
<input
id="enableFastInsert"
ng-model="$ctrl.enableFastInsert"
type="checkbox"
ng-true-value="1"
ng-false-value="0">
<span translate>LOTS.ENABLE_FAST_INSERT</span>
</label>
<p class="help-block" translate>LOTS.ENABLE_FAST_INSERT_DESCRIPTION</p>
</div>
<bh-add-item callback="$ctrl.form.addItem()" disable="true">
</bh-add-item>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<div ng-if="!row.groupHeader" class="ui-grid-cell-contents">
<a id="aggregated_details" ng-if="!row.entity.detailled && (row.entity.quantity_consumed || row.entity.quantity_consumed == 0)
&& (row.entity.quantity_lost || row.entity.quantity_lost == 0)"
<a id="aggregated_details"
ng-if="(grid.appScope.stockOut[row.entity.inventory_uuid] > 0)
&& (!row.entity.detailled && (row.entity.quantity_consumed >= 0 && row.entity.quantity_lost >= 0))
&& !(row.entity.quantity_consumed == 0 && row.entity.quantity_lost == 0)"
href ng-click="grid.appScope.setConsumptionByLots(row.entity)" data-lots>
<span ng-hide="row.entity.lots.length">
<i class="fa fa-sign-out"></i>
<span translate>STOCK.AGGREGATED_STOCK_CONSUMPTION.DETAILS</span>
</span>
</a>

<a id="aggregated_movements" ng-if="row.entity.detailled" href ng-click="grid.appScope.setConsumptionByLots(row.entity)" data-lots>
<a
id="aggregated_movements"
ng-if="(grid.appScope.stockOut[row.entity.inventory_uuid] > 0) && row.entity.detailled"
href ng-click="grid.appScope.setConsumptionByLots(row.entity)" data-lots>
<span ng-hide="row.entity.lots.length">
<i class="fa fa-sign-out"></i>
<span translate>STOCK.AGGREGATED_STOCK_CONSUMPTION.AGGREGATED_MOVEMENTS</span>
Expand Down
16 changes: 14 additions & 2 deletions server/controllers/stock/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -994,13 +994,25 @@ async function createAggregatedConsumption(req, res, next) {
.filter(l => ((l.quantity_consumed + l.quantity_lost) > l.oldQuantity));

if (checkInvalid.length) {
throw new Error('Invalid data');
throw new Error('Invalid data! Some lots have consumed or lost more stock than they originally had.');
}

// Here we want that the detailed consumption can only concern the periods when there is out of stock
movement.lots.forEach(lot => {
if (movement.stock_out[lot.inventory_uuid] === 0) {
lot.detailled = [];
}

// Here we initialize an empty array just to check that there are no details
if (!lot.detailled) {
lot.detailled = [];
}
});

// only consider lots that have consumed or lost.
// Here we filter the consumption of batches that do not have chronological details
const lots = movement.lots
.filter(l => ((l.quantity_consumed > 0 || l.quantity_lost > 0) && (!l.detailled)));
.filter(l => ((l.quantity_consumed > 0 || l.quantity_lost > 0) && (l.detailled.length === 0)));

const consumptionDetailled = movement.lots
.filter(l => l.detailled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ async function stockExitAggregateConsumptionReceipt(documentUuid, session, optio
const report = new ReportManager(STOCK_AGGREGATE_CONSUMPTION_TEMPLATE, session, optionReport);

/**
* TODO consider the donor also in a donation transaction
* For aggregate consumption
*
* This implementation doesn't handle donor informations
*/

const sql = `
SELECT i.code, i.text, BUID(m.document_uuid) AS document_uuid,
m.quantity, m.unit_cost, (m.quantity * m.unit_cost) AS total , m.date, m.description,
u.display_name AS user_display_name,
l.label, l.expiration_date, d.text AS depot_name,
dm.text as document_reference, ig.tracking_expiration,
dm.text as document_reference, ig.tracking_expiration, iu.text AS unit,
IF(ig.tracking_expiration = 1, TRUE, FALSE) as expires
FROM stock_movement m
JOIN lot l ON l.uuid = m.lot_uuid
JOIN inventory i ON i.uuid = l.inventory_uuid
JOIN inventory_group ig ON ig.uuid = i.group_uuid
JOIN inventory_unit AS iu ON iu.id = i.unit_id
JOIN depot d ON d.uuid = m.depot_uuid
JOIN user u ON u.id = m.user_id
LEFT JOIN document_map dm ON dm.uuid = m.document_uuid
Expand Down
6 changes: 3 additions & 3 deletions test/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3045,9 +3045,9 @@ INSERT INTO `lot` (`uuid`, `label`, `initial_quantity`, `quantity`, `unit_cost`,
INSERT INTO `lot` (`uuid`, `label`, `initial_quantity`, `quantity`, `unit_cost`, `description`, `expiration_date`, `inventory_uuid`, `origin_uuid`, `delay`, `entry_date`, `is_assigned`) VALUES (0xD080D354417D47F18E8B1561E98823D9, 'PL1', 1000, 1000, 9.5100, NULL, DATE_ADD(CURRENT_DATE, INTERVAL 2 YEAR), 0x43F3DECBFCE9940A426EE62186BC2150, 0x192E85A91616498F91345965DDDE311C, 0, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 0);
INSERT INTO `lot` (`uuid`, `label`, `initial_quantity`, `quantity`, `unit_cost`, `description`, `expiration_date`, `inventory_uuid`, `origin_uuid`, `delay`, `entry_date`, `is_assigned`) VALUES (0xE36AFF4F99C244A897B770E34A21E658, 'lot 1', 1000, 1000, 1.4600, NULL, DATE_ADD(CURRENT_DATE, INTERVAL 2 YEAR), 0x43F3DECBFCE9426E940AB2150E62186C, 0x3BEA58085E864F96BC0EB48CC9181C14, 0, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 0);

INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x32A81E1C81134CA5AA0A63ECF9B3435E, 0x957E34378E664E25B62E771C6443E209, 0xBD4B14524742E4FAA128246814140877, 0xACAA9876EF834D9F84E1BB7C2AF22777, NULL, 'Entrée de stock par intégration', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 1.4600, 0, 1, 9, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));
INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x5AB8E771153449549A3EE2D7149ABB9D, 0x9985985CB9A549D4BF8C1E64B273724C, 0xBD4B14524742E4FAA128246814140877, 0xD080D354417D47F18E8B1561E98823D9, NULL, 'Entrée de stock par intégration', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 9.5100, 0, 1, 10, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));
INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x63352AD0F54E483195A14E0A6A14493E, 0x957E34378E664E25B62E771C6443E209, 0xBD4B14524742E4FAA128246814140877, 0xE36AFF4F99C244A897B770E34A21E658, NULL, 'Entrée de stock par intégration', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 1.4600, 0, 1, 9, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));
INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x32A81E1C81134CA5AA0A63ECF9B3435E, 0x957E34378E664E25B62E771C6443E209, 0xBD4B14524742E4FAA128246814140877, 0xACAA9876EF834D9F84E1BB7C2AF22777, NULL, 'Entrée de stock par intégration - agrege', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 1.4600, 0, 1, 9, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));
INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x5AB8E771153449549A3EE2D7149ABB9D, 0x9985985CB9A549D4BF8C1E64B273724C, 0xBD4B14524742E4FAA128246814140877, 0xD080D354417D47F18E8B1561E98823D9, NULL, 'Entrée de stock par intégration - agrege', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 9.5100, 0, 1, 10, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));
INSERT INTO `stock_movement` (`uuid`, `document_uuid`, `depot_uuid`, `lot_uuid`, `entity_uuid`, `description`, `flux_id`, `date`, `quantity`, `unit_cost`, `is_exit`, `user_id`, `reference`, `invoice_uuid`, `stock_requisition_uuid`, `period_id`) VALUES (0x63352AD0F54E483195A14E0A6A14493E, 0x957E34378E664E25B62E771C6443E209, 0xBD4B14524742E4FAA128246814140877, 0xE36AFF4F99C244A897B770E34A21E658, NULL, 'Entrée de stock par intégration - agrege', 13, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), 1000, 1.4600, 0, 1, 9, NULL, NULL, DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), '%Y%m'));

INSERT INTO `stock_movement_status` (`uuid`, `start_date`, `end_date`, `quantity`, `in_quantity`, `out_quantity`, `inventory_uuid`, `depot_uuid`) VALUES (0x3247DD7E697E11EBBE3394E70BC7DDA4, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), DATE_ADD(CURRENT_DATE, INTERVAL -1 WEEK), 1000.0000, 1000.0000, 0.0000, 0x43F3DECBFCE9940A426EE62186BC2150, 0xBD4B14524742E4FAA128246814140877);
INSERT INTO `stock_movement_status` (`uuid`, `start_date`, `end_date`, `quantity`, `in_quantity`, `out_quantity`, `inventory_uuid`, `depot_uuid`) VALUES (0x32486DED697E11EBBE3394E70BC7DDA4, DATE_ADD(CURRENT_DATE, INTERVAL -12 WEEK), DATE_ADD(CURRENT_DATE, INTERVAL -1 WEEK), 2000.0000, 2000.0000, 0.0000, 0x43F3DECBFCE9426E940AB2150E62186C, 0xBD4B14524742E4FAA128246814140877);
Expand Down

0 comments on commit 66152aa

Please sign in to comment.