Skip to content

Commit

Permalink
Implement API for aggregate consumption
Browse files Browse the repository at this point in the history
  • Loading branch information
lomamech authored and jniles committed Mar 3, 2021
1 parent ad216e8 commit d3fee32
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 47 deletions.
6 changes: 6 additions & 0 deletions client/src/i18n/en/stock.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
"ALERT" : "Alert",
"ADJUSTMENT" : "Adjustment",
"ADJUSTMENT_TYPE" : "Adjustment Type",
"AGGREGATED_STOCK_CONSUMPTION": {
"DESCRIPTION": "This aggregated stock consumption module makes it possible to define for a warehouse and for a period the quantity of stock consumed by product but especially by batch, while specifying for each product the number of days of out of stock",
"TITLE": "Aggregate stock Consumption"
},
"AMOUNT" : "Amount",
"APPROVISIONING" : "Quantity to order",
"AT_LEAST_ONE_CHECKED" : "At least one option must be checked",
Expand Down Expand Up @@ -150,6 +154,7 @@
"QUANTITY_RECEIVED" : "Received Quantity",
"QUANTITY_DIFFERENCE" : "Difference",
"QUANTITY_CONSUMED" : "Quantity Consumed",
"QUANTITY_IN_STOCK" : "Quantity in stock",
"QUANTITY_LOST" : "Quantity Lost",
"QUANTITY_REMAINING" : "Quantity Remaining",
"INITIAL_QUANTITY" : "Initial Quantity",
Expand Down Expand Up @@ -221,6 +226,7 @@
"ENABLE_STRICT_DEPOT_DISTRIBUTION_HELP_TEXT" : "Limits the depots a user can interact with to the depots that the user has access to. Thus, if a user cannot distribute stock from a depot, they also cannot transfer stock to that depot."
},
"STOCK_FLUX" : {
"AGGREGATE_CONSUMPTION" : "Aggregate consumption",
"FROM_PURCHASE" : "From Purchase Order",
"FROM_OTHER_DEPOT" : "From Depot",
"FROM_ADJUSTMENT" : "Adjustment (Positive)",
Expand Down
5 changes: 5 additions & 0 deletions client/src/i18n/fr/stock.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"ALERT" : "Alert",
"ADJUSTMENT" : "Ajustement",
"ADJUSTMENT_TYPE" : "Type d'Ajustement",
"AGGREGATED_STOCK_CONSUMPTION": {
"DESCRIPTION": "Ce module de consommation de stock aggregée permet de definir pour un dépôt et pour une période la quantité de stock consommée par produits mais surtout par lot, tout en précisant pour chaque produit le nombre de jour de rupture de stock",
"TITLE": "Consommation de stock aggregée"
},
"AMOUNT" : "Montant",
"APPROVISIONING" : "Quantité à commander",
"AT_LEAST_ONE_CHECKED" : "Au moins une option doit être coché",
Expand Down Expand Up @@ -222,6 +226,7 @@
"ENABLE_STRICT_DEPOT_DISTRIBUTION_HELP_TEXT" : "Limite les dépôts qui peuvent recevoir du stock à partir d'un dépôt donné; lors de la sortie de stock vers un dépôt, seul les dépôts autorisés peuvent s'afficher pour le dépôt donné afin de recevoir du stock"
},
"STOCK_FLUX" : {
"AGGREGATE_CONSUMPTION" : "Consommation aggregée",
"FROM_PURCHASE" : "Commande d'achat",
"FROM_OTHER_DEPOT" : "En provenance d'un dépôt",
"FROM_ADJUSTMENT" : "Ajustement (Positif)",
Expand Down
4 changes: 4 additions & 0 deletions client/src/js/services/StockService.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ function StockService(Api, StockFilterer, HttpCache, util, Periods) {
// API for stock requisition
const stockRequestorType = new Api('/stock/requestor_type/');

// API for stock Aggregated Consumption
const aggregatedConsumption = new Api('/stock/aggregated_consumption');

// Overide the stock assign api
stockAssign.remove = uuid => {
return stockAssign.$http.put(`/stock/assign/${uuid}/remove`)
Expand Down Expand Up @@ -208,5 +211,6 @@ function StockService(Api, StockFilterer, HttpCache, util, Periods) {
statusLabelMap,
downloadTemplate,
status,
aggregatedConsumption,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ol class="headercrumb">
<li class="static" translate>TREE.STOCK</li>
<li ng-class="{ 'title' : !StockCtrl.depot.uuid, 'static' : StockCtrl.depot.uuid }">
<span translate>INVENTORY_ADJUSTMENT.TITLE</span>
<span translate>STOCK.AGGREGATED_STOCK_CONSUMPTION.TITLE</span>
</li>
<li class="title" ng-if="StockCtrl.depot.uuid">
<span>{{ StockCtrl.depot.text }}</span>
Expand Down Expand Up @@ -31,11 +31,16 @@
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4">

<!-- date -->
<bh-date-editor
date-value="StockCtrl.movement.date"
on-change="StockCtrl.onDateChange(date)">
</bh-date-editor>
<bh-fiscal-year-select
fiscal-id="StockCtrl.movement.fiscal_id"
on-select-fiscal-callback="StockCtrl.onSelectFiscalYear(fiscalYear)">
</bh-fiscal-year-select>

<bh-period-selection
fiscal-year-id="StockCtrl.movement.fiscal_id"
period-id="StockCtrl.movement.period_id"
on-select-callback="StockCtrl.onSelectPeriod(period)">
</bh-period-selection>

<!-- note -->
<div class="form-group"
Expand All @@ -57,8 +62,8 @@
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<h3 translate>INVENTORY_ADJUSTMENT.TITLE</h3>
<p translate>INVENTORY_ADJUSTMENT.DESC</p>
<h3 translate>STOCK.AGGREGATED_STOCK_CONSUMPTION.TITLE</h3>
<p translate>STOCK.AGGREGATED_STOCK_CONSUMPTION.DESCRIPTION</p>
</div>
</div>

Expand Down Expand Up @@ -88,7 +93,7 @@ <h3 translate>INVENTORY_ADJUSTMENT.TITLE</h3>
<!-- grid -->
<div id="stock-adjustment-grid"
ui-grid="StockCtrl.gridOptions"
style="height: 600px; width: 100%;"
style="height: 400px; width: 100%;"
ui-grid-auto-resize
ui-grid-resize-columns
ui-grid-grouping>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ function StockAggregatedConsumptionController(
// global variables
vm.Stock = new StockForm('StockInventoryAdjustment');
vm.movement = {};
vm.stockOut = {};

vm.onDateChange = date => {
vm.movement.date = date;
vm.onSelectFiscalYear = (fiscalYear) => {
setupStock();
vm.movement.fiscal_id = fiscalYear.id;
};

vm.onSelectPeriod = (period) => {
vm.movement.date = period.end_date;
vm.movement.period_id = period.id;
loadInventories(vm.depot);
};

Expand Down Expand Up @@ -63,13 +70,13 @@ function StockAggregatedConsumptionController(
headerCellFilter : 'translate',
}, {
field : 'label',
width : 90,
width : 120,
displayName : 'TABLE.COLUMNS.LOT',
headerCellFilter : 'translate',
enableSorting : true,
}, {
field : 'old_quantity',
width : 90,
width : 120,
displayName : 'STOCK.QUANTITY_IN_STOCK',
headerCellFilter : 'translate',
enableFiltering : false,
Expand All @@ -89,14 +96,6 @@ function StockAggregatedConsumptionController(
cellTemplate : 'modules/stock/aggregated_consumption/templates/quantity_lost.tmpl.html',
aggregationType : uiGridConstants.aggregationTypes.sum,
enableFiltering : false,
}, {
field : 'quantity_remaining',
width : 150,
displayName : 'STOCK.QUANTITY_REMAINING',
headerCellFilter : 'translate',
cellTemplate : 'modules/stock/aggregated_consumption/templates/quantity_remaining.tmpl.html',
aggregationType : uiGridConstants.aggregationTypes.sum,
enableFiltering : false,
}, {
field : 'days_stock_out',
width : 150,
Expand All @@ -123,7 +122,6 @@ function StockAggregatedConsumptionController(

vm.grouping = new Grouping(vm.gridOptions, true, 'text', true, true);


// register api
function onRegisterApiFn(gridApi) {
vm.gridApi = gridApi;
Expand All @@ -141,10 +139,6 @@ function StockAggregatedConsumptionController(
}

function startup() {
vm.movement = {
date : new Date(),
};

setupStock();
}

Expand All @@ -154,6 +148,8 @@ function StockAggregatedConsumptionController(
};

function loadInventories(depot) {
if (!vm.movement.date) { return 0; }

vm.loading = true;
setupStock();

Expand Down Expand Up @@ -209,6 +205,9 @@ function StockAggregatedConsumptionController(
is_exit : 0,
flux_id : INVENTORY_ADJUSTMENT,
user_id : Session.user.id,
stock_out : vm.stockOut,
fiscal_id : vm.movement.fiscal_id,
period_id : vm.movement.period_id,
};

const lots = vm.Stock.store.data.map((row) => {
Expand All @@ -217,15 +216,10 @@ function StockAggregatedConsumptionController(
});

movement.lots = lots.filter(lot => {
return lot.quantity !== lot.oldQuantity;
return (lot.quantity_consumed > 0 || lot.quantity_lost > 0);
});

if (!movement.lots.length) {
Notify.warn('INVENTORY_ADJUSTMENT.NO_CHANGE');
return 0;
}

return Stock.inventoryAdjustment.create(movement)
return Stock.aggregatedConsumption.create(movement)
.then(() => {
// since we have effectively performed an inventory, instead of rendering a receipt,
// we will render the "Articles in Stock" report for this depot.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
type="number"
class="form-control"
style="padding-left : 5px !important;text-align: right;"
ng-model="row.entity.days_stock_out"
ng-change="row.entity.valdiate()" required>
ng-model="grid.appScope.stockOut[row.treeNode.children[0].row.entity.inventory_uuid]" required>
</div>

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function StockInventoryAdjustmentController(
// global variables
vm.Stock = new StockForm('StockInventoryAdjustment');
vm.movement = {};
vm.stockOut = {};

vm.onDateChange = date => {
vm.movement.date = date;
Expand Down
1 change: 1 addition & 0 deletions server/config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ exports.configure = function configure(app) {
// stock integration
app.post('/stock/integration', stock.createIntegration);
app.post('/stock/inventory_adjustment', stock.createInventoryAdjustment);
app.post('/stock/aggregated_consumption', stock.createAggregatedConsumption);

// stock settings API
app.get('/stock/setting/:id?', stockSetting.list);
Expand Down
1 change: 1 addition & 0 deletions server/controllers/stock/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const flux = {
FROM_INTEGRATION : 13,
INVENTORY_RESET : 14,
INVENTORY_ADJUSTMENT : 15,
AGGREGATE_CONSUMPTION : 16,
};

// exports
Expand Down
102 changes: 102 additions & 0 deletions server/controllers/stock/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ exports.assign = assign;
exports.requisition = requisition;
exports.requestorType = requestorType;
exports.createInventoryAdjustment = createInventoryAdjustment;
exports.createAggregatedConsumption = createAggregatedConsumption;

exports.listStatus = core.listStatus;
// stock consumption
Expand Down Expand Up @@ -975,3 +976,104 @@ function getStockTransfers(req, res, next) {
.catch(next)
.done();
}


/**
* POST /stock/aggregated_consumption
* Stock Aggregated Consumption
*/
async function createAggregatedConsumption(req, res, next) {
try {
const movement = req.body;

console.log('NEWWWWWW');
console.log(movement);

if (!movement.depot_uuid) {
throw new Error('No defined depot');
}

// only consider lots that have consumed or lost.
const lots = movement.lots
.filter(l => (l.quantity_consumed > 0 || l.quantity_lost > 0));

const periodId = movement.period_id;

// pass reverse operations
const trx = db.transaction();

const consumptionUuid = uuid();
const lossUuid = uuid();

// get all lots with positive quantity_consumed
const stockConsumptionQuantities = lots.filter(lot => lot.quantity_consumed > 0);

// get all lots with negative quantity_lost
const stockLossQuantities = lots.filter(lot => lot.quantity_lost > 0);

stockConsumptionQuantities.forEach(lot => {
const consumptionMovementObject = {
uuid : db.bid(uuid()),
lot_uuid : db.bid(lot.uuid),
depot_uuid : db.bid(movement.depot_uuid),
document_uuid : db.bid(consumptionUuid),
quantity : lot.quantity_consumed,
unit_cost : lot.unit_cost,
date : new Date(movement.date),
entity_uuid : movement.entity_uuid,
is_exit : 1,
flux_id : core.flux.AGGREGATE_CONSUMPTION,
description : movement.description,
user_id : req.session.user.id,
period_id : periodId,
};
trx.addQuery('INSERT INTO stock_movement SET ?', consumptionMovementObject);
});

stockLossQuantities.forEach(lot => {
const lossMovementObject = {
uuid : db.bid(uuid()),
lot_uuid : db.bid(lot.uuid),
depot_uuid : db.bid(movement.depot_uuid),
document_uuid : db.bid(consumptionUuid),
quantity : lot.quantity_lost,
unit_cost : lot.unit_cost,
date : new Date(movement.date),
entity_uuid : movement.entity_uuid,
is_exit : 1,
flux_id : core.flux.TO_LOSS,
description : movement.description,
user_id : req.session.user.id,
period_id : periodId,
};
trx.addQuery('INSERT INTO stock_movement SET ?', lossMovementObject);
});

const stockConsumptionParams = [
db.bid(consumptionUuid), 1, req.session.project.id, req.session.enterprise.currency_id,
];

const stockLossParams = [
db.bid(lossUuid), 1, req.session.project.id, req.session.enterprise.currency_id,
];

if (req.session.stock_settings.enable_auto_stock_accounting) {
if (stockConsumptionQuantities.length > 0) {
trx.addQuery('CALL PostStockMovement(?)', [stockConsumptionParams]);
}

if (stockLossQuantities.length > 0) {
trx.addQuery('CALL PostStockMovement(?)', [stockLossParams]);
}
}

console.log('ICI NOUS SOMMMES : NA ZO MEKA MAIS NA ZO KOMA TE');

await trx.execute();

res.status(201).json({});
} catch (err) {
next(err);
}
}

3 changes: 2 additions & 1 deletion server/models/bhima.sql
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,8 @@ INSERT INTO `flux` VALUES
(12, 'STOCK_FLUX.TO_ADJUSTMENT'),
(13, 'STOCK_FLUX.FROM_INTEGRATION'),
(14, 'STOCK_FLUX.INVENTORY_RESET'),
(15, 'STOCK_FLUX.INVENTORY_ADJUSTMENT');
(15, 'STOCK_FLUX.INVENTORY_ADJUSTMENT'),
(16, 'STOCK_FLUX.AGGREGATE_CONSUMPTION');

-- Roles Actions

Expand Down

0 comments on commit d3fee32

Please sign in to comment.