Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UI to change the order of the cost center step-down allocation steps #6003

Merged
merged 2 commits into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/src/i18n/en/cost_center.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
"EDIT_ALLOCATION_BASIS": "Edit allocation basis",
"EDIT_ALLOCATION_KEYS" : "Edit Allocation Keys",
"EDIT_COST_CENTER" : "Update the Cost Center Information",
"EDIT_STEP_ORDER" : "Edit order of cost allocation steps",
"PRINCIPAL": "Principal Cost Center",
"NO_COST_CENTER_DEFINED": "** Cost Center Not Defined **",
"SELECT_ALLOCATION_BASIS": "Select allocation basis",
"STEP_DOWN_COST_ALLOCATION": "Step-down cost allocation",
"STEP_ORDER": "Allocation Step Order",
"ONLY_FOR_EXPLOITATION_ACCOUNTS": "Only for operating accounts (income and expenses). For others accounts, the cost center will not be considered",
"UPDATE_ALLOCATION_QUANTITIES": "Update",
"UPDATE_ALLOCATION_QUANTITIES_TOOLTIP": "Update system-computed cost center allocation quantities",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/fr/cost_center.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
"EDIT_ALLOCATION_BASIS": "Modifier la base d'allocation",
"EDIT_ALLOCATION_KEYS" : "Modifier les clés de répartition",
"EDIT_COST_CENTER" : "Mise à jour des informations du centre de coût",
"EDIT_STEP_ORDER" : "Modifier l'ordre des étapes de l'allocation des coûts",
"PRINCIPAL": "Centre de coût Principal",
"NO_COST_CENTER_DEFINED": "** Aucun centre de cout **",
"SELECT_ALLOCATION_BASIS": "Sélectionnez la base d'allocation",
"STEP_DOWN_COST_ALLOCATION": "Allocation séquentielle des coûts",
"STEP_ORDER": "Ordre des étapes de l'allocation",
"ONLY_FOR_EXPLOITATION_ACCOUNTS": "Uniquement pour les comptes d'exploitations (produits et charges). Pour les autres comptes, le centre de cout ne sera pas pris en compte",
"UPDATE_ALLOCATION_QUANTITIES": "Mettre à jour",
"UPDATE_ALLOCATION_QUANTITIES_TOOLTIP": "Mettre à jour les quantités d'allocation des centres de coûts calculées par le système",
Expand Down
5 changes: 5 additions & 0 deletions client/src/modules/cost_center/cost_center.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
<i class="fa fa-table"></i> <span translate>ALLOCATION_BASES</span>
</a>
</li>
<li role="menuitem">
<a href data-method="step_order" ng-click="CostCenterCtrl.editAllocationStepOrder()">
<i class="fa fa-table"></i> <span translate>COST_CENTER.EDIT_STEP_ORDER</span>
</a>
</li>

<li role="separator" class="divider"></li>

Expand Down
9 changes: 9 additions & 0 deletions client/src/modules/cost_center/cost_center.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function CostCenterController(CostCenters, ModalService, Notify, uiGridConstants
vm.deleteCostCenter = deleteCostCenter;
vm.toggleFilter = toggleFilter;
vm.openEditAllocationBasisModal = openEditAllocationBasisModal;
vm.editAllocationStepOrder = editAllocationStepOrder;

// global variables
vm.gridApi = {};
Expand Down Expand Up @@ -159,5 +160,13 @@ function CostCenterController(CostCenters, ModalService, Notify, uiGridConstants
}).result.catch(angular.noop);
}

function editAllocationStepOrder() {
$uibModal.open({
templateUrl : 'modules/cost_center/modals/edit_allocation_step_order.modal.html',
controller : 'AllocationEditStepOrderController as ModalCtrl',
// size : 'lg',
}).result.catch(angular.noop);
}

loadCostCenters();
}
6 changes: 6 additions & 0 deletions client/src/modules/cost_center/cost_center.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,11 @@ function CostCenterService(Api, $uibModal) {
.then(service.util.unwrapHttpResponse);
};

service.setAllocationStepOrder = (options) => {
const url = `/cost_center/step_order/multi`;
return service.$http.put(url, { params : options })
.then(service.util.unwrapHttpResponse);
};

return service;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<form
name="ModalForm"
bh-submit="ModalCtrl.submit()"
data-modal="allocation-bases"
novalidate>

<div class="modal-header">
<div class="bhima-title">
<ol class="headercrumb">
<li class="static" translate>TREE.FINANCE</li>
<li class="static" translate>COST_CENTER.TITLE</li>
<li class="title" translate>COST_CENTER.EDIT_STEP_ORDER</li>
</ol>
</div>
</div>

<div class="modal-body">
<div class="container-fluid">
<div
id="allocation-bases-grid"
class="modal-grid"
style="height: 200px;"
ui-grid="ModalCtrl.gridOptions"
ui-grid-resize-columns
ui-grid-move-columns>
<bh-grid-loading-indicator
loading-state="ModalCtrl.loading">
</bh-grid-loading-indicator>
</div>
</div>
</div>

<div class="modal-footer">
<button type="button" class="btn btn-default"
ng-click="ModalCtrl.cancel()" data-method="close">
<span translate>FORM.BUTTONS.CANCEL</span>
</button>

<bh-loading-button loading-state="ModalForm.$loading">
<span translate>FORM.BUTTONS.SUBMIT</span>
</bh-loading-button>
</div>

</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
angular.module('bhima.controllers')
.controller('AllocationEditStepOrderController', AllocationEditStepOrderController);

AllocationEditStepOrderController.$inject = [
'CostCenterService', 'NotifyService', '$uibModalInstance', 'uiGridConstants',
];

function AllocationEditStepOrderController(CostCenters, Notify, Instance, uiGridConstants) {

const vm = this;

vm.loading = false;
vm.cancel = Instance.close;
vm.loadCostCenters = loadCostCenters;
vm.moveStepDown = moveStepDown;
vm.moveStepUp = moveStepUp;
vm.submit = submit;

// global variables
vm.gridApi = {};
vm.filterEnabled = false;

// options for the UI grid
vm.gridOptions = {
appScopeProvider : vm,
enableColumnMenus : false,
flatEntityAccess : true,
enableRowReordering : true,
enableSorting : false,
onRegisterApi : onRegisterApiFn,
columnDefs : [
{
field : 'label',
displayName : 'FORM.LABELS.DESIGNATION',
headerCellFilter : 'translate',
enableSorting : false,
},
{
field : 'step_order',
displayName : 'COST_CENTER.STEP_ORDER',
headerCellFilter : 'translate',
headerCellClass : 'allocationBasisColHeader',
defaultSort : { direction : uiGridConstants.ASC, priority : 1 },
type : 'number',
visible : true,
},
{
field : 'reorder',
displayName : '',
cellTemplate : '/modules/cost_center/templates/reorder_allocation_steps.tmpl.html',
enableSorting : false,
enableFiltering : false,
},
],
};

function loadCostCenters() {
vm.loading = true;
CostCenters.read()
.then((data) => {
const auxData = data.filter(item => !item.is_principal);
auxData.sort((a, b) => Number(a.step_order) - Number(b.step_order));

// rewrite the step order
auxData.forEach((value, idx) => {
value.step_order = idx + 1;
});

vm.data = auxData;
vm.gridOptions.data = vm.data;
})
.catch(Notify.handleError)
.finally(() => {
vm.loading = false;
});
}

function onRegisterApiFn(gridApi) {
vm.gridApi = gridApi;
}

function moveStepDown(row) {
const stepOrder = row.step_order;
const upper = vm.data.find(r => r.step_order === stepOrder + 1);
row.step_order++;
upper.step_order--;
vm.gridOptions.data = vm.data;
vm.gridApi.core.refreshRows();
}

function moveStepUp(row) {
const stepOrder = row.step_order;
const lower = vm.data.find(r => r.step_order === stepOrder - 1);
row.step_order--;
lower.step_order++;
vm.gridOptions.data = vm.data;
vm.gridApi.core.refreshRows();
}

function submit() {
vm.loading = true;
const newStepOrder = vm.gridOptions.data.map(row => ({
id : row.id,
step_order : row.step_order,
}));
CostCenters.setAllocationStepOrder({ new_order : newStepOrder })
.then(() => {
vm.loading = false;
Instance.close();
Notify.success('FORM.INFO.UPDATE_SUCCESS');
});
}

loadCostCenters();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="ui-grid-cell-contents text-center">
<button type="button" class="btn btn-sm" style="padding-top: 0"
ng-hide="row.entity.step_order === 1"
ng-click="grid.appScope.moveStepUp(row.entity)">
<span class="fa fa-arrow-up"></span>
</button>

<button type="button" class="btn btn-sm" style="padding-top: 0"
ng-hide="row.entity.step_order === grid.appScope.data.length"
ng-click="grid.appScope.moveStepDown(row.entity)">
<span class="fa fa-arrow-down"></span>
</button>
</div>
1 change: 1 addition & 0 deletions server/config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ exports.configure = function configure(app) {
app.post('/cost_center', costCenter.create);
app.put('/cost_center/:id', costCenter.update);
app.delete('/cost_center/:id', costCenter.delete);
app.put('/cost_center/step_order/multi', costCenter.setAllocationStepOrder);

// Step-down allocation basis API
app.get('/cost_center_allocation_basis', costAllocationBasis.list);
Expand Down
23 changes: 21 additions & 2 deletions server/controllers/finance/cost_center.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const FilterParser = require('../../lib/filter');
async function lookupCostCenter(id) {
const sqlCostCenter = `
SELECT fc.id, fc.label, fc.is_principal, fc.project_id,
fc.allocation_method, fc.allocation_basis_id,
fc.allocation_method, fc.allocation_basis_id, fc.step_order,
cab.name AS allocation_basis_name, cab.units as allocation_basis_units,
cab.is_predefined AS allocation_basis_is_predefined,
cabval.quantity AS allocation_basis_quantity
Expand Down Expand Up @@ -68,7 +68,7 @@ async function lookupCostCenter(id) {
function list(req, res, next) {
const filters = new FilterParser(req.query, { tableAlias : 'f' });
const sql = `
SELECT f.id, f.label, f.is_principal, f.project_id,
SELECT f.id, f.label, f.is_principal, f.project_id, f.step_order,
f.allocation_method, f.allocation_basis_id,
GROUP_CONCAT(' ', LOWER(ar.description)) AS abbrs,
GROUP_CONCAT(' ', s.name) serviceNames, p.name AS projectName,
Expand Down Expand Up @@ -341,6 +341,23 @@ function assignCostCenterParams(accountsCostCenter, rubrics, key) {
return rubrics;
}


// PUT /cost_center/step_order/multi
function setAllocationStepOrder(req, res, next) {
const { params } = req.body;
const query = 'UPDATE `cost_center` SET `step_order` = ? WHERE `id` = ?';
const transaction = db.transaction();
params.new_order.forEach(row => {
transaction.addQuery(query, [row.step_order, row.id]);
});

transaction.execute()
.then(() => {
res.sendStatus(204);
})
.catch(next);
}

// get list of costCenter
exports.list = list;
// get details of a costCenter
Expand All @@ -355,3 +372,5 @@ exports.delete = del;
exports.getAllCostCenterAccounts = getAllCostCenterAccounts;
// Assign Cost Center Params
exports.assignCostCenterParams = assignCostCenterParams;

exports.setAllocationStepOrder = setAllocationStepOrder;