Skip to content

Commit

Permalink
feat(report): implement delete archive report
Browse files Browse the repository at this point in the history
This commit implements the delete functionality for the report page.
All reports can now be deleted from the report page without any needed
customization from the report author.
  • Loading branch information
Jonathan Niles authored and sfount committed Nov 10, 2016
1 parent 62b97e6 commit a2f167e
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 59 deletions.
7 changes: 7 additions & 0 deletions client/src/partials/reports/baseReports.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function BaseReportService($http, Modal, util) {
service.listSavedReports = listSavedReports;
service.openConfiguration = openConfiguration;
service.requestPDF = requestPDF;
service.deleteReport = deleteReport;

function requestKey(key) {
var url = '/reports/keys/';
Expand Down Expand Up @@ -74,4 +75,10 @@ function BaseReportService($http, Modal, util) {

return $http.get(url, { params : options });
}

function deleteReport(uuid) {
var url = '/reports/archive/'.concat(uuid);
return $http.delete(url)
.then(util.unwrapHttpResponse);
}
}
55 changes: 36 additions & 19 deletions client/src/partials/reports/reports.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
angular.module('bhima.controllers')
.controller('ReportsController', ReportsController);

ReportsController.$inject = ['$state', 'BaseReportService', '$uibModal'];
ReportsController.$inject = ['$state', 'BaseReportService', '$uibModal', 'NotifyService'];

function ReportsController($state, SavedReports, Modal) {
function ReportsController($state, SavedReports, Modal, Notify) {
var vm = this;
var keyTarget = $state.params.key;

vm.report = {};
vm.loading = true;
vm.hasError = false;
vm.createReport = createReport;
vm.deleteReport = deleteReport;

vm.gridOptions = {
fastWatch : true,
flatEntityAccess : true,
enableColumnMenus : false,
enableSorting : false
enableSorting : false,
appScopeProvider : vm
};

var typeTemplate = '<div class="ui-grid-cell-contents"><i class="fa fa-file-pdf-o"></i></div>';
Expand All @@ -32,25 +32,42 @@ function ReportsController($state, SavedReports, Modal) {
{ field : 'actions', displayName : '', cellTemplate : '/partials/templates/actionsDropdown.html', width : 80 }
];

// Load report information based on key
SavedReports.requestKey(keyTarget)
.then(function (result) {
vm.report = result[0];

// Load archived reports
return SavedReports.listSavedReports(vm.report.id)
.then(function (results) {
function loadSavedReports() {
vm.loading = true;
vm.hasError = false;

// Load report information based on key
SavedReports.requestKey(keyTarget)
.then(function (result) {
vm.report = result[0];

// Load archived reports
return SavedReports.listSavedReports(vm.report.id)
.then(function (results) {
vm.gridOptions.data = results;
});
})
.catch(function (error) {
vm.hasError = true;
})
.finally(function () {
vm.loading = false;
vm.gridOptions.data = results;
});
})
.catch(function (error) {
vm.loading = false;
vm.hasError = true;
});

}

function createReport() {
SavedReports.openConfiguration(vm.report);
}

function deleteReport(uuid) {
SavedReports.deleteReport(uuid)
.then(function () {
Notify.success('FORM.INFO.DELETE_SUCCESS');
loadSavedReports();
})
.catch(Notify.handleError);
}

loadSavedReports();
}
3 changes: 1 addition & 2 deletions client/src/partials/templates/actionsDropdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
<ul class="dropdown-menu-right" uib-dropdown-menu>
<li><a href="/reports/archive/{{row.entity.uuid}}" download><i class="fa fa-cloud-download"></i> {{ "REPORT.DOWNLOAD" | translate }}</a></li>
<li><a href><span class="text-muted"><i class="fa fa-envelope"></i> {{ "TABLE.COLUMNS.EMAIL" | translate }}</span></a></li>
<li><a style="color : #a94442" href><i class="fa fa-trash"></i> {{ "REPORT.DELETE" | translate }}</a></li>
<li><a href ng-click="grid.appScope.deleteReport(row.entity.uuid)"><span class="text-danger"><i class="fa fa-trash"></i> {{ "REPORT.DELETE" | translate }}</span></a></li>
</ul>

</span>
</div>
4 changes: 2 additions & 2 deletions server/config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ exports.configure = function configure(app) {
app.get('/reports/finance/income_expense', financeReports.incomeExpense.document);
app.get('/reports/finance/balance', financeReports.balance.document);
app.get('/reports/finance/account', financeReports.reportAccounts.document);

app.get('/reports/finance/journal', financeReports.journal.report);

app.get('/reports/keys/:key', report.keys);

Expand All @@ -377,7 +377,7 @@ exports.configure = function configure(app) {

// lookup saved report document
app.get('/reports/archive/:uuid', report.sendArchived);
app.get('/reports/finance/journal', financeReports.journal.report);
app.delete('/reports/archive/:uuid', report.deleteArchived);

// patient group routes
app.get('/patients/groups', patientGroups.list);
Expand Down
74 changes: 68 additions & 6 deletions server/controllers/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ const db = require('../lib/db');
exports.keys = keys;
exports.list = list;
exports.sendArchived = sendArchived;
exports.deleteArchived = deleteArchived;

// the global report path
// @TODO This will have to factor in the type of report - report uuid can be looked up in `saved_report` table
const REPORT_PATH = path.resolve(path.join(__dirname, '../reports/'));

/**
* @function keys
Expand All @@ -31,7 +36,7 @@ exports.sendArchived = sendArchived;
*/
function keys(req, res, next) {
let key = req.params.key;
let sql = 'SELECT * FROM report WHERE report_key = ?';
let sql = 'SELECT * FROM report WHERE report_key = ?;';

db.exec(sql, [key])
.then(function (keyDetail) {
Expand All @@ -41,6 +46,16 @@ function keys(req, res, next) {
.done();
}

function fetchReport(uuid) {
let sql = `
SELECT BUID(saved_report.uuid) AS uuid, label, report_id, parameters, saved_report.link, timestamp, user_id, user.display_name
FROM saved_report LEFT JOIN user ON saved_report.user_id = user.id
WHERE report_id = ?;
`;

return db.exec(sql, [uuid]);
}

/**
* @function list
*
Expand All @@ -61,6 +76,25 @@ function list(req, res, next) {
.done();
}

/**
* @function lookupArchivedReport
*
* @description
* Finds an archived report by it's UUID.
*
* @param {String} uuid - the report's uuid.
* @returns {Promise} - the report record
*/
function lookupArchivedReport(uuid) {
let sql = `
SELECT BUID(saved_report.uuid) as uuid, label, report_id, parameters, link,
timestamp, user_id, user.display_name
FROM saved_report left join user on saved_report.user_id = user.id
WHERE uuid = ?;
`;
return db.one(sql, [db.bid(uuid)]);
}

/**
* @function sendArchived
*
Expand All @@ -71,10 +105,38 @@ function list(req, res, next) {
* GET /reports/archive/:uuid
*/
function sendArchived(req, res, next) {
// @TODO This will have to factor in the type of report - report uuid can be looked up in `saved_report` table
let reportPath = path.resolve(path.join(__dirname, '../reports/'));
let extension = '.pdf';
let reportUuid = req.params.uuid;
lookupArchivedReport(req.params.uuid)
.then(report => {
res.sendFile(report.link);
})
.catch(next)
.done();
}

res.sendFile(reportPath.concat('/', reportUuid, extension));

/**
* @function deleteArchived
*
* @description
* Deletes a report from the server. This cleans up both the record of the
* report stored in saved_report and the file stored on the disk.
*
* DELETE /reports/archive/:uuid
*/
function deleteArchived(req, res, next) {
let filePath;

lookupArchivedReport(req.params.uuid)
.then(report => {
filePath = report.link;
return db.exec('DELETE FROM saved_report WHERE uuid = ?;', [ db.bid(req.params.uuid) ]);
})
.then(() => {
fs.unlink(filePath, err => {
if (err) { return next(err); }
res.sendStatus(204);
});
})
.catch(next)
.done();
}
35 changes: 5 additions & 30 deletions server/lib/ReportManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,7 @@ const defaults = {

// Constants
const SAVE_DIR = path.resolve(path.join(__dirname, '../reports/'));
const DETAIL_SQL = `
SELECT r.uuid, r.label, r.type, r.parameters, r.link, r.timestamp, r.user_id
FROM report AS r WHERE r.uuid = ?;
`;
const LIST_SQL = `
SELECT r.uuid, r.label, r.type, r.parameters, r.link, r.timestamp, r.user_id
FROM report AS r WHERE r.type = ?;
`;
const DELETE_SQL = `
DELETE FROM report WHERE uuid = ?;
`;
const UPDATE_SQL = `
UPDATE report SET ? WHERE uuid = ?;
`;

const SAVE_SQL = `
INSERT INTO saved_report SET ?;
`;
Expand Down Expand Up @@ -147,7 +134,7 @@ class ReportManager {
if (this.options.saveReport) {
// FIXME This is not correctly deferred
// FIXME PDF report is sent back to the client even though this is a save operation
// FIXME Errors are not propegated
// FIXME Errors are not propagated
return this.save()
.then(function (result) {
return { headers: renderHeaders, report };
Expand Down Expand Up @@ -185,7 +172,7 @@ class ReportManager {
const data = {
uuid : db.bid(reportId),
label : options.label,
link : reportId,
link : link,
timestamp : new Date(),
user_id : options.user.id,
report_id : options.reportId
Expand All @@ -196,24 +183,12 @@ class ReportManager {

db.exec(SAVE_SQL, data)
.then(() => dfd.resolve({ uuid: reportId }))
.catch(dfd.reject);
.catch(dfd.reject)
.done();
});

return dfd.promise;
}

// crud operations on reports
list(type) {
return db.exec(LIST_SQL, [type]);
}

remove(uuid) {
return db.exec(DELETE_SQL, [uuid]);
}

update(uuid, data) {
return db.exec(UPDATE_SQL, [data, uuid]);
}
}

module.exports = ReportManager;

0 comments on commit a2f167e

Please sign in to comment.