Skip to content

Commit

Permalink
feat(voucher): create cash transfer, generic income and expense tools (
Browse files Browse the repository at this point in the history
…#1586)

* Journal voucher tools : generic income, expense and cash transfer
Fix grid rows updating

Test e2e for generic income and expense

Cash transfer tool and test

update test values

Fix and enhancements

Fix test e2e

Fix and enhancements

voucher tools

Fix and enhancements

* Fix rebase errors

* Fix and enhancements

* Fix e2e errors
  • Loading branch information
mbayopanda authored and jniles committed May 9, 2017
1 parent eec654f commit 1a8d00f
Show file tree
Hide file tree
Showing 25 changed files with 860 additions and 128 deletions.
1 change: 1 addition & 0 deletions client/src/i18n/en/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
"FIRST_NAME":"First Name",
"FROM_ACCOUNT":"From Account",
"FROM":"From",
"FOR":"For",
"FUNCTION":"Function",
"GAIN_ACCOUNT":"Gain on Exchange Rate Account",
"GENDER":"Sex",
Expand Down
7 changes: 7 additions & 0 deletions client/src/i18n/en/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@
"VOUCHER":"Voucher"},
"TYPES":{"SUPPORT_PAYMENT_DESCRIPTION":"Debt transfer from {{ patientName }} ({{ patientReference}}) for invoice {{ invoiceReference }}."},
"GLOBAL":{"CASHFLOW_OPTION":"Cashflow Option",
"TRANSFER_DESCRIPTION": "Transfer: From {{ fromAccount }} to {{ toAccount }} for {{ amount }} {{ symbol }}",
"CONVENTION_INVOICES":"Convention - Invoices payment",
"SUPPORT_FORM":"Patients Support - Form",
"SUPPORT_TEXT":"When the above two fields are filled in, we will look for open debts for the patient to assign to the \"Support Patient\" Account.",
"IMPORT_TRANSACTION":"Import transactions",
"GENERIC_EXPENSE":"Generic Expense",
"GENERIC_INCOME":"Generic Income",
"ORIGIN_ACCOUNT":"Provenance Account",
"DESTINATION_ACCOUNT":"Destination Account",
"TRANSFER_ACCOUNT":"Transfer Account",
"CASH_TRANSFER":"Cash Transfer",
"REPORT":"Voucher Report",
"TITLE":"Voucher",
"TOOLS":"Toolkit",
Expand Down
1 change: 1 addition & 0 deletions client/src/i18n/fr/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
"FIRST_NAME":"Prenom",
"FROM_ACCOUNT":"Du compte",
"FROM":"De",
"FOR":"Pour",
"FUNCTION":"Fonction",
"GAIN_ACCOUNT":"Compte excedant",
"GENDER":"Sexe",
Expand Down
7 changes: 7 additions & 0 deletions client/src/i18n/fr/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@
"TYPES":{"SUPPORT_PAYMENT_DESCRIPTION":"Prise en charge de {{ patientName }} ({{ patientReference}}) pour la facture {{ invoiceReference }}."},
"GLOBAL":{"CASHFLOW_OPTION":"Option pour cashflow",
"CONVENTION_INVOICES":"Convention - Paiement factures",
"TRANSFER_DESCRIPTION": "Transfert: De {{ fromAccount }} à {{ toAccount }} pour {{ amount }} {{ symbol }}",
"SUPPORT_FORM":"Prise en Charge des patients",
"SUPPORT_TEXT":"Lorsque les deux champs ci-dessus sont remplis, Les dettes du patient apparaissent en vue qu'une \"Prise en Charge\" puissent être attribue à un Compte.",
"ERROR_SAME_ACCOUNT":"Vous ne pouvez pas utiliser le même compte deux fois dans cette transaction. Veuillez sélectionner deux comptes différents.",
"GENERIC_EXPENSE":"Depense Generique",
"GENERIC_INCOME":"Recette Generique",
"CASH_TRANSFER":"Transfert d'argent",
"ORIGIN_ACCOUNT":"Compte de provenance",
"DESTINATION_ACCOUNT":"Compte de destination",
"TRANSFER_ACCOUNT":"Compte de transfert",
"IMPORT_TRANSACTION":"Importer les transactions",
"RECEIPT":{"SUCCESS":"Bon de paiement enregistré avec succès."},
"REPORT":"Rapport des Quittances",
Expand Down
2 changes: 1 addition & 1 deletion client/src/js/components/bhFindPatient.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ angular.module('bhima.components')
onRegisterApi: '&', // expose force refresh API
required: '<', // bind the required (for ng-required)
validationTrigger: '<', // bind validation trigger
suppressReset: '@' // bind a string
suppressReset: '<' // bind the reset
}
});

Expand Down
4 changes: 4 additions & 0 deletions client/src/modules/templates/accountList.tmpl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<a href>
<span style="display:inline-block; min-width:80px;">[{{ match.model.number }}]</span>
<span ng-bind-html="match.model.label | uibTypeaheadHighlight:query"></span>
</a>
2 changes: 1 addition & 1 deletion client/src/modules/templates/breadcrumb.tmpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<i class="fa" ng-class="'{{d.icon}}'"></i> {{ d.selected | translate }} <span class="caret"></span>
</a>
<ul class="pull-right" uib-dropdown-menu>
<li ng-repeat="opt in d.option" class="pull-left">
<li ng-repeat="opt in d.option" class="text-left">
<a href ng-click="vm.helperDropdown(opt, d)" id="{{ vm.prefix + opt.id }}" data-method="{{ opt.dataMethod }}">
<i class="fa" ng-class="'{{opt.icon}}'"></i> <span translate>{{ opt.label }}</span>
</a>
Expand Down
122 changes: 71 additions & 51 deletions client/src/modules/vouchers/complex-voucher.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ComplexJournalVoucherController.$inject = [
'VoucherService', '$translate', 'CurrencyService', 'SessionService',
'FindEntityService', 'FindReferenceService', 'NotifyService',
'VoucherToolkitService', 'ReceiptModal', 'bhConstants', 'GridAggregatorService',
'uiGridConstants', 'VoucherForm',
'uiGridConstants', 'VoucherForm', '$timeout',
];

/**
Expand All @@ -19,7 +19,9 @@ ComplexJournalVoucherController.$inject = [
* @todo - Implement caching mechanism for incomplete forms (via AppCache)
* @todo/@fixme - this error notification system needs serious refactor.
*/
function ComplexJournalVoucherController(Vouchers, $translate, Currencies, Session, FindEntity, FindReference, Notify, Toolkit, Receipts, bhConstants, GridAggregators, uiGridConstants, VoucherForm) {
function ComplexJournalVoucherController(Vouchers, $translate, Currencies, Session,
FindEntity, FindReference, Notify, Toolkit, Receipts, bhConstants,
GridAggregators, uiGridConstants, VoucherForm, $timeout) {
var vm = this;

// bind constants
Expand Down Expand Up @@ -78,69 +80,87 @@ function ComplexJournalVoucherController(Vouchers, $translate, Currencies, Sessi

// toolkit action definition
var conventionPaymentTool = Toolkit.tools.convention_payment;
var supportPatientTool = Toolkit.tools.support_patient;
var supportPatientTool = Toolkit.tools.support_patient;
var genericIncomeTool = Toolkit.tools.generic_income;
var genericExpenseTool = Toolkit.tools.generic_expense;
var cashTransferTool = Toolkit.tools.cash_transfer;

// action on convention payment tool
conventionPaymentTool.action = openConventionPaymentTool;

// action on suppot patient tool
supportPatientTool.action = openSupportPatientTool;

// open convention payment function
function openConventionPaymentTool() {
Toolkit.open(conventionPaymentTool)
.then(function (result) {
if (!result) { return; }

var rows = result.rows;
var n = result.rows.length;

while (n--) {
vm.Voucher.addItems(1);

var lastRowIdx = vm.Voucher.store.data.length - 1;
var lastRow = vm.Voucher.store.data[lastRowIdx];

lastRow.configure(rows[n]);
}

vm.Voucher.validate();
vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ROW);
});
conventionPaymentTool.action = openVoucherTool(conventionPaymentTool);
genericIncomeTool.action = openVoucherTool(genericIncomeTool);
genericExpenseTool.action = openVoucherTool(genericExpenseTool);
cashTransferTool.action = openVoucherTool(cashTransferTool);
supportPatientTool.action = openVoucherTool(supportPatientTool);

/**
* @function openVoucherTool
*
* @description open the modal of the tool
*/
function openVoucherTool(voucherTool) {
return function () {
return Toolkit.open(voucherTool).then(processVoucherToolRows);
};
}

// open support patient function
function openSupportPatientTool() {
Toolkit.open(supportPatientTool)
.then(function (result) {
if (!result) { return; }

var rows = result.rows;
// Selected the transaction type
vm.Voucher.details.type_id = rows.typeId;

var n = result.rows.length;
/**
* @function processVoucherToolRows
*
* @description this function handle the result of the tool modal
*/
function processVoucherToolRows(result) {
if (!result) { return; }

while (n--) {
vm.Voucher.addItems(1);
vm.Voucher.replaceFormRows(result.rows);

var lastRowIdx = vm.Voucher.store.data.length - 1;
var lastRow = vm.Voucher.store.data[lastRowIdx];
// force updating details
updateView(result);
}

lastRow.configure(rows[n]);
}
/**
* @method updateView
*
* @description
* this function force to update details of the voucher
* and remove unnecessary rows
*
* @param {object} result
*/
function updateView(result) {
$timeout(function () {
// transaction type
vm.Voucher.details.type_id = result.type_id || vm.Voucher.details.type_id;

// description
vm.Voucher.description(result.description || vm.Voucher.details.description);

// currency
vm.Voucher.details.currency_id = result.currency_id || vm.Voucher.details.currency_id;

removeNullRows();
}, 0);
}

vm.Voucher.validate();
vm.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ROW);
});
/**
* @function removeNullRows
*
* @description remove null rows
*/
function removeNullRows() {
var gridData = JSON.parse(JSON.stringify(vm.gridOptions.data));
gridData.forEach(function (item) {
if (!item.account_id) {
vm.Voucher.store.remove(item.uuid);
}
});
}

/** ======================== end voucher tools ======================= */

// bind the startup method as a reset method
vm.submit = submit;
vm.currencySymbol = currencySymbol;
vm.openEntityModal = openEntityModal;
vm.currencySymbol = currencySymbol;
vm.openEntityModal = openEntityModal;
vm.openReferenceModal = openReferenceModal;

// load the available currencies
Expand Down
3 changes: 1 addition & 2 deletions client/src/modules/vouchers/complex-voucher.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,10 @@
append-to-body="true">

<ui-select-match placeholder="{{ 'FORM.SELECT.TRANSFER_TYPE' | translate }}">
<span translate>{{$select.selected.text}}</span>
<span translate>{{ $select.selected.text }}</span>
</ui-select-match>

<ui-select-choices
ui-select-focus-patch
repeat="item.id as item in ComplexVoucherCtrl.types | filter:{ 'hrText' : $select.search }"
group-by="'type'">
<div ng-bind-html="item.hrText | highlight: $select.search"></div>
Expand Down
45 changes: 31 additions & 14 deletions client/src/modules/vouchers/toolkit.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,36 @@ function VoucherToolkitService($http, Modal, util) {
// tools of advanced journal voucher
service.tools = {
// this tool help to import transaction rows for a convention payment
'convention_payment' : {
icon : 'fa-building',
label : 'VOUCHERS.GLOBAL.CONVENTION_INVOICES',
controller : 'ConventionPaymentKitController',
templateUrl : 'modules/vouchers/toolkit/convention_payment.modal.html'
convention_payment : {
icon : 'fa-building',
label : 'VOUCHERS.GLOBAL.CONVENTION_INVOICES',
controller : 'ConventionPaymentKitController',
templateUrl : 'modules/vouchers/toolkit/convention_payment/convention_payment.modal.html',
},
generic_income : {
icon : 'fa-level-down',
label : 'VOUCHERS.GLOBAL.GENERIC_INCOME',
controller : 'GenericIncomeKitController',
templateUrl : 'modules/vouchers/toolkit/generic_income/generic_income.html',
},
generic_expense : {
icon : 'fa-level-up',
label : 'VOUCHERS.GLOBAL.GENERIC_EXPENSE',
controller : 'GenericExpenseKitController',
templateUrl : 'modules/vouchers/toolkit/generic_expense/generic_expense.html',
},
cash_transfer : {
icon : 'fa-reply-all',
label : 'VOUCHERS.GLOBAL.CASH_TRANSFER',
controller : 'CashTransferKitController',
templateUrl : 'modules/vouchers/toolkit/cash_transfer/cash_transfer.html',
},
support_patient : {
icon : 'fa-wpforms',
label : 'VOUCHERS.GLOBAL.SUPPORT_FORM',
controller : 'SupportPatientKitController',
templateUrl : 'modules/vouchers/toolkit/support_patient/support_patient.modal.html'
},
'support_patient' : {
icon : 'fa-wpforms',
label : 'VOUCHERS.GLOBAL.SUPPORT_FORM',
controller : 'SupportPatientKitController',
templateUrl : 'modules/vouchers/toolkit/support_patient.modal.html'
}


};

// service options
Expand All @@ -50,7 +66,8 @@ function VoucherToolkitService($http, Modal, util) {
controller : option.controller,
controllerAs : 'ToolCtrl',
size : 'md',
resolve : { data : function () { return option; } }
backdrop : 'static',
resolve : { data: function () { return option; } },
});

return instance.result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<div class="modal-header">
<ol class="headercrumb">
<li class="static" translate>{{ ToolCtrl.tool.label }}</li>
<li class="title" translate>VOUCHERS.GLOBAL.IMPORT_TRANSACTION</li>
</ol>
</div>

<form name="ToolForm" bh-submit="ToolCtrl.import(ToolForm)" bh-form-defaults novalidate>
<div class="modal-body">

<!-- select the cashbox (to debit) -->
<div
class="form-group"
ng-class="{ 'has-error' : ToolForm.$submitted && ToolForm.cashbox.$invalid }">
<label class="control-label" translate>
FORM.LABELS.CASHBOX
</label>
(<label class="control-label" translate>FORM.LABELS.DEBIT</label>)

<ui-select
name="cashbox"
ng-model="ToolCtrl.cashbox"
on-select="ToolCtrl.select()"
required>
<ui-select-match placeholder="{{ 'FORM.PLACEHOLDERS.CASHBOX' | translate }}">
<span>{{$select.selected.label}} ({{$select.selected.symbol}})</span>
</ui-select-match>
<ui-select-choices ui-select-focus-patch repeat="cashbox in ToolCtrl.cashboxes | filter:$select.search">
<span ng-bind-html="cashbox.label | highlight:$select.search"></span>
(<span ng-bind-html="cashbox.symbol | highlight:$select.search"></span>)
</ui-select-choices>
</ui-select>

<div class="help-block" ng-messages="ToolForm.cashbox.$error" ng-show="ToolForm.$submitted">
<div ng-messages-include="modules/templates/messages.tmpl.html"></div>
</div>
</div>

<!-- select the transfer account (to credit) -->
<div
class="form-group"
ng-class="{ 'has-error' : ToolForm.$submitted && ToolForm.account.$invalid }">
<label class="control-label" translate>VOUCHERS.GLOBAL.TRANSFER_ACCOUNT</label>
(<label class="control-label" translate>FORM.LABELS.CREDIT</label>)

<!-- input typeahead -->
<input
type="text"
class="form-control"
name="account"
ng-disabled="!ToolCtrl.cashbox"
ng-model="ToolCtrl.account"
uib-typeahead="account as account.label for account in ToolCtrl.accounts.data | filter:$viewValue | limitTo:8"
typeahead-no-results="ToolCtrl.noEntity"
typeahead-loading="ToolCtrl.loadingEntity"
typeahead-template-url="/modules/templates/accountList.tmpl.html"
placeholder="{{ 'FORM.PLACEHOLDERS.ACCOUNT' | translate }}"
required>
<!-- /input typeahead -->

<div class="help-block" ng-messages="ToolForm.account.$error" ng-show="ToolForm.$submitted">
<div ng-messages-include="modules/templates/messages.tmpl.html"></div>
</div>
</div>

<!-- amount -->
<div class="form-group">
<label translate>FORM.LABELS.AMOUNT</label>
<div class="input-group">
<span class="input-group-addon">{{ ToolCtrl.cashbox.symbol }}</span>
<input class="form-control" type="number" ng-model="ToolCtrl.amount" ng-disabled="!ToolCtrl.cashbox" required>
</div>
</div>

</div>

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

<bh-loading-button loading-state="ToolForm.$loading" disabled="ToolCtrl.$invalid">
<span translate>FORM.BUTTONS.SUBMIT</span>
</bh-loading-button>
</div>
</form>
Loading

0 comments on commit 1a8d00f

Please sign in to comment.