Skip to content

Commit

Permalink
feat(patients): link to patient vouchers
Browse files Browse the repository at this point in the history
This commit embeds an additional link in the patient registry to show
the patient's vouchers.  This compliments the original two links
already shown of the payments and invoices.

Closes #1954
  • Loading branch information
jniles committed Aug 19, 2017
1 parent e8ed369 commit 7ecab3d
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 108 deletions.
1 change: 0 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ SESS_RESAVE=0
SESS_UNSET='destroy'

LOG_LEVEL='warn'
# LOG_LEVEL='warn'
# LOG_LEVEL='debug'
UPLOAD_DIR='client/upload'

Expand Down
29 changes: 17 additions & 12 deletions client/src/i18n/en/patient_registry.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
{"PATIENT_REGISTRY":{"CARD":"Card",
"DAY":"day",
"DAYS":"days",
"INVOICES":"View Invoices",
"INVOICE": "Invoice",
"MONTH":"month",
"MONTHS":"months",
"PAYMENTS":"View Cash Payments",
"YEAR_OLD":"year old",
"YEARS_OLD":"years old",
"TITLE":"Patients",
"RECORD":"Record"}}
{
"PATIENT_REGISTRY":{
"CARD":"Card",
"DAY":"day",
"DAYS":"days",
"INVOICES":"View Invoices",
"INVOICE": "Invoice",
"VOUCHERS" : "View Vouchers",
"MONTH":"month",
"MONTHS":"months",
"PAYMENTS":"View Cash Payments",
"YEAR_OLD":"year old",
"YEARS_OLD":"years old",
"TITLE":"Patients",
"RECORD":"Record"
}
}
126 changes: 70 additions & 56 deletions client/src/i18n/en/vouchers.json
Original file line number Diff line number Diff line change
@@ -1,56 +1,70 @@
{"VOUCHERS":{"COMPLEX":{"ADD_ITEMS":"Add item(s)",
"CASH_PAYMENT":"Cash Payment",
"CREATE_SUCCESS":"Successfully posted",
"CREATE_ERROR":"An error occurred when post",
"CREDITOR":"Creditor (C)",
"DEBTOR":"Debtor (D)",
"DEB_CRED":"Debtor/Creditor",
"DESCRIPTION":"This module allows you to make advanced journal transactions manually",
"ENTITY":"Entity (Debtor/Creditor)",
"ERROR_ACCOUNT":"Selected accounts are invalid",
"ERROR_AMOUNT":"Amount's values are invalid",
"ERROR_TOTALS":"The totals are not balanced",
"ERROR_PRECISION":"The amounts entered cannot have more than 4 decimal places in precision",
"INVALID_VALUES":"There are invalid values detected",
"PATIENT_INVOICE":"Patient Invoice",
"REFERENCE":"Reference",
"ROWS":"Row(s)",
"SELECT_DOCUMENT_TYPE":"Please select the document type",
"TITLE":"Advanced Journal Vouchers",
"VALID_TOTALS":"Transactions are valid (balanced transaction)",
"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",
"TRANSFER_TYPE_INFO":"Transaction Type in case we have either incomes or expenses",
"USE_FINANCIAL_ACCOUNT":"Use of cashes or banks accounts in this transaction",
"RECEIPT":{"SUCCESS":"Voucher Payment recorded successfully."},
"ERROR_SAME_ACCOUNT":"You cannot use the same account twice to in this transaction. Please select two different accounts."},
"SIMPLE":{"CASH_PAYMENT":"Client Payment",
"CASH_RETURN":"Cash Return (Payback)",
"CONVENTION_PAYMENT":"Convention Payment",
"CREDIT_NOTE":"Credit Note",
"EXPENSE":"Expenses",
"INCOME":"Incomes",
"INVOICING":"Invoicing",
"SALARY_PAYMENT":"Salary Payment",
"GENERIC_EXPENSE":"Other Expenses",
"GENERIC_INCOME":"Other Incomes",
"PURCHASES":"Purchases",
"SUPPORT_INCOME":"Support Incomes",
"TITLE":"Simple Voucher",
"TRANSFER":"Money Transfer",
"TRANSFER_PATIENT_INVOICE_AMOUNT":"Patient Invoice Debt Transfer"},
"REPORT":"Report"}}
{
"VOUCHERS" : {
"COMPLEX":{
"ADD_ITEMS":"Add item(s)",
"CASH_PAYMENT":"Cash Payment",
"CREATE_SUCCESS":"Successfully posted",
"CREATE_ERROR":"An error occurred when post",
"CREDITOR":"Creditor (C)",
"DEBTOR":"Debtor (D)",
"DEB_CRED":"Debtor/Creditor",
"DESCRIPTION":"This module allows you to make advanced journal transactions manually",
"ENTITY":"Entity (Debtor/Creditor)",
"ERROR_ACCOUNT":"Selected accounts are invalid",
"ERROR_AMOUNT":"Amount's values are invalid",
"ERROR_TOTALS":"The totals are not balanced",
"ERROR_PRECISION":"The amounts entered cannot have more than 4 decimal places in precision",
"INVALID_VALUES":"There are invalid values detected",
"PATIENT_INVOICE":"Patient Invoice",
"REFERENCE":"Reference",
"ROWS":"Row(s)",
"SELECT_DOCUMENT_TYPE":"Please select the document type",
"TITLE":"Advanced Journal Vouchers",
"VALID_TOTALS":"Transactions are valid (balanced transaction)",
"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",
"TRANSFER_TYPE_INFO":"Transaction Type in case we have either incomes or expenses",
"USE_FINANCIAL_ACCOUNT":"Use of cashes or banks accounts in this transaction",
"RECEIPT":{
"SUCCESS":"Voucher Payment recorded successfully."
},
"ERROR_SAME_ACCOUNT":"You cannot use the same account twice to in this transaction. Please select two different accounts."
},
"SIMPLE":{
"CASH_PAYMENT":"Client Payment",
"CASH_RETURN":"Cash Return (Payback)",
"CONVENTION_PAYMENT":"Convention Payment",
"CREDIT_NOTE":"Credit Note",
"EXPENSE":"Expenses",
"INCOME":"Incomes",
"INVOICING":"Invoicing",
"SALARY_PAYMENT":"Salary Payment",
"GENERIC_EXPENSE":"Other Expenses",
"GENERIC_INCOME":"Other Incomes",
"PURCHASES":"Purchases",
"SUPPORT_INCOME":"Support Incomes",
"TITLE":"Simple Voucher",
"TRANSFER":"Money Transfer",
"TRANSFER_PATIENT_INVOICE_AMOUNT":"Patient Invoice Debt Transfer"
},
"REPORT":"Report"
}
}
29 changes: 17 additions & 12 deletions client/src/i18n/fr/patient_registry.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
{"PATIENT_REGISTRY":{"CARD":"Carte",
"DAY":"jour",
"DAYS":"jours",
"INVOICES":"Les factures",
"INVOICE":"La facture",
"MONTH":"mois",
"MONTHS":"mois",
"PAYMENTS":"Les paiements",
"RECORD":"Enregistrement",
"YEAR_OLD":"an",
"YEARS_OLD":"ans",
"TITLE":"Registre des patients"}}
{
"PATIENT_REGISTRY":{
"CARD":"Carte",
"DAY":"jour",
"DAYS":"jours",
"INVOICES":"Les Factures",
"VOUCHERS":"Les Bordereaux",
"INVOICE":"La facture",
"MONTH":"mois",
"MONTHS":"mois",
"PAYMENTS":"Les Paiements",
"RECORD":"Enregistrement",
"YEAR_OLD":"an",
"YEARS_OLD":"ans",
"TITLE":"Registre des Patients"
}
}
2 changes: 1 addition & 1 deletion client/src/js/services/FilterService.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ function FilterService(Store) {
// return filters for the view - this method will always be compatible with the bhFilter component
FilterList.prototype.formatView = function formatView() {
var activeFilters = this._filterActiveFilters();
var activeKeys = activeFilters.map(function (filter) { return filter._key; });
var activeKeys = activeFilters.map(function (filter) { return filter._key; });

function keysInActive(filter) { return activeKeys.indexOf(filter._key) !== -1; }

Expand Down
5 changes: 5 additions & 0 deletions client/src/modules/patients/templates/action.cell.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@
<span class="fa fa-money"></span> <span translate>PATIENT_REGISTRY.PAYMENTS</span>
</a>
</li>
<li>
<a data-method="voucher" ui-sref="vouchers({ filters : [{ key : 'entity_uuid', value : row.entity.debtor_uuid, displayValue: row.entity.display_name }]})" href>
<span class="fa fa-address-card-o"></span> <span translate>PATIENT_REGISTRY.VOUCHERS</span>
</a>
</li>
</ul>
</div>
17 changes: 11 additions & 6 deletions client/src/modules/vouchers/voucher-registry.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,6 @@ function VoucherController(Vouchers, Notify, uiGridGroupingConstants,
Receipts.voucher(uuid);
}

function isEmpty(object) {
return Object.keys(object).length === 0;
}

function load(filters) {
// flush error and loading states
vm.hasError = false;
Expand Down Expand Up @@ -212,6 +208,15 @@ function VoucherController(Vouchers, Notify, uiGridGroupingConstants,

// initialize module
function startup() {
var changes;

if ($state.params.filters.length) {
changes = angular.copy($state.params.filters);

Vouchers.filters.replaceFilters(changes);
Vouchers.cacheFilters();
}

Vouchers.transactionType()
.then(function (store) {
vm.transactionTypes = store;
Expand All @@ -228,15 +233,15 @@ function VoucherController(Vouchers, Notify, uiGridGroupingConstants,
// column configuration has direct access to the grid API to alter the current
// state of the columns - this will be saved if the user saves the grid configuration
gridColumns.openConfigurationModal();
};
}


vm.saveGridState = state.saveGridState;
// saves the grid's current configuration
function clearGridState() {
state.clearGridState();
$state.reload();
};
}

startup();
}
3 changes: 3 additions & 0 deletions client/src/modules/vouchers/vouchers.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ angular.module('bhima.routes')
url : '/vouchers',
controller : 'VoucherController as VoucherCtrl',
templateUrl : 'modules/vouchers/voucher-registry.html',
params : {
filters : [],
},
})

.state('simpleVouchers.barcode', {
Expand Down
32 changes: 15 additions & 17 deletions client/src/modules/vouchers/vouchers.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,20 @@ function VoucherService(Api, $http, TransactionTypeStore, Modal,

voucherFilters.registerDefaultFilters([
{ key : 'period', label : 'TABLE.COLUMNS.PERIOD', valueFilter : 'translate' },
{ key : 'custom_period_start', label : 'PERIODS.START', comparitor: '>', valueFilter : 'date' },
{ key : 'custom_period_end', label : 'PERIODS.END', comparitor: '<', valueFilter : 'date' },
{ key : 'custom_period_start', label : 'PERIODS.START', comparitor : '>', valueFilter : 'date' },
{ key : 'custom_period_end', label : 'PERIODS.END', comparitor : '<', valueFilter : 'date' },
{ key : 'limit', label : 'FORM.LABELS.LIMIT' }]);

voucherFilters.registerCustomFilters([
{ key: 'user_id', label: 'FORM.LABELS.USER' },
{ key: 'reference', label: 'FORM.LABELS.REFERENCE' },
{ key: 'dateFrom', label: 'FORM.LABELS.DATE', comparitor: '>', valueFilter: 'date' },
{ key: 'dateTo', label: 'FORM.LABELS.DATE', comparitor: '<', valueFilter: 'date' },
{ key: 'reversed', label: 'FORM.INFO.ANNULLED' },
{ key: 'description', label: 'FORM.LABELS.DESCRIPTION' },
{ key: 'type_ids', label: 'FORM.LABELS.TRANSACTION_TYPE' }]);


if(filterCache.filters){
{ key : 'user_id', label : 'FORM.LABELS.USER' },
{ key : 'reference', label : 'FORM.LABELS.REFERENCE' },
{ key : 'reversed', label : 'FORM.INFO.ANNULLED' },
{ key : 'description', label : 'FORM.LABELS.DESCRIPTION' },
{ key : 'entity_uuid', label : 'FORM.LABELS.ENTITY' },
{ key : 'type_ids', label : 'FORM.LABELS.TRANSACTION_TYPE' }]);


if (filterCache.filters) {
voucherFilters.loadCache(filterCache.filters);
}

Expand All @@ -78,16 +77,16 @@ function VoucherService(Api, $http, TransactionTypeStore, Modal,

function removeFilter(key) {
voucherFilters.resetFilterState(key);
};
}

// load filters from cache
function cacheFilters() {
filterCache.filters = voucherFilters.formatCache();
};
}

function loadCachedFilters() {
voucherFilters.loadCache(filterCache.filters || {});
};
}

// returns true if the key starts with an underscore
function isInternalKey(key) {
Expand All @@ -111,7 +110,6 @@ function VoucherService(Api, $http, TransactionTypeStore, Modal,
* Wraps the prototype create method.
*/
function create(voucher) {

var v = angular.copy(voucher);

// format items for posting, removing validation keys and unlinking old objects
Expand Down Expand Up @@ -169,7 +167,7 @@ function VoucherService(Api, $http, TransactionTypeStore, Modal,

// return serialized options
return $httpParamSerializer(options);
};
}

/**
* @function openSearchModal
Expand Down
11 changes: 8 additions & 3 deletions server/controllers/finance/vouchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,18 @@ function lookupVoucher(vUuid) {
}

function find(options) {
db.convert(options, ['uuid', 'reference_uuid', 'entity_uuid']);

const filters = new FilterParser(options, { tableAlias : 'v', autoParseStatements : false });
const referenceStatement = `CONCAT_WS('.', '${entityIdentifier}', p.abbr, v.reference) = ?`;
let typeIds = [];

if(options.type_ids) {
if (options.type_ids) {
typeIds = typeIds.concat(options.type_ids);
}

const sql = `
SELECT
SELECT
BUID(v.uuid) as uuid, v.date, v.project_id, v.currency_id, v.amount,
v.description, v.user_id, v.type_id, u.display_name, transaction_type.text,
CONCAT_WS('.', '${entityIdentifier}', p.abbr, v.reference) AS reference,
Expand All @@ -139,7 +141,10 @@ function find(options) {

filters.fullText('description');

filters.custom('type_ids', 'v.type_id IN (?)', typeIds);
// @todo - could this be improved
filters.custom('entity_uuid', 'v.uuid IN (SELECT DISTINCT voucher_uuid FROM voucher_item WHERE entity_uuid = ?)');

filters.custom('type_ids', 'v.type_id IN (?)', typeIds);

// @todo - could this be improved
filters.custom('account_id', 'v.uuid IN (SELECT DISTINCT voucher_uuid FROM voucher_item WHERE account_id = ?)');
Expand Down

0 comments on commit 7ecab3d

Please sign in to comment.