Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lifetime calculation in days not months #5226

3 changes: 2 additions & 1 deletion client/src/i18n/en/stock.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"ITEMS" : "Items",
"LEGEND" : "Legend",
"LIFETIME" : "Lifetime",
"LOT_LIFETIME" : "Lifetime By Lot",
"LOT_LIFETIME" : "Lifetime by Usage",
"CURRENT_QUANTITY" : "Current Quantity",
"RISK" : "Risk",
"RISK_QUANTITY" : "Risk Quantity",
Expand Down Expand Up @@ -192,6 +192,7 @@
"REQUIRES_PO" : "Requires a purchase order",
"RESPONSIBLE" : "Stock Manager",
"RISK_OF_EXPIRATION" : "Risk of expiration",
"RISK_OF_STOCK_OUT" : "Risk of stock out",
"ROWS" : "Rows",
"SEARCH" : "Search",
"SECURITY" : "Security Stock",
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 @@ -192,6 +192,7 @@
"REQUIRES_PO" : "Nécessitant une commande d'achat",
"RESPONSIBLE" : "Gestionnaire du stock",
"RISK_OF_EXPIRATION" : "Risque de péremption",
"RISK_OF_STOCK_OUT" : "Risque de rupture",
"ROWS" : "Lignes",
"SEARCH" : "Chercher",
"SECURITY" : "Stock de securité",
Expand Down
14 changes: 8 additions & 6 deletions client/src/js/services/LotService.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,24 @@ function LotService(Api, $http, util) {
* NOTE: Once a case is found to be true, all following cases are ignored.
* 1. If the stock is exhausted, warn about that.
* (Recall that the user can choose to display exhausted lots in Lots Registry.)
* 2. If the Lot is expired, warn about that.
* 3. If the Lot is near expiration, warn about that.
* 2. If the Lot is near expiration, warn about that.
* NOTE that this assumes the CMM and that stock exits all come from this
* lot exclusively. But the CMM is based on not only on this lot, but on
* an aggregate all lots of this inventory item, so there is no guarantee
* that this will be correct.
* 3. If the Lot is expired, warn about that.
* 4. If a Lot is at risk of running out, warn about that. Again this is
* based on the aggregate CMM which may not work out exactly for this
* Lot in practice.
*
* Based on this logic, only one of the warning flags should be set to true.
*/
lots.computeLotWarningFlags = (lot) => {
lots.exhausted = false;
lots.expired = false;
lots.near_expiration = false;
lots.at_risk = false;
lot.exhausted = false;
lot.expired = false;
lot.near_expiration = false;
lot.at_risk = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽


if (lot.quantity <= 0) {
lot.exhausted = true;
} else if (lot.lifetime < 0) {
Expand All @@ -75,6 +76,7 @@ function LotService(Api, $http, util) {
lot.at_risk = true;
}

return lot;
};

return lots;
Expand Down
38 changes: 31 additions & 7 deletions client/src/modules/stock/lots/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function StockLotsController(

// grouping box
vm.groupingBox = LotsRegistry.groupingBox;

// barcode scanner
vm.openBarcodeScanner = openBarcodeScanner;

Expand Down Expand Up @@ -145,23 +146,46 @@ function StockLotsController(
.then((lots) => {
const current = new Date();

const totals = {
expired : 0,
'at-risk-of-expiring' : 0,
'at-risk' : 0,
'out-of-stock' : 0,
};

lots.forEach((lot) => {
const delay = moment(new Date(lot.expiration_date)).diff(current);
lot.delay_expiration = moment.duration(delay).humanize(true);
LotService.computeLotWarningFlags(lot);

if (lot.expired) {
totals.expired += 1;
}

if (lot.at_risk) {
totals['at-risk'] += 1;
}

if (lot.near_expiration) {
totals['at-risk-of-expiring'] += 1;
}

if (lot.exhausted) {
totals['out-of-stock'] += 1;
}

// serialize tag names for filters
lot.tagNames = lot.tags.map(tag => tag.name).join(',');
lot.tags.forEach(addColorStyle);
});

vm.totals = totals;

lots.forEach(LotsRegistry.formatLotsWithoutExpirationDate);

// FIXME(@jniles): we should do this ordering on the server via an ORDER BY
lots.sort(LotsRegistry.orderByDepot);

// serialize tag names for filters
vm.gridOptions.data = lots.map(lot => {
lot.tagNames = lot.tags.map(tag => tag.name).join(',');
lot.tags.forEach(addColorStyle);
return lot;
});
vm.gridOptions.data = lots;

vm.grouping.unfoldAllGroups();
vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
Expand Down
78 changes: 11 additions & 67 deletions client/src/modules/stock/lots/registry.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,70 +92,6 @@ function LotsRegistryService(uiGridConstants, Session) {
cellClass : 'text-right',
headerCellFilter : 'translate',
}, {
field : 'avg_consumption',
displayName : 'STOCK.CMM',
headerTooltip : 'STOCK.CMM',
cellClass : 'text-right',
headerCellFilter : 'translate',
type : 'number',
}, {
field : 'S_MONTH',
displayName : 'STOCK.MSD',
headerTooltip : 'STOCK.MSD',
cellClass : 'text-right',
headerCellFilter : 'translate',
type : 'number',
}, {
field : 'lifetime',
displayName : 'STOCK.LIFETIME',
headerTooltip : 'STOCK.LIFETIME',
headerCellFilter : 'translate',
cellClass : 'text-right',
cellTemplate : 'modules/stock/lots/templates/lifetime.cell.html',
type : 'number',
sort : {
direction : uiGridConstants.ASC,
priority : 2,
},
}, {
field : 'S_LOT_LIFETIME',
displayName : 'STOCK.LOT_LIFETIME',
headerTooltip : 'STOCK.LOT_LIFETIME',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/lots/templates/lot_lifetime.cell.html',
cellClass : 'text-right',
type : 'number',
}, {
field : 'S_RISK',
displayName : 'STOCK.RISK',
headerTooltip : 'STOCK.RISK',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/lots/templates/risk.cell.html',
cellClass : 'text-right',
type : 'number',
sort : {
direction : uiGridConstants.DESC,
priority : 3,
},
},
{
field : 'IS_IN_RISK_EXPIRATION',
displayName : 'STOCK.STATUS.IS_IN_RISK_OF_EXPIRATION',
headerTooltip : 'STOCK.STATUS.IS_IN_RISK_OF_EXPIRATION',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/lots/templates/in_risk_of_expiration.html',
cellClass : 'text-right',
type : 'number',
},
{
field : 'S_RISK_QUANTITY',
displayName : 'STOCK.RISK_QUANTITY',
headerTooltip : 'STOCK.RISK_QUANTITY',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/lots/templates/risk_quantity.cell.html',
type : 'number',
},
{
field : 'tagNames',
displayName : 'TAG.LABEL',
headerTooltip : 'TAG.LABEL',
Expand All @@ -176,18 +112,24 @@ function LotsRegistryService(uiGridConstants, Session) {

<span class="fa fa-circle icon-expired legend"></span>
<strong>
<span translate>STOCK.EXPIRATION</span>:
<span translate>STOCK.EXPIRED</span>: {{grid.appScope.totals.expired}}
</strong>

<span class="fa fa-circle icon-at-risk-of-expiring legend"></span>
<strong>
<span translate>STOCK.RISK_OF_EXPIRATION</span>: {{grid.appScope.totals['at-risk-of-expiring']}}
</strong>

<span class="fa fa-circle icon-at-risk legend"></span>
<strong>
<span translate>STOCK.RISK_OF_EXPIRATION</span>:
<span translate>STOCK.RISK_OF_STOCK_OUT</span>: {{grid.appScope.totals['at-risk']}}
</strong>

<span class="fa fa-circle icon-out-of-stock legend"></span>
<strong>
<span translate>STOCK.STATUS.STOCK_OUT</span>:
<span translate>STOCK.STATUS.STOCK_OUT</span>: {{grid.appScope.totals['out-of-stock']}}
</strong>

</div>
`;

Expand All @@ -205,6 +147,8 @@ function LotsRegistryService(uiGridConstants, Session) {
delete lot.expiration_date;
delete lot.lifetime;
delete lot.S_LOT_LIFETIME;
delete lot.S_RISK;
delete lot.S_RISK_QUANTITY;
}
};

Expand Down

This file was deleted.

4 changes: 2 additions & 2 deletions client/src/modules/stock/lots/templates/lifetime.cell.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="ui-grid-cell-contents text-right">
<span ng-if="row.entity.hasExpirationDate">
{{ row.entity.lifetime }} <span translate>FORM.LABELS.MONTH</span>
<span ng-if="row.entity.hasExpirationDate && !row.entity.flags.expired">
{{ row.entity.lifetime }} <span translate>FORM.LABELS.DAYS</span>
</span>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="ui-grid-cell-contents text-right">
<span ng-if="row.entity.hasExpirationDate">
{{ row.entity.S_LOT_LIFETIME }} <span translate>FORM.LABELS.MONTH</span>
<span ng-if="row.entity.lifetime_lot">
{{ row.entity.lifetime_lot}} <span translate>FORM.LABELS.DAYS</span>
</span>
</div>
6 changes: 3 additions & 3 deletions client/src/modules/stock/lots/templates/risk.cell.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="ui-grid-cell-contents text-right" ng-class="{'text-danger': row.entity.S_RISK < 0, 'text-success': row.entity.S_RISK >= 0}">
<span ng-if="row.entity.hasExpirationDate">
{{ row.entity.S_RISK }} <span translate>FORM.LABELS.MONTH</span>
<div class="ui-grid-cell-contents text-right" ng-class="{'text-danger': row.entity.S_RISK > 0}">
<span ng-if="row.entity.hasExpirationDate && !row.entity.flags.expired && row.entity.avg_consumption > 0">
{{ row.entity.S_RISK }} <span translate>FORM.LABELS.DAYS</span>
</span>
</div>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div class="ui-grid-cell-contents text-right" ng-class="{'text-danger': row.entity.S_RISK < 0, 'text-success': row.entity.S_RISK >= 0}">
<div class="ui-grid-cell-contents text-right" ng-class="{'text-danger': row.entity.S_RISK > 0}">
{{ row.entity.S_RISK_QUANTITY }}
</div>
</div>
8 changes: 6 additions & 2 deletions client/src/modules/stock/lots/templates/row.expired.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid"
ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'"
class="ui-grid-cell"
ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader, 'at-risk-of-expiring': row.entity.near_expiration,
'expired': row.entity.expired, 'at-risk': row.entity.at_risk, 'out-of-stock': row.entity.exhausted,
ng-class="{
'ui-grid-row-header-cell': col.isRowHeader,
'at-risk-of-expiring': row.entity.near_expiration,
'expired': row.entity.expired,
'at-risk': row.entity.at_risk,
'out-of-stock': row.entity.exhausted,
}"
data-vals="{{col.isRowHeader}}"
role="{{col.isRowHeader ? 'rowheader' : 'gridcell'}}"
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"angular-translate-loader-static-files": "^2.18.4",
"angular-translate-loader-url": "^2.18.4",
"angular-ui-bootstrap": "^2.5.6",
"angular-ui-grid": "^4.9.0",
"angular-ui-grid": "^4.10.0",
"body-parser": "^1.18.3",
"bootstrap": "^3.3.0",
"chart.js": "^2.9.4",
Expand All @@ -106,7 +106,7 @@
"cross-env": "^7.0.3",
"csvtojson": "^2.0.8",
"debug": "^4.3.1",
"delay": "^4.4.1",
"delay": "^5.0.0",
"dotenv": "^8.0.0",
"excel4node": "^1.7.0",
"express": "^4.16.4",
Expand Down Expand Up @@ -167,7 +167,7 @@
"gulp-template": "^5.0.0",
"gulp-typescript": "^5.0.0",
"gulp-uglify": "^3.0.1",
"karma": "^6.0.3",
"karma": "^6.0.4",
"karma-chai": "^0.1.0",
"karma-chai-dom": "^1.1.0",
"karma-chai-spies": "^0.1.4",
Expand Down
Loading