diff --git a/client/src/modules/stock/lots/registry.js b/client/src/modules/stock/lots/registry.js
index b98067695e..8e20657787 100644
--- a/client/src/modules/stock/lots/registry.js
+++ b/client/src/modules/stock/lots/registry.js
@@ -124,9 +124,10 @@ function StockLotsController(Stock, Notify,
if($state.params.filters) {
var changes = [{ key : $state.params.filters.key, value : $state.params.filters.value }]
- stockLotFilters.replaceFilters(changes);
+ stockLotFilters.replaceFilters(changes);
Stock.cacheFilters(filterKey);
}
+
load(stockLotFilters.formatHTTP(true));
vm.latestViewFilters = stockLotFilters.formatView();
}
@@ -160,14 +161,14 @@ function StockLotsController(Stock, Notify,
toggleLoadingIndicator();
Stock.lots.read(null, filters)
- .then(function(lots){
- vm.gridOptions.data = lots;
- vm.grouping.unfoldAllGroups();
- })
- .catch(errorHandler)
- .finally(function (){
- toggleLoadingIndicator();
- });
+ .then(function (lots) {
+ vm.gridOptions.data = lots;
+ vm.grouping.unfoldAllGroups();
+ })
+ .catch(errorHandler)
+ .finally(function (){
+ toggleLoadingIndicator();
+ });
}
// remove a filter with from the filter object, save the filters and reload
diff --git a/client/src/modules/stock/movements/modals/search.modal.html b/client/src/modules/stock/movements/modals/search.modal.html
index 141b028010..a3380ea461 100644
--- a/client/src/modules/stock/movements/modals/search.modal.html
+++ b/client/src/modules/stock/movements/modals/search.modal.html
@@ -20,13 +20,13 @@
@@ -59,27 +59,16 @@
-
+
{{$select.selected.label}}
-
+
-
-
-
@@ -91,7 +80,7 @@
-
-
+
diff --git a/client/src/modules/stock/movements/modals/search.modal.js b/client/src/modules/stock/movements/modals/search.modal.js
index 4b2d88b623..a315fabcf1 100644
--- a/client/src/modules/stock/movements/modals/search.modal.js
+++ b/client/src/modules/stock/movements/modals/search.modal.js
@@ -1,32 +1,32 @@
angular.module('bhima.controllers')
-.controller('SearchMovementsModalController', SearchMovementsModalController);
+ .controller('SearchMovementsModalController', SearchMovementsModalController);
SearchMovementsModalController.$inject = [
- 'data', 'NotifyService', '$uibModalInstance', 'FluxService',
- '$translate', 'PeriodService', 'Store', 'util'
+ 'data', 'NotifyService', '$uibModalInstance', 'FluxService',
+ '$translate', 'PeriodService', 'Store', 'util',
];
function SearchMovementsModalController(data, Notify, Instance, Flux, $translate, Periods, Store, util) {
var vm = this;
- var changes = new Store({ identifier : 'key'});
+ var changes = new Store({ identifier : 'key' });
+
+ var searchQueryOptions = [
+ 'is_exit', 'depot_uuid', 'inventory_uuid', 'label', 'flux_id', 'dateFrom', 'dateTo',
+ ];
vm.filters = data;
vm.searchQueries = {};
vm.defaultQueries = {};
- var searchQueryOptions = [
- 'is_exit', 'depot_uuid', 'inventory_uuid', 'label', 'flux_id', 'dateFrom', 'dateTo'
- ];
-
- // load flux
+ // load flux
Flux.read()
- .then(function (rows) {
+ .then(function (rows) {
vm.fluxes = rows.map(function (row) {
row.label = $translate.instant(row.label);
return row;
});
- })
- .catch(Notify.handleError);
+ })
+ .catch(Notify.handleError);
// default filter period - directly write to changes list
vm.onSelectPeriod = function onSelectPeriod(period) {
@@ -50,7 +50,7 @@ function SearchMovementsModalController(data, Notify, Instance, Flux, $translate
// assign already defined custom filters to searchQueries object
vm.searchQueries = util.maskObjectFromKeys(data, searchQueryOptions);
- if(data.limit) {
+ if (data.limit) {
vm.defaultQueries.limit = data.limit;
}
@@ -58,11 +58,11 @@ function SearchMovementsModalController(data, Notify, Instance, Flux, $translate
vm.onSelectLimit = function onSelectLimit(value) {
// input is type value, this will only be defined for a valid number
if (angular.isDefined(value)) {
- changes.post({ key: 'limit', value: value });
+ changes.post({ key : 'limit', value : value });
}
};
- // deletes a filter from the custom filter object,
+ // deletes a filter from the custom filter object,
// this key will no longer be written to changes on exit
vm.clear = function clear(key) {
delete vm.searchQueries[key];
@@ -70,16 +70,16 @@ function SearchMovementsModalController(data, Notify, Instance, Flux, $translate
vm.cancel = function cancel() { Instance.close(); };
- vm.submit = function submit(form) {
+ vm.submit = function submit() {
// push all searchQuery values into the changes array to be applied
angular.forEach(vm.searchQueries, function (value, key) {
if (angular.isDefined(value)) {
- changes.post({ key: key, value: value });
+ changes.post({ key : key, value : value });
}
});
var loggedChanges = changes.getAll();
-
+
return Instance.close(loggedChanges);
};
}
diff --git a/client/src/modules/stock/movements/registry.js b/client/src/modules/stock/movements/registry.js
index 9287acec7a..b44cd9353b 100644
--- a/client/src/modules/stock/movements/registry.js
+++ b/client/src/modules/stock/movements/registry.js
@@ -4,7 +4,7 @@ angular.module('bhima.controllers')
StockMovementsController.$inject = [
'StockService', 'NotifyService', 'uiGridConstants', '$translate',
'StockModalService', 'LanguageService', 'SessionService', 'FluxService',
- 'ReceiptModal', 'GridGroupingService', '$state', 'GridColumnService', 'GridStateService'
+ 'ReceiptModal', 'GridGroupingService', '$state', 'GridColumnService', 'GridStateService',
];
/**
@@ -21,129 +21,114 @@ function StockMovementsController(Stock, Notify,
var state;
var gridColumns;
- vm.gridApi = {};
-
// bind flux id with receipt
var mapFlux = {
- 1: { receipt: ReceiptModal.stockEntryPurchaseReceipt },
- 2: { receipt: ReceiptModal.stockEntryDepotReceipt },
- 3: { receipt: ReceiptModal.stockAdjustmentReceipt },
- 8: { receipt: ReceiptModal.stockExitDepotReceipt },
- 9: { receipt: ReceiptModal.stockExitPatientReceipt },
- 10: { receipt: ReceiptModal.stockExitServiceReceipt },
- 11: { receipt: ReceiptModal.stockExitLossReceipt },
- 12: { receipt: ReceiptModal.stockAdjustmentReceipt },
- 13: { receipt: ReceiptModal.stockEntryIntegrationReceipt },
+ 1 : { receipt : ReceiptModal.stockEntryPurchaseReceipt },
+ 2 : { receipt : ReceiptModal.stockEntryDepotReceipt },
+ 3 : { receipt : ReceiptModal.stockAdjustmentReceipt },
+ 8 : { receipt : ReceiptModal.stockExitDepotReceipt },
+ 9 : { receipt : ReceiptModal.stockExitPatientReceipt },
+ 10 : { receipt : ReceiptModal.stockExitServiceReceipt },
+ 11 : { receipt : ReceiptModal.stockExitLossReceipt },
+ 12 : { receipt : ReceiptModal.stockAdjustmentReceipt },
+ 13 : { receipt : ReceiptModal.stockEntryIntegrationReceipt },
};
// grouping box
vm.groupingBox = [
- { label: 'STOCK.INVENTORY', value: 'text' },
- { label: 'STOCK.IO', value: 'io' },
- { label: 'STOCK.LOT', value: 'label' },
+ { label : 'STOCK.INVENTORY', value : 'text' },
+ { label : 'STOCK.IO', value : 'io' },
+ { label : 'STOCK.LOT', value : 'label' },
];
+ vm.gridApi = {};
+
// global variables
vm.enterprise = Session.enterprise;
// grid columns
- var columns = [
- {
- field: 'depot_text',
- displayName: 'STOCK.DEPOT',
- headerCellFilter: 'translate',
- aggregationType: uiGridConstants.aggregationTypes.count
- },
-
- {
- field: 'io',
- displayName: 'STOCK.IO',
- headerCellFilter: 'translate',
- cellTemplate: 'modules/stock/movements/templates/io.cell.html'
- },
-
- {
- field: 'text',
- displayName: 'STOCK.INVENTORY',
- headerCellFilter: 'translate'
- },
-
- {
- field: 'label',
- displayName: 'STOCK.LOT',
- headerCellFilter: 'translate'
- },
-
- {
- field: 'quantity',
- displayName: 'STOCK.QUANTITY',
- headerCellFilter: 'translate',
- aggregationType: uiGridConstants.aggregationTypes.sum,
- cellClass: 'text-right',
- footerCellClass: 'text-right'
- },
-
- {
- field: 'unit_type',
- width: 75,
- displayName: 'TABLE.COLUMNS.UNIT',
- headerCellFilter: 'translate',
- cellTemplate: 'modules/stock/inventories/templates/unit.tmpl.html'
- },
-
- {
- field: 'unit_cost',
- displayName: 'STOCK.UNIT_COST',
- headerCellFilter: 'translate',
- cellFilter: 'currency:grid.appScope.enterprise.currency_id',
- cellClass: 'text-right'
- },
-
- {
- field: 'cost',
- displayName: 'STOCK.COST',
- headerCellFilter: 'translate',
- aggregationType: totalCost,
- cellClass: 'text-right',
- cellTemplate: 'modules/stock/movements/templates/cost.cell.html',
- footerCellFilter: 'currency:grid.appScope.enterprise.currency_id',
- footerCellClass: 'text-right'
- },
-
- {
- field: 'date',
- displayName: 'FORM.LABELS.DATE',
- headerCellFilter: 'translate',
- cellFilter: 'date',
- cellClass: 'text-right'
- },
-
- {
- field: 'flux_id',
- displayName: 'STOCK.FLUX',
- headerCellFilter: 'translate',
- cellTemplate: 'modules/stock/movements/templates/flux.cell.html'
- },
-
- {
- field: 'action',
- displayName: '',
- enableFiltering: false,
- enableSorting: false,
- cellTemplate: 'modules/stock/movements/templates/action.cell.html'
- },
- ];
+ var columns = [{
+ field : 'depot_text',
+ displayName : 'STOCK.DEPOT',
+ headerCellFilter : 'translate',
+ aggregationType : uiGridConstants.aggregationTypes.count,
+ aggregationHideLabel : true,
+ }, {
+ field : 'io',
+ displayName : 'STOCK.IO',
+ headerCellFilter : 'translate',
+ cellTemplate : 'modules/stock/movements/templates/io.cell.html',
+ }, {
+ field : 'text',
+ displayName : 'STOCK.INVENTORY',
+ headerCellFilter : 'translate',
+ }, {
+ field : 'label',
+ displayName : 'STOCK.LOT',
+ headerCellFilter : 'translate',
+ }, {
+ field : 'quantity',
+ type: 'number',
+ displayName : 'STOCK.QUANTITY',
+ headerCellFilter : 'translate',
+ aggregationType : uiGridConstants.aggregationTypes.sum,
+ aggregationHideLabel : true,
+ cellClass : 'text-right',
+ footerCellClass : 'text-right',
+ }, {
+ field : 'unit_type',
+ width : 75,
+ displayName : 'TABLE.COLUMNS.UNIT',
+ headerCellFilter : 'translate',
+ cellTemplate : 'modules/stock/inventories/templates/unit.tmpl.html',
+ }, {
+ field : 'unit_cost',
+ type : 'number',
+ displayName : 'STOCK.UNIT_COST',
+ headerCellFilter : 'translate',
+ cellFilter : 'currency:grid.appScope.enterprise.currency_id',
+ cellClass : 'text-right',
+ }, {
+ field : 'cost',
+ type : 'number',
+ displayName : 'STOCK.COST',
+ headerCellFilter : 'translate',
+ aggregationType : totalCost,
+ aggregationHideLabel : true,
+ cellFilter : 'currency:grid.appScope.enterprise.currency_id',
+ cellClass : 'text-right',
+ footerCellFilter : 'currency:grid.appScope.enterprise.currency_id',
+ footerCellClass : 'text-right',
+ }, {
+ field : 'date',
+ type: 'date',
+ displayName : 'FORM.LABELS.DATE',
+ headerCellFilter : 'translate',
+ cellFilter : 'date',
+ cellClass : 'text-right',
+ }, {
+ field : 'flux_id',
+ displayName : 'STOCK.FLUX',
+ headerCellFilter : 'translate',
+ cellTemplate : 'modules/stock/movements/templates/flux.cell.html',
+ }, {
+ field : 'action',
+ displayName : '',
+ enableFiltering : false,
+ enableSorting : false,
+ cellTemplate : 'modules/stock/movements/templates/action.cell.html',
+ }];
// options for the UI grid
vm.gridOptions = {
- appScopeProvider: vm,
- enableColumnMenus: false,
- columnDefs: columns,
- enableSorting: true,
- showColumnFooter: true,
- onRegisterApi: onRegisterApi,
- fastWatch: true,
- flatEntityAccess: true,
+ appScopeProvider : vm,
+ enableColumnMenus : false,
+ columnDefs : columns,
+ enableSorting : true,
+ showColumnFooter : true,
+ onRegisterApi : onRegisterApi,
+ fastWatch : true,
+ flatEntityAccess : true,
};
vm.grouping = new Grouping(vm.gridOptions, true, 'depot_text', vm.grouped, true);
@@ -215,35 +200,41 @@ function StockMovementsController(Stock, Notify,
// column configuration has direct access to the grid API to alter the current
// state of the columns - this will be saved if the user saves the grid configuration
gridColumns.openConfigurationModal();
- };
+ }
vm.saveGridState = state.saveGridState;
function clearGridState() {
state.clearGridState();
$state.reload();
- };
+ }
// load stock lots in the grid
function load(filters) {
vm.hasError = false;
vm.loading = true;
- Stock.movements.read(null, filters).then(function (rows) {
- // set flux name
- rows.forEach(function (row) {
- row.fluxName = getFluxName(row.flux_id);
- });
+ Stock.movements.read(null, filters)
+ .then(function (rows) {
+ // preprocess data
+ rows.forEach(function (row) {
+
+ // compute the fluxName from its ID
+ row.fluxName = getFluxName(row.flux_id);
- vm.gridOptions.data = rows;
+ // compute the row cost
+ row.cost = row.quantity * row.unit_cost;
+ });
- // force expand grid
- vm.grouping.unfoldAllGroups();
- })
- .catch(Notify.handleError)
- .finally(function () {
- vm.loading = false;
- });
+ vm.gridOptions.data = rows;
+
+ // force expand grid
+ vm.grouping.unfoldAllGroups();
+ })
+ .catch(Notify.handleError)
+ .finally(function () {
+ vm.loading = false;
+ });
}
// search modal
@@ -267,10 +258,9 @@ function StockMovementsController(Stock, Notify,
// initialize module
function startup() {
-
- if($state.params.filters) {
+ if ($state.params.filters) {
var changes = [{ key : $state.params.filters.key, value : $state.params.filters.value }]
- stockMovementFilters.replaceFilters(changes);
+ stockMovementFilters.replaceFilters(changes);
Stock.cacheFilters(filterKey);
}
diff --git a/client/src/modules/stock/movements/templates/action.cell.html b/client/src/modules/stock/movements/templates/action.cell.html
index 3f0b325641..f8b0085976 100644
--- a/client/src/modules/stock/movements/templates/action.cell.html
+++ b/client/src/modules/stock/movements/templates/action.cell.html
@@ -1,4 +1,4 @@
-
+
FORM.BUTTONS.ACTIONS
diff --git a/client/src/modules/stock/movements/templates/cost.cell.html b/client/src/modules/stock/movements/templates/cost.cell.html
deleted file mode 100644
index e8e5b1f820..0000000000
--- a/client/src/modules/stock/movements/templates/cost.cell.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- {{ row.entity.unit_cost * row.entity.quantity | currency: grid.appScope.enterprise.currency_id }}
-
\ No newline at end of file
diff --git a/server/config/routes.js b/server/config/routes.js
index 2ed580ffc1..e921671fc2 100644
--- a/server/config/routes.js
+++ b/server/config/routes.js
@@ -42,7 +42,7 @@ const snis = require('../controllers/medical/snis');
const medicalReports = require('../controllers/medical/reports');
const diagnoses = require('../controllers/medical/diagnoses');
-// humaine ressource route
+// human resources routes
const employees = require('../controllers/payroll/employees');
const employeeReports = require('../controllers/payroll/reports');
@@ -175,12 +175,12 @@ exports.configure = function configure(app) {
// API for journal
app.get('/journal', journal.list);
app.get('/journal/count', journal.count);
-
+
app.get('/journal/:record_uuid', journal.getTransaction);
app.post('/journal/:record_uuid/edit', journal.editTransaction);
app.post('/journal/:uuid/reverse', journal.reverse);
-
+
// API for general ledger
app.get('/general_ledger', generalLedger.list);
@@ -318,7 +318,7 @@ exports.configure = function configure(app) {
// interface for linking entities, it renders a report for a particular entity
app.get('/refenceLookup/:codeRef/:language', refenceLookup.getEntity);
-
+
// interface for employee report
app.get('/reports/payroll/employees', employeeReports.employeeRegistrations);
diff --git a/server/controllers/stock/core.js b/server/controllers/stock/core.js
index dbbff7279d..5301fc2a0e 100644
--- a/server/controllers/stock/core.js
+++ b/server/controllers/stock/core.js
@@ -8,7 +8,7 @@
* @requires lib/db
* @requires lib/filter
* @requires config/identifiers
- **/
+ */
const moment = require('moment');
const db = require('../../lib/db');
@@ -54,24 +54,27 @@ exports.getInventoryMovements = getInventoryMovements;
* @description returns a list of lots
*
* @param {string} sql - An optional sql script of selecting in lot
- * @param {object} params - A request query object
- * @param {string} finalClause - An optional final clause (GROUP BY, HAVING, ...) to add to query built
+ * @param {object} parameters - A request query object
+ * @param {string} finalClauseParameter - An optional final clause (GROUP BY, HAVING, ...) to add to query built
*/
function getLots(sqlQuery, parameters, finalClauseParameter) {
const finalClause = finalClauseParameter;
- const params = parameters;
+ const params = parameters;
const sql = sqlQuery || `
- SELECT
- BUID(l.uuid) AS uuid, l.label, l.initial_quantity, l.unit_cost, BUID(l.origin_uuid) AS origin_uuid,
- l.expiration_date, BUID(l.inventory_uuid) AS inventory_uuid, i.delay, l.entry_date,
- i.code, i.text, BUID(m.depot_uuid) AS depot_uuid, d.text AS depot_text, iu.text AS unit_type
- FROM lot l
- JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
- JOIN stock_movement m ON m.lot_uuid = l.uuid AND m.flux_id = ${flux.FROM_PURCHASE}
- JOIN depot d ON d.uuid = m.depot_uuid
- `;
+ SELECT
+ BUID(l.uuid) AS uuid, l.label, l.initial_quantity, l.unit_cost, BUID(l.origin_uuid) AS origin_uuid,
+ l.expiration_date, BUID(l.inventory_uuid) AS inventory_uuid, i.delay, l.entry_date,
+ i.code, i.text, BUID(m.depot_uuid) AS depot_uuid, d.text AS depot_text, iu.text AS unit_type
+ FROM lot l
+ JOIN inventory i ON i.uuid = l.inventory_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
+ JOIN stock_movement m ON m.lot_uuid = l.uuid AND m.flux_id = ${flux.FROM_PURCHASE}
+ JOIN depot d ON d.uuid = m.depot_uuid
+`;
+
+ // make sure all uuids are properly converted to binary
db.convert(params, ['uuid', 'depot_uuid', 'lot_uuid', 'inventory_uuid', 'document_uuid', 'entity_uuid']);
+
const filters = new FilterParser(params, { autoParseStatements : false });
filters.equals('uuid', 'uuid', 'l');
@@ -84,6 +87,7 @@ function getLots(sqlQuery, parameters, finalClauseParameter) {
filters.equals('text', 'text', 'i');
filters.equals('label', 'label', 'l');
filters.equals('is_exit', 'is_exit', 'm');
+ filters.equals('flux_id', 'flux_id', 'm');
filters.period('defaultPeriod', 'date');
filters.period('defaultPeriodEntry', 'entry_date', 'l');
@@ -92,13 +96,14 @@ function getLots(sqlQuery, parameters, finalClauseParameter) {
filters.dateFrom('expiration_date_from', 'expiration_date', 'l');
filters.dateTo('expiration_date_to', 'expiration_date', 'l');
+
filters.dateFrom('entry_date_from', 'entry_date', 'l');
filters.dateTo('entry_date_to', 'entry_date', 'l');
filters.dateFrom('dateFrom', 'date', 'm');
filters.dateTo('dateTo', 'date', 'm');
- // If finalClause is an empty string, filterParser will not group, it will be an empty string
+ // if finalClause is an empty string, filterParser will not group, it will be an empty string
filters.setGroup(finalClause || '');
const query = filters.applyQuery(sql);
@@ -131,38 +136,38 @@ function getLotsDepot(depotUuid, params, finalClause) {
delete params.status;
}
- if(Number(params.includeEmptyLot) === 0){
+ if (Number(params.includeEmptyLot) === 0) {
exludeToken = 'HAVING quantity > 0';
delete params.includeEmptyLot;
}
const sql = `
- SELECT BUID(l.uuid) AS uuid, l.label, l.initial_quantity,
- SUM(m.quantity * IF(m.is_exit = 1, -1, 1)) AS quantity,
- d.text AS depot_text, l.unit_cost, l.expiration_date,
- BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
+ SELECT BUID(l.uuid) AS uuid, l.label, l.initial_quantity,
+ SUM(m.quantity * IF(m.is_exit = 1, -1, 1)) AS quantity,
+ d.text AS depot_text, l.unit_cost, l.expiration_date,
+ BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
l.entry_date, i.code, i.text, BUID(m.depot_uuid) AS depot_uuid,
i.avg_consumption, i.purchase_interval, i.delay,
iu.text AS unit_type
- FROM stock_movement m
+ FROM stock_movement m
JOIN lot l ON l.uuid = m.lot_uuid
JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
- JOIN depot d ON d.uuid = m.depot_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
+ JOIN depot d ON d.uuid = m.depot_uuid
`;
const clause = finalClause || ` GROUP BY l.uuid, m.depot_uuid ${exludeToken}`;
return getLots(sql, params, clause)
- .then(stockManagementProcess)
- .then((rows) => {
- if (status) {
- return rows.filter((row) => {
- return row.status === status;
- });
- }
- return rows;
+ .then(stockManagementProcess)
+ .then((rows) => {
+ if (status) {
+ return rows.filter((row) => {
+ return row.status === status;
});
+ }
+ return rows;
+ });
}
/**
@@ -181,27 +186,27 @@ function getLotsMovements(depotUuid, params) {
params.depot_uuid = depotUuid;
}
- if(params.groupByDocument === 1){
+ if (params.groupByDocument === 1) {
finalClause = 'GROUP BY document_uuid';
delete params.groupByDocument;
}
const sql = `
- SELECT
- BUID(l.uuid) AS uuid, l.label, l.initial_quantity, m.quantity, m.reference, m.description,
- d.text AS depot_text, IF(is_exit = 1, "OUT", "IN") AS io, l.unit_cost,
- l.expiration_date, BUID(l.inventory_uuid) AS inventory_uuid,
- BUID(l.origin_uuid) AS origin_uuid, l.entry_date, i.code, i.text,
- BUID(m.depot_uuid) AS depot_uuid, m.is_exit, m.date, BUID(m.document_uuid) AS document_uuid,
- m.flux_id, BUID(m.entity_uuid) AS entity_uuid, m.unit_cost,
- f.label AS flux_label, i.delay,
- iu.text AS unit_type
- FROM stock_movement m
- JOIN lot l ON l.uuid = m.lot_uuid
- JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
- JOIN depot d ON d.uuid = m.depot_uuid
- JOIN flux f ON f.id = m.flux_id
+ SELECT
+ BUID(l.uuid) AS uuid, l.label, l.initial_quantity, m.quantity, m.reference, m.description,
+ d.text AS depot_text, IF(is_exit = 1, "OUT", "IN") AS io, l.unit_cost,
+ l.expiration_date, BUID(l.inventory_uuid) AS inventory_uuid,
+ BUID(l.origin_uuid) AS origin_uuid, l.entry_date, i.code, i.text,
+ BUID(m.depot_uuid) AS depot_uuid, m.is_exit, m.date, BUID(m.document_uuid) AS document_uuid,
+ m.flux_id, BUID(m.entity_uuid) AS entity_uuid, m.unit_cost,
+ f.label AS flux_label, i.delay,
+ iu.text AS unit_type
+ FROM stock_movement m
+ JOIN lot l ON l.uuid = m.lot_uuid
+ JOIN inventory i ON i.uuid = l.inventory_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
+ JOIN depot d ON d.uuid = m.depot_uuid
+ JOIN flux f ON f.id = m.flux_id
`;
return getLots(sql, params, finalClause);
@@ -222,34 +227,34 @@ function getLotsOrigins(depotUuid, params) {
}
const sql = `
- SELECT BUID(l.uuid) AS uuid, l.label, l.unit_cost, l.expiration_date,
- BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
- l.entry_date, i.code, i.text, origin.display_name, origin.reference,
+ SELECT BUID(l.uuid) AS uuid, l.label, l.unit_cost, l.expiration_date,
+ BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
+ l.entry_date, i.code, i.text, origin.display_name, origin.reference,
BUID(m.document_uuid) AS document_uuid, m.flux_id,
iu.text AS unit_type
- FROM lot l
- JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
+ FROM lot l
+ JOIN inventory i ON i.uuid = l.inventory_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
JOIN (
- SELECT
+ SELECT
p.uuid, CONCAT_WS('.', '${identifiers.PURCHASE_ORDER.key}', proj.abbr, p.reference) AS reference,
'STOCK.PURCHASE_ORDER' AS display_name
- FROM
+ FROM
purchase p JOIN project proj ON proj.id = p.project_id
- UNION
- SELECT
+ UNION
+ SELECT
d.uuid, CONCAT_WS('.', '${identifiers.DONATION.key}', proj.abbr, d.reference) AS reference,
- 'STOCK.DONATION' AS display_name
- FROM
+ 'STOCK.DONATION' AS display_name
+ FROM
donation d JOIN project proj ON proj.id = d.project_id
- UNION
- SELECT
+ UNION
+ SELECT
i.uuid, CONCAT_WS('.', '${identifiers.INTEGRATION.key}', proj.abbr, i.reference) AS reference,
- 'STOCK.INTEGRATION' AS display_name
- FROM
- integration i JOIN project proj ON proj.id = i.project_id
- ) AS origin ON origin.uuid = l.origin_uuid
- JOIN stock_movement m ON m.lot_uuid = l.uuid AND m.is_exit = 0
+ 'STOCK.INTEGRATION' AS display_name
+ FROM
+ integration i JOIN project proj ON proj.id = i.project_id
+ ) AS origin ON origin.uuid = l.origin_uuid
+ JOIN stock_movement m ON m.lot_uuid = l.uuid AND m.is_exit = 0
AND m.flux_id IN (${flux.FROM_PURCHASE}, ${flux.FROM_DONATION}, ${flux.FROM_INTEGRATION})
`;
@@ -310,10 +315,10 @@ function getStockConsumption(periodIds) {
const sql = `
SELECT SUM(s.quantity) AS quantity, BUID(i.uuid) AS uuid, i.text, i.code, d.text
FROM stock_consumption s
- JOIN inventory i ON i.uuid = s.inventory_uuid
+ JOIN inventory i ON i.uuid = s.inventory_uuid
JOIN depot d ON d.uuid = s.depot_uuid
JOIN period p ON p.id = s.period_id
- WHERE p.id IN (?)
+ WHERE p.id IN (?)
GROUP BY i.uuid, d.uuid
`;
return db.exec(sql, [periodIds]);
@@ -344,12 +349,13 @@ function getStockConsumptionAverage(periodId, periodDate, numberOfMonths) {
'SELECT id FROM period WHERE DATE(?) BETWEEN DATE(start_date) AND DATE(end_date) LIMIT 1;';
const queryStockConsumption = `
- SELECT ROUND(AVG(s.quantity)) AS quantity, BUID(i.uuid) AS uuid, i.text, i.code, BUID(d.uuid) AS depot_uuid, d.text AS depot_text
+ SELECT ROUND(AVG(s.quantity)) AS quantity, BUID(i.uuid) AS uuid, i.text, i.code, BUID(d.uuid) AS depot_uuid,
+ d.text AS depot_text
FROM stock_consumption s
- JOIN inventory i ON i.uuid = s.inventory_uuid
+ JOIN inventory i ON i.uuid = s.inventory_uuid
JOIN depot d ON d.uuid = s.depot_uuid
JOIN period p ON p.id = s.period_id
- WHERE p.id IN (?)
+ WHERE p.id IN (?)
GROUP BY i.uuid, d.uuid
`;
@@ -391,18 +397,18 @@ function getInventoryQuantityAndConsumption(params) {
}
const sql = `
- SELECT BUID(l.uuid) AS uuid, l.label, l.initial_quantity,
- SUM(m.quantity * IF(m.is_exit = 1, -1, 1)) AS quantity,
- d.text AS depot_text, l.unit_cost, l.expiration_date,
- BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
+ SELECT BUID(l.uuid) AS uuid, l.label, l.initial_quantity,
+ SUM(m.quantity * IF(m.is_exit = 1, -1, 1)) AS quantity,
+ d.text AS depot_text, l.unit_cost, l.expiration_date,
+ BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
l.entry_date, i.code, i.text, BUID(m.depot_uuid) AS depot_uuid,
i.avg_consumption, i.purchase_interval, i.delay,
iu.text AS unit_type
- FROM stock_movement m
+ FROM stock_movement m
JOIN lot l ON l.uuid = m.lot_uuid
JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
- JOIN depot d ON d.uuid = m.depot_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
+ JOIN depot d ON d.uuid = m.depot_uuid
`;
const clause = ' GROUP BY l.inventory_uuid, m.depot_uuid ';
@@ -450,14 +456,14 @@ function getInventoryMovements(params) {
SELECT BUID(l.uuid) AS uuid, l.label, l.initial_quantity,
d.text AS depot_text, l.unit_cost, l.expiration_date,
m.quantity, m.is_exit, m.date,
- BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
+ BUID(l.inventory_uuid) AS inventory_uuid, BUID(l.origin_uuid) AS origin_uuid,
l.entry_date, i.code, i.text, BUID(m.depot_uuid) AS depot_uuid,
i.avg_consumption, i.purchase_interval, i.delay, iu.text AS unit_type
- FROM stock_movement m
+ FROM stock_movement m
JOIN lot l ON l.uuid = m.lot_uuid
JOIN inventory i ON i.uuid = l.inventory_uuid
- JOIN inventory_unit iu ON iu.id = i.unit_id
- JOIN depot d ON d.uuid = m.depot_uuid
+ JOIN inventory_unit iu ON iu.id = i.unit_id
+ JOIN depot d ON d.uuid = m.depot_uuid
`;
return getLots(sql, params, ' ORDER BY m.date ASC ')
@@ -486,11 +492,6 @@ function getInventoryMovements(params) {
movement.exit.quantity = line.quantity;
movement.exit.unit_cost = stockUnitCost;
movement.exit.value = line.quantity * line.unit_cost;
-
- // stock status
- movement.stock.quantity = stockQuantity;
- movement.stock.unit_cost = stockUnitCost;
- movement.stock.value = stockValue;
} else {
const newQuantity = line.quantity + stockQuantity;
const newValue = (line.unit_cost * line.quantity) + stockValue;
@@ -504,12 +505,13 @@ function getInventoryMovements(params) {
movement.entry.quantity = line.quantity;
movement.entry.unit_cost = line.unit_cost;
movement.entry.value = line.quantity * line.unit_cost;
-
- // stock status
- movement.stock.quantity = stockQuantity;
- movement.stock.unit_cost = stockUnitCost;
- movement.stock.value = stockValue;
}
+
+ // stock status
+ movement.stock.quantity = stockQuantity;
+ movement.stock.unit_cost = stockUnitCost;
+ movement.stock.value = stockValue;
+
return movement;
});
diff --git a/test/end-to-end/stock/stock.movements.spec.js b/test/end-to-end/stock/stock.movements.spec.js
index b2d30bf115..11cb84ae53 100644
--- a/test/end-to-end/stock/stock.movements.spec.js
+++ b/test/end-to-end/stock/stock.movements.spec.js
@@ -1,7 +1,6 @@
const FU = require('../shared/FormUtils');
const GU = require('../shared/GridUtils');
const helpers = require('../shared/helpers');
-const components = require('../shared/components');
const SearchModal = require('../shared/search.page');
const Filters = require('../shared/components/bhFilters');
@@ -39,11 +38,11 @@ function StockMovementsRegistryTests() {
GU.expectRowCount(gridId, 15 + (2 * depotGroupingRow));
});
- it('find exit movements', () => {
+ it('filters by entry/exit', () => {
// for Exit
modal.setEntryExit(1);
modal.submit();
- GU.expectRowCount(gridId, 16 + depotGroupingRow);
+ GU.expectRowCount(gridId, 8 + depotGroupingRow);
});
it('find movements by depot', () => {
@@ -67,43 +66,43 @@ function StockMovementsRegistryTests() {
it('find by lots reasons for purchase order', () => {
// FIX ME: reasons must not depend on translations
- //selection with `id` works but it is not completed
+ // selection with `id` works but it is not completed
modal.setMovementReason('Commande d\'achat');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
+ GU.expectRowCount(gridId, 8 + depotGroupingRow);
});
it('find by lots reasons for distribution to patient', () => {
- // to patient
+ // to patient
modal.setMovementReason('Vers un patient');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
+ GU.expectRowCount(gridId, 2 + depotGroupingRow);
});
it('find by lots reasons for distribution to depot', () => {
modal.setMovementReason('Vers un depot');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
+ GU.expectRowCount(gridId, 2 + depotGroupingRow);
});
it('find by lots reasons for distribution from depot', () => {
// from depot
modal.setMovementReason('En provenance d\'un depot');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
+ GU.expectRowCount(gridId, 1 + depotGroupingRow);
});
it('find by lots reasons for positive adjustement', () => {
modal.setMovementReason('Ajustement (Positif)');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
+ GU.expectRowCount(gridId, 1 + depotGroupingRow);
});
it('find by lots reasons for negative adjustement', () => {
modal.setMovementReason('Ajustement (Negatif)');
modal.submit();
- GU.expectRowCount(gridId, 24 + depotGroupingRow);
- });
+ GU.expectRowCount(gridId, 1 + depotGroupingRow);
+ });
it('find lots by date - Fev 2017', () => {
modal.setdateInterval('02/02/2017', '02/02/2017', 'date');