Skip to content

Commit

Permalink
Merge pull request #407 from sfount/feature-html-renderer
Browse files Browse the repository at this point in the history
(Feature) Render Server HTML, PDF
  • Loading branch information
jniles committed May 22, 2016
2 parents bb25dd1 + 44201b3 commit 0ff4a2a
Show file tree
Hide file tree
Showing 55 changed files with 481 additions and 5,120 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dist: trusty
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq mysql-server-5.6 mysql-client-5.6 mysql-client-core-5.6
- sudo apt-get install wkhtmltopdf
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

Expand Down
9 changes: 7 additions & 2 deletions client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@
"BILLING_SERVICES" : "Billing Services Applied",
"INVALID_DETAILS" : "This invoice contains invalid details",
"INVALID_ITEMS" : "This invoice contains invalid items",
"PAGE_TITLE" : "Patient Invoice"
"PAGE_TITLE" : "Patient Invoice",
"SUCCESS" : "Patient invoice successfully recorded."
},
"PATIENT_REG": {
"FIND_PATIENT" : "Find a Patient",
Expand Down Expand Up @@ -774,6 +775,7 @@
"PHONE" : "Telephone",
"POSITION" : "Position",
"PO_BOX" : "Poste Office Box",
"PRICE" : "Price",
"PRICE_LIST" : "Price List",
"PROFIT" : "Profit",
"PROFIT_CENTER" : "Profit Center",
Expand All @@ -785,6 +787,7 @@
"REF_GROUP" : "Ref. Groupe",
"RESULT" : "Result",
"RESULT_ACCOUNT_SCT" : "Result Account section",
"RECEIPT" : "Receipt",
"SECTOR" : "Sector",
"SERVICE" : "Service",
"SORTING": {
Expand All @@ -797,9 +800,11 @@
},
"TEXT" : "Text",
"TOTAL" : "Total",
"TRANSACTION_ID" : "Transaction ID",
"TYPE" : "Type",
"VALUE" : "Value",
"VILLAGE" : "Village"
"VILLAGE" : "Village",
"QUANTITY" : "Quantity"
}
},
"TREE": {
Expand Down
2 changes: 1 addition & 1 deletion client/src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var bhima = angular.module('bhima', [
'ngStorage', 'chart.js', 'tmh.dynamicLocale', 'ngFileUpload', 'ui.grid',
'ui.grid.selection', 'ui.grid.autoResize', 'ui.grid.resizeColumns',
'angularMoment', 'ngMessages', 'ui.grid.pagination', 'ui.grid.moveColumns',
'ui.grid.grouping', 'growlNotifications', 'ngAnimate'
'ui.grid.grouping', 'growlNotifications', 'ngAnimate', 'ngSanitize'
]);


Expand Down
58 changes: 29 additions & 29 deletions client/src/js/directives/bhUnique.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
angular.module('bhima.directives')
.directive('bhUnique', UniqueDirective);

UniqueDirective.$inject = ['$q', 'UniqueValidatorService'];

/**
* Unique Input Directive
/**
* Unique Input Directive
*
* This input extends an input to add an asynchronous unique constraint. The
* directive will make HTTP requests to a specified URL and expect to recieve
* `true` and `false` values. This will then update the $valid property
* on the angluar form record.
* This input extends an input to add an asynchronous unique constraint. The
* directive will make HTTP requests to a specified URL and expect to recieve
* `true` and `false` values. This will then update the $valid property
* on the angluar form record.
*
* The UniqueValidator service is used and therefore the URL provided will be
* The UniqueValidator service is used and therefore the URL provided will be
* required to implement the `exists` API. See the `services/UniqueValidatorService`
* documentation for more details and examples.
*
* @example
*
* @example
*
* // will result in a HTTP GET request to /users/attribute/:value/exists
* <input id="email" type="email" bh-unique="/users/attribute">
*
* @module directives/bhUnique
*/
function UniqueDirective($q, UniqueValidator) {
return {
restrict : 'A',
function UniqueDirective($q, UniqueValidator) {
return {
restrict : 'A',
require : 'ngModel',
scope : {
scope : {
bhUnique : '@bhUnique'
},
link : function uniqueLink(scope, element, attrs, ctrl) {
link : function uniqueLink(scope, element, attrs, ctrl) {
var validationUrl = attrs.bhUnique;

// the $error that will be passed on to ng-messages if this directive fails
// to validate the input
var exceptionKey = 'exception';

ctrl.$asyncValidators.unique = function (modelValue, viewValue) {
// deferred object must be used to handle catch statement within

// deferred object must be used to handle catch statement within
// this scope - $q does not currently support chaining catch statements
var deferred = $q.defer();
var deferred = $q.defer();

// don't make an HTTP request unless there is content to validate
if (ctrl.$isEmpty(modelValue)) {
if (ctrl.$isEmpty(modelValue)) {
return $q.when();
}

UniqueValidator.check(validationUrl, viewValue)
.then(function (valueExists) {
// as we have recieved a valid HTTP response there is nothing wrong
.then(function (valueExists) {

// as we have recieved a valid HTTP response there is nothing wrong
// with the connection to the server
ctrl.$setValidity(exceptionKey, true);
if (valueExists) {
ctrl.$setValidity(exceptionKey, true);

if (valueExists) {
deferred.reject();
} else {
deferred.resolve();
}
})
.catch(function (error) {
// expose that there has been an issue beyond the directives control
.catch(function (error) {

// expose that there has been an issue beyond the directives control
// to the view
ctrl.$setValidity(exceptionKey, false);
deferred.reject();
Expand Down
53 changes: 28 additions & 25 deletions client/src/js/services/receipts/ReceiptModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,55 @@ angular.module('bhima.services')
.service('ReceiptModal', ReceiptModal);

ReceiptModal.$inject = ['$uibModal', 'ReceiptService'];
/**
* Receipts Modal Service

/**
* Receipts Modal Service
*
* This service is responsible for combining receipt service data with the
* receipts modal controller and providing a clean interface to be used within
* module controllers.
*
* @todo Discuss how the render target PDF should be templated. Suggestion:
* - IF pdf - use /src/services/receipts/modal/pdf.tmpl.html
* - IF json - specifiy individual target /partials/patient_invoice/receipt/...
* This service is responsible for combining receipt service data with the
* receipts modal controller and providing a clean interface to be used within
* module controllers.
*
* @module services/receipts/ReceiptModal
*/
function ReceiptModal(Modal, Receipts) {
function ReceiptModal(Modal, Receipts) {
var service = this;
var modalConfiguration = {

var modalConfiguration = {
templateUrl : '/js/services/receipts/modal/receiptModal.tmpl.html',
controller : 'ReceiptModalController as ReceiptCtrl',
size : 'md',
backdrop : 'static',
animation : false
};

// expose available receipts
service.invoice = invoice;

function invoice(uuid) {
/**
* Invokes a patient invoice receipt
*
* @param {String} uuid Target invoice UUID
* @param {Boolean} notifyCreated Defines if a success message should be shown for entity creation
*/
function invoice(uuid, notifyCreated) {

/** @todo Discuss if these should be overridable from the controller or if the config should be set here */
var options = {
title : 'PATIENT_INVOICE.PAGE_TITLE',
identifier : 'reference',
renderer : 'json',
template : 'partials/patient_invoice/receipt/invoice.receipt.tmpl.html',
var options = {
title : 'PATIENT_INVOICE.PAGE_TITLE',
createdKey : 'PATIENT_INVOICE.SUCCESS',
identifier : 'reference',
renderer : Receipts.renderers.PDF,
notifyCreated : notifyCreated
};

var invoiceRequest = Receipts.invoice(uuid, { render : options.renderer });
var invoiceProvider = {
resolve : {
var invoiceProvider = {
resolve : {
receipt : function receiptProvider() { return { promise : invoiceRequest }; },
options : function templateProvider() { return options; },
options : function optionsProvider() { return options; },
}
};

var configuration = angular.extend(modalConfiguration, invoiceProvider);
var instance = Modal.open(configuration);
return instance.result;
Expand Down
19 changes: 14 additions & 5 deletions client/src/js/services/receipts/ReceiptService.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ ReceiptService.$inject = ['$http', 'util'];
* This service is responsible for interfacing with any receipts routes on the
* server.
*
* @todo currently this server 1:1 maps with the ReceiptModal service/controller.
* This relationship improved or justified with unit tests.
* @module services/receipts/ReciptService
*/
function ReceiptService($http, util) {
var service = this;

var renderers = {
PDF : 'pdf',
HTML : 'html',
JSON : 'json'
};

service.invoice = invoice;

service.renderers = renderers;

/**
* Fetch invoice report data from /reports/invoices/:uuid
*
Expand All @@ -28,7 +32,12 @@ function ReceiptService($http, util) {
*/
function invoice(uuid, options) {
var route = '/reports/invoices/'.concat(uuid);
return $http.get(route, { params : options })
var responseType = null;

if (options.render === renderers.PDF) {
responseType = 'arraybuffer';
}
return $http.get(route, {params: options, responseType: responseType})
.then(util.unwrapHttpResponse);
}
}
56 changes: 36 additions & 20 deletions client/src/js/services/receipts/modal/receiptModal.tmpl.html
Original file line number Diff line number Diff line change
@@ -1,35 +1,51 @@
<div class="modal-header">
<div style="display : inline-block">
<ol class="headercrumb">
<li class="static">{{ ReceiptCtrl.title | translate }}</li>
<li class="title">
{{ "COLUMNS.RECEIPT" | translate }}
{{ "TABLE.COLUMNS.RECEIPT" | translate }}
<span ng-if="ReceiptCtrl.identifier" class="label label-warning">{{ReceiptCtrl.receipt[ReceiptCtrl.identifier]}}</span>
</li>
</ol>
</div>
<div
id="receipt-confirm-created"
ng-if="ReceiptCtrl.notifyCreated"
style="padding-top : 8px"
class="pull-right">
<span class="text-success">
<span class="glyphicon glyphicon-ok-circle"></span>
{{ReceiptCtrl.createdKey | translate}}
</span>
</div>
</div>

<!-- Tempoarary Loading State -->
<div style="padding : 10px;" ng-if="!ReceiptCtrl.receipt">
<p class="text-info"><span class="glyphicon glyphicon-hourglass"></span> {{"RECEIPTS.LOADING"}}</p>
</div>

<!-- TODO Investigate if this should use latest ui-router standards -->
<div ng-switch on="ReceiptCtrl.renderer">

<!-- JSON Should be exposed to a view provided by the template passed to the -->
<!-- controller by the Receipt Modal service -->
<div ng-switch-when="json">

<!-- TODO Modal height etc. should be standardised -->
<div class="bh-modal-content">
<div ng-include="ReceiptCtrl.template"></div>
</div>
</div>

<!-- PDFs are downloaded through the GET request - they can be displayed using -->
<!-- ng-src -->
<div ng-switch-when="pdf">

<!-- Google Chrome obejct seems to add 5px below outside or margin/padding model - this can be removed if it causes issues -->
<object id="pdf" ng-src="{{ReceiptCtrl.receipt}}" type="application/pdf" style="width : 100%; height : 50vh; margin-bottom : -5px;">
<!-- PDF -->
<div ng-switch-when="ReceiptCtrl.renderers.PDF">

<iframe
id="pdf"
ng-src="{{ReceiptCtrl.receipt}}"
type="application/pdf"
style="width : 100%; height : 50vh; margin-bottom : -5px; border : none;">
<!-- TODO: Translate -->
<p>Unable to display PDF. Please contact your system administrator</p>
</object>
<!--<p>Unable to display PDF. Please contact your system administrator</p>-->
</iframe>
</div>

<!-- HTML -->
<div ng-switch-when="ReceiptCtrl.renderers.HTML">

<div class="bh-modal-content">
<div ng-bind-html="ReceiptCtrl.receipt"></div>
</div>
</div>

<!-- CSV -->
Expand Down
Loading

0 comments on commit 0ff4a2a

Please sign in to comment.