Skip to content

Commit

Permalink
feat(vouchers): implement manual Prise En Charge form
Browse files Browse the repository at this point in the history
This commit implements a manual Prise En Charge form on the Complex Voucher page.  The manual form does not rely on hardware compatibilities of a barcode scanner.  The user must specify an account and a patient, the form will load all the patient's bills, and then correctly assign the patient to the voucher.
  • Loading branch information
lomamech authored and jniles committed May 8, 2017
1 parent c309572 commit 2ff9b91
Show file tree
Hide file tree
Showing 13 changed files with 338 additions and 8 deletions.
2 changes: 2 additions & 0 deletions client/src/i18n/en/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"TYPES":{"SUPPORT_PAYMENT_DESCRIPTION":"Debt transfer from {{ patientName }} ({{ patientReference}}) for invoice {{ invoiceReference }}."},
"GLOBAL":{"CASHFLOW_OPTION":"Cashflow Option",
"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",
"REPORT":"Voucher Report",
"TITLE":"Voucher",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/fr/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"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",
"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.",
"IMPORT_TRANSACTION":"Importer les transactions",
"RECEIPT":{"SUCCESS":"Bon de paiement enregistré avec succès."},
Expand Down
1 change: 1 addition & 0 deletions client/src/js/components/bhBreadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ function BreadcrumbController() {

/** call the appropriate function and update the dropdown label **/
vm.helperDropdown = function helperDropdown(child, parent) {

parent.selected = child.label;
child.action(child);
};
Expand Down
6 changes: 3 additions & 3 deletions client/src/modules/templates/breadcrumb.tmpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
<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">
<a href ng-click="vm.helperDropdown(opt, d)" id="{{ vm.prefix + opt.id }}" data-method="{{ opt.dataMethod }}" translate>
{{ opt.label }}
<li ng-repeat="opt in d.option" class="pull-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>
</li>
</ul>
Expand Down
30 changes: 30 additions & 0 deletions client/src/modules/vouchers/complex-voucher.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,14 @@ function ComplexJournalVoucherController(Vouchers, $translate, Currencies, Sessi

// toolkit action definition
var conventionPaymentTool = Toolkit.tools.convention_payment;
var supportPatientTool = Toolkit.tools.support_patient;

// 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)
Expand All @@ -105,6 +109,32 @@ function ComplexJournalVoucherController(Vouchers, $translate, Currencies, Sessi
});
}

// 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;

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);
});
}

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

// bind the startup method as a reset method
Expand Down
9 changes: 9 additions & 0 deletions client/src/modules/vouchers/toolkit.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,19 @@ function VoucherToolkitService($http, Modal, util) {
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'
},
'support_patient' : {
icon : 'fa-wpforms',
label : 'VOUCHERS.GLOBAL.SUPPORT_FORM',
controller : 'SupportPatientKitController',
templateUrl : 'modules/vouchers/toolkit/support_patient.modal.html'
}


};

// service options
Expand Down
2 changes: 1 addition & 1 deletion client/src/modules/vouchers/toolkit/convention_payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function ConventionPaymentKitController(Instance, DebtorGroup, Notify, Cashbox,
row.entity = formatEntity(invoice.entity_uuid);

// this is need to display references in the grid nicely
row.reference = getInvoiceReference(invoice.uuid);
row.document = getInvoiceReference(invoice.uuid);

// add the row in to the
rows.push(row);
Expand Down
187 changes: 187 additions & 0 deletions client/src/modules/vouchers/toolkit/support_patient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
angular.module('bhima.controllers')
.controller('SupportPatientKitController', SupportPatientKitController);

// DI definition
SupportPatientKitController.$inject = [
'$uibModalInstance', 'NotifyService', 'SessionService', 'data', 'bhConstants',
'DebtorService', 'PatientInvoiceService'
];

// Import transaction rows for a Support Patient
function SupportPatientKitController(Instance, Notify, Session, Data, bhConstants, Debtors, Invoices) {
var vm = this;

// global variables
vm.enterprise = Session.enterprise;
vm.gridOptions = {};
vm.tool = Data;
vm.patientInvoice = false;

var MAX_DECIMAL_PRECISION = bhConstants.precision.MAX_DECIMAL_PRECISION;

// expose to the view
vm.selectPatientInvoices = selectPatientInvoices;
vm.close = Instance.close;
vm.import = submit;
vm.loadInvoice = loadInvoice;
vm.onSelectAccount = onSelectAccount;

// debtors from store
Debtors.store()
.then(function (data) {
vm.patients = data;
})
.catch(Notify.handleError);

// get debtor group invoices
function selectPatientInvoices(debtorId) {
// load patient invoices
vm.debtorUuid = debtorId;

Debtors.invoices(debtorId, { balanced : 0 })
.then(function (invoices) {

vm.gridOptions.data = invoices || [];

// total amount
vm.totalInvoices = vm.gridOptions.data.reduce(function (current, previous) {
return current + previous.balance;
}, 0);

// make sure we are always within precision
vm.totalInvoices = Number.parseFloat(vm.totalInvoices.toFixed(MAX_DECIMAL_PRECISION));

return Invoices.search({debtor_uuid : debtorId});
})
.then(function (data) {
vm.invoices = data;
})
.catch(Notify.handleError);
}

function loadInvoice(patient){
vm.patient = patient;
selectPatientInvoices(patient.debtor_uuid);
}

function onSelectAccount(account) {
vm.account_id = account.id;
}

// generate transaction rows
function generateTransactionRows(result) {
var rows = [];
var supportAccountId = result.account_id;
var supportedAccountId = result.patient.account_id;
var invoices = result.invoices;
rows.typeId = bhConstants.transactionType.SUPPORT_INCOME;

// first, generate a support row
var supportRow = generateRow();
supportRow.account_id = supportAccountId;
supportRow.debit = vm.totalSelected;
supportRow.credit = 0;
rows.push(supportRow);

// then loop through each selected item and credit it with the Supported account
invoices.forEach(function (invoice) {
var row = generateRow();

row.account_id = supportedAccountId;
row.reference_uuid = invoice.uuid;
row.entity_uuid = invoice.entity_uuid;
row.credit = invoice.balance;

// this is needed for a nice display in the grid
row.entity = formatEntity(invoice.entity_uuid);

// this is need to display references in the grid nicely
row.document = getInvoiceReference(invoice.uuid);

// add the row in to the
rows.push(row);
});

return rows;
}

// format entityco
function formatEntity(uuid) {
var entity = vm.patients.get(uuid);
return {
label: entity.text,
type: 'D',
uuid: entity.uuid
};
}

// get invoice reference
function getInvoiceReference(uuid) {
var invoice = vm.invoices.filter(function (item) {
return item.uuid === uuid;
})[0];

if (invoice) {
invoice.document_type = 'VOUCHERS.COMPLEX.PATIENT_INVOICE';
}

return invoice;
}

// generate row element
function generateRow() {
return {
account_id : undefined,
debit : 0,
credit : 0,
reference_uuid : undefined,
entity_uuid : undefined
};
}

/* ================ Invoice grid parameters ===================== */
vm.gridOptions.appScopeProvider = vm;
vm.gridOptions.enableFiltering = true;
vm.gridOptions.onRegisterApi = onRegisterApi;
vm.gridOptions.fastWatch = true;
vm.gridOptions.flatEntityAccess = true;

vm.gridOptions.columnDefs = [
{ field : 'reference', displayName : 'TABLE.COLUMNS.REFERENCE', headerCellFilter: 'translate' },
{ field : 'date', cellFilter:'date', displayName : 'TABLE.COLUMNS.BILLING_DATE', headerCellFilter : 'translate', enableFiltering: false },
{ field : 'balance', displayName : 'TABLE.COLUMNS.BALANCE',
headerCellFilter : 'translate', enableFiltering: false,
cellTemplate: '/modules/templates/grid/balance.cell.html'
}
];

function onRegisterApi(gridApi) {
vm.gridApi = gridApi;
vm.gridApi.selection.on.rowSelectionChanged(null, rowSelectionCallback);
vm.gridApi.selection.on.rowSelectionChangedBatch(null, rowSelectionCallback);
}

function rowSelectionCallback(row) {
vm.selectedRows = vm.gridApi.selection.getSelectedRows();
vm.totalSelected = vm.selectedRows.reduce(function (current, previous) {
return current + previous.balance;
}, 0);

vm.totalSelected = Number.parseFloat(vm.totalSelected.toFixed(MAX_DECIMAL_PRECISION));
}

/* ================ End Invoice grid parameters ===================== */

// submission
function submit(form) {
if (form.$invalid) { return; }

var bundle = generateTransactionRows({
account_id: vm.account_id,
patient: vm.patient,
invoices: vm.selectedRows
});

Instance.close({ rows: bundle, patient: vm.patient });
}
}
59 changes: 59 additions & 0 deletions client/src/modules/vouchers/toolkit/support_patient.modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<div class="modal-header">
<ol class="headercrumb">
<li class="static" translate>{{ ToolCtrl.tool.label }}</li>
</ol>
</div>

<form name="ToolForm" bh-submit="ToolCtrl.import(ToolForm)" novalidate>
<div class="modal-body">
<bh-account-select
name="account_id"
account-id="ToolCtrl.account_id"
on-select-callback="ToolCtrl.onSelectAccount(account)">
</bh-account-select>

<bh-find-patient
suppress-reset="false"
on-search-complete="ToolCtrl.loadInvoice(patient)"
on-register-api="ToolCtrl.onRegisterApiCallback(api)"
validation-trigger="ToolForm.$submitted"
required="true">
</bh-find-patient>

<!-- select invoices -->
<div ng-show="ToolCtrl.debtorUuid">
<div
id="invoiceGrid"
style="height: 40vh; margin-bottom: 20px;"
ui-grid="ToolCtrl.gridOptions"
ui-grid-filtering
ui-grid-auto-resize
ui-grid-selection>
</div>
</div>

<p ng-show="!ToolCtrl.debtorUuid" class="text-info">
<i class="fa fa-info-circle"></i> <span translate> VOUCHERS.GLOBAL.SUPPORT_TEXT </span>
</p>

<div ng-show="ToolCtrl.debtorUuid" class="text-right">
<span translate>FORM.LABELS.TOTAL_BILLED</span>: <strong class="text-danger">{{ ToolCtrl.totalInvoices || 0 | currency: ToolCtrl.enterprise.currency_id }}</strong><br>
<span translate>FORM.LABELS.TOTAL_SELECTED_INVOICES</span>: <strong class="text-success">{{ ToolCtrl.totalSelected || 0 | currency: ToolCtrl.enterprise.currency_id }}</strong>
</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 || !ToolCtrl.selectedRows.length">
<span translate>FORM.BUTTONS.SUBMIT</span>
</bh-loading-button>
</div>
</form>
2 changes: 0 additions & 2 deletions test/end-to-end/edit_journal/edit_journal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ describe('Edit Posting Journal', () => {
it('edits a transaction change value of Debit and Credit', () => {
FU.buttons.grouping();
element.all(by.css('[class="fa fa-edit"]')).get(0).click();

const debitCell = GU.getCellName(gridId, 1, 5);
const creditCell = GU.getCellName(gridId, 2, 6);

doubleClick(debitCell);
debitCell.element(by.css('input')).sendKeys(150);

Expand Down
Loading

0 comments on commit 2ff9b91

Please sign in to comment.