From fb0aa7a3a3ae1955f130bc38486a9d563a8b3609 Mon Sep 17 00:00:00 2001 From: "Chelsea H. Komlo" Date: Tue, 28 Jan 2014 06:40:38 +0530 Subject: [PATCH] Refactoring view client controller --- .../client/ViewClientController.js | 798 ++++++++---------- app/scripts/mifosXComponents.js | 403 ++++----- app/scripts/models/clientStatus.js | 102 +++ test/SpecRunner.html | 147 ++-- .../{ => client}/ClientControllerSpec.js | 0 .../client/ViewClientControllerSpec.js | 79 ++ test/spec/models/ClientStatusSpec.js | 47 ++ 7 files changed, 869 insertions(+), 707 deletions(-) create mode 100644 app/scripts/models/clientStatus.js rename test/spec/controllers/{ => client}/ClientControllerSpec.js (100%) create mode 100644 test/spec/controllers/client/ViewClientControllerSpec.js create mode 100644 test/spec/models/ClientStatusSpec.js diff --git a/app/scripts/controllers/client/ViewClientController.js b/app/scripts/controllers/client/ViewClientController.js index 2074ce95..e3c9cc7a 100644 --- a/app/scripts/controllers/client/ViewClientController.js +++ b/app/scripts/controllers/client/ViewClientController.js @@ -1,460 +1,388 @@ -(function(module) { - mifosX.controllers = _.extend(module, { - ViewClientController: function(scope, routeParams , route, location, resourceFactory, http, $modal, API_VERSION,$rootScope,$upload) { - scope.client = []; - scope.identitydocuments = []; - scope.buttons = []; - scope.clientdocuments = []; - scope.staffData = {}; - scope.openLoan = true; - scope.openSaving = true; - scope.routeToLoan = function(id){ - location.path('/viewloanaccount/' + id); - }; - scope.routeToSaving = function(id){ - location.path('/viewsavingaccount/' + id); - }; - scope.haveFile = []; - resourceFactory.clientResource.get({clientId: routeParams.id} , function(data) { - scope.client = data; - scope.staffData.staffId = data.staffId; - if (data.imagePresent) { - http({ - method:'GET', - url: $rootScope.hostUrl + API_VERSION + '/clients/'+routeParams.id+'/images' - }).then(function(imageData) { - scope.image = imageData.data; - }); - } - if (data.status.value == "Pending") { - scope.buttons = [{ - name:"label.button.edit", - href:"#/editclient", - icon :"icon-edit" - }, - { - name:"label.button.activate", - href:"#/client", - subhref:"activate", - icon :"icon-ok-sign" - }, - { - name:"label.button.close", - href:"#/client", - subhref:"close", - icon :"icon-remove-circle" - }] - - } - - if (data.status.value == "Active") { - scope.buttons = [{ - name:"label.button.edit", - href:"#/editclient", - icon :"icon-edit" - }, - { - name:"label.button.newloan", - href:"#/newclientloanaccount", - icon :"icon-plus" - }, - { - name:"label.button.newsaving", - href:"#/new_client_saving_application", - icon :"icon-plus" - }, - { - name:"label.button.transferclient", - href:"#/transferclient", - icon :"icon-arrow-right" - }, - { - name:"label.button.close", - href:"#/client", - subhref:"close", - icon :"icon-remove-circle" - }] - } - - if (data.status.value == "Transfer in progress") { - scope.buttons = [{ - name:"label.button.accepttransfer", - href:"#/client", - subhref:"acceptclienttransfer", - icon :"icon-check-sign" - }, - { - name:"label.button.rejecttransfer", - href:"#/client", - subhref:"rejecttransfer", - icon :"icon-remove" - }, - { - name:"label.button.undotransfer", - href:"#/client", - subhref:"undotransfer", - icon :"icon-undo" - }] - } - - if (data.status.value == "Transfer on hold") { - scope.buttons = [{ - name:"label.button.undotransfer", - href:"#/client", - subhref:"undotransfer", - icon :"icon-undo" - }] - } - - if (data.status.value == "Pending" || data.status.value == "Active"){ - if(data.staffId) { - - } - else { - scope.buttons.push({ - name:"label.button.assignstaff", - href:"#/client", - subhref:"assignstaff", - icon :"icon-user" - }); - } - } - - scope.buttonsArray = { - options: [{ - name:"button.clientscreenreports" - }] +(function (module) { + mifosX.controllers = _.extend(module, { + ViewClientController: function (scope, routeParams, route, location, resourceFactory, http, $modal, API_VERSION, $rootScope, $upload) { + scope.client = []; + scope.identitydocuments = []; + scope.buttons = []; + scope.clientdocuments = []; + scope.staffData = {}; + scope.openLoan = true; + scope.openSaving = true; + scope.routeToLoan = function (id) { + location.path('/viewloanaccount/' + id); }; - scope.buttonsArray.singlebuttons = scope.buttons; - resourceFactory.runReportsResource.get({reportSource: 'ClientSummary',genericResultSet: 'false',R_clientId: routeParams.id} , function(data) { - scope.client.ClientSummary = data[0]; - }); - }); - scope.deleteClient = function () { - $modal.open({ - templateUrl: 'deleteClient.html', - controller: ClientDeleteCtrl - }); - }; - scope.uploadPic = function () { - $modal.open({ - templateUrl: 'uploadpic.html', - controller: UploadPicCtrl - }); - }; - var UploadPicCtrl = function ($scope, $modalInstance) { - $scope.onFileSelect = function($files) { - scope.file = $files[0]; + scope.routeToSaving = function (id) { + location.path('/viewsavingaccount/' + id); }; - $scope.upload = function () { - if (scope.file) { - $upload.upload({ - url: $rootScope.hostUrl + API_VERSION + '/clients/'+routeParams.id+'/images', - data: {}, - file: scope.file - }).then(function(imageData) { - // to fix IE not refreshing the model - if (!scope.$$phase) { - scope.$apply(); - } - route.reload(); + scope.haveFile = []; + resourceFactory.clientResource.get({clientId: routeParams.id}, function (data) { + scope.client = data; + scope.staffData.staffId = data.staffId; + if (data.imagePresent) { + http({ + method: 'GET', + url: $rootScope.hostUrl + API_VERSION + '/clients/' + routeParams.id + '/images' + }).then(function (imageData) { + scope.image = imageData.data; }); } - $modalInstance.close('upload'); - }; - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; - }; - scope.unassignStaffCenter = function () { - $modal.open({ - templateUrl: 'clientunassignstaff.html', - controller: ClientUnassignCtrl - }); - }; - var ClientDeleteCtrl = function ($scope, $modalInstance) { - $scope.delete = function () { - resourceFactory.clientResource.delete({clientId: routeParams.id}, {}, function(data){ - location.path('/clients'); + + var clientStatus = new mifosX.models.ClientStatus() + + if (clientStatus.statusKnown(data.status.value)) { + scope.buttons = clientStatus.getStatus(data.status.value); + } + + if (data.status.value == "Pending" || data.status.value == "Active") { + if (data.staffId) { + + } + else { + scope.buttons.push(clientStatus.getStatus("Assign Staff")); + } + } + + scope.buttonsArray = { + options: [ + { + name: "button.clientscreenreports" + } + ] + }; + scope.buttonsArray.singlebuttons = scope.buttons; + resourceFactory.runReportsResource.get({reportSource: 'ClientSummary', genericResultSet: 'false', R_clientId: routeParams.id}, function (data) { + scope.client.ClientSummary = data[0]; + }); + }); + scope.deleteClient = function () { + $modal.open({ + templateUrl: 'deleteClient.html', + controller: ClientDeleteCtrl }); - $modalInstance.close('delete'); }; - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); + scope.uploadPic = function () { + $modal.open({ + templateUrl: 'uploadpic.html', + controller: UploadPicCtrl + }); }; - }; - var ClientUnassignCtrl = function ($scope, $modalInstance) { - $scope.unassign = function () { - resourceFactory.clientResource.save({clientId: routeParams.id, command : 'unassignstaff'}, scope.staffData,function(data){ + var UploadPicCtrl = function ($scope, $modalInstance) { + $scope.onFileSelect = function ($files) { + scope.file = $files[0]; + }; + $scope.upload = function () { + if (scope.file) { + $upload.upload({ + url: $rootScope.hostUrl + API_VERSION + '/clients/' + routeParams.id + '/images', + data: {}, + file: scope.file + }).then(function (imageData) { + // to fix IE not refreshing the model + if (!scope.$$phase) { + scope.$apply(); + } + route.reload(); + }); + } + $modalInstance.close('upload'); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + }; + scope.unassignStaffCenter = function () { + $modal.open({ + templateUrl: 'clientunassignstaff.html', + controller: ClientUnassignCtrl + }); + }; + var ClientDeleteCtrl = function ($scope, $modalInstance) { + $scope.delete = function () { + resourceFactory.clientResource.delete({clientId: routeParams.id}, {}, function (data) { + location.path('/clients'); + }); + $modalInstance.close('delete'); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + }; + var ClientUnassignCtrl = function ($scope, $modalInstance) { + $scope.unassign = function () { + resourceFactory.clientResource.save({clientId: routeParams.id, command: 'unassignstaff'}, scope.staffData, function (data) { + route.reload(); + }); + $modalInstance.close('unassign'); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + }; + resourceFactory.clientAccountResource.get({clientId: routeParams.id}, function (data) { + scope.clientAccounts = data; + }); + scope.isClosed = function (loanaccount) { + if (loanaccount.status.code === "loanStatusType.closed.written.off" || + loanaccount.status.code === "loanStatusType.closed.obligations.met" || + loanaccount.status.code === "loanStatusType.closed.reschedule.outstanding.amount" || + loanaccount.status.code === "loanStatusType.withdrawn.by.client" || + loanaccount.status.code === "loanStatusType.rejected") { + return true; + } else { + return false; + } + }; + scope.isSavingClosed = function (savingaccount) { + if (savingaccount.status.code === "savingsAccountStatusType.withdrawn.by.applicant" || + savingaccount.status.code === "savingsAccountStatusType.closed" || + savingaccount.status.code === "savingsAccountStatusType.rejected") { + return true; + } else { + return false; + } + }; + scope.setLoan = function () { + if (scope.openLoan) { + scope.openLoan = false + } else { + scope.openLoan = true; + } + }; + scope.setSaving = function () { + if (scope.openSaving) { + scope.openSaving = false; + } else { + scope.openSaving = true; + } + }; + resourceFactory.clientNotesResource.getAllNotes({clientId: routeParams.id}, function (data) { + scope.clientNotes = data; + }); + scope.getClientIdentityDocuments = function () { + resourceFactory.clientResource.getAllClientDocuments({clientId: routeParams.id, anotherresource: 'identifiers'}, function (data) { + scope.identitydocuments = data; + for (var i = 0; i < scope.identitydocuments.length; i++) { + resourceFactory.clientIdentifierResource.get({clientIdentityId: scope.identitydocuments[i].id}, function (data) { + for (var j = 0; j < scope.identitydocuments.length; j++) { + if (data.length > 0 && scope.identitydocuments[j].id == data[0].parentEntityId) { + for (var l in data) { + + var loandocs = {}; + loandocs = API_VERSION + '/' + data[l].parentEntityType + '/' + data[l].parentEntityId + '/documents/' + data[l].id + '/attachment?tenantIdentifier=default'; + data[l].docUrl = loandocs; + } + scope.identitydocuments[j].documents = data; + } + } + }); + } + }); + }; + + resourceFactory.DataTablesResource.getAllDataTables({apptable: 'm_client'}, function (data) { + scope.clientdatatables = data; + }); + + scope.dataTableChange = function (clientdatatable) { + resourceFactory.DataTablesResource.getTableDetails({datatablename: clientdatatable.registeredTableName, + entityId: routeParams.id, genericResultSet: 'true'}, function (data) { + scope.datatabledetails = data; + scope.datatabledetails.isData = data.data.length > 0 ? true : false; + scope.datatabledetails.isMultirow = data.columnHeaders[0].columnName == "id" ? true : false; + scope.singleRow = []; + for (var i in data.columnHeaders) { + if (scope.datatabledetails.columnHeaders[i].columnCode) { + for (var j in scope.datatabledetails.columnHeaders[i].columnValues) { + for (var k in data.data) { + if (data.data[k].row[i] == scope.datatabledetails.columnHeaders[i].columnValues[j].id) { + data.data[k].row[i] = scope.datatabledetails.columnHeaders[i].columnValues[j].value; + } + } + } + } + } + if (scope.datatabledetails.isData) { + for (var i in data.columnHeaders) { + if (!scope.datatabledetails.isMultirow) { + var row = {}; + row.key = data.columnHeaders[i].columnName; + row.value = data.data[0].row[i]; + scope.singleRow.push(row); + } + } + } + + }); + }; + scope.deleteAll = function (apptableName, entityId) { + resourceFactory.DataTablesResource.delete({datatablename: apptableName, entityId: entityId, genericResultSet: 'true'}, {}, function (data) { route.reload(); }); - $modalInstance.close('unassign'); }; - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; - }; - resourceFactory.clientAccountResource.get({clientId: routeParams.id} , function(data) { - scope.clientAccounts = data; - }); - scope.isClosed = function(loanaccount) { - if(loanaccount.status.code === "loanStatusType.closed.written.off" || - loanaccount.status.code === "loanStatusType.closed.obligations.met" || - loanaccount.status.code === "loanStatusType.closed.reschedule.outstanding.amount" || - loanaccount.status.code === "loanStatusType.withdrawn.by.client" || - loanaccount.status.code === "loanStatusType.rejected") { - return true; - } else{ - return false; - } - }; - scope.isSavingClosed = function(savingaccount) { - if (savingaccount.status.code === "savingsAccountStatusType.withdrawn.by.applicant" || - savingaccount.status.code === "savingsAccountStatusType.closed" || - savingaccount.status.code === "savingsAccountStatusType.rejected") { - return true; - } else{ - return false; - } - }; - scope.setLoan = function(){ - if(scope.openLoan){ - scope.openLoan = false - }else{ - scope.openLoan = true; - } - }; - scope.setSaving = function(){ - if(scope.openSaving){ - scope.openSaving = false; - }else{ - scope.openSaving = true; - } - }; - resourceFactory.clientNotesResource.getAllNotes({clientId: routeParams.id} , function(data) { - scope.clientNotes = data; - }); - scope.getClientIdentityDocuments = function () { - resourceFactory.clientResource.getAllClientDocuments({clientId: routeParams.id, anotherresource: 'identifiers'} , function(data) { - scope.identitydocuments = data; - for(var i = 0; i 0 && scope.identitydocuments[j].id == data[0].parentEntityId) - { - for(var l in data){ - var loandocs = {}; - loandocs = API_VERSION + '/' + data[l].parentEntityType + '/' + data[l].parentEntityId + '/documents/' + data[l].id + '/attachment?tenantIdentifier=default'; - data[l].docUrl = loandocs; - } - scope.identitydocuments[j].documents = data; - } - } - }); - } - }); - }; + scope.getClientDocuments = function () { + resourceFactory.clientDocumentsResource.getAllClientDocuments({clientId: routeParams.id}, function (data) { + for (var l in data) { - resourceFactory.DataTablesResource.getAllDataTables({apptable: 'm_client'} , function(data) { - scope.clientdatatables = data; - }); - - scope.dataTableChange = function(clientdatatable) { - resourceFactory.DataTablesResource.getTableDetails({datatablename: clientdatatable.registeredTableName, - entityId: routeParams.id, genericResultSet: 'true'} , function(data) { - scope.datatabledetails = data; - scope.datatabledetails.isData = data.data.length > 0 ? true : false; - scope.datatabledetails.isMultirow = data.columnHeaders[0].columnName == "id" ? true : false; - scope.singleRow = []; - for(var i in data.columnHeaders) { - if (scope.datatabledetails.columnHeaders[i].columnCode) { - for (var j in scope.datatabledetails.columnHeaders[i].columnValues){ - for(var k in data.data) { - if (data.data[k].row[i] == scope.datatabledetails.columnHeaders[i].columnValues[j].id) { - data.data[k].row[i] = scope.datatabledetails.columnHeaders[i].columnValues[j].value; + var loandocs = {}; + loandocs = API_VERSION + '/' + data[l].parentEntityType + '/' + data[l].parentEntityId + '/documents/' + data[l].id + '/attachment?tenantIdentifier=default'; + data[l].docUrl = loandocs; } - } + scope.clientdocuments = data; + }); + }; + + scope.deleteDocument = function (documentId, index) { + resourceFactory.clientDocumentsResource.delete({clientId: routeParams.id, documentId: documentId}, '', function (data) { + scope.clientdocuments.splice(index, 1); + }); + }; + + scope.downloadDocument = function (documentId) { + resourceFactory.clientDocumentsResource.get({clientId: routeParams.id, documentId: documentId}, '', function (data) { + scope.clientdocuments.splice(index, 1); + }); + }; + + scope.isLoanNotClosed = function (loanaccount) { + if (loanaccount.status.code === "loanStatusType.closed.written.off" || + loanaccount.status.code === "loanStatusType.closed.obligations.met" || + loanaccount.status.code === "loanStatusType.closed.reschedule.outstanding.amount" || + loanaccount.status.code === "loanStatusType.withdrawn.by.client" || + loanaccount.status.code === "loanStatusType.rejected") { + return false; + } else { + return true; } - } + }; + + scope.isSavingNotClosed = function (savingaccount) { + if (savingaccount.status.code === "savingsAccountStatusType.withdrawn.by.applicant" || + savingaccount.status.code === "savingsAccountStatusType.closed" || + savingaccount.status.code === "savingsAccountStatusType.rejected") { + return false; + } else { + return true; + } + }; + + scope.saveNote = function () { + resourceFactory.clientResource.save({clientId: routeParams.id, anotherresource: 'notes'}, this.formData, function (data) { + var today = new Date(); + temp = { id: data.resourceId, note: scope.formData.note, createdByUsername: "test", createdOn: today }; + scope.clientNotes.push(temp); + scope.formData.note = ""; + scope.predicate = '-id'; + }); } - if(scope.datatabledetails.isData){ - for(var i in data.columnHeaders){ - if(!scope.datatabledetails.isMultirow){ - var row = {}; - row.key = data.columnHeaders[i].columnName; - row.value = data.data[0].row[i]; - scope.singleRow.push(row); + + scope.deleteClientIdentifierDocument = function (clientId, entityId, index) { + resourceFactory.clientIdenfierResource.delete({clientId: clientId, id: entityId}, '', function (data) { + scope.identitydocuments.splice(index, 1); + }); + }; + + scope.downloadClientIdentifierDocument = function (identifierId, documentId) { + console.log(identifierId, documentId); + }; + // devcode: !production + // *********************** InVenture controller *********************** + + scope.fetchInventureScore = function () { + // dummy data for the graph - DEBUG purpose + var inventureScore = getRandomInt(450, 800); + var natAverage = getRandomInt(450, 800); + var industryAverage = getRandomInt(450, 800); + var inventureMinScore = 300; + var inventureMaxScore = 850; + + // dummy data for inventure loan recommendation - DEBUG purpose + scope.inventureAgricultureLimit = '21,000'; + scope.inventureFishermenLimit = '27,500'; + scope.inventureHousingLimit = '385,000'; + scope.inventureBusinessLimit = '10,000'; + + // this part is used to generate data to see the look of the graph + function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; } - }} - }); - }; - scope.deleteAll = function (apptableName, entityId) { - resourceFactory.DataTablesResource.delete({datatablename:apptableName, entityId:entityId, genericResultSet:'true'}, {}, function(data){ - route.reload(); - }); - }; + // CHART1 - comparison chart control + var comparisonData = [ + { + key: "Score Comparison", + values: [ + { + "label": "National Average", + "value": (natAverage) + }, + { + "label": "Agriculture Average", + "value": (industryAverage) + }, + { + "label": "This Client", + "value": (inventureScore) + } + ] + } + ]; - scope.getClientDocuments = function () { - resourceFactory.clientDocumentsResource.getAllClientDocuments({clientId: routeParams.id} , function(data) { - for(var l in data){ + // add the comparison chart to the viewclient.html + nv.addGraph(function () { + var comparisonChart = nv.models.discreteBarChart() + .x(function (d) { + return d.label + }) + .y(function (d) { + return d.value + }) + .staggerLabels(true) + .tooltips(true) + .showValues(true); - var loandocs = {}; - loandocs = API_VERSION + '/' + data[l].parentEntityType + '/' + data[l].parentEntityId + '/documents/' + data[l].id + '/attachment?tenantIdentifier=default'; - data[l].docUrl = loandocs; - } - scope.clientdocuments = data; - }); - }; + // set all display value to integer + comparisonChart.yAxis.tickFormat(d3.format('d')); + comparisonChart.valueFormat(d3.format('d')); + comparisonChart.forceY([inventureMinScore, inventureMaxScore]); - scope.deleteDocument = function (documentId, index) { - resourceFactory.clientDocumentsResource.delete({clientId: routeParams.id, documentId: documentId}, '', function(data) { - scope.clientdocuments.splice(index,1); - }); - }; + d3.select('#inventureBarChart svg') + .datum(comparisonData) + .transition().duration(1500) + .call(comparisonChart); - scope.downloadDocument = function(documentId) { - resourceFactory.clientDocumentsResource.get({clientId: routeParams.id, documentId: documentId}, '', function(data) { - scope.clientdocuments.splice(index,1); - }); - }; + nv.utils.windowResize(comparisonChart.update); + return comparisonChart; + }); - scope.isLoanNotClosed = function (loanaccount) { - if(loanaccount.status.code === "loanStatusType.closed.written.off" || - loanaccount.status.code === "loanStatusType.closed.obligations.met" || - loanaccount.status.code === "loanStatusType.closed.reschedule.outstanding.amount" || - loanaccount.status.code === "loanStatusType.withdrawn.by.client" || - loanaccount.status.code === "loanStatusType.rejected") { - return false; - } else { - return true; - } - }; + // CHART2 - inventure score bullet chart control + nv.addGraph(function () { + var bullet = nv.models.bulletChart() + .tooltips(false); - scope.isSavingNotClosed = function (savingaccount) { - if (savingaccount.status.code === "savingsAccountStatusType.withdrawn.by.applicant" || - savingaccount.status.code === "savingsAccountStatusType.closed" || - savingaccount.status.code === "savingsAccountStatusType.rejected") { - return false; - } else { - return true; - } - }; + d3.select('#inventureBulletChart svg') + .datum(scoreData()) + .transition().duration(1500) + .call(bullet); - scope.saveNote = function() { - resourceFactory.clientResource.save({clientId: routeParams.id, anotherresource: 'notes'}, this.formData , function(data){ - var today = new Date(); - temp = { id: data.resourceId , note : scope.formData.note , createdByUsername : "test" , createdOn : today } ; - scope.clientNotes.push(temp); - scope.formData.note = ""; - scope.predicate = '-id'; - }); + nv.utils.windowResize(bullet.update); + return bullet; + }); + + function scoreData() { + return { + "title": "", + "ranges": [(inventureMinScore - 300), (inventureMaxScore - 300)], + "measures": [(inventureScore - 300)], + "markers": [(inventureScore - 300)]}; + } + + // this will be used to display the score on the viewclient.html + scope.inventureScore = inventureScore; + }; // endcode } - - scope.deleteClientIdentifierDocument = function (clientId, entityId, index){ - resourceFactory.clientIdenfierResource.delete({clientId: clientId, id: entityId}, '', function(data) { - scope.identitydocuments.splice(index,1); - }); - }; - - scope.downloadClientIdentifierDocument=function (identifierId, documentId){ - console.log(identifierId,documentId); - }; - // devcode: !production - // *********************** InVenture controller *********************** - - scope.fetchInventureScore = function(){ - // dummy data for the graph - DEBUG purpose - var inventureScore = getRandomInt(450,800); - var natAverage = getRandomInt(450,800); - var industryAverage = getRandomInt(450,800); - var inventureMinScore = 300; - var inventureMaxScore = 850; - - // dummy data for inventure loan recommendation - DEBUG purpose - scope.inventureAgricultureLimit = '21,000'; - scope.inventureFishermenLimit = '27,500'; - scope.inventureHousingLimit = '385,000'; - scope.inventureBusinessLimit = '10,000'; - - // this part is used to generate data to see the look of the graph - function getRandomInt (min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - // CHART1 - comparison chart control - var comparisonData = [ - { - key: "Score Comparison", - values: [ - { - "label" : "National Average", - "value" : (natAverage) - }, - { - "label" : "Agriculture Average", - "value" : (industryAverage) - }, - { - "label" : "This Client", - "value" : (inventureScore) - } - ] - } - ]; - - // add the comparison chart to the viewclient.html - nv.addGraph(function() { - var comparisonChart = nv.models.discreteBarChart() - .x(function(d) { return d.label }) - .y(function(d) { return d.value }) - .staggerLabels(true) - .tooltips(true) - .showValues(true); - - // set all display value to integer - comparisonChart.yAxis.tickFormat(d3.format('d')); - comparisonChart.valueFormat(d3.format('d')); - comparisonChart.forceY([inventureMinScore, inventureMaxScore]); - - d3.select('#inventureBarChart svg') - .datum(comparisonData) - .transition().duration(1500) - .call(comparisonChart); - - nv.utils.windowResize(comparisonChart.update); - return comparisonChart; - }); - - // CHART2 - inventure score bullet chart control - nv.addGraph(function() { - var bullet = nv.models.bulletChart() - .tooltips(false); - - d3.select('#inventureBulletChart svg') - .datum(scoreData()) - .transition().duration(1500) - .call(bullet); - - nv.utils.windowResize(bullet.update); - return bullet; - }); - - function scoreData() { - return { - "title": "", - "ranges": [(inventureMinScore - 300), (inventureMaxScore - 300)], - "measures": [(inventureScore - 300)], - "markers": [(inventureScore - 300)]}; - } - - // this will be used to display the score on the viewclient.html - scope.inventureScore = inventureScore; - }; // endcode - } - }); - mifosX.ng.application.controller('ViewClientController', ['$scope', '$routeParams', '$route', '$location', 'ResourceFactory', '$http','$modal', 'API_VERSION','$rootScope','$upload', mifosX.controllers.ViewClientController]).run(function($log) { - $log.info("ViewClientController initialized"); - }); -}(mifosX.controllers || {})); + }); + mifosX.ng.application.controller('ViewClientController', ['$scope', '$routeParams', '$route', '$location', 'ResourceFactory', '$http', '$modal', 'API_VERSION', '$rootScope', '$upload', mifosX.controllers.ViewClientController]).run(function ($log) { + $log.info("ViewClientController initialized"); + }); +}(mifosX.controllers || {})); \ No newline at end of file diff --git a/app/scripts/mifosXComponents.js b/app/scripts/mifosXComponents.js index 85914783..d385e88d 100644 --- a/app/scripts/mifosXComponents.js +++ b/app/scripts/mifosXComponents.js @@ -1,202 +1,205 @@ -define(['underscore', 'mifosX'], function() { - var components = { - models: [ - 'LoggedInUser', - 'roleMap', - 'Langs' - ], - services: [ - 'ResourceFactoryProvider', - 'HttpServiceProvider', - 'AuthenticationService', - 'SessionManager', - 'Paginator' - ], - controllers: [ - 'main/MainController', - 'main/LoginFormController', - 'main/TaskController', - 'main/SearchController', - 'main/NavigationController', - 'collection/CollectionSheetController', - 'loanAccount/ViewLoanDetailsController', - 'loanAccount/NewLoanAccAppController', - 'loanAccount/LoanAccountActionsController', - 'loanAccount/AddLoanChargeController', - 'loanAccount/AddLoanCollateralController', - 'loanAccount/AssignLoanOfficerController', - 'loanAccount/EditLoanAccAppController', - 'loanAccount/ViewLoanCollateralController', - 'loanAccount/EditLoanCollateralController', - 'loanAccount/ViewLoanChargeController', - 'loanAccount/EditLoanChargeController', - 'loanAccount/NewJLGLoanAccAppController', - 'loanAccount/LoanDocumentController', - 'loanAccount/ViewLoanTransactionController', - 'loanAccount/LoanScreenReportController', - 'groups/AssignStaffController', - 'client/ClientController', - 'client/EditClientController', - 'client/ViewClientController', - 'client/CreateClientController', - 'client/TransactionClientController', - 'client/ClientActionsController', - 'client/ClientDocumentController', - 'client/ClientIdentifierController', - 'client/UploadClientIdentifierDocumentController', - 'client/ClientScreenReportController', - 'product/LoanProductController', - 'product/CreateLoanProductController', - 'product/CreateSavingProductController', - 'product/EditSavingProductController', - 'product/EditLoanProductController', - 'product/ChargeController', - 'product/ViewChargeController', - 'product/SavingProductController', - 'product/ViewSavingProductController', - 'product/ViewLoanProductController', - 'user/UserController', - 'user/UserFormController', - 'user/UserSettingController', - 'user/UserListController', - 'user/ViewUserController', - 'organization/RoleController', - 'organization/ViewRoleController', - 'organization/CreateRoleController', - 'organization/MakerCheckerController', - 'organization/OfficesController', - 'organization/ViewOfficeController', - 'organization/CreateOfficeController', - 'organization/EditOfficeController', - 'organization/CurrencyConfigController', - 'organization/CreateUserController', - 'organization/EditUserController', - 'organization/ViewEmployeeController', - 'organization/EditEmployeeController', - 'organization/EmployeeController', - 'organization/CreateEmployeeController', - 'organization/ManageFundsController', - 'accounting/AccFreqPostingController', - 'accounting/AccCoaController', - 'accounting/AccCreateGLAccountContoller', - 'accounting/AccViewGLAccountContoller', - 'accounting/AccEditGLAccountController', - 'accounting/ViewTransactionController', - 'accounting/JournalEntryController', - 'accounting/SearchTransactionController', - 'accounting/AccountingClosureController', - 'accounting/ViewAccountingClosureController', - 'accounting/AccountingRuleController', - 'accounting/AccCreateRuleController', - 'accounting/AccEditRuleController', - 'accounting/ViewAccRuleController', - 'system/CodeController', - 'system/EditCodeController', - 'system/ViewCodeController', - 'system/AddCodeController', - 'system/ViewDataTableController', - 'system/DataTableController', - 'system/ReportsController', - 'system/ViewReportController', - 'system/CreateReportController', - 'system/EditReportController', - 'system/CreateDataTableController', - 'system/EditDataTableController', - 'system/MakeDataTableEntryController', - 'system/DataTableEntryController', - 'system/SchedulerJobsController', - 'system/ViewSchedulerJobController', - 'system/EditSchedulerJobController', - 'system/ViewSchedulerJobHistoryController', - 'organization/HolController', - 'organization/ViewHolController', - 'organization/EditHolidayController', - 'organization/AddHolController', - 'reports/ViewReportsController', - 'reports/RunReportsController', - 'reports/XBRLController', - 'reports/XBRLReportController', - 'savings/CreateSavingAccountController', - 'savings/ViewSavingDetailsController', - 'private/SuperuserController', - 'groups/GroupController', - 'groups/ViewGroupController', - 'groups/AttachMeetingController', - 'groups/EditMeetingController', - 'savings/EditSavingAccountController', - 'savings/SavingAccountActionsController', - 'accounttransfers/ViewAccountTransferDetailsController', - 'accounttransfers/MakeAccountTransferController', - 'savings/ViewSavingsTransactionController', - 'savings/AddNewSavingsChargeController', - 'groups/CreateGroupController', - 'groups/AddMemberController', - 'groups/EditGroupController', - 'groups/GroupAttendanceController', - 'groups/CloseGroupController', - 'groups/AddRoleController', - 'groups/MemberManageController', - 'groups/TransferClientsController', - 'centers/CenterController', - 'centers/ViewCenterController', - 'centers/CreateCenterController', - 'centers/EditCenterController', - 'centers/CloseCenterController', - 'centers/AddGroupController', - 'centers/CenterAttendanceController', - 'product/CreateChargeController', - 'product/EditChargeController', - 'configurations/GlobalConfigurationController', - 'product/productmix/ProductMixController', - 'product/productmix/ViewProductMixController', - 'product/productmix/AddProductMixController', - 'organization/BulkLoanReassignmentController', - 'system/AuditController', - 'system/ViewAuditController', - 'template/TemplateController', - 'template/CreateTemplateController', - 'template/ViewTemplateController', - 'template/EditTemplateController', - 'loanAccount/GuarantorController', - 'loanAccount/EditGuarantorController', - 'main/ViewCheckerinboxController', - 'main/ExpertSearchController', - 'main/ProfileController', - 'main/ViewMakerCheckerTaskController' - ], - filters: [ - 'StatusLookup', - 'DateFormat', - 'DayMonthFormat', - 'YesOrNo', - 'UrlToString', - 'sort', - 'DotRemove', - ], - directives: [ - 'DialogDirective', - 'PanelDirective', - 'BigPanelDirective', - 'OnBlurDirective', - 'LateValidateDirective', - 'TreeviewDirective', - 'CkEditorDirective', - 'AutofocusDirective', - 'SummaryDirective', - 'FormValidateDirective', - 'FormSubmitValidateDirective', - 'ApiValidationDirective', - 'ActivitiesDisplayPanelDirective', - 'ScrollbarTopDirective', - 'ChosenComboboxDirective' - ] - }; +define(['underscore', 'mifosX'], function () { + var components = { + models: [ + 'ClientStatus', + 'LoggedInUser', + 'roleMap', + 'Langs' + ], + services: [ + 'ResourceFactoryProvider', + 'HttpServiceProvider', + 'AuthenticationService', + 'SessionManager', + 'Paginator' + ], + controllers: [ + 'main/MainController', + 'main/LoginFormController', + 'main/TaskController', + 'main/SearchController', + 'main/NavigationController', + 'collection/CollectionSheetController', + 'loanAccount/ViewLoanDetailsController', + 'loanAccount/NewLoanAccAppController', + 'loanAccount/LoanAccountActionsController', + 'loanAccount/AddLoanChargeController', + 'loanAccount/AddLoanCollateralController', + 'loanAccount/AssignLoanOfficerController', + 'loanAccount/EditLoanAccAppController', + 'loanAccount/ViewLoanCollateralController', + 'loanAccount/EditLoanCollateralController', + 'loanAccount/ViewLoanChargeController', + 'loanAccount/EditLoanChargeController', + 'loanAccount/NewJLGLoanAccAppController', + 'loanAccount/LoanDocumentController', + 'loanAccount/ViewLoanTransactionController', + 'loanAccount/LoanScreenReportController', + 'groups/AssignStaffController', + 'client/ClientController', + 'client/EditClientController', + 'client/ViewClientController', + 'client/CreateClientController', + 'client/TransactionClientController', + 'client/ClientActionsController', + 'client/ClientDocumentController', + 'client/ClientIdentifierController', + 'client/UploadClientIdentifierDocumentController', + 'client/ClientScreenReportController', + 'product/LoanProductController', + 'product/CreateLoanProductController', + 'product/CreateSavingProductController', + 'product/EditSavingProductController', + 'product/EditLoanProductController', + 'product/ChargeController', + 'product/ViewChargeController', + 'product/SavingProductController', + 'product/ViewSavingProductController', + 'product/ViewLoanProductController', + 'user/UserController', + 'user/UserFormController', + 'user/UserSettingController', + 'user/UserListController', + 'user/ViewUserController', + 'organization/RoleController', + 'organization/ViewRoleController', + 'organization/CreateRoleController', + 'organization/MakerCheckerController', + 'organization/OfficesController', + 'organization/ViewOfficeController', + 'organization/CreateOfficeController', + 'organization/EditOfficeController', + 'organization/CurrencyConfigController', + 'organization/CreateUserController', + 'organization/EditUserController', + 'organization/ViewEmployeeController', + 'organization/EditEmployeeController', + 'organization/EmployeeController', + 'organization/CreateEmployeeController', + 'organization/ManageFundsController', + 'accounting/AccFreqPostingController', + 'accounting/AccCoaController', + 'accounting/AccCreateGLAccountContoller', + 'accounting/AccViewGLAccountContoller', + 'accounting/AccEditGLAccountController', + 'accounting/ViewTransactionController', + 'accounting/JournalEntryController', + 'accounting/SearchTransactionController', + 'accounting/AccountingClosureController', + 'accounting/ViewAccountingClosureController', + 'accounting/AccountingRuleController', + 'accounting/AccCreateRuleController', + 'accounting/AccEditRuleController', + 'accounting/ViewAccRuleController', + 'system/CodeController', + 'system/EditCodeController', + 'system/ViewCodeController', + 'system/AddCodeController', + 'system/ViewDataTableController', + 'system/DataTableController', + 'system/ReportsController', + 'system/ViewReportController', + 'system/CreateReportController', + 'system/EditReportController', + 'system/CreateDataTableController', + 'system/EditDataTableController', + 'system/MakeDataTableEntryController', + 'system/DataTableEntryController', + 'system/SchedulerJobsController', + 'system/ViewSchedulerJobController', + 'system/EditSchedulerJobController', + 'system/ViewSchedulerJobHistoryController', + 'organization/HolController', + 'organization/ViewHolController', + 'organization/EditHolidayController', + 'organization/AddHolController', + 'reports/ViewReportsController', + 'reports/RunReportsController', + 'reports/XBRLController', + 'reports/XBRLReportController', + 'savings/CreateSavingAccountController', + 'savings/ViewSavingDetailsController', + 'private/SuperuserController', + 'groups/GroupController', + 'groups/ViewGroupController', + 'groups/AttachMeetingController', + 'groups/EditMeetingController', + 'savings/EditSavingAccountController', + 'savings/SavingAccountActionsController', + 'accounttransfers/ViewAccountTransferDetailsController', + 'accounttransfers/MakeAccountTransferController', + 'savings/ViewSavingsTransactionController', + 'savings/AddNewSavingsChargeController', + 'groups/CreateGroupController', + 'groups/AddMemberController', + 'groups/EditGroupController', + 'groups/GroupAttendanceController', + 'groups/CloseGroupController', + 'groups/AddRoleController', + 'groups/MemberManageController', + 'groups/TransferClientsController', + 'centers/CenterController', + 'centers/ViewCenterController', + 'centers/CreateCenterController', + 'centers/EditCenterController', + 'centers/CloseCenterController', + 'centers/AddGroupController', + 'centers/CenterAttendanceController', + 'product/CreateChargeController', + 'product/EditChargeController', + 'configurations/GlobalConfigurationController', + 'product/productmix/ProductMixController', + 'product/productmix/ViewProductMixController', + 'product/productmix/AddProductMixController', + 'organization/BulkLoanReassignmentController', + 'system/AuditController', + 'system/ViewAuditController', + 'template/TemplateController', + 'template/CreateTemplateController', + 'template/ViewTemplateController', + 'template/EditTemplateController', + 'loanAccount/GuarantorController', + 'loanAccount/EditGuarantorController', + 'main/ViewCheckerinboxController', + 'main/ExpertSearchController', + 'main/ProfileController', + 'main/ViewMakerCheckerTaskController' + ], + filters: [ + 'StatusLookup', + 'DateFormat', + 'DayMonthFormat', + 'YesOrNo', + 'UrlToString', + 'sort', + 'DotRemove', + ], + directives: [ + 'DialogDirective', + 'PanelDirective', + 'BigPanelDirective', + 'OnBlurDirective', + 'LateValidateDirective', + 'TreeviewDirective', + 'CkEditorDirective', + 'AutofocusDirective', + 'SummaryDirective', + 'FormValidateDirective', + 'FormSubmitValidateDirective', + 'ApiValidationDirective', + 'ActivitiesDisplayPanelDirective', + 'ScrollbarTopDirective', + 'ChosenComboboxDirective' + ] + }; - require(_.reduce(_.keys(components), function(list, group) { - return list.concat(_.map(components[group], function(name) { return group + "/" + name; })); - }, [ - 'routes', - 'initialTasks', - 'webstorage-configuration' - ])); + require(_.reduce(_.keys(components), function (list, group) { + return list.concat(_.map(components[group], function (name) { + return group + "/" + name; + })); + }, [ + 'routes', + 'initialTasks', + 'webstorage-configuration' + ])); }); diff --git a/app/scripts/models/clientStatus.js b/app/scripts/models/clientStatus.js new file mode 100644 index 00000000..136b874b --- /dev/null +++ b/app/scripts/models/clientStatus.js @@ -0,0 +1,102 @@ +(function (module) { + mifosX.models = _.extend(module, { + ClientStatus: function () { + + this.getStatus = function (status) { + return this.statusTypes[status]; + }; + + this.allStatusTypes = function () { + return Object.keys(this.statusTypes); + }; + + this.statusKnown = function (status) { + return this.allStatusTypes().indexOf(status) > -1; + }; + + this.statusTypes = { + "Pending": [ + { + name: "label.button.edit", + href: "#/editclient", + icon: "icon-edit" + }, + { + name: "label.button.activate", + href: "#/client", + subhref: "activate", + icon: "icon-ok-sign" + }, + { + name: "label.button.close", + href: "#/client", + subhref: "close", + icon: "icon-remove-circle" + } + ], + "Active": [ + { + name: "label.button.edit", + href: "#/editclient", + icon: "icon-edit" + }, + { + name: "label.button.newloan", + href: "#/newclientloanaccount", + icon: "icon-plus" + }, + { + name: "label.button.newsaving", + href: "#/new_client_saving_application", + icon: "icon-plus" + }, + { + name: "label.button.transferclient", + href: "#/transferclient", + icon: "icon-arrow-right" + }, + { + name: "label.button.close", + href: "#/client", + subhref: "close", + icon: "icon-remove-circle" + } + ], + "Transfer in progress": [ + { + name: "label.button.accepttransfer", + href: "#/client", + subhref: "acceptclienttransfer", + icon: "icon-check-sign" + }, + { + name: "label.button.rejecttransfer", + href: "#/client", + subhref: "rejecttransfer", + icon: "icon-remove" + }, + { + name: "label.button.undotransfer", + href: "#/client", + subhref: "undotransfer", + icon: "icon-undo" + } + ], + "Transfer on hold": [ + { + name: "label.button.undotransfer", + href: "#/client", + subhref: "undotransfer", + icon: "icon-undo" + } + ], + "Assign Staff": { + name: "label.button.assignstaff", + href: "#/client", + subhref: "assignstaff", + icon: "icon-user" + } + } + } + }); +}(mifosX.models || {})); \ No newline at end of file diff --git a/test/SpecRunner.html b/test/SpecRunner.html index c2596180..4501cee9 100644 --- a/test/SpecRunner.html +++ b/test/SpecRunner.html @@ -1,92 +1,95 @@ + "http://www.w3.org/TR/html4/loose.dtd"> - Jasmine Spec Runner - + Jasmine Spec Runner + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + })(); + diff --git a/test/spec/controllers/ClientControllerSpec.js b/test/spec/controllers/client/ClientControllerSpec.js similarity index 100% rename from test/spec/controllers/ClientControllerSpec.js rename to test/spec/controllers/client/ClientControllerSpec.js diff --git a/test/spec/controllers/client/ViewClientControllerSpec.js b/test/spec/controllers/client/ViewClientControllerSpec.js new file mode 100644 index 00000000..7ad1509c --- /dev/null +++ b/test/spec/controllers/client/ViewClientControllerSpec.js @@ -0,0 +1,79 @@ +describe("ViewClientController", function () { + var clientResourceCallback, clientAccountResourceCallback, clientNotesResourceCallback, dataTablesResourceCallback, + runReportsResourceCallback; + var statusTypes = ["Active", "Pending", "Transfer in progress", "Transfer on hold"]; + + beforeEach(function () { + + this.scope = {}; + + this.resourceFactory = { + + clientResource: { + get: jasmine.createSpy('clientResource.get()').andCallFake(function (query, callback) { + clientResourceCallback = callback; + }) + }, + clientAccountResource: { + get: jasmine.createSpy('clientAccountResource.get()').andCallFake(function (callback) { + clientAccountResourceCallback = callback; + }) + }, + clientNotesResource: { + getAllNotes: jasmine.createSpy('clientNotesResource.getAllNotes()').andCallFake(function (callback) { + clientNotesResourceCallback = callback; + }) + }, + DataTablesResource: { + getAllDataTables: jasmine.createSpy('DataTablesResource.getAllDataTables()').andCallFake(function (callback) { + dataTablesResourceCallback = callback; + }) + }, + runReportsResource: { + get: jasmine.createSpy('runReportsResource.get()').andCallFake(function (callback) { + runReportsResourceCallback = callback; + }) + } + }; + + this.routeParams = jasmine.createSpy(); + this.route = jasmine.createSpy(); + this.location = jasmine.createSpyObj("location", ["path"]); + this.http = jasmine.createSpy(); + this.modal = jasmine.createSpy(); + this.API_VERSION = jasmine.createSpy(); + this.rooteScope = jasmine.createSpy(); + this.upload = jasmine.createSpy(); + + this.controller = new mifosX.controllers.ViewClientController(this.scope, + this.routeParams, + this.route, + this.location, + this.resourceFactory, + this.http, + this.modal, + this.API_VERSION, + this.rootScope, + this.upload); + }); + + statusTypes.forEach(function (clientStatus) { + + it("should set the value of scope buttons based on the status of the client", function () { + + clientResourceCallback({status: {value: clientStatus} }); + var expectedPendingButtons = new mifosX.models.ClientStatus().getStatus(clientStatus); + + expect(this.scope.buttons[0]).toEqual(expectedPendingButtons[0]); + expect(this.scope.buttons[1]).toEqual(expectedPendingButtons[1]); + }); + }); + + it("should add to the scope a button that assigns staff if the status of the client is active or pending", function () { + clientResourceCallback({status: {value: "Transfer on hold"} }); + var expectedPendingButtons = new mifosX.models.ClientStatus().getStatus("Transfer on hold"); + + expect(this.scope.buttons[0]).toEqual(expectedPendingButtons[0]); + expect(this.scope.buttons[1]).toEqual(expectedPendingButtons[1]); + }); +}); \ No newline at end of file diff --git a/test/spec/models/ClientStatusSpec.js b/test/spec/models/ClientStatusSpec.js new file mode 100644 index 00000000..cf26eff2 --- /dev/null +++ b/test/spec/models/ClientStatusSpec.js @@ -0,0 +1,47 @@ +describe("ClientStatus", function () { + + it("should assign the correct information for a pending status", function () { + var clientStatus = new mifosX.models.ClientStatus(); + var pendingStatus = clientStatus.statusTypes["Pending"]; + + expect(clientStatus.getStatus("Pending")).toEqual(pendingStatus); + + }); + + it("should assign the correct information for an active status", function () { + var clientStatus = new mifosX.models.ClientStatus(); + var activeStatus = clientStatus.statusTypes["Active"]; + + expect(clientStatus.getStatus("Active")).toEqual(activeStatus); + + }); + + it("should assign the correct information for a status that is a transfer in progress", function () { + var clientStatus = new mifosX.models.ClientStatus(); + var transferInProgressStatus = clientStatus.statusTypes["Transfer in progress"]; + + expect(clientStatus.getStatus("Transfer in progress")).toEqual(transferInProgressStatus); + + }); + + it("should assign the correct information for a status that is a transfer on hold", function () { + var clientStatus = new mifosX.models.ClientStatus(); + var transferOnHoldStatus = clientStatus.statusTypes["Transfer on hold"]; + + expect(clientStatus.getStatus("Transfer on hold")).toEqual(transferOnHoldStatus); + }); + + describe("testing if a status is known", function () { + it("should return true if statusTypes includes given status", function () { + var clientStatus = new mifosX.models.ClientStatus(); + + expect(clientStatus.statusKnown("Active")).toEqual(true); + }); + + it("should return false if statusTypes does not include a given status", function () { + var clientStatus = new mifosX.models.ClientStatus(); + + expect(clientStatus.statusKnown("Not included status")).toEqual(false); + }); + }); +}); \ No newline at end of file