Skip to content

Commit

Permalink
Feat(inventory) download log as excel
Browse files Browse the repository at this point in the history
closes #3976
  • Loading branch information
jeremielodi committed Dec 3, 2019
1 parent 3d0cf46 commit 64554bd
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 11 deletions.
4 changes: 4 additions & 0 deletions client/src/modules/inventory/list/modals/log.modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
</div>
</div>
<div class="modal-footer">
<a target='_blank' class="btn btn-primary" data-method="exports" href="/inventory/download/log/{{$ctrl.inventory.uuid}}?lang={{$ctrl.lang}}">
<span class="fa fa-file-excel-o"></span> <span translate>DOWNLOADS.EXCEL</span>
</a>

<button type="button" class="btn btn-default" data-method="close" ng-click="$ctrl.close()">
<span translate>FORM.BUTTONS.CLOSE</span>
</button>
Expand Down
6 changes: 3 additions & 3 deletions client/src/modules/inventory/list/modals/log.modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ angular.module('bhima.controllers')
.controller('InventoryLogModalController', InventoryLogModalController);

InventoryLogModalController.$inject = [
'data', '$uibModalInstance', 'InventoryService',
'data', '$uibModalInstance', 'InventoryService', 'LanguageService',
];

function InventoryLogModalController(data, Instance, Inventory) {
function InventoryLogModalController(data, Instance, Inventory, LanguageService) {
const vm = this;
vm.close = Instance.close;

vm.lang = LanguageService.key;
Inventory.read(data.uuid).then(inventory => {
vm.inventory = inventory;
});
Expand Down
1 change: 1 addition & 0 deletions server/config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ exports.configure = function configure(app) {
app.delete('/inventory/metadata/:uuid', inventory.deleteInventory);

app.get('/inventory/log/:uuid', inventory.logs);
app.get('/inventory/download/log/:uuid', inventory.logDownLoad);

/** Inventory Group API endpoints */
app.post('/inventory/groups', inventory.createInventoryGroups);
Expand Down
79 changes: 78 additions & 1 deletion server/controllers/inventory/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
*
* TODO: We should migrate the inventory to using the regular bhima guidelines.
*/

const _ = require('lodash');
const core = require('./inventory/core');
const groups = require('./inventory/groups');
const types = require('./inventory/types');
const units = require('./inventory/units');
const importing = require('./import');
const util = require('../../lib/util');

const xlsx = require('../../lib/renderers/xlsx');
const ReportManager = require('../../lib/ReportManager');

// exposed routes
exports.createInventoryItems = createInventoryItems;
Expand Down Expand Up @@ -52,6 +56,9 @@ exports.deleteInventory = deleteInventory;
exports.importing = importing;

exports.logs = inventoryLog;
exports.logDownLoad = logDownLoad;


// ======================= inventory metadata =============================
/**
* POST /inventory/metadata
Expand Down Expand Up @@ -88,6 +95,76 @@ function inventoryLog(req, res, next) {
}).catch(next);
}

// get inventory log as excel
// GET /inventory/download/log/:uuid?rendere=xlsx?lang=fr

async function logDownLoad(req, res, next) {
try {
const { lang } = req.query;
const rows = await core.inventoryLog(req.params.uuid);
// inventory columns

const dictionary = util.loadDictionary(lang);

const inventory = await core.getItemsMetadata({ uuid : req.params.uuid });

const lines = [
{ column1 : '', column2 : '', column3 : '' },
];

lines.push({
column1 : _.get(dictionary, 'FORM.LABELS.INVENTORY'),
column2 : inventory[0].label || '',
column3 : '',
});

lines.push({ column1 : '', column2 : '', column3 : '' });
rows.forEach(r => {
const text = JSON.parse(r.text);
lines.push({
column1 : _.get(dictionary, 'FORM.LABELS.USER'),
column2 : _.get(dictionary, 'FORM.LABELS.DATE'),
column3 : '',
});

lines.push({ column1 : r.userName, column2 : r.log_timestamp, column3 : '' });

lines.push({
column1 : '',
column2 : _.get(dictionary, 'FORM.LABELS.FROM'),
column3 : _.get(dictionary, 'FORM.LABELS.TO'),
});

const currentchanges = Object.keys(text.current);
currentchanges.forEach(cc => {
const line2 = {
column1 : _.get(dictionary, core.inventoryColsMap[cc]),
column2 : text.last[cc],
column3 : text.current[cc],
};
lines.push(line2);
});

lines.push({ column1 : '', column2 : '', column3 : '' });
});


const options = {
csvKey : 'rows',
suppressDefaultFormatting : true,
suppressDefaultFiltering : true,
renderer : 'xlsx',
filename : 'FORM.LABELS.CHANGES',
};

const report = new ReportManager('', req.session, options);
const result = await report.render({ rows : lines }, null, { lang });
res.set(xlsx.headers).send(result.report);
} catch (error) {
next(error);
}

}

/**
* GET /inventory/metadata/
Expand Down
36 changes: 30 additions & 6 deletions server/controllers/inventory/inventory/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ const errors = {
},
};

const inventoryColsMap = {
code : 'FORM.LABELS.CODE',
consumable : 'FORM.LABELS.CONSUMABLE',
default_quantity : 'FORM.LABELS.DEFAULT_QUANTITY',
group_uuid : 'FORM.LABELS.GROUP',
inventoryGroup : 'FORM.LABELS.GROUP',
label : 'FORM.LABELS.LABEL',
text : 'FORM.LABELS.LABEL',
note : 'FORM.INFO.NOTE',
price : 'FORM.LABELS.UNIT_PRICE',
sellable : 'INVENTORY.SELLABLE',
type_id : 'FORM.LABELS.TYPE',
inventoryType : 'FORM.LABELS.TYPE',
unit_id : 'FORM.LABELS.UNIT',
inventoryUnit : 'FORM.LABELS.UNIT',
unit_volume : 'FORM.LABELS.VOLUME',
unit_weight : 'FORM.LABELS.WEIGHT',
};

exports.getIds = getIds;
exports.getItemsMetadata = getItemsMetadata;
exports.getItemsMetadataById = getItemsMetadataById;
Expand All @@ -47,7 +66,7 @@ exports.errors = errors;
exports.errorHandler = errorHandler;
exports.remove = remove;
exports.inventoryLog = inventoryLog;

exports.inventoryColsMap = inventoryColsMap;
/**
* Create inventory metadata in the database
*
Expand Down Expand Up @@ -171,8 +190,10 @@ function getItemsMetadata(params) {
db.convert(params, ['inventory_uuids', 'uuid', 'group_uuid']);
const filters = new FilterParser(params, { tableAlias : 'inventory', autoParseStatements : false });

const sql = `SELECT BUID(inventory.uuid) as uuid, inventory.code, inventory.text AS label, inventory.price, iu.abbr AS unit,
it.text AS type, ig.name AS groupName, BUID(ig.uuid) AS group_uuid, ig.expires, ig.unique_item, inventory.consumable,inventory.locked, inventory.stock_min,
const sql = `
SELECT BUID(inventory.uuid) as uuid, inventory.code, inventory.text AS label, inventory.price, iu.abbr AS unit,
it.text AS type, ig.name AS groupName, BUID(ig.uuid) AS group_uuid, ig.expires, ig.unique_item,
inventory.consumable,inventory.locked, inventory.stock_min,
inventory.stock_max, inventory.created_at AS timestamp, inventory.type_id, inventory.unit_id,
inventory.note, inventory.unit_weight, inventory.unit_volume,
ig.sales_account, ig.stock_account, ig.donation_account, inventory.sellable, inventory.note,
Expand Down Expand Up @@ -222,10 +243,13 @@ function remove(_uuid) {
* @return {Promise} Returns a database query promise
*/
function getItemsMetadataById(uid) {
const sql = `SELECT BUID(i.uuid) as uuid, i.code, i.text AS label, i.price, iu.abbr AS unit,
it.text AS type, ig.name AS groupName, BUID(ig.uuid) AS group_uuid, ig.expires, ig.unique_item, i.consumable, i.locked, i.stock_min,
const sql = `
SELECT BUID(i.uuid) as uuid, i.code, i.text AS label, i.price, iu.abbr AS unit,
it.text AS type, ig.name AS groupName, BUID(ig.uuid) AS group_uuid, ig.expires,
ig.unique_item, i.consumable, i.locked, i.stock_min,
i.stock_max, i.created_at AS timestamp, i.type_id, i.unit_id, i.unit_weight, i.unit_volume,
ig.sales_account, i.default_quantity, i.avg_consumption, i.delay, i.purchase_interval, i.last_purchase, i.num_purchase
ig.sales_account, i.default_quantity, i.avg_consumption, i.delay, i.purchase_interval,
i.last_purchase, i.num_purchase
FROM inventory AS i JOIN inventory_type AS it
JOIN inventory_unit AS iu JOIN inventory_group AS ig ON
i.type_id = it.id AND i.group_uuid = ig.uuid AND
Expand Down
16 changes: 15 additions & 1 deletion test/integration/inventory/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

const helpers = require('../helpers');
const shared = require('./shared');
const xlsx = require('../../../server/lib/renderers/xlsx.js');

describe('(/inventory/metadata) The inventory metadata http API', () => {
describe.only('(/inventory/metadata) The inventory metadata http API', () => {
let inventoryList;

// inventory list items
Expand All @@ -19,6 +20,8 @@ describe('(/inventory/metadata) The inventory metadata http API', () => {
sellable : 1,
};

const inventoryUuid = 'c8a406a9-53d6-429f-84d8-fc497875a580';

const metadataUpdate = {
code : '1000012', // code must be unique
text : '[IT] Inventory Article updated',
Expand All @@ -31,6 +34,16 @@ describe('(/inventory/metadata) The inventory metadata http API', () => {
text : 'Albendazo', // should find "Albendazole"
};

it('GET /inventory/download/log/?lang=fr donwload log as Ms excel', () => {
return agent.get(`/inventory/download/log/${inventoryUuid}?lang=fr`)
.then(res => {
expect(res).to.have.status(200);
expect(res.headers['content-type']).to.be.equal(xlsx.headers['Content-Type']);
})
.catch(helpers.handler);
});


it('POST /inventory/metadata create a new inventory metadata', () => {
return agent.post('/inventory/metadata')
.send(metadata)
Expand All @@ -41,6 +54,7 @@ describe('(/inventory/metadata) The inventory metadata http API', () => {
.catch(helpers.handler);
});


it('PUT /inventory/metadata/:uuid update an existing inventory metadata', () => {
return agent.put(`/inventory/metadata/${metadata.uuid}`)
.send(metadataUpdate)
Expand Down

0 comments on commit 64554bd

Please sign in to comment.