From 2f29aca16e5ff89ad0e3c27e81f8d3a1a39d4a9b Mon Sep 17 00:00:00 2001 From: jeremielodi Date: Mon, 24 Aug 2020 14:07:01 +0100 Subject: [PATCH] (stock entry) find donation modal --- client/src/modules/donor/donation.service.js | 15 +++ client/src/modules/stock/entry/entry.js | 25 ++-- .../entry/modals/findDonation.modal.html | 54 ++++++++ .../stock/entry/modals/findDonation.modal.js | 117 ++++++++++++++++++ client/src/modules/stock/stock.service.js | 14 +++ server/config/routes.js | 9 ++ server/controllers/admin/donation.js | 60 +++++++++ 7 files changed, 283 insertions(+), 11 deletions(-) create mode 100644 client/src/modules/donor/donation.service.js create mode 100644 client/src/modules/stock/entry/modals/findDonation.modal.html create mode 100644 client/src/modules/stock/entry/modals/findDonation.modal.js create mode 100644 server/controllers/admin/donation.js diff --git a/client/src/modules/donor/donation.service.js b/client/src/modules/donor/donation.service.js new file mode 100644 index 0000000000..342fc0c559 --- /dev/null +++ b/client/src/modules/donor/donation.service.js @@ -0,0 +1,15 @@ +angular.module('bhima.services') + .service('DonationService', DonationService); + +DonationService.$inject = ['PrototypeApiService']; + +/** + * Role Service + * + * A service wrapper for the /donors HTTP endpoint. + * + */ +function DonationService(Api) { + const service = new Api('/donations/'); + return service; +} diff --git a/client/src/modules/stock/entry/entry.js b/client/src/modules/stock/entry/entry.js index 24d351c4eb..70a4cafc12 100644 --- a/client/src/modules/stock/entry/entry.js +++ b/client/src/modules/stock/entry/entry.js @@ -260,7 +260,7 @@ function StockEntryController( * @description * set movement information according the selected entity and populate the grid */ - function handleSelectedEntity(_entities, _type) { + function handleSelectedEntity(_entities, _type, noPopulate = false) { if (!_entities || !_entities.length) { resetSelectedEntity(); return; @@ -276,7 +276,10 @@ function StockEntryController( setDescription(vm.movement.entity); // populate the grid - populate(_entities); + if (!noPopulate) { + populate(_entities); + } + } /** @@ -348,9 +351,17 @@ function StockEntryController( function handleDonationSelection() { const description = $translate.instant('STOCK.RECEPTION_DONATION'); initSelectedEntity(description); + if (vm.gridOptions.data.length === 0) { vm.addItems(1); } + + StockModal.openFindDonation() + .then((donation) => { + handleSelectedEntity(donation, 'donation', true); + setSelectedEntity(vm.movement.entity.instance); + }) + .catch(Notify.handleError); } /** @@ -505,7 +516,6 @@ function StockEntryController( .catch(Notify.handleError); } - /** * @method submitIntegration * @description prepare the stock movement and send data to the server as new stock integration @@ -547,14 +557,7 @@ function StockEntryController( user_id : vm.stockForm.details.user_id, }; - /* - the origin_uuid of lots is set on the client - because donation table depends on donor, and donor management - is not yet implemented in the application - - TODO: add a donor management module - */ - movement.lots = Stock.processLotsFromStore(vm.stockForm.store.data, Uuid()); + movement.lots = Stock.processLotsFromStore(vm.stockForm.store.data, vm.movement.entity.uuid); return Stock.stocks.create(movement) .then((document) => { diff --git a/client/src/modules/stock/entry/modals/findDonation.modal.html b/client/src/modules/stock/entry/modals/findDonation.modal.html new file mode 100644 index 0000000000..b64d4eb99a --- /dev/null +++ b/client/src/modules/stock/entry/modals/findDonation.modal.html @@ -0,0 +1,54 @@ +
+ + + + + + + +
\ No newline at end of file diff --git a/client/src/modules/stock/entry/modals/findDonation.modal.js b/client/src/modules/stock/entry/modals/findDonation.modal.js new file mode 100644 index 0000000000..af636fac79 --- /dev/null +++ b/client/src/modules/stock/entry/modals/findDonation.modal.js @@ -0,0 +1,117 @@ +angular.module('bhima.controllers') + .controller('StockFindDonationModalController', StockFindDonationModalController); + +StockFindDonationModalController.$inject = [ + '$uibModalInstance', 'DonationService', 'NotifyService', + 'uiGridConstants', 'GridFilteringService', 'ReceiptModal', + 'bhConstants', +]; + +function StockFindDonationModalController( + Instance, Donation, Notify, + uiGridConstants, Filtering, Receipts, bhConstants, +) { + const vm = this; + + // global + vm.selectedRow = {}; + + /* ======================= Grid configurations ============================ */ + vm.filterEnabled = false; + vm.gridOptions = { appScopeProvider : vm }; + + const filtering = new Filtering(vm.gridOptions); + + const columns = [ + { + field : 'reference', + displayName : 'TABLE.COLUMNS.REFERENCE', + headerCellFilter : 'translate', + cellTemplate : 'modules/stock/entry/modals/templates/purchase_reference.tmpl.html', + }, + + { + field : 'date', + cellFilter : 'date:"'.concat(bhConstants.dates.format, '"'), + filter : { condition : filtering.filterByDate }, + displayName : 'TABLE.COLUMNS.DATE', + headerCellFilter : 'translate', + sort : { priority : 0, direction : 'desc' }, + }, + + { + field : 'display_name', + displayName : 'TREE.DONOR', + headerCellFilter : 'translate', + }, + { + field : 'project_name', + displayName : 'FORM.LABELS.PROJECT', + headerCellFilter : 'translate', + }, + { + field : 'description', + displayName : 'FORM.LABELS.DESCRIPTION', + headerCellFilter : 'translate', + }, + ]; + + vm.gridOptions.columnDefs = columns; + vm.gridOptions.multiSelect = false; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridOptions.onRegisterApi = onRegisterApi; + vm.toggleFilter = toggleFilter; + + // bind methods + vm.submit = submit; + vm.cancel = cancel; + vm.showReceipt = showReceipt; + + function onRegisterApi(gridApi) { + vm.gridApi = gridApi; + vm.gridApi.selection.on.rowSelectionChanged(null, rowSelectionCallback); + } + + function rowSelectionCallback(row) { + vm.selectedRow = row.entity; + } + + /** toggle filter */ + function toggleFilter() { + vm.filterEnabled = !vm.filterEnabled; + vm.gridOptions.enableFiltering = vm.filterEnabled; + vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); + } + + /** get purchase document */ + function showReceipt(uuid) { + Receipts.purchase(uuid); + } + + /* ======================= End Grid ======================================== */ + function load() { + vm.loading = true; + Donation.read() + .then(donations => { + vm.gridOptions.data = donations; + }) + .catch(() => { + vm.hasError = true; + }) + .finally(() => { + vm.loading = false; + }); + } + + // submit + function submit() { + if (!vm.selectedRow || (vm.selectedRow && !vm.selectedRow.uuid)) { return null; } + return Instance.close([].concat(vm.selectedRow)); + } + // cancel + function cancel() { + Instance.close(); + } + + load(); +} diff --git a/client/src/modules/stock/stock.service.js b/client/src/modules/stock/stock.service.js index 629b24d264..7a0704dee7 100644 --- a/client/src/modules/stock/stock.service.js +++ b/client/src/modules/stock/stock.service.js @@ -24,6 +24,7 @@ function StockModalService(Modal) { service.openFindService = openFindService; service.openFindDepot = openFindDepot; service.openFindPurchase = openFindPurchase; + service.openFindDonation = openFindDonation; service.openDefineLots = openDefineLots; service.openFindTansfer = openFindTansfer; service.openActionStockAssign = openActionStockAssign; @@ -226,6 +227,19 @@ function StockModalService(Modal) { return instance.result; } + /** search donation */ + function openFindDonation(request) { + const params = angular.extend(modalParameters, { + templateUrl : 'modules/stock/entry/modals/findDonation.modal.html', + controller : 'StockFindDonationModalController', + controllerAs : '$ctrl', + resolve : { data : () => request }, + }); + + const instance = Modal.open(params); + return instance.result; + } + /** search transfer */ function openFindTansfer(request) { const params = angular.extend(modalParameters, { diff --git a/server/config/routes.js b/server/config/routes.js index f3b9bf8de1..b872f75f01 100644 --- a/server/config/routes.js +++ b/server/config/routes.js @@ -26,6 +26,7 @@ const install = require('../controllers/install'); const rolesCtrl = require('../controllers/admin/roles'); const users = require('../controllers/admin/users'); const donor = require('../controllers/admin/donor'); +const donation = require('../controllers/admin/donation'); const projects = require('../controllers/admin/projects'); const enterprises = require('../controllers/admin/enterprises'); const services = require('../controllers/admin/services'); @@ -571,6 +572,14 @@ exports.configure = function configure(app) { app.get('/donors/:id', donor.detail); app.put('/donors/:id', donor.update); app.delete('/donors/:id', donor.remove); + + // donor controller + app.get('/donations', donation.read); + app.post('/donations', donation.create); + app.get('/donations/:uuid', donation.detail); + app.put('/donations/:uuid', donation.update); + app.delete('/donations/:uuid', donation.remove); + // projects controller app.get('/projects/:id', projects.detail); app.put('/projects/:id', projects.update); diff --git a/server/controllers/admin/donation.js b/server/controllers/admin/donation.js new file mode 100644 index 0000000000..d3c008b03d --- /dev/null +++ b/server/controllers/admin/donation.js @@ -0,0 +1,60 @@ +const db = require('../../lib/db'); + +module.exports = { + create, + update, + read, + remove, + detail, +}; + +function create(req, res, next) { + const data = req.body; + data.uuid = data.uuid ? db.bid(data.uuid) : db.uuid(); + + db.exec(`INSERT INTO donation SET ?`, data).then(() => { + res.sendStatus(201); + }).catch(next); +} + +function update(req, res, next) { + const data = req.body; + const { uuid } = req.params; + db.exec(`UPDATE donation SET ? WHERE uuid=?`, [data, db.bid(uuid)]).then(() => { + res.sendStatus(200); + }).catch(next); +} + +function read(req, res, next) { + const sql = ` + SELECT BUID(dt.uuid) as uuid, dt.reference, dt.project_id, + dt.description, + dt.date, + dt.donor_id, d.display_name, p.name as project_name + FROM donation dt + JOIN project p ON p.id= dt.project_id + JOIN donor d ON d.id= dt.donor_id + `; + + db.exec(sql).then(donations => { + res.status(200).json(donations); + }).catch(next); +} + +function detail(req, res, next) { + const sql = ` + SELECT BUID(uuid) as uuid, reference, project_id, description, date, donor_id + FROM donation + WHERE uuid=?`; + const { uuid } = req.params; + db.one(sql, db.bid(uuid)).then(donation => { + res.status(200).json(donation); + }).catch(next); +} + +function remove(req, res, next) { + const { uuid } = req.params; + db.exec(`DELETE FROM donation WHERE uuid=?`, db.bid(uuid)).then(() => { + res.sendStatus(200); + }).catch(next); +}