From 28e154847508dd63b0fef46c72ca91714463a8e2 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Wed, 13 Feb 2013 14:06:55 +0000 Subject: [PATCH] WIP: submit and modify loan application. support for loan purpose, loan collateral, loan fees. Restrict modification of loan application details to be only allowed in 'submitted and pending approval' state which is first improved required to reach loan and cash based accounting integration. --- .../0001a-mifosplatform-core-ddl-latest.sql | 16 + .../0002-mifosng-base-reference-data.sql | 45 ++- .../bare-bones-demo/bk_bare_bones_demo.sql | 136 +++----- .../ceda/bk_ceda_trial.sql | 152 +++------ .../ceda/bk_core_with_custom_and_coa.sql | 136 +++----- .../ceda/ceda-schema-customisations.sql | 177 +++++++--- .../ceda/ceda-user-office-product-setup.sql | 3 + .../default-demo/bk_mifostenant-default.sql | 53 ++- .../extra-datatables-and-code-values.sql | 64 +++- ...-loanpurpose-add-loan-collateral-table.sql | 18 + mifosng-provider/build.gradle | 1 + .../codes/data/CodeValueData.java | 4 + .../codes/domain/CodeValue.java | 4 + .../domain/CodeValueRepositoryWrapper.java | 34 ++ .../service/CodeValueReadPlatformService.java | 25 +- .../CodeValueReadPlatformServiceImpl.java | 12 +- .../core/data/DataValidatorBuilder.java | 48 ++- .../core/serialization/FromJsonHelper.java | 39 ++- .../LoanChargeNotFoundException.java | 12 +- .../LoanCollateralNotFoundException.java | 20 ++ .../api/ClientIdentifiersApiResource.java | 5 +- ...WritePlatformServiceJpaRepositoryImpl.java | 14 +- .../loanaccount/api/LoansApiResource.java | 104 ++++-- .../command/LoanChargeCommand.java | 31 +- .../loanaccount/data/LoanAccountData.java | 145 ++++++--- .../data/LoanBasicDetailsData.java | 37 ++- .../loanaccount/data/LoanCollateralData.java | 26 ++ .../portfolio/loanaccount/domain/Loan.java | 307 ++++++++++++------ .../loanaccount/domain/LoanCharge.java | 42 ++- .../loanaccount/domain/LoanCollateral.java | 106 ++++++ .../domain/LoanCollateralRepository.java | 8 + .../domain/LoanScheduleWrapper.java | 12 +- ...ndPendingApprovalStateCannotBeDeleted.java | 16 + ...dPendingApprovalStateCannotBeModified.java | 16 + ...ndPendingApprovalStateCannotBeDeleted.java | 15 - ...entsAmortizationLoanScheduleGenerator.java | 4 +- .../FlatMethodLoanScheduleGenerator.java | 4 +- ...ateLoanScheduleQueryFromApiJsonHelper.java | 125 ++++--- ...anApplicationCommandFromApiJsonHelper.java | 209 ++++++++---- ...nChargeCommandFromApiJsonDeserializer.java | 7 +- ...WritePlatformServiceJpaRepositoryImpl.java | 65 +++- .../loanaccount/service/LoanAssembler.java | 46 ++- .../service/LoanChargeAssembler.java | 3 - .../service/LoanCollateralAssembler.java | 71 ++++ .../LoanCollateralReadPlatformService.java | 10 + ...LoanCollateralReadPlatformServiceImpl.java | 63 ++++ .../service/LoanReadPlatformServiceImpl.java | 29 +- ...WritePlatformServiceJpaRepositoryImpl.java | 58 ++-- 48 files changed, 1732 insertions(+), 845 deletions(-) create mode 100644 mifosng-db/patches/06-alter-loan-add-loanpurpose-add-loan-collateral-table.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepositoryWrapper.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanCollateralNotFoundException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanCollateralData.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateral.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateralRepository.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified.java delete mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralAssembler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformServiceImpl.java diff --git a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql b/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql index 3ca4caf92..c754f4ecd 100644 --- a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql +++ b/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql @@ -26,6 +26,7 @@ DROP TABLE IF EXISTS `m_group_client`; DROP TABLE IF EXISTS `m_guarantor`; DROP TABLE IF EXISTS `m_loan`; DROP TABLE IF EXISTS `m_loan_charge`; +DROP TABLE IF EXISTS `m_loan_collateral`; DROP TABLE IF EXISTS `m_loan_officer_assignment_history`; DROP TABLE IF EXISTS `m_loan_repayment_schedule`; DROP TABLE IF EXISTS `m_loan_transaction`; @@ -501,6 +502,7 @@ CREATE TABLE `m_loan` ( `fund_id` bigint(20) DEFAULT NULL, `loan_officer_id` bigint(20) DEFAULT NULL, `guarantor_id` bigint(20) DEFAULT NULL, + `loanpurpose_cv_id` INT(11) DEFAULT NULL, `loan_status_id` smallint(5) NOT NULL, `currency_code` varchar(3) NOT NULL, `currency_digits` smallint(5) NOT NULL, @@ -544,12 +546,14 @@ CREATE TABLE `m_loan` ( KEY `FK7C885877240145` (`fund_id`), KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), KEY `FK_m_loan_m_staff` (`loan_officer_id`), + KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), KEY `group_id` (`group_id`), CONSTRAINT `FK7C885877240145` FOREIGN KEY (`fund_id`) REFERENCES `m_fund` (`id`), CONSTRAINT `FKB6F935D87179A0CB` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`), CONSTRAINT `FKB6F935D8C8D4B434` FOREIGN KEY (`product_id`) REFERENCES `m_product_loan` (`id`), CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`), CONSTRAINT `FK_m_loan_m_staff` FOREIGN KEY (`loan_officer_id`) REFERENCES `m_staff` (`id`), + CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `m_loan_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -602,6 +606,18 @@ CREATE TABLE `m_loan_charge` ( CONSTRAINT `m_loan_charge_ibfk_2` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `m_loan_officer_assignment_history` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `loan_id` bigint(20) NOT NULL, diff --git a/mifosng-db/0002-mifosng-base-reference-data.sql b/mifosng-db/0002-mifosng-base-reference-data.sql index 9499dd940..979c405cf 100644 --- a/mifosng-db/0002-mifosng-base-reference-data.sql +++ b/mifosng-db/0002-mifosng-base-reference-data.sql @@ -202,14 +202,6 @@ VALUES INSERT INTO `m_organisation_currency` (`id`, `code`, `decimal_places`, `name`, `display_symbol`, `internationalized_name_code`) VALUES (21,'USD',2,'US Dollar','$','currency.USD'); --- create single code and code value for client identifiers -INSERT INTO `m_code` -(`id`,`code_name`, `is_system_defined`) VALUES (1,'Customer Identifier',1); - -INSERT INTO `m_code_value` -(`id`,`code_id`,`code_value`,`order_position`) -VALUES (1,1,'Passport number',0); - INSERT INTO `m_office` (`id`, `parent_id`, `hierarchy`, `external_id`, `name`, `opening_date`) VALUES (1,NULL,'.','1','Head Office','2009-01-01'); @@ -520,4 +512,39 @@ from x_registered_table r; insert into m_permission(grouping, `code`, entity_name, action_name) select 'datatable', concat('DELETE_', r.registered_table_name), r.registered_table_name, 'DELETE' -from x_registered_table r; \ No newline at end of file +from x_registered_table r; + + +-- create single code and code value for client identifiers +INSERT INTO `m_code` +(`code_name`, `is_system_defined`) +VALUES +('Customer Identifier',1), +('LoanCollateral',1), +('LoanPurpose',1), +('Gender',1), +('YesNo',1); + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Passport', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Customer Identifier"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Id', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Customer Identifier"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Drivers License', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Customer Identifier"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Any Other Id Type', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Customer Identifier"; \ No newline at end of file diff --git a/mifosng-db/multi-tenant-demo-backups/bare-bones-demo/bk_bare_bones_demo.sql b/mifosng-db/multi-tenant-demo-backups/bare-bones-demo/bk_bare_bones_demo.sql index bda187f8d..1cc950e26 100644 --- a/mifosng-db/multi-tenant-demo-backups/bare-bones-demo/bk_bare_bones_demo.sql +++ b/mifosng-db/multi-tenant-demo-backups/bare-bones-demo/bk_bare_bones_demo.sql @@ -184,96 +184,6 @@ INSERT INTO `c_configuration` VALUES (1,'maker-checker',0); /*!40000 ALTER TABLE `c_configuration` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `extra_client_details` --- - -DROP TABLE IF EXISTS `extra_client_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_client_details` ( - `client_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`client_id`), - CONSTRAINT `FK_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_client_details` --- - -LOCK TABLES `extra_client_details` WRITE; -/*!40000 ALTER TABLE `extra_client_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_client_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_family_details` --- - -DROP TABLE IF EXISTS `extra_family_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_family_details` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `client_id` bigint(20) NOT NULL, - `Name` varchar(40) DEFAULT NULL, - `Date of Birth` date DEFAULT NULL, - `Points Score` int(11) DEFAULT NULL, - `Education_cd_Highest` int(11) DEFAULT NULL, - `Other Notes` text, - PRIMARY KEY (`id`), - KEY `FK_Extra Family Details Data_1` (`client_id`), - CONSTRAINT `FK_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_family_details` --- - -LOCK TABLES `extra_family_details` WRITE; -/*!40000 ALTER TABLE `extra_family_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_family_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_loan_details` --- - -DROP TABLE IF EXISTS `extra_loan_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_loan_details` ( - `loan_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`loan_id`), - CONSTRAINT `FK_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_loan_details` --- - -LOCK TABLES `extra_loan_details` WRITE; -/*!40000 ALTER TABLE `extra_loan_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_loan_details` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `m_appuser` -- @@ -458,7 +368,7 @@ CREATE TABLE `m_code` ( `is_system_defined` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `code_name` (`code_name`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -467,7 +377,7 @@ CREATE TABLE `m_code` ( LOCK TABLES `m_code` WRITE; /*!40000 ALTER TABLE `m_code` DISABLE KEYS */; -INSERT INTO `m_code` VALUES (1,'Customer Identifier',1); +INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'LoanCollateral',1),(3,'LoanPurpose',1),(4,'Gender',1),(5,'YesNo',1); /*!40000 ALTER TABLE `m_code` ENABLE KEYS */; UNLOCK TABLES; @@ -487,7 +397,7 @@ CREATE TABLE `m_code_value` ( UNIQUE KEY `code_value` (`code_id`,`code_value`), KEY `FKCFCEA42640BE071Z` (`code_id`), CONSTRAINT `FKCFCEA42640BE071Z` FOREIGN KEY (`code_id`) REFERENCES `m_code` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -496,7 +406,7 @@ CREATE TABLE `m_code_value` ( LOCK TABLES `m_code_value` WRITE; /*!40000 ALTER TABLE `m_code_value` DISABLE KEYS */; -INSERT INTO `m_code_value` VALUES (1,1,'Passport number',0); +INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',1),(3,1,'Drivers License',2),(4,1,'Any Other Id Type',3); /*!40000 ALTER TABLE `m_code_value` ENABLE KEYS */; UNLOCK TABLES; @@ -799,6 +709,7 @@ CREATE TABLE `m_loan` ( `fund_id` bigint(20) DEFAULT NULL, `loan_officer_id` bigint(20) DEFAULT NULL, `guarantor_id` bigint(20) DEFAULT NULL, + `loanpurpose_cv_id` int(11) DEFAULT NULL, `loan_status_id` smallint(5) NOT NULL, `currency_code` varchar(3) NOT NULL, `currency_digits` smallint(5) NOT NULL, @@ -842,6 +753,7 @@ CREATE TABLE `m_loan` ( KEY `FK7C885877240145` (`fund_id`), KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), KEY `FK_m_loan_m_staff` (`loan_officer_id`), + KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), KEY `group_id` (`group_id`), KEY `FK_m_loan_guarantor` (`guarantor_id`), CONSTRAINT `FK_m_loan_guarantor` FOREIGN KEY (`guarantor_id`) REFERENCES `m_guarantor` (`id`), @@ -849,6 +761,7 @@ CREATE TABLE `m_loan` ( CONSTRAINT `FKB6F935D87179A0CB` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`), CONSTRAINT `FKB6F935D8C8D4B434` FOREIGN KEY (`product_id`) REFERENCES `m_product_loan` (`id`), CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`), + CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `FK_m_loan_m_staff` FOREIGN KEY (`loan_officer_id`) REFERENCES `m_staff` (`id`), CONSTRAINT `m_loan_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -903,6 +816,35 @@ LOCK TABLES `m_loan_charge` WRITE; /*!40000 ALTER TABLE `m_loan_charge` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `m_loan_collateral` +-- + +DROP TABLE IF EXISTS `m_loan_collateral`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `m_loan_collateral` +-- + +LOCK TABLES `m_loan_collateral` WRITE; +/*!40000 ALTER TABLE `m_loan_collateral` DISABLE KEYS */; +/*!40000 ALTER TABLE `m_loan_collateral` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `m_loan_officer_assignment_history` -- @@ -1189,7 +1131,7 @@ CREATE TABLE `m_permission` ( LOCK TABLES `m_permission` WRITE; /*!40000 ALTER TABLE `m_permission` DISABLE KEYS */; -INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance \n\nSheet','Balance \n\nSheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds \n\nDisbursed Between Dates Summary','Funds \n\nDisbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans \n\nAwaiting Disbursal','Loans \n\nAwaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial \n\nBalance','Trial \n\nBalance','READ',1); +INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance Sheet','Balance Sheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds Disbursed Between Dates Summary','Funds Disbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans Awaiting Disbursal','Loans Awaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial Balance','Trial Balance','READ',1); /*!40000 ALTER TABLE `m_permission` ENABLE KEYS */; UNLOCK TABLES; @@ -1784,7 +1726,7 @@ CREATE TABLE `stretchy_report` ( LOCK TABLES `stretchy_report` WRITE; /*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */; -INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans \n\nAwaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\n\n\nl.account_no as \"Loan Account No.\", pl.`name` as \"Product\", f.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\n\n\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office \n\nounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = \n\nounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join \n\nm_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-\n\n1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \n\n\"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, \n\nl.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\", ifnull(cur.display_symbol, \n\nl.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(\r\n if\n\n(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n \n\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal \n\nRepaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \n\n\"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest Outstanding\",\r\nsum(if(r.duedate \n\n<= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round(\r\n \n\n(sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum\n\n(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on \n\nr.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by \n\nounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull\n\n(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if\n\n(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n \r\n \n\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n \n\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\n\n\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\n\n\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency \n\ncur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule \n\nr on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \n\n\"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \n\n\"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by \n\nl.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring\n\n(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\n \n\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, \n\n0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \n\n\"Principal Overdue\",\r\n \r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , \n\n2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\n\n\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\n\n\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join \n\nm_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived \n\nis false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-\n\n1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} \n\nor -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds \n\nDisbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum\n\n(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin \n\nm_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand \n\n(ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull\n\n(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance \n\nSheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial \n\nBalance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); +INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans Awaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", \r\nc.display_name as \"Name\", l.account_no as \"Loan Account No.\", pl.`name` as \"Product\", \r\nf.`name` as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, l.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(if(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal Repaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest utstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round((sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0)) , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0)), 2) as char) \r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds Disbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nround(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance Sheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial Balance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); /*!40000 ALTER TABLE `stretchy_report` ENABLE KEYS */; UNLOCK TABLES; @@ -1846,4 +1788,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2013-02-07 15:16:53 +-- Dump completed on 2013-02-13 14:05:05 diff --git a/mifosng-db/multi-tenant-demo-backups/ceda/bk_ceda_trial.sql b/mifosng-db/multi-tenant-demo-backups/ceda/bk_ceda_trial.sql index 255184d15..b6999de24 100644 --- a/mifosng-db/multi-tenant-demo-backups/ceda/bk_ceda_trial.sql +++ b/mifosng-db/multi-tenant-demo-backups/ceda/bk_ceda_trial.sql @@ -1,6 +1,6 @@ -- MySQL dump 10.13 Distrib 5.1.60, for Win32 (ia32) -- --- Host: localhost Database: mifostenant-default +-- Host: localhost Database: mifostenant-ceda -- ------------------------------------------------------ -- Server version 5.1.60-community @@ -246,96 +246,6 @@ LOCK TABLES `client additional data` WRITE; /*!40000 ALTER TABLE `client additional data` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `extra_client_details` --- - -DROP TABLE IF EXISTS `extra_client_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_client_details` ( - `client_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`client_id`), - CONSTRAINT `FK_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_client_details` --- - -LOCK TABLES `extra_client_details` WRITE; -/*!40000 ALTER TABLE `extra_client_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_client_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_family_details` --- - -DROP TABLE IF EXISTS `extra_family_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_family_details` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `client_id` bigint(20) NOT NULL, - `Name` varchar(40) DEFAULT NULL, - `Date of Birth` date DEFAULT NULL, - `Points Score` int(11) DEFAULT NULL, - `Education_cd_Highest` int(11) DEFAULT NULL, - `Other Notes` text, - PRIMARY KEY (`id`), - KEY `FK_Extra Family Details Data_1` (`client_id`), - CONSTRAINT `FK_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_family_details` --- - -LOCK TABLES `extra_family_details` WRITE; -/*!40000 ALTER TABLE `extra_family_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_family_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_loan_details` --- - -DROP TABLE IF EXISTS `extra_loan_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_loan_details` ( - `loan_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`loan_id`), - CONSTRAINT `FK_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_loan_details` --- - -LOCK TABLES `extra_loan_details` WRITE; -/*!40000 ALTER TABLE `extra_loan_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_loan_details` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `impact measurement` -- @@ -459,7 +369,7 @@ CREATE TABLE `m_appuser_role` ( LOCK TABLES `m_appuser_role` WRITE; /*!40000 ALTER TABLE `m_appuser_role` DISABLE KEYS */; -INSERT INTO `m_appuser_role` VALUES (1,1); +INSERT INTO `m_appuser_role` VALUES (1,1),(2,1); /*!40000 ALTER TABLE `m_appuser_role` ENABLE KEYS */; UNLOCK TABLES; @@ -521,7 +431,7 @@ CREATE TABLE `m_client` ( UNIQUE KEY `external_id` (`external_id`), KEY `FKCE00CAB3E0DD567A` (`office_id`), CONSTRAINT `FKCE00CAB3E0DD567A` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -530,6 +440,7 @@ CREATE TABLE `m_client` ( LOCK TABLES `m_client` WRITE; /*!40000 ALTER TABLE `m_client` DISABLE KEYS */; +INSERT INTO `m_client` VALUES (1,'000000001',2,NULL,'Kampala',NULL,'Client1',NULL,'Kampala Client1',NULL,'2011-02-13',0); /*!40000 ALTER TABLE `m_client` ENABLE KEYS */; UNLOCK TABLES; @@ -591,7 +502,7 @@ CREATE TABLE `m_code` ( LOCK TABLES `m_code` WRITE; /*!40000 ALTER TABLE `m_code` DISABLE KEYS */; -INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'Gender',0),(3,'YesNo',0),(4,'FieldOfEmployment',0),(5,'EducationLevel',0),(6,'MaritalStatus',0),(7,'PovertyStatus',0),(8,'PurposeOfLoan',0),(9,'CollateralType',0); +INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'LoanCollateral',1),(3,'LoanPurpose',1),(4,'Gender',1),(5,'YesNo',1),(6,'FieldOfEmployment',0),(7,'EducationLevel',0),(8,'MaritalStatus',0),(9,'PovertyStatus',0); /*!40000 ALTER TABLE `m_code` ENABLE KEYS */; UNLOCK TABLES; @@ -620,7 +531,7 @@ CREATE TABLE `m_code_value` ( LOCK TABLES `m_code_value` WRITE; /*!40000 ALTER TABLE `m_code_value` DISABLE KEYS */; -INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',2),(3,1,'Drivers License',3),(4,1,'Any Other Id Type',4),(5,2,'gender.Male',1),(6,2,'gender.Female',2),(7,3,'option.Yes',1),(8,3,'option.No',2),(9,4,'option.Banker',1),(10,4,'option.SoftwareDeveloper',2),(11,5,'option.University',1),(12,5,'option.Secondary',2),(13,5,'option.Primary',3),(14,6,'option.Married',1),(15,6,'option.Single',2),(16,6,'option.Divorced',3),(17,6,'option.Widow',4),(18,7,'option.PovertyStatus.Band1',1),(19,7,'option.PovertyStatus.Band2',2),(20,7,'option.PovertyStatus.Band3',3),(21,8,'option.Agriculture',1),(22,8,'option.Manufacturing',2),(23,8,'option.HousingImprovement',3),(24,9,'option.House',1),(25,9,'option.Television',2),(26,9,'option.Gold',3); +INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',1),(3,1,'Drivers License',2),(4,1,'Any Other Id Type',3),(5,6,'option.Banker',1),(6,6,'option.SoftwareDeveloper',5),(7,7,'option.University',1),(8,7,'option.Secondary',7),(9,7,'option.Primary',8),(10,8,'option.Married',1),(11,8,'option.Single',10),(12,8,'option.Divorced',11),(13,8,'option.Widow',12),(14,9,'option.PovertyStatus.Band1',1),(15,9,'option.PovertyStatus.Band2',14),(16,9,'option.PovertyStatus.Band3',15),(17,2,'option.House',1),(18,2,'option.Television',17),(19,2,'option.Gold',18),(20,3,'option.Agriculture',1),(21,3,'option.Manufacturing',20),(22,3,'option.HousingImprovement',21),(23,4,'option.Male',1),(24,4,'option.Female',23),(25,5,'option.Yes',1),(26,5,'option.No',25); /*!40000 ALTER TABLE `m_code_value` ENABLE KEYS */; UNLOCK TABLES; @@ -923,6 +834,7 @@ CREATE TABLE `m_loan` ( `fund_id` bigint(20) DEFAULT NULL, `loan_officer_id` bigint(20) DEFAULT NULL, `guarantor_id` bigint(20) DEFAULT NULL, + `loanpurpose_cv_id` int(11) DEFAULT NULL, `loan_status_id` smallint(5) NOT NULL, `currency_code` varchar(3) NOT NULL, `currency_digits` smallint(5) NOT NULL, @@ -966,6 +878,7 @@ CREATE TABLE `m_loan` ( KEY `FK7C885877240145` (`fund_id`), KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), KEY `FK_m_loan_m_staff` (`loan_officer_id`), + KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), KEY `group_id` (`group_id`), KEY `FK_m_loan_guarantor` (`guarantor_id`), CONSTRAINT `FK_m_loan_guarantor` FOREIGN KEY (`guarantor_id`) REFERENCES `m_guarantor` (`id`), @@ -973,9 +886,10 @@ CREATE TABLE `m_loan` ( CONSTRAINT `FKB6F935D87179A0CB` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`), CONSTRAINT `FKB6F935D8C8D4B434` FOREIGN KEY (`product_id`) REFERENCES `m_product_loan` (`id`), CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`), + CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `FK_m_loan_m_staff` FOREIGN KEY (`loan_officer_id`) REFERENCES `m_staff` (`id`), CONSTRAINT `m_loan_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -984,6 +898,7 @@ CREATE TABLE `m_loan` ( LOCK TABLES `m_loan` WRITE; /*!40000 ALTER TABLE `m_loan` DISABLE KEYS */; +INSERT INTO `m_loan` VALUES (1,'000000001',NULL,1,NULL,1,NULL,2,NULL,21,100,'UGX',2,'1000000.000000',NULL,'24.000000',3,'24.000000',1,1,12,2,1,2,12,1,'0.000000','2011-02-16 00:00:00',NULL,'2011-02-21',NULL,NULL,NULL,'2012-02-21',NULL,NULL,NULL,NULL,NULL,NULL,1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,2); /*!40000 ALTER TABLE `m_loan` ENABLE KEYS */; UNLOCK TABLES; @@ -1015,7 +930,7 @@ CREATE TABLE `m_loan_charge` ( KEY `m_loan_charge_ibfk_2` (`loan_id`), CONSTRAINT `m_loan_charge_ibfk_1` FOREIGN KEY (`charge_id`) REFERENCES `m_charge` (`id`), CONSTRAINT `m_loan_charge_ibfk_2` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1024,9 +939,40 @@ CREATE TABLE `m_loan_charge` ( LOCK TABLES `m_loan_charge` WRITE; /*!40000 ALTER TABLE `m_loan_charge` DISABLE KEYS */; +INSERT INTO `m_loan_charge` VALUES (1,1,1,0,2,'2011-09-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(2,1,1,0,2,'2011-08-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(3,1,1,0,2,'2011-03-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(4,1,1,0,2,'2012-01-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(5,1,1,0,2,'2011-10-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(6,1,1,0,2,'2012-02-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(7,1,1,0,2,'2011-07-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(8,1,1,0,2,'2011-12-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(9,1,1,0,2,'2011-11-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(10,1,1,0,2,'2011-06-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(11,1,1,0,2,'2011-05-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0),(12,1,1,0,2,'2011-04-21',1,NULL,NULL,'1500.000000','0.000000',NULL,NULL,'1500.000000',0); /*!40000 ALTER TABLE `m_loan_charge` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `m_loan_collateral` +-- + +DROP TABLE IF EXISTS `m_loan_collateral`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `m_loan_collateral` +-- + +LOCK TABLES `m_loan_collateral` WRITE; +/*!40000 ALTER TABLE `m_loan_collateral` DISABLE KEYS */; +INSERT INTO `m_loan_collateral` VALUES (1,1,17,' house valued at y'),(2,1,19,' some gold jewellery'),(3,1,18,' small tv worth x'); +/*!40000 ALTER TABLE `m_loan_collateral` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `m_loan_officer_assignment_history` -- @@ -1097,7 +1043,7 @@ CREATE TABLE `m_loan_repayment_schedule` ( PRIMARY KEY (`id`), KEY `FK488B92AA40BE0710` (`loan_id`), CONSTRAINT `FK488B92AA40BE0710` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1106,6 +1052,7 @@ CREATE TABLE `m_loan_repayment_schedule` ( LOCK TABLES `m_loan_repayment_schedule` WRITE; /*!40000 ALTER TABLE `m_loan_repayment_schedule` DISABLE KEYS */; +INSERT INTO `m_loan_repayment_schedule` VALUES (1,1,'2011-02-21','2011-03-21',1,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(2,1,'2011-03-21','2011-04-21',2,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(3,1,'2011-04-21','2011-05-21',3,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(4,1,'2011-05-21','2011-06-21',4,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(5,1,'2011-06-21','2011-07-21',5,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(6,1,'2011-07-21','2011-08-21',6,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(7,1,'2011-08-21','2011-09-21',7,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(8,1,'2011-09-21','2011-10-21',8,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(9,1,'2011-10-21','2011-11-21',9,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(10,1,'2011-11-21','2011-12-21',10,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(11,1,'2011-12-21','2012-01-21',11,'83333.330000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL),(12,1,'2012-01-21','2012-02-21',12,'83333.370000',NULL,NULL,'20000.000000',NULL,NULL,'1500.000000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'\0',1,'2013-02-13 13:55:38','2013-02-13 13:55:38',1,NULL); /*!40000 ALTER TABLE `m_loan_repayment_schedule` ENABLE KEYS */; UNLOCK TABLES; @@ -1313,7 +1260,7 @@ CREATE TABLE `m_permission` ( LOCK TABLES `m_permission` WRITE; /*!40000 ALTER TABLE `m_permission` DISABLE KEYS */; -INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance \n\nSheet','Balance \n\nSheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds \n\nDisbursed Between Dates Summary','Funds \n\nDisbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans \n\nAwaiting Disbursal','Loans \n\nAwaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial \n\nBalance','Trial \n\nBalance','READ',1),(248,'datatable','CREATE_client additional data','client additional data','CREATE',1),(249,'datatable','CREATE_impact measurement','impact measurement','CREATE',1),(250,'datatable','CREATE_loan additional data','loan additional data','CREATE',1),(251,'datatable','READ_client additional data','client additional data','READ',1),(252,'datatable','READ_impact measurement','impact measurement','READ',1),(253,'datatable','READ_loan additional data','loan additional data','READ',1),(254,'datatable','UPDATE_client additional data','client additional data','UPDATE',1),(255,'datatable','UPDATE_impact measurement','impact measurement','UPDATE',1),(256,'datatable','UPDATE_loan additional data','loan additional data','UPDATE',1),(257,'datatable','DELETE_client additional data','client additional data','DELETE',1),(258,'datatable','DELETE_impact measurement','impact measurement','DELETE',1),(259,'datatable','DELETE_loan additional data','loan additional data','DELETE',1); +INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance Sheet','Balance Sheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds Disbursed Between Dates Summary','Funds Disbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans Awaiting Disbursal','Loans Awaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial Balance','Trial Balance','READ',1),(248,'datatable','CREATE_client additional data','client additional data','CREATE',1),(249,'datatable','CREATE_impact measurement','impact measurement','CREATE',1),(250,'datatable','CREATE_loan additional data','loan additional data','CREATE',1),(251,'datatable','READ_client additional data','client additional data','READ',1),(252,'datatable','READ_impact measurement','impact measurement','READ',1),(253,'datatable','READ_loan additional data','loan additional data','READ',1),(254,'datatable','UPDATE_client additional data','client additional data','UPDATE',1),(255,'datatable','UPDATE_impact measurement','impact measurement','UPDATE',1),(256,'datatable','UPDATE_loan additional data','loan additional data','UPDATE',1),(257,'datatable','DELETE_client additional data','client additional data','DELETE',1),(258,'datatable','DELETE_impact measurement','impact measurement','DELETE',1),(259,'datatable','DELETE_loan additional data','loan additional data','DELETE',1); /*!40000 ALTER TABLE `m_permission` ENABLE KEYS */; UNLOCK TABLES; @@ -1354,7 +1301,7 @@ CREATE TABLE `m_portfolio_command_source` ( KEY `loan_id` (`office_id`), CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`), CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1363,6 +1310,7 @@ CREATE TABLE `m_portfolio_command_source` ( LOCK TABLES `m_portfolio_command_source` WRITE; /*!40000 ALTER TABLE `m_portfolio_command_source` DISABLE KEYS */; +INSERT INTO `m_portfolio_command_source` VALUES (1,'CREATE','CLIENT',2,NULL,1,NULL,'/clients/template',1,'{\"officeId\":\"2\",\"firstname\":\"Kampala\",\"middlename\":\"\",\"lastname\":\"Client1\",\"fullname\":\"\",\"externalId\":\"\",\"dateFormat\":\"yyyy-MM-dd\",\"locale\":\"en\",\"joinedDate\":\"2011-02-13\"}',1,'2013-02-13 13:52:45',NULL,NULL,1),(2,'CREATE','LOAN',2,NULL,1,1,'/loans',1,'{\"clientId\":\"1\",\"dateFormat\":\"yyyy-MM-dd\",\"locale\":\"en\",\"productId\":\"1\",\"loanOfficerId\":\"2\",\"submittedOnDate\":\"2011-02-16\",\"loanPurposeId\":\"21\",\"principal\":\"1,000,000.00\",\"loanTermFrequency\":\"12\",\"loanTermFrequencyType\":\"2\",\"numberOfRepayments\":\"12\",\"repaymentEvery\":\"1\",\"repaymentFrequencyType\":\"2\",\"transactionProcessingStrategyId\":\"2\",\"expectedDisbursementDate\":\"2011-02-21\",\"repaymentsStartingFromDate\":\"\",\"interestRatePerPeriod\":\"24\",\"interestRateFrequencyType\":\"3\",\"amortizationType\":\"1\",\"interestType\":\"1\",\"interestCalculationPeriodType\":\"1\",\"interestChargedFromDate\":\"\",\"inArrearsTolerance\":\"\",\"charges\":[{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-03-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-04-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-05-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-06-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-07-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-08-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-09-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-10-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-11-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2011-12-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2012-01-21\"},{\"chargeId\":\"1\",\"amount\":\"1,500\",\"specifiedDueDate\":\"2012-02-21\"}],\"collateral\":[{\"id\":\"\",\"type\":\"18\",\"description\":\" small tv worth x\"},{\"id\":\"\",\"type\":\"17\",\"description\":\" house valued at y\"},{\"id\":\"\",\"type\":\"19\",\"description\":\" some gold jewellery\"}]}',1,'2013-02-13 13:55:38',NULL,NULL,1); /*!40000 ALTER TABLE `m_portfolio_command_source` ENABLE KEYS */; UNLOCK TABLES; @@ -1910,7 +1858,7 @@ CREATE TABLE `stretchy_report` ( LOCK TABLES `stretchy_report` WRITE; /*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */; -INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans \n\nAwaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\n\n\nl.account_no as \"Loan Account No.\", pl.`name` as \"Product\", f.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\n\n\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office \n\nounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = \n\nounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join \n\nm_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-\n\n1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \n\n\"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, \n\nl.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\", ifnull(cur.display_symbol, \n\nl.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(\r\n if\n\n(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n \n\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal \n\nRepaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \n\n\"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest Outstanding\",\r\nsum(if(r.duedate \n\n<= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round(\r\n \n\n(sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum\n\n(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on \n\nr.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by \n\nounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull\n\n(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if\n\n(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n \r\n \n\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n \n\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\n\n\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\n\n\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency \n\ncur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule \n\nr on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \n\n\"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \n\n\"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by \n\nl.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring\n\n(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\n \n\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, \n\n0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \n\n\"Principal Overdue\",\r\n \r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , \n\n2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\n\n\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\n\n\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join \n\nm_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived \n\nis false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-\n\n1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} \n\nor -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds \n\nDisbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum\n\n(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin \n\nm_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand \n\n(ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull\n\n(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance \n\nSheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial \n\nBalance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); +INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans Awaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", \r\nc.display_name as \"Name\", l.account_no as \"Loan Account No.\", pl.`name` as \"Product\", \r\nf.`name` as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, l.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(if(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal Repaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest utstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round((sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0)) , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0)), 2) as char) \r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds Disbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nround(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance Sheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial Balance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); /*!40000 ALTER TABLE `stretchy_report` ENABLE KEYS */; UNLOCK TABLES; @@ -1973,4 +1921,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2013-02-07 15:22:48 +-- Dump completed on 2013-02-13 14:04:12 diff --git a/mifosng-db/multi-tenant-demo-backups/ceda/bk_core_with_custom_and_coa.sql b/mifosng-db/multi-tenant-demo-backups/ceda/bk_core_with_custom_and_coa.sql index fd34242e8..0963a221f 100644 --- a/mifosng-db/multi-tenant-demo-backups/ceda/bk_core_with_custom_and_coa.sql +++ b/mifosng-db/multi-tenant-demo-backups/ceda/bk_core_with_custom_and_coa.sql @@ -1,6 +1,6 @@ -- MySQL dump 10.13 Distrib 5.1.60, for Win32 (ia32) -- --- Host: localhost Database: mifostenant-default +-- Host: localhost Database: mifostenant-ceda -- ------------------------------------------------------ -- Server version 5.1.60-community @@ -246,96 +246,6 @@ LOCK TABLES `client additional data` WRITE; /*!40000 ALTER TABLE `client additional data` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `extra_client_details` --- - -DROP TABLE IF EXISTS `extra_client_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_client_details` ( - `client_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`client_id`), - CONSTRAINT `FK_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_client_details` --- - -LOCK TABLES `extra_client_details` WRITE; -/*!40000 ALTER TABLE `extra_client_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_client_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_family_details` --- - -DROP TABLE IF EXISTS `extra_family_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_family_details` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `client_id` bigint(20) NOT NULL, - `Name` varchar(40) DEFAULT NULL, - `Date of Birth` date DEFAULT NULL, - `Points Score` int(11) DEFAULT NULL, - `Education_cd_Highest` int(11) DEFAULT NULL, - `Other Notes` text, - PRIMARY KEY (`id`), - KEY `FK_Extra Family Details Data_1` (`client_id`), - CONSTRAINT `FK_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_family_details` --- - -LOCK TABLES `extra_family_details` WRITE; -/*!40000 ALTER TABLE `extra_family_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_family_details` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `extra_loan_details` --- - -DROP TABLE IF EXISTS `extra_loan_details`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `extra_loan_details` ( - `loan_id` bigint(20) NOT NULL, - `Business Description` varchar(100) DEFAULT NULL, - `Years in Business` int(11) DEFAULT NULL, - `Gender_cd` int(11) DEFAULT NULL, - `Education_cv` varchar(60) DEFAULT NULL, - `Next Visit` date DEFAULT NULL, - `Highest Rate Paid` decimal(19,6) DEFAULT NULL, - `Comment` text, - PRIMARY KEY (`loan_id`), - CONSTRAINT `FK_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `extra_loan_details` --- - -LOCK TABLES `extra_loan_details` WRITE; -/*!40000 ALTER TABLE `extra_loan_details` DISABLE KEYS */; -/*!40000 ALTER TABLE `extra_loan_details` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `impact measurement` -- @@ -459,7 +369,7 @@ CREATE TABLE `m_appuser_role` ( LOCK TABLES `m_appuser_role` WRITE; /*!40000 ALTER TABLE `m_appuser_role` DISABLE KEYS */; -INSERT INTO `m_appuser_role` VALUES (1,1); +INSERT INTO `m_appuser_role` VALUES (1,1),(2,1); /*!40000 ALTER TABLE `m_appuser_role` ENABLE KEYS */; UNLOCK TABLES; @@ -591,7 +501,7 @@ CREATE TABLE `m_code` ( LOCK TABLES `m_code` WRITE; /*!40000 ALTER TABLE `m_code` DISABLE KEYS */; -INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'Gender',0),(3,'YesNo',0),(4,'FieldOfEmployment',0),(5,'EducationLevel',0),(6,'MaritalStatus',0),(7,'PovertyStatus',0),(8,'PurposeOfLoan',0),(9,'CollateralType',0); +INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'LoanCollateral',1),(3,'LoanPurpose',1),(4,'Gender',1),(5,'YesNo',1),(6,'FieldOfEmployment',0),(7,'EducationLevel',0),(8,'MaritalStatus',0),(9,'PovertyStatus',0); /*!40000 ALTER TABLE `m_code` ENABLE KEYS */; UNLOCK TABLES; @@ -620,7 +530,7 @@ CREATE TABLE `m_code_value` ( LOCK TABLES `m_code_value` WRITE; /*!40000 ALTER TABLE `m_code_value` DISABLE KEYS */; -INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',2),(3,1,'Drivers License',3),(4,1,'Any Other Id Type',4),(5,2,'gender.Male',1),(6,2,'gender.Female',2),(7,3,'option.Yes',1),(8,3,'option.No',2),(9,4,'option.Banker',1),(10,4,'option.SoftwareDeveloper',2),(11,5,'option.University',1),(12,5,'option.Secondary',2),(13,5,'option.Primary',3),(14,6,'option.Married',1),(15,6,'option.Single',2),(16,6,'option.Divorced',3),(17,6,'option.Widow',4),(18,7,'option.PovertyStatus.Band1',1),(19,7,'option.PovertyStatus.Band2',2),(20,7,'option.PovertyStatus.Band3',3),(21,8,'option.Agriculture',1),(22,8,'option.Manufacturing',2),(23,8,'option.HousingImprovement',3),(24,9,'option.House',1),(25,9,'option.Television',2),(26,9,'option.Gold',3); +INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',1),(3,1,'Drivers License',2),(4,1,'Any Other Id Type',3),(5,6,'option.Banker',1),(6,6,'option.SoftwareDeveloper',5),(7,7,'option.University',1),(8,7,'option.Secondary',7),(9,7,'option.Primary',8),(10,8,'option.Married',1),(11,8,'option.Single',10),(12,8,'option.Divorced',11),(13,8,'option.Widow',12),(14,9,'option.PovertyStatus.Band1',1),(15,9,'option.PovertyStatus.Band2',14),(16,9,'option.PovertyStatus.Band3',15),(17,2,'option.House',1),(18,2,'option.Television',17),(19,2,'option.Gold',18),(20,3,'option.Agriculture',1),(21,3,'option.Manufacturing',20),(22,3,'option.HousingImprovement',21),(23,4,'option.Male',1),(24,4,'option.Female',23),(25,5,'option.Yes',1),(26,5,'option.No',25); /*!40000 ALTER TABLE `m_code_value` ENABLE KEYS */; UNLOCK TABLES; @@ -923,6 +833,7 @@ CREATE TABLE `m_loan` ( `fund_id` bigint(20) DEFAULT NULL, `loan_officer_id` bigint(20) DEFAULT NULL, `guarantor_id` bigint(20) DEFAULT NULL, + `loanpurpose_cv_id` int(11) DEFAULT NULL, `loan_status_id` smallint(5) NOT NULL, `currency_code` varchar(3) NOT NULL, `currency_digits` smallint(5) NOT NULL, @@ -966,6 +877,7 @@ CREATE TABLE `m_loan` ( KEY `FK7C885877240145` (`fund_id`), KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), KEY `FK_m_loan_m_staff` (`loan_officer_id`), + KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), KEY `group_id` (`group_id`), KEY `FK_m_loan_guarantor` (`guarantor_id`), CONSTRAINT `FK_m_loan_guarantor` FOREIGN KEY (`guarantor_id`) REFERENCES `m_guarantor` (`id`), @@ -973,6 +885,7 @@ CREATE TABLE `m_loan` ( CONSTRAINT `FKB6F935D87179A0CB` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`), CONSTRAINT `FKB6F935D8C8D4B434` FOREIGN KEY (`product_id`) REFERENCES `m_product_loan` (`id`), CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`), + CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `FK_m_loan_m_staff` FOREIGN KEY (`loan_officer_id`) REFERENCES `m_staff` (`id`), CONSTRAINT `m_loan_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1027,6 +940,35 @@ LOCK TABLES `m_loan_charge` WRITE; /*!40000 ALTER TABLE `m_loan_charge` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `m_loan_collateral` +-- + +DROP TABLE IF EXISTS `m_loan_collateral`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `m_loan_collateral` +-- + +LOCK TABLES `m_loan_collateral` WRITE; +/*!40000 ALTER TABLE `m_loan_collateral` DISABLE KEYS */; +/*!40000 ALTER TABLE `m_loan_collateral` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `m_loan_officer_assignment_history` -- @@ -1313,7 +1255,7 @@ CREATE TABLE `m_permission` ( LOCK TABLES `m_permission` WRITE; /*!40000 ALTER TABLE `m_permission` DISABLE KEYS */; -INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance \n\nSheet','Balance \n\nSheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds \n\nDisbursed Between Dates Summary','Funds \n\nDisbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans \n\nAwaiting Disbursal','Loans \n\nAwaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial \n\nBalance','Trial \n\nBalance','READ',1),(248,'datatable','CREATE_client additional data','client additional data','CREATE',1),(249,'datatable','CREATE_impact measurement','impact measurement','CREATE',1),(250,'datatable','CREATE_loan additional data','loan additional data','CREATE',1),(251,'datatable','READ_client additional data','client additional data','READ',1),(252,'datatable','READ_impact measurement','impact measurement','READ',1),(253,'datatable','READ_loan additional data','loan additional data','READ',1),(254,'datatable','UPDATE_client additional data','client additional data','UPDATE',1),(255,'datatable','UPDATE_impact measurement','impact measurement','UPDATE',1),(256,'datatable','UPDATE_loan additional data','loan additional data','UPDATE',1),(257,'datatable','DELETE_client additional data','client additional data','DELETE',1),(258,'datatable','DELETE_impact measurement','impact measurement','DELETE',1),(259,'datatable','DELETE_loan additional data','loan additional data','DELETE',1); +INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance Sheet','Balance Sheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds Disbursed Between Dates Summary','Funds Disbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans Awaiting Disbursal','Loans Awaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial Balance','Trial Balance','READ',1),(248,'datatable','CREATE_client additional data','client additional data','CREATE',1),(249,'datatable','CREATE_impact measurement','impact measurement','CREATE',1),(250,'datatable','CREATE_loan additional data','loan additional data','CREATE',1),(251,'datatable','READ_client additional data','client additional data','READ',1),(252,'datatable','READ_impact measurement','impact measurement','READ',1),(253,'datatable','READ_loan additional data','loan additional data','READ',1),(254,'datatable','UPDATE_client additional data','client additional data','UPDATE',1),(255,'datatable','UPDATE_impact measurement','impact measurement','UPDATE',1),(256,'datatable','UPDATE_loan additional data','loan additional data','UPDATE',1),(257,'datatable','DELETE_client additional data','client additional data','DELETE',1),(258,'datatable','DELETE_impact measurement','impact measurement','DELETE',1),(259,'datatable','DELETE_loan additional data','loan additional data','DELETE',1); /*!40000 ALTER TABLE `m_permission` ENABLE KEYS */; UNLOCK TABLES; @@ -1910,7 +1852,7 @@ CREATE TABLE `stretchy_report` ( LOCK TABLES `stretchy_report` WRITE; /*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */; -INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans \n\nAwaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\n\n\nl.account_no as \"Loan Account No.\", pl.`name` as \"Product\", f.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\n\n\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office \n\nounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = \n\nounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join \n\nm_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-\n\n1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \n\n\"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, \n\nl.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\", ifnull(cur.display_symbol, \n\nl.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(\r\n if\n\n(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n \n\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal \n\nRepaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \n\n\"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest Outstanding\",\r\nsum(if(r.duedate \n\n<= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round(\r\n \n\n(sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum\n\n(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on \n\nr.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by \n\nounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull\n\n(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if\n\n(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n \r\n \n\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n \n\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\n\n\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\n\n\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency \n\ncur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule \n\nr on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \n\n\"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \n\n\"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by \n\nl.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring\n\n(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\n \n\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, \n\n0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \n\n\"Principal Overdue\",\r\n \r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , \n\n2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\n\n\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\n\n\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join \n\nm_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived \n\nis false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-\n\n1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} \n\nor -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds \n\nDisbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum\n\n(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin \n\nm_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand \n\n(ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull\n\n(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance \n\nSheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial \n\nBalance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); +INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans Awaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", \r\nc.display_name as \"Name\", l.account_no as \"Loan Account No.\", pl.`name` as \"Product\", \r\nf.`name` as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, l.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(if(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal Repaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest utstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round((sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0)) , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0)), 2) as char) \r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds Disbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nround(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance Sheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial Balance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); /*!40000 ALTER TABLE `stretchy_report` ENABLE KEYS */; UNLOCK TABLES; @@ -1973,4 +1915,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2013-02-07 15:22:56 +-- Dump completed on 2013-02-13 13:47:48 diff --git a/mifosng-db/multi-tenant-demo-backups/ceda/ceda-schema-customisations.sql b/mifosng-db/multi-tenant-demo-backups/ceda/ceda-schema-customisations.sql index 9c985615e..4104aa364 100644 --- a/mifosng-db/multi-tenant-demo-backups/ceda/ceda-schema-customisations.sql +++ b/mifosng-db/multi-tenant-demo-backups/ceda/ceda-schema-customisations.sql @@ -1,47 +1,146 @@ DELETE FROM `mifostenant-ceda`.`ref_loan_transaction_processing_strategy` WHERE id in (1, 3, 4); -INSERT INTO `mifostenant-ceda`.`m_code` (`id`,`code_name`, `is_system_defined`) +INSERT INTO `mifostenant-ceda`.`m_code` (`code_name`, `is_system_defined`) VALUES -(2,'Gender', '0'), -(3,'YesNo', '0'), -(4,'FieldOfEmployment', '0'), -(5,'EducationLevel', '0'), -(6,'MaritalStatus', '0'), -(7,'PovertyStatus', '0'), -(8,'PurposeOfLoan', '0'), -(9,'CollateralType', '0'); +('FieldOfEmployment', '0'), +('EducationLevel', '0'), +('MaritalStatus', '0'), +('PovertyStatus', '0'); + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Banker', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "FieldOfEmployment"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.SoftwareDeveloper', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "FieldOfEmployment"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.University', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "EducationLevel"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Secondary', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "EducationLevel"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Primary', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "EducationLevel"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Married', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "MaritalStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Single', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "MaritalStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Divorced', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "MaritalStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Widow', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "MaritalStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.PovertyStatus.Band1', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "PovertyStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.PovertyStatus.Band2', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "PovertyStatus"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.PovertyStatus.Band3', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "PovertyStatus"; + +-- ======= ADD in loan purspose and collateral values to enable this functionality +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.House', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanCollateral"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Television', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanCollateral"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Gold', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanCollateral"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Agriculture', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanPurpose"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Manufacturing', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanPurpose"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.HousingImprovement', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "LoanPurpose"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Male', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Gender"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Female', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Gender"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Yes', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "YesNo"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.No', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "YesNo"; -DELETE FROM `mifostenant-ceda`.`m_code_value` WHERE id > 0; -INSERT INTO `mifostenant-ceda`.`m_code_value` -(`code_id`,`code_value`,`order_position`) -VALUES -(1, 'Passport', 1), -(1, 'Id', 2), -(1, 'Drivers License', 3), -(1, 'Any Other Id Type', 4), -(2, 'gender.Male', 1), -(2, 'gender.Female', 2), -(3, 'option.Yes', 1), -(3, 'option.No', 2), -(4, 'option.Banker', 1), -(4, 'option.SoftwareDeveloper', 2), -(5, 'option.University', 1), -(5, 'option.Secondary', 2), -(5, 'option.Primary', 3), -(6, 'option.Married', 1), -(6, 'option.Single', 2), -(6, 'option.Divorced', 3), -(6, 'option.Widow', 4), -(7, 'option.PovertyStatus.Band1', 1), -(7, 'option.PovertyStatus.Band2', 2), -(7, 'option.PovertyStatus.Band3', 3), -(8, 'option.Agriculture', 1), -(8, 'option.Manufacturing', 2), -(8, 'option.HousingImprovement', 3), -(9, 'option.House', 1), -(9, 'option.Television', 2), -(9, 'option.Gold', 3); DROP TABLE IF EXISTS `mifostenant-ceda`.`client additional data`; CREATE TABLE `mifostenant-ceda`.`client additional data` ( diff --git a/mifosng-db/multi-tenant-demo-backups/ceda/ceda-user-office-product-setup.sql b/mifosng-db/multi-tenant-demo-backups/ceda/ceda-user-office-product-setup.sql index 296f55291..dd47de1c6 100644 --- a/mifosng-db/multi-tenant-demo-backups/ceda/ceda-user-office-product-setup.sql +++ b/mifosng-db/multi-tenant-demo-backups/ceda/ceda-user-office-product-setup.sql @@ -30,6 +30,9 @@ VALUES (0, 1, 'keithwoodlock', 'Keith', 'Woodlock', '4f607e9b6cffbe7d3db92d4bfa3391c7aa751727b4ea29d08fddf9dd72e6e7e3', 'keithwoodlock@gmail.com', 0, 1, 1, 1, 1); +INSERT INTO `mifostenant-ceda`.`m_appuser_role` +(`appuser_id`,`role_id`) VALUES (2,1); + UPDATE `mifostenant-ceda`.`m_office` SET `name` = 'CEDA Microfinance Ltd.' WHERE id=1; INSERT INTO `mifostenant-ceda`.`m_office` diff --git a/mifosng-db/multi-tenant-demo-backups/default-demo/bk_mifostenant-default.sql b/mifosng-db/multi-tenant-demo-backups/default-demo/bk_mifostenant-default.sql index d10acd328..4fbe3c164 100644 --- a/mifosng-db/multi-tenant-demo-backups/default-demo/bk_mifostenant-default.sql +++ b/mifosng-db/multi-tenant-demo-backups/default-demo/bk_mifostenant-default.sql @@ -397,7 +397,7 @@ CREATE TABLE `m_client` ( UNIQUE KEY `external_id` (`external_id`), KEY `FKCE00CAB3E0DD567A` (`office_id`), CONSTRAINT `FKCE00CAB3E0DD567A` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -406,6 +406,7 @@ CREATE TABLE `m_client` ( LOCK TABLES `m_client` WRITE; /*!40000 ALTER TABLE `m_client` DISABLE KEYS */; +INSERT INTO `m_client` VALUES (1,'000000001',1,NULL,'Test',NULL,'User',NULL,'Test User',NULL,'2009-02-13',0); /*!40000 ALTER TABLE `m_client` ENABLE KEYS */; UNLOCK TABLES; @@ -458,7 +459,7 @@ CREATE TABLE `m_code` ( `is_system_defined` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `code_name` (`code_name`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -467,7 +468,7 @@ CREATE TABLE `m_code` ( LOCK TABLES `m_code` WRITE; /*!40000 ALTER TABLE `m_code` DISABLE KEYS */; -INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'Gender',1),(3,'Education',1); +INSERT INTO `m_code` VALUES (1,'Customer Identifier',1),(2,'LoanCollateral',1),(3,'LoanPurpose',1),(4,'Gender',1),(5,'YesNo',1),(6,'Education',1); /*!40000 ALTER TABLE `m_code` ENABLE KEYS */; UNLOCK TABLES; @@ -487,7 +488,7 @@ CREATE TABLE `m_code_value` ( UNIQUE KEY `code_value` (`code_id`,`code_value`), KEY `FKCFCEA42640BE071Z` (`code_id`), CONSTRAINT `FKCFCEA42640BE071Z` FOREIGN KEY (`code_id`) REFERENCES `m_code` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -496,7 +497,7 @@ CREATE TABLE `m_code_value` ( LOCK TABLES `m_code_value` WRITE; /*!40000 ALTER TABLE `m_code_value` DISABLE KEYS */; -INSERT INTO `m_code_value` VALUES (1,1,'Passport number',0),(2,2,'Male',1),(3,2,'Female',2),(4,3,'Primary',1),(5,3,'Secondary',2),(6,3,'University',3); +INSERT INTO `m_code_value` VALUES (1,1,'Passport',1),(2,1,'Id',1),(3,1,'Drivers License',2),(4,1,'Any Other Id Type',3),(5,4,'option.Male',1),(6,4,'option.Female',5),(7,5,'option.Yes',1),(8,5,'option.No',7),(9,6,'Primary',1),(10,6,'Secondary',9),(11,6,'University',10); /*!40000 ALTER TABLE `m_code_value` ENABLE KEYS */; UNLOCK TABLES; @@ -799,6 +800,7 @@ CREATE TABLE `m_loan` ( `fund_id` bigint(20) DEFAULT NULL, `loan_officer_id` bigint(20) DEFAULT NULL, `guarantor_id` bigint(20) DEFAULT NULL, + `loanpurpose_cv_id` int(11) DEFAULT NULL, `loan_status_id` smallint(5) NOT NULL, `currency_code` varchar(3) NOT NULL, `currency_digits` smallint(5) NOT NULL, @@ -842,6 +844,7 @@ CREATE TABLE `m_loan` ( KEY `FK7C885877240145` (`fund_id`), KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), KEY `FK_m_loan_m_staff` (`loan_officer_id`), + KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), KEY `group_id` (`group_id`), KEY `FK_m_loan_guarantor` (`guarantor_id`), CONSTRAINT `FK_m_loan_guarantor` FOREIGN KEY (`guarantor_id`) REFERENCES `m_guarantor` (`id`), @@ -849,6 +852,7 @@ CREATE TABLE `m_loan` ( CONSTRAINT `FKB6F935D87179A0CB` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`), CONSTRAINT `FKB6F935D8C8D4B434` FOREIGN KEY (`product_id`) REFERENCES `m_product_loan` (`id`), CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`), + CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `FK_m_loan_m_staff` FOREIGN KEY (`loan_officer_id`) REFERENCES `m_staff` (`id`), CONSTRAINT `m_loan_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -903,6 +907,35 @@ LOCK TABLES `m_loan_charge` WRITE; /*!40000 ALTER TABLE `m_loan_charge` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `m_loan_collateral` +-- + +DROP TABLE IF EXISTS `m_loan_collateral`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `m_loan_collateral` +-- + +LOCK TABLES `m_loan_collateral` WRITE; +/*!40000 ALTER TABLE `m_loan_collateral` DISABLE KEYS */; +/*!40000 ALTER TABLE `m_loan_collateral` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `m_loan_officer_assignment_history` -- @@ -1189,7 +1222,7 @@ CREATE TABLE `m_permission` ( LOCK TABLES `m_permission` WRITE; /*!40000 ALTER TABLE `m_permission` DISABLE KEYS */; -INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance \n\nSheet','Balance \n\nSheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds \n\nDisbursed Between Dates Summary','Funds \n\nDisbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans \n\nAwaiting Disbursal','Loans \n\nAwaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial \n\nBalance','Trial \n\nBalance','READ',1); +INSERT INTO `m_permission` VALUES (1,'special','ALL_FUNCTIONS',NULL,NULL,0),(2,'special','ALL_FUNCTIONS_READ',NULL,NULL,0),(3,'special','CHECKER_SUPER_USER',NULL,NULL,0),(4,'special','REPORTING_SUPER_USER',NULL,NULL,0),(5,'authorisation','READ_PERMISSION','PERMISSION','READ',0),(6,'authorisation','PERMISSIONS_ROLE','ROLE','PERMISSIONS',1),(7,'authorisation','CREATE_ROLE','ROLE','CREATE',1),(8,'authorisation','CREATE_ROLE_CHECKER','ROLE','CREATE',1),(9,'authorisation','READ_ROLE','ROLE','READ',0),(10,'authorisation','UPDATE_ROLE','ROLE','UPDATE',1),(11,'authorisation','UPDATE_ROLE_CHECKER','ROLE','UPDATE',1),(12,'authorisation','DELETE_ROLE','ROLE','DELETE',1),(13,'authorisation','DELETE_ROLE_CHECKER','ROLE','DELETE',1),(14,'authorisation','CREATE_USER','USER','CREATE',1),(15,'authorisation','CREATE_USER_CHECKER','USER','CREATE',1),(16,'authorisation','READ_USER','USER','READ',0),(17,'authorisation','UPDATE_USER','USER','UPDATE',1),(18,'authorisation','UPDATE_USER_CHECKER','USER','UPDATE',1),(19,'authorisation','DELETE_USER','USER','DELETE',1),(20,'authorisation','DELETE_USER_CHECKER','USER','DELETE',1),(21,'configuration','READ_CONFIGURATION','CONFIGURATION','READ',1),(22,'configuration','UPDATE_CONFIGURATION','CONFIGURATION','UPDATE',1),(23,'configuration','UPDATE_CONFIGURATION_CHECKER','CONFIGURATION','UPDATE',1),(24,'configuration','READ_CODE','CODE','READ',0),(25,'configuration','CREATE_CODE','CODE','CREATE',1),(26,'configuration','CREATE_CODE_CHECKER','CODE','CREATE',1),(27,'configuration','UPDATE_CODE','CODE','UPDATE',1),(28,'configuration','UPDATE_CODE_CHECKER','CODE','UPDATE',1),(29,'configuration','DELETE_CODE','CODE','DELETE',1),(30,'configuration','DELETE_CODE_CHECKER','CODE','DELETE',1),(31,'configuration','READ_CODEVALUE','CODEVALUE','READ',0),(32,'configuration','CREATE_CODEVALUE','CODEVALUE','CREATE',1),(33,'configuration','CREATE_CODEVALUE_CHECKER','CODEVALUE','CREATE',1),(34,'configuration','UPDATE_CODEVALUE','CODEVALUE','UPDATE',1),(35,'configuration','UPDATE_CODEVALUE_CHECKER','CODEVALUE','UPDATE',1),(36,'configuration','DELETE_CODEVALUE','CODEVALUE','DELETE',1),(37,'configuration','DELETE_CODEVALUE_CHECKER','CODEVALUE','DELETE',1),(38,'configuration','READ_CURRENCY','CURRENCY','READ',0),(39,'configuration','UPDATE_CURRENCY','CURRENCY','UPDATE',1),(40,'configuration','UPDATE_CURRENCY_CHECKER','CURRENCY','UPDATE',1),(41,'configuration','UPDATE_PERMISSION','PERMISSION','UPDATE',1),(42,'configuration','UPDATE_PERMISSION_CHECKER','PERMISSION','UPDATE',1),(43,'configuration','READ_DATATABLE','DATATABLE','READ',0),(44,'configuration','REGISTER_DATATABLE','DATATABLE','REGISTER',1),(45,'configuration','REGISTER_DATATABLE_CHECKER','DATATABLE','REGISTER',1),(46,'configuration','DEREGISTER_DATATABLE','DATATABLE','DEREGISTER',1),(47,'configuration','DEREGISTER_DATATABLE_CHECKER','DATATABLE','DEREGISTER',1),(48,'configuration','READ_AUDIT','AUDIT','READ',0),(49,'organisation','READ_MAKERCHECKER','MAKERCHECKER','READ',0),(50,'organisation','READ_CHARGE','CHARGE','READ',0),(51,'organisation','CREATE_CHARGE','CHARGE','CREATE',1),(52,'organisation','CREATE_CHARGE_CHECKER','CHARGE','CREATE',1),(53,'organisation','UPDATE_CHARGE','CHARGE','UPDATE',1),(54,'organisation','UPDATE_CHARGE_CHECKER','CHARGE','UPDATE',1),(55,'organisation','DELETE_CHARGE','CHARGE','DELETE',1),(56,'organisation','DELETE_CHARGE_CHECKER','CHARGE','DELETE',1),(57,'organisation','READ_FUND','FUND','READ',0),(58,'organisation','CREATE_FUND','FUND','CREATE',1),(59,'organisation','CREATE_FUND_CHECKER','FUND','CREATE',1),(60,'organisation','UPDATE_FUND','FUND','UPDATE',1),(61,'organisation','UPDATE_FUND_CHECKER','FUND','UPDATE',1),(62,'organisation','DELETE_FUND','FUND','DELETE',1),(63,'organisation','DELETE_FUND_CHECKER','FUND','DELETE',1),(64,'organisation','READ_LOANPRODUCT','LOANPRODUCT','READ',0),(65,'organisation','CREATE_LOANPRODUCT','LOANPRODUCT','CREATE',1),(66,'organisation','CREATE_LOANPRODUCT_CHECKER','LOANPRODUCT','CREATE',1),(67,'organisation','UPDATE_LOANPRODUCT','LOANPRODUCT','UPDATE',1),(68,'organisation','UPDATE_LOANPRODUCT_CHECKER','LOANPRODUCT','UPDATE',1),(69,'organisation','DELETE_LOANPRODUCT','LOANPRODUCT','DELETE',1),(70,'organisation','DELETE_LOANPRODUCT_CHECKER','LOANPRODUCT','DELETE',1),(71,'organisation','READ_OFFICE','OFFICE','READ',0),(72,'organisation','CREATE_OFFICE','OFFICE','CREATE',1),(73,'organisation','CREATE_OFFICE_CHECKER','OFFICE','CREATE',1),(74,'organisation','UPDATE_OFFICE','OFFICE','UPDATE',1),(75,'organisation','UPDATE_OFFICE_CHECKER','OFFICE','UPDATE',1),(76,'organisation','READ_OFFICETRANSACTION','OFFICETRANSACTION','READ',0),(77,'organisation','DELETE_OFFICE_CHECKER','OFFICE','DELETE',1),(78,'organisation','CREATE_OFFICETRANSACTION','OFFICETRANSACTION','CREATE',1),(79,'organisation','CREATE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','CREATE',1),(80,'organisation','DELETE_OFFICETRANSACTION','OFFICETRANSACTION','DELETE',1),(81,'organisation','DELETE_OFFICETRANSACTION_CHECKER','OFFICETRANSACTION','DELETE',1),(82,'organisation','READ_STAFF','STAFF','READ',0),(83,'organisation','CREATE_STAFF','STAFF','CREATE',1),(84,'organisation','CREATE_STAFF_CHECKER','STAFF','CREATE',1),(85,'organisation','UPDATE_STAFF','STAFF','UPDATE',1),(86,'organisation','UPDATE_STAFF_CHECKER','STAFF','UPDATE',1),(87,'organisation','DELETE_STAFF','STAFF','DELETE',1),(88,'organisation','DELETE_STAFF_CHECKER','STAFF','DELETE',1),(89,'organisation','READ_SAVINGSPRODUCT','SAVINGSPRODUCT','READ',0),(90,'organisation','CREATE_SAVINGSPRODUCT','SAVINGSPRODUCT','CREATE',1),(91,'organisation','CREATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','CREATE',1),(92,'organisation','UPDATE_SAVINGSPRODUCT','SAVINGSPRODUCT','UPDATE',1),(93,'organisation','UPDATE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','UPDATE',1),(94,'organisation','DELETE_SAVINGSPRODUCT','SAVINGSPRODUCT','DELETE',1),(95,'organisation','DELETE_SAVINGSPRODUCT_CHECKER','SAVINGSPRODUCT','DELETE',1),(96,'organisation','READ_DEPOSITPRODUCT','DEPOSITPRODUCT','READ',0),(97,'organisation','CREATE_DEPOSITPRODUCT','DEPOSITPRODUCT','CREATE',1),(98,'organisation','CREATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','CREATE',1),(99,'organisation','UPDATE_DEPOSITPRODUCT','DEPOSITPRODUCT','UPDATE',1),(100,'organisation','UPDATE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','UPDATE',1),(101,'organisation','DELETE_DEPOSITPRODUCT','DEPOSITPRODUCT','DELETE',1),(102,'organisation','DELETE_DEPOSITPRODUCT_CHECKER','DEPOSITPRODUCT','DELETE',1),(103,'portfolio','READ_LOAN','LOAN','READ',0),(104,'portfolio','CREATE_LOAN','LOAN','CREATE',1),(105,'portfolio','CREATE_LOAN_CHECKER','LOAN','CREATE',1),(106,'portfolio','UPDATE_LOAN','LOAN','UPDATE',1),(107,'portfolio','UPDATE_LOAN_CHECKER','LOAN','UPDATE',1),(108,'portfolio','DELETE_LOAN','LOAN','DELETE',1),(109,'portfolio','DELETE_LOAN_CHECKER','LOAN','DELETE',1),(110,'portfolio','READ_CLIENT','CLIENT','READ',0),(111,'portfolio','CREATE_CLIENT','CLIENT','CREATE',1),(112,'portfolio','CREATE_CLIENT_CHECKER','CLIENT','CREATE',1),(113,'portfolio','UPDATE_CLIENT','CLIENT','UPDATE',1),(114,'portfolio','UPDATE_CLIENT_CHECKER','CLIENT','UPDATE',1),(115,'portfolio','DELETE_CLIENT','CLIENT','DELETE',1),(116,'portfolio','DELETE_CLIENT_CHECKER','CLIENT','DELETE',1),(117,'portfolio','READ_CLIENTIMAGE','CLIENTIMAGE','READ',0),(118,'portfolio','CREATE_CLIENTIMAGE','CLIENTIMAGE','CREATE',1),(119,'portfolio','CREATE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','CREATE',1),(120,'portfolio','DELETE_CLIENTIMAGE','CLIENTIMAGE','DELETE',1),(121,'portfolio','DELETE_CLIENTIMAGE_CHECKER','CLIENTIMAGE','DELETE',1),(122,'portfolio','READ_CLIENTNOTE','CLIENTNOTE','READ',0),(123,'portfolio','CREATE_CLIENTNOTE','CLIENTNOTE','CREATE',1),(124,'portfolio','CREATE_CLIENTNOTE_CHECKER','CLIENTNOTE','CREATE',1),(125,'portfolio','UPDATE_CLIENTNOTE','CLIENTNOTE','UPDATE',1),(126,'portfolio','UPDATE_CLIENTNOTE_CHECKER','CLIENTNOTE','UPDATE',1),(127,'portfolio','DELETE_CLIENTNOTE','CLIENTNOTE','DELETE',1),(128,'portfolio','DELETE_CLIENTNOTE_CHECKER','CLIENTNOTE','DELETE',1),(129,'portfolio','READ_CLIENTIDENTIFIER','CLIENTIDENTIFIER','READ',0),(130,'portfolio','CREATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','CREATE',1),(131,'portfolio','CREATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','CREATE',1),(132,'portfolio','UPDATE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','UPDATE',1),(133,'portfolio','UPDATE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','UPDATE',1),(134,'portfolio','DELETE_CLIENTIDENTIFIER','CLIENTIDENTIFIER','DELETE',1),(135,'portfolio','DELETE_CLIENTIDENTIFIER_CHECKER','CLIENTIDENTIFIER','DELETE',1),(136,'portfolio','READ_DOCUMENT','DOCUMENT','READ',0),(137,'portfolio','CREATE_DOCUMENT','DOCUMENT','CREATE',1),(138,'portfolio','CREATE_DOCUMENT_CHECKER','DOCUMENT','CREATE',1),(139,'portfolio','UPDATE_DOCUMENT','DOCUMENT','UPDATE',1),(140,'portfolio','UPDATE_DOCUMENT_CHECKER','DOCUMENT','UPDATE',1),(141,'portfolio','DELETE_DOCUMENT','DOCUMENT','DELETE',1),(142,'portfolio','DELETE_DOCUMENT_CHECKER','DOCUMENT','DELETE',1),(143,'portfolio','READ_GROUP','GROUP','READ',0),(144,'portfolio','CREATE_GROUP','GROUP','CREATE',1),(145,'portfolio','CREATE_GROUP_CHECKER','GROUP','CREATE',1),(146,'portfolio','UPDATE_GROUP','GROUP','UPDATE',1),(147,'portfolio','UPDATE_GROUP_CHECKER','GROUP','UPDATE',1),(148,'portfolio','DELETE_GROUP','GROUP','DELETE',1),(149,'portfolio','DELETE_GROUP_CHECKER','GROUP','DELETE',1),(150,'portfolio','CREATE_LOANCHARGE','LOANCHARGE','CREATE',1),(151,'portfolio','CREATE_LOANCHARGE_CHECKER','LOANCHARGE','CREATE',1),(152,'portfolio','UPDATE_LOANCHARGE','LOANCHARGE','UPDATE',1),(153,'portfolio','UPDATE_LOANCHARGE_CHECKER','LOANCHARGE','UPDATE',1),(154,'portfolio','DELETE_LOANCHARGE','LOANCHARGE','DELETE',1),(155,'portfolio','DELETE_LOANCHARGE_CHECKER','LOANCHARGE','DELETE',1),(156,'portfolio','WAIVE_LOANCHARGE','LOANCHARGE','WAIVE',1),(157,'portfolio','WAIVE_LOANCHARGE_CHECKER','LOANCHARGE','WAIVE',1),(158,'portfolio','READ_DEPOSITACCOUNT','DEPOSITACCOUNT','READ',0),(159,'portfolio','CREATE_DEPOSITACCOUNT','DEPOSITACCOUNT','CREATE',1),(160,'portfolio','CREATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','CREATE',1),(161,'portfolio','UPDATE_DEPOSITACCOUNT','DEPOSITACCOUNT','UPDATE',1),(162,'portfolio','UPDATE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','UPDATE',1),(163,'portfolio','DELETE_DEPOSITACCOUNT','DEPOSITACCOUNT','DELETE',1),(164,'portfolio','DELETE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','DELETE',1),(165,'portfolio','READ_SAVINGSACCOUNT','SAVINGSACCOUNT','READ',0),(166,'portfolio','CREATE_SAVINGSACCOUNT','SAVINGSACCOUNT','CREATE',1),(167,'portfolio','CREATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','CREATE',1),(168,'portfolio','UPDATE_SAVINGSACCOUNT','SAVINGSACCOUNT','UPDATE',1),(169,'portfolio','UPDATE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','UPDATE',1),(170,'portfolio','DELETE_SAVINGSACCOUNT','SAVINGSACCOUNT','DELETE',1),(171,'portfolio','DELETE_SAVINGSACCOUNT_CHECKER','SAVINGSACCOUNT','DELETE',1),(172,'portfolio','READ_GUARANTOR','GUARANTOR','READ',0),(173,'portfolio','CREATE_GUARANTOR','GUARANTOR','CREATE',1),(174,'portfolio','CREATE_GUARANTOR_CHECKER','GUARANTOR','CREATE',1),(175,'portfolio','UPDATE_GUARANTOR','GUARANTOR','UPDATE',1),(176,'portfolio','UPDATE_GUARANTOR_CHECKER','GUARANTOR','UPDATE',1),(177,'portfolio','DELETE_GUARANTOR','GUARANTOR','DELETE',1),(178,'portfolio','DELETE_GUARANTOR_CHECKER','GUARANTOR','DELETE',1),(179,'transaction_loan','APPROVE_LOAN','LOAN','APPROVE',1),(180,'transaction_loan','APPROVEINPAST_LOAN','LOAN','APPROVEINPAST',1),(181,'transaction_loan','REJECT_LOAN','LOAN','REJECT',1),(182,'transaction_loan','REJECTINPAST_LOAN','LOAN','REJECTINPAST',1),(183,'transaction_loan','WITHDRAW_LOAN','LOAN','WITHDRAW',1),(184,'transaction_loan','WITHDRAWINPAST_LOAN','LOAN','WITHDRAWINPAST',1),(185,'transaction_loan','APPROVALUNDO_LOAN','LOAN','APPROVALUNDO',1),(186,'transaction_loan','DISBURSE_LOAN','LOAN','DISBURSE',1),(187,'transaction_loan','DISBURSEINPAST_LOAN','LOAN','DISBURSEINPAST',1),(188,'transaction_loan','DISBURSALUNDO_LOAN','LOAN','DISBURSALUNDO',1),(189,'transaction_loan','REPAYMENT_LOAN','LOAN','REPAYMENT',1),(190,'transaction_loan','REPAYMENTINPAST_LOAN','LOAN','REPAYMENTINPAST',1),(191,'transaction_loan','ADJUST_LOAN','LOAN','ADJUST',1),(192,'transaction_loan','WAIVEINTERESTPORTION_LOAN','LOAN','WAIVEINTERESTPORTION',1),(193,'transaction_loan','WRITEOFF_LOAN','LOAN','WRITEOFF',1),(194,'transaction_loan','CLOSE_LOAN','LOAN','CLOSE',1),(195,'transaction_loan','CLOSEASRESCHEDULED_LOAN','LOAN','CLOSEASRESCHEDULED',1),(196,'transaction_loan','UPDATELOANOFFICER_LOAN','LOAN','UPDATELOANOFFICER',1),(197,'transaction_loan','UPDATELOANOFFICER_LOAN_CHECKER','LOAN','UPDATELOANOFFICER',1),(198,'transaction_loan','REMOVELOANOFFICER_LOAN','LOAN','REMOVELOANOFFICER',1),(199,'transaction_loan','REMOVELOANOFFICER_LOAN_CHECKER','LOAN','REMOVELOANOFFICER',1),(200,'transaction_loan','BULKREASSIGN_LOAN','LOAN','BULKREASSIGN',1),(201,'transaction_loan','BULKREASSIGN_LOAN_CHECKER','LOAN','BULKREASSIGN',1),(202,'transaction_loan','APPROVE_LOAN_CHECKER','LOAN','APPROVE',1),(203,'transaction_loan','APPROVEINPAST_LOAN_CHECKER','LOAN','APPROVEINPAST',1),(204,'transaction_loan','REJECT_LOAN_CHECKER','LOAN','REJECT',1),(205,'transaction_loan','REJECTINPAST_LOAN_CHECKER','LOAN','REJECTINPAST',1),(206,'transaction_loan','WITHDRAW_LOAN_CHECKER','LOAN','WITHDRAW',1),(207,'transaction_loan','WITHDRAWINPAST_LOAN_CHECKER','LOAN','WITHDRAWINPAST',1),(208,'transaction_loan','APPROVALUNDO_LOAN_CHECKER','LOAN','APPROVALUNDO',1),(209,'transaction_loan','DISBURSE_LOAN_CHECKER','LOAN','DISBURSE',1),(210,'transaction_loan','DISBURSEINPAST_LOAN_CHECKER','LOAN','DISBURSEINPAST',1),(211,'transaction_loan','DISBURSALUNDO_LOAN_CHECKER','LOAN','DISBURSALUNDO',1),(212,'transaction_loan','REPAYMENT_LOAN_CHECKER','LOAN','REPAYMENT',1),(213,'transaction_loan','REPAYMENTINPAST_LOAN_CHECKER','LOAN','REPAYMENTINPAST',1),(214,'transaction_loan','ADJUST_LOAN_CHECKER','LOAN','ADJUST',1),(215,'transaction_loan','WAIVEINTERESTPORTION_LOAN_CHECKER','LOAN','WAIVEINTERESTPORTION',1),(216,'transaction_loan','WRITEOFF_LOAN_CHECKER','LOAN','WRITEOFF',1),(217,'transaction_loan','CLOSE_LOAN_CHECKER','LOAN','CLOSE',1),(218,'transaction_loan','CLOSEASRESCHEDULED_LOAN_CHECKER','LOAN','CLOSEASRESCHEDULED',1),(219,'transaction_deposit','APPROVE_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVE',1),(220,'transaction_deposit','REJECT_DEPOSITACCOUNT','DEPOSITACCOUNT','REJECT',1),(221,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAW',1),(222,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','DEPOSITACCOUNT','APPROVALUNDO',1),(223,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','DEPOSITACCOUNT','WITHDRAWAL',1),(224,'transaction_deposit','INTEREST_DEPOSITACCOUNT','DEPOSITACCOUNT','INTEREST',1),(225,'transaction_deposit','RENEW_DEPOSITACCOUNT','DEPOSITACCOUNT','RENEW',1),(226,'transaction_deposit','APPROVE_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVE',1),(227,'transaction_deposit','REJECT_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','REJECT',1),(228,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAW',1),(229,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','APPROVALUNDO',1),(230,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','WITHDRAWAL',1),(231,'transaction_deposit','INTEREST_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','INTEREST',1),(232,'transaction_deposit','RENEW_DEPOSITACCOUNT_CHECKER','DEPOSITACCOUNT','RENEW',1),(233,'report','READ_Active Loans Portfolio Status','Active Loans Portfolio Status','READ',1),(234,'report','READ_Active Loans Summary per Branch','Active Loans Summary per Branch','READ',1),(235,'report','READ_Balance Sheet','Balance Sheet','READ',1),(236,'report','READ_Client Listing','Client Listing','READ',1),(237,'report','READ_Client Loans Listing','Client Loans Listing','READ',1),(238,'report','READ_Funds Disbursed Between Dates Summary','Funds Disbursed Between Dates Summary','READ',1),(239,'report','READ_Funds Disbursed Between Dates Summary by Office','Funds Disbursed Between Dates Summary by Office','READ',1),(240,'report','READ_Income Statement','Income Statement','READ',1),(241,'report','READ_Loans Awaiting Disbursal','Loans Awaiting Disbursal','READ',1),(242,'report','READ_Loans Awaiting Disbursal Summary','Loans Awaiting Disbursal Summary','READ',1),(243,'report','READ_Loans Awaiting Disbursal Summary by Month','Loans Awaiting Disbursal Summary by Month','READ',1),(244,'report','READ_Portfolio at Risk','Portfolio at Risk','READ',1),(245,'report','READ_Portfolio at Risk by Branch','Portfolio at Risk by Branch','READ',1),(246,'report','READ_Trial Balance','Trial Balance','READ',1); /*!40000 ALTER TABLE `m_permission` ENABLE KEYS */; UNLOCK TABLES; @@ -1230,7 +1263,7 @@ CREATE TABLE `m_portfolio_command_source` ( KEY `loan_id` (`office_id`), CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`), CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1239,6 +1272,7 @@ CREATE TABLE `m_portfolio_command_source` ( LOCK TABLES `m_portfolio_command_source` WRITE; /*!40000 ALTER TABLE `m_portfolio_command_source` DISABLE KEYS */; +INSERT INTO `m_portfolio_command_source` VALUES (1,'CREATE','CLIENT',1,NULL,1,NULL,'/clients/template',1,'{\"officeId\":\"1\",\"firstname\":\"Test\",\"middlename\":\"\",\"lastname\":\"User\",\"fullname\":\"\",\"externalId\":\"\",\"dateFormat\":\"dd MMMM yyyy\",\"locale\":\"en\",\"joinedDate\":\"13 February 2009\"}',1,'2013-02-13 13:45:12',NULL,NULL,1); /*!40000 ALTER TABLE `m_portfolio_command_source` ENABLE KEYS */; UNLOCK TABLES; @@ -1784,7 +1818,7 @@ CREATE TABLE `stretchy_report` ( LOCK TABLES `stretchy_report` WRITE; /*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */; -INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans \n\nAwaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\n\n\nl.account_no as \"Loan Account No.\", pl.`name` as \"Product\", f.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\n\n\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office \n\nounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = \n\nounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join \n\nm_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-\n\n1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \n\n\"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, \n\nl.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\", ifnull(cur.display_symbol, \n\nl.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(\r\n if\n\n(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n \n\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal \n\nRepaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \n\n\"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest Outstanding\",\r\nsum(if(r.duedate \n\n<= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round(\r\n \n\n(sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum\n\n(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on \n\nr.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by \n\nounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull\n\n(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if\n\n(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n \r\n \n\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n \n\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\n\n\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\n\n\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency \n\ncur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule \n\nr on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \n\n\"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \n\n\"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by \n\nl.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring\n\n(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\n \n\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, \n\n0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \n\n\"Principal Overdue\",\r\n \r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , \n\n2) as char)\r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\n\n\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\n\n\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join \n\nm_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived \n\nis false\r\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-\n\n1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} \n\nor -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds \n\nDisbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum\n\n(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin \n\nm_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand \n\n(ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull\n\n(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance \n\nSheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial \n\nBalance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); +INSERT INTO `stretchy_report` VALUES (1,'Client Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client Account No.\", \r\nc.display_name as \"Name\", \n\nc.joined_date as \"Joined\", c.external_id as \"External Id\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\nwhere o.id = ${officeId}\r\nand c.is_deleted=0\r\n\n\norder by ounder.hierarchy, c.account_no','Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).',1,1),(2,'Client Loans Listing','Table',NULL,'Client','select ounder.`name` as \"Office/Branch\", c.account_no as \"Client \n\nAccount No.\", \r\nc.display_name as \"Name\", \r\nlo.display_name as \"Loan Officer\", l.account_no as \"Loan Account No.\", l.external_id as \"External Id\", \r\n\n\np.name as Loan, st.enum_message_property as \"Status\", \r\nf.`name` as Fund,\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount,\n\n\r\nl.arrearstolerance_amount as \"Arrears Tolerance Amount\",\r\nl.number_of_repayments as \"Expected No. Repayments\",\r\nl.annual_nominal_interest_rate as \" Annual \n\nNominal Interest Rate\", \r\nl.nominal_interest_rate_per_period as \"Nominal Interest Rate Per Period\",\r\n\r\nipf.enum_message_property as \"Interest Rate Frequency\n\n\",\r\nim.enum_message_property as \"Interest Method\",\r\nicp.enum_message_property as \"Interest Calculated in Period\",\r\nl.term_frequency as \"Term Frequency\",\n\n\r\ntf.enum_message_property as \"Term Frequency Period\",\r\nl.repay_every as \"Repayment Frequency\",\r\nrf.enum_message_property as \"Repayment Frequency Period\",\n\n\r\nam.enum_message_property as \"Amortization\",\r\n\r\nl.total_charges_due_at_disbursement_derived as \"Total Charges Due At Disbursement\",\r\n\r\ndate( \n\nl.submittedon_date) as Submitted, date(l.approvedon_date) Approved, l.expected_disbursedon_date As \"Expected Disbursal\",\r\ndate(l.expected_firstrepaymenton_date) as \n\n\"Expected First Repayment\", date(l.interest_calculated_from_date) as \"Interest Calculated From\" ,\r\ndate(l.disbursedon_date) as Disbursed, date\n\n(l.expected_maturedon_date) \"Expected Maturity\",\r\ndate(l.maturedon_date) as \"Matured On\", date(l.closedon_date) as Closed,\r\ndate(l.rejectedon_date) as \n\nRejected, date(l.rescheduledon_date) as Rescheduled, \r\ndate(l.withdrawnon_date) as Withdrawn, date(l.writtenoffon_date) \"Written Off\"\r\nfrom m_office o \r\njoin \n\nm_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on \n\nc.office_id = ounder.id\r\nleft join m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_product_loan p on p.id = \n\nl.product_id\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join r_enum_value st on st.enum_name = \"loan_status_id\" and st.enum_id = l.loan_status_id\r\nleft join \n\nr_enum_value ipf on ipf.enum_name = \"interest_period_frequency_enum\" and ipf.enum_id = l.interest_period_frequency_enum\r\nleft join r_enum_value im on im.enum_name \n\n= \"interest_method_enum\" and im.enum_id = l.interest_method_enum\r\nleft join r_enum_value tf on tf.enum_name = \"term_period_frequency_enum\" and tf.enum_id = \n\nl.term_period_frequency_enum\r\nleft join r_enum_value icp on icp.enum_name = \"interest_calculated_in_period_enum\" and icp.enum_id = \n\nl.interest_calculated_in_period_enum\r\nleft join r_enum_value rf on rf.enum_name = \"repayment_period_frequency_enum\" and rf.enum_id = \n\nl.repayment_period_frequency_enum\r\nleft join r_enum_value am on am.enum_name = \"amortization_method_enum\" and am.enum_id = l.amortization_method_enum\r\n\r\nleft \n\njoin m_currency cur on cur.code = l.currency_code\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\norder by ounder.hierarchy, 2 , l.id','Individual Client Report\r\n\r\nPretty \n\nwide report that lists the basic details of client loans. \r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t have that client browser/memory impact).',1,1),(5,'Loans Awaiting Disbursal','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", \r\nc.display_name as \"Name\", l.account_no as \"Loan Account No.\", pl.`name` as \"Product\", \r\nf.`name` as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nl.principal_amount as Principal, \r\ndate(l.approvedon_date) \"Approved\", l.expected_disbursedon_date \"Expected Disbursal\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\norder by ounder.hierarchy, l.expected_disbursedon_date, c.display_name','Individual Client Report',1,1),(6,'Loans Awaiting Disbursal Summary','Table',NULL,'Loan Portfolio','SELECT ounder.`name` \n\nas \"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, f.`name` as Fund,\r\nsum(l.principal_amount) as \n\nPrincipal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat\n\n(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_product_loan pl on pl.id = \n\nl.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\n\n\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, l.currency_code, f.`name`\r\norder by ounder.hierarchy, pl.`name`, \n\nl.currency_code, f.`name`','Individual Client Report',1,1),(7,'Loans Awaiting Disbursal Summary by Month','Table',NULL,'Loan Portfolio','SELECT ounder.`name` as \n\n\"Office/Branch\", pl.`name` as \"Product\", \r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nyear(l.expected_disbursedon_date) as \"Year\", \n\nmonthname(l.expected_disbursedon_date) as \"Month\",\r\nsum(l.principal_amount) as Principal\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like \n\nconcat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on \n\nl.client_id = c.id\r\njoin m_product_loan pl on pl.id = l.product_id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = \n\nl.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand \n\n(l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \n\n\"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 200\r\ngroup by ounder.hierarchy, pl.`name`, \n\nl.currency_code, year(l.expected_disbursedon_date), month(l.expected_disbursedon_date)\r\norder by ounder.hierarchy, pl.`name`, l.currency_code, year\n\n(l.expected_disbursedon_date), month(l.expected_disbursedon_date)','Individual Client Report',1,1),(10,'Active Loans Portfolio Status','Table',NULL,'Loan','select \n\nounder.`name` as \"Office/Branch\", lo.display_name as \"Loan Officer\", c.display_name as \"Name\", \r\np.`name` as Loan, f.`name` as Fund, l.account_no as \"Loan \n\nAccount No\",\r\nl.disbursedon_date as Disbursed, ifnull(cur.display_symbol, l.currency_code) as Currency,\r\nsum(r.principal_amount - ifnull\n\n(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(r.interest_amount - ifnull(r.interest_completed_derived, 0)) as \"Interest Outstanding\",\r\n\n\n\r\nif(datediff(curdate(), min(r.duedate)) < 0, 0, datediff(curdate(), min(r.duedate))) as \"Days Overdue\", \r\nmin(r.installment) as \"First Overdue Installment\n\n\",\r\nmin(r.duedate) as \"First Overdue Installment Date\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, \n\n0))\r\n , 0)) as \"Principal Overdue\",\r\nsum(if(r.duedate <= curdate(), \r\n (ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, \n\n0))\r\n , 0)) as \"Interest Overdue\"\r\n\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand \n\nounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join \n\nm_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan \n\np on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\n\n\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \n\n\"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 \n\n= ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.id\r\norder by ounder.hierarchy, p.`name`, l.currency_code, c.display_name, l.account_no','Individual Client \n\nReport',1,1),(11,'Active Loans Summary per Branch','Table',NULL,'Loan Portfolio','select ounder.`name` as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency,\r\ncount(distinct(c.id)) as \"No. of Clients\", count(distinct(l.id)) as \"No. of Active Loans\",\r\ncount(distinct(if(r.duedate <= curdate(), \r\n if(r.principal_amount - ifnull(r.principal_completed_derived, 0) > 0, l.id, null), null)\r\n )) as \"No. of Loans in Arrears\",\r\n\r\nsum(l.principal_amount) as \"Total Loans Disbursed\",\r\nsum(ifnull(r.principal_completed_derived, 0)) as \"Total Principal Repaid\",\r\nsum(ifnull(r.interest_completed_derived, 0)) as \"Total Interest Repaid\",\r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Total Principal Outstanding\",\r\nsum(ifnull(r.interest_amount, 0) - ifnull(r.interest_completed_derived, 0)) as \"Total Interest utstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Total Principal in Arrears\",\r\ncast(round((sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(15,'Portfolio at Risk','Table',NULL,'Loan Portfolio','select ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) * 100) / sum(r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 2) as char)\r\n as \"Portfolio at Risk %\"\r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by l.currency_code\r\norder by l.currency_code',NULL,1,1),(16,'Portfolio at Risk by Branch','Table',NULL,'Loan Portfolio','select concat(substring(\"........................................\", 1, \r\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1) * 4)), \r\nounder.`name`) as \"Office/Branch\",\r\nifnull(cur.display_symbol, l.currency_code) as Currency, \r\nsum(r.principal_amount - ifnull(r.principal_completed_derived, 0)) as \"Principal Outstanding\",\r\nsum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0))\r\n , 0)) as \"Principal Overdue\",\r\n cast(round(\r\n (sum(if(r.duedate <= curdate(), \r\n (r.principal_amount - ifnull(r.principal_completed_derived, 0)) , 0)) * 100) / \r\n sum(r.principal_amount - ifnull(r.principal_completed_derived, 0)), 2) as char) \r\n as \"Portfolio at Risk %\"\r\n \r\nfrom m_office o \r\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\nleft join m_staff lo on lo.id = l.loan_officer_id\r\nleft join m_currency cur on cur.code = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nleft join m_product_loan p on p.id = l.product_id\r\nleft join m_loan_repayment_schedule r on r.loan_id = l.id\r\n and r.completed_derived is false\r\nwhere o.id = ${officeId}\r\nand (l.currency_code = \"${currencyId}\" or \"-1\" = \"${currencyId}\")\r\nand (l.product_id = \"${loanProductId}\" or \"-1\" = \"${loanProductId}\")\r\nand (ifnull(l.loan_officer_id, -10) = \"${loanOfficerId}\" or \"-1\" = \"${loanOfficerId}\")\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand l.loan_status_id = 300\r\ngroup by ounder.hierarchy, l.currency_code\r\norder by ounder.hierarchy, l.currency_code',NULL,1,1),(20,'Funds Disbursed Between Dates Summary','Table',NULL,'Fund','select ifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, \r\nround(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office ounder \r\njoin m_client c on c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand (l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\ngroup by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)\r\norder by ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(21,'Funds Disbursed Between Dates Summary by Office','Table',NULL,'Fund','select ounder.`name` as \"Office/Branch\", \n\nifnull(f.`name`, \'-\') as Fund, ifnull(cur.display_symbol, l.currency_code) as Currency, round(sum(l.principal_amount), 4) as disbursed_amount\r\nfrom m_office o\r\n\n\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\r\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\r\njoin m_client c \n\non c.office_id = ounder.id\r\njoin m_loan l on l.client_id = c.id\r\njoin m_currency cur on cur.`code` = l.currency_code\r\nleft join m_fund f on f.id = l.fund_id\r\n\n\nwhere disbursedon_date between \'${startDate}\' and \'${endDate}\'\r\nand o.id = ${officeId}\r\nand (ifnull(l.fund_id, -10) = ${fundId} or -1 = ${fundId})\r\nand \n\n(l.currency_code = \'${currencyId}\' or \'-1\' = \'${currencyId}\')\r\ngroup by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, \n\nl.currency_code)\r\norder by ounder.`name`, ifnull(f.`name`, \'-\') , ifnull(cur.display_symbol, l.currency_code)',NULL,1,1),(48,'Balance Sheet','Pentaho',NULL,'Accounting',NULL,'Balance Sheet',1,0),(49,'Income Statement','Pentaho',NULL,'Accounting',NULL,'Profit and Loss Statement',1,0),(50,'Trial Balance','Pentaho',NULL,'Accounting',NULL,'Trial Balance Report',1,0); /*!40000 ALTER TABLE `stretchy_report` ENABLE KEYS */; UNLOCK TABLES; @@ -1834,6 +1868,7 @@ CREATE TABLE `x_registered_table` ( LOCK TABLES `x_registered_table` WRITE; /*!40000 ALTER TABLE `x_registered_table` DISABLE KEYS */; +INSERT INTO `x_registered_table` VALUES ('extra_client_details','m_client'),('extra_family_details','m_loan'),('extra_loan_details','m_loan'); /*!40000 ALTER TABLE `x_registered_table` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -1846,4 +1881,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2013-02-07 15:16:33 +-- Dump completed on 2013-02-13 13:46:24 diff --git a/mifosng-db/multi-tenant-demo-backups/default-demo/extra-datatables-and-code-values.sql b/mifosng-db/multi-tenant-demo-backups/default-demo/extra-datatables-and-code-values.sql index 6b36bb3a1..4b5c4baa5 100644 --- a/mifosng-db/multi-tenant-demo-backups/default-demo/extra-datatables-and-code-values.sql +++ b/mifosng-db/multi-tenant-demo-backups/default-demo/extra-datatables-and-code-values.sql @@ -1,13 +1,53 @@ -- add code and code values for datatables dropdowns -INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (2, 'Gender', 1); -INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (3, 'Education', 1); -INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Male', 1); -INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Female', 2); +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Male', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Gender"; -INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Primary', 1); -INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Secondary', 2); -INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'University', 3); +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Female', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Gender"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.Yes', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "YesNo"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'option.No', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "YesNo"; + +INSERT INTO `m_code` +(`code_name`, `is_system_defined`) +VALUES +('Education',1); + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Primary', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Education"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'Secondary', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Education"; + +INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) +select mc.id, 'University', ifnull(max(mv.id), 1) +from m_code mc +join m_code_value mv on mv.code_id = mc.id +where mc.`code_name` = "Education"; + +-- ========= datatables======= DROP TABLE IF EXISTS `extra_client_details`; CREATE TABLE `extra_client_details` ( @@ -49,4 +89,12 @@ CREATE TABLE `extra_loan_details` ( `Comment` text, PRIMARY KEY (`loan_id`), CONSTRAINT `FK_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- datatables mapping +INSERT INTO `x_registered_table` +(`registered_table_name`,`application_table_name`) +VALUES +('extra_client_details', 'm_client'), +('extra_family_details', 'm_loan'), +('extra_loan_details', 'm_loan'); \ No newline at end of file diff --git a/mifosng-db/patches/06-alter-loan-add-loanpurpose-add-loan-collateral-table.sql b/mifosng-db/patches/06-alter-loan-add-loanpurpose-add-loan-collateral-table.sql new file mode 100644 index 000000000..872b09235 --- /dev/null +++ b/mifosng-db/patches/06-alter-loan-add-loanpurpose-add-loan-collateral-table.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS `m_loan_collateral`; +CREATE TABLE `m_loan_collateral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `loan_id` bigint(20) NOT NULL, + `type_cv_id` int(11) NOT NULL, + `description` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK_collateral_m_loan` (`loan_id`), + KEY `FK_collateral_code_value` (`type_cv_id`), + CONSTRAINT `FK_collateral_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`), + CONSTRAINT `FK_collateral_code_value` FOREIGN KEY (`type_cv_id`) REFERENCES `m_code_value` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +ALTER TABLE `m_loan` +ADD COLUMN `loanpurpose_cv_id` INT(11) DEFAULT NULL AFTER `guarantor_id`, +ADD KEY `FK_m_loanpurpose_codevalue` (`loanpurpose_cv_id`), +ADD CONSTRAINT `FK_m_loanpurpose_codevalue` FOREIGN KEY (`loanpurpose_cv_id`) REFERENCES `m_code_value` (`id`); \ No newline at end of file diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index b7b954ae0..ca062319b 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -100,6 +100,7 @@ dependencies { [group: 'com.sun.jersey.contribs', name: 'jersey-multipart', version: jerseyVersion], [group: 'com.google.code.gson', name: 'gson', version: '2.2.2'], + [group: 'com.google.guava', name: 'guava', version: '14.0-rc2'], [group: 'org.springframework.data', name: 'spring-data-jpa', version: springDataJpaVersion], diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java index 454c157d9..d38794194 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java @@ -18,6 +18,10 @@ public class CodeValueData { return new CodeValueData(id, name, position); } + public static CodeValueData instance(final Long id, final String name) { + return new CodeValueData(id, name, null); + } + private CodeValueData(final Long id, final String name, final Integer position) { this.id = id; this.name = name; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java index 6f5a537fe..e118423fd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java @@ -12,6 +12,7 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.codes.CodeConstants.CODEVALUE_JSON_INPUT_PARAMS; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -81,4 +82,7 @@ public class CodeValue extends AbstractPersistable { return actualChanges; } + public CodeValueData toData() { + return CodeValueData.instance(this.getId(), this.label, this.position); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepositoryWrapper.java new file mode 100644 index 000000000..f806148be --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepositoryWrapper.java @@ -0,0 +1,34 @@ +package org.mifosplatform.infrastructure.codes.domain; + +import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + *

+ * Wrapper for {@link CodeValueRepository} that is responsible for checking if + * {@link CodeValue} is returned when using findOne repository + * method and throwing an appropriate not found exception. + *

+ * + *

+ * This is to avoid need for checking and throwing in multiple areas of code + * base where {@link CodeValueRepository} is required. + *

+ */ +@Service +public class CodeValueRepositoryWrapper { + + private final CodeValueRepository repository; + + @Autowired + public CodeValueRepositoryWrapper(final CodeValueRepository repository) { + this.repository = repository; + } + + public CodeValue findOneWithNotFoundDetection(final Long id) { + final CodeValue codeValue = this.repository.findOne(id); + if (codeValue == null) { throw new CodeValueNotFoundException(id); } + return codeValue; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java index 0b191d500..5736e2abf 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java @@ -9,20 +9,25 @@ import org.mifosplatform.infrastructure.codes.data.CodeValueData; * * There are two types of code information in the platform: *
    - *
  1. System defined codes
  2. - *
  3. User defined codes
  4. + *
  5. System defined codes
  6. + *
  7. User defined codes
  8. *
* - *

System defined codes cannot be altered or removed but their code values may be allowed to be added to or removed.

+ *

+ * System defined codes cannot be altered or removed but their code values may + * be allowed to be added to or removed. + *

* - *

User defined codes can be changed in any way by application users with system permissions.

+ *

+ * User defined codes can be changed in any way by application users with system + * permissions. + *

*/ public interface CodeValueReadPlatformService { - // system defined code value data - Collection retrieveCustomIdentifierCodeValues(); - - Collection retrieveAllCodeValues(final Long codeId); - - CodeValueData retrieveCodeValue(final Long codeValueId); + Collection retrieveCodeValuesByCode(final String code); + + Collection retrieveAllCodeValues(final Long codeId); + + CodeValueData retrieveCodeValue(final Long codeValueId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java index e7ca06021..42a78d33c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java @@ -43,14 +43,14 @@ public class CodeValueReadPlatformServiceImpl implements CodeValueReadPlatformSe } @Override - public Collection retrieveCustomIdentifierCodeValues() { + public Collection retrieveCodeValuesByCode(final String code) { context.authenticatedUser(); final CodeValueDataMapper rm = new CodeValueDataMapper(); final String sql = "select " + rm.schema() + "where c.code_name like ? order by position"; - return this.jdbcTemplate.query(sql, rm, new Object[] { "Customer Identifier" }); + return this.jdbcTemplate.query(sql, rm, new Object[] { code }); } @Override @@ -63,16 +63,16 @@ public class CodeValueReadPlatformServiceImpl implements CodeValueReadPlatformSe return this.jdbcTemplate.query(sql, rm, new Object[] { codeId }); } - + @Override - public CodeValueData retrieveCodeValue(Long codeValueId){ - + public CodeValueData retrieveCodeValue(Long codeValueId) { + context.authenticatedUser(); final CodeValueDataMapper rm = new CodeValueDataMapper(); final String sql = "select " + rm.schema() + "where cv.id = ? order by position"; return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { codeValueId }); - + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java index fd8baedf5..419de2230 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java @@ -11,6 +11,8 @@ public class DataValidatorBuilder { private final List dataValidationErrors; private String resource; private String parameter; + private String arrayPart; + private Integer arrayIndex; private Object value; private boolean ignoreNullValue = false; @@ -32,6 +34,12 @@ public class DataValidatorBuilder { return this; } + public DataValidatorBuilder parameterAtIndexArray(final String arrayPart, final Integer arrayIndex) { + this.arrayPart = arrayPart; + this.arrayIndex = arrayIndex; + return this; + } + public DataValidatorBuilder value(Object value) { this.value = value; return this; @@ -102,11 +110,19 @@ public class DataValidatorBuilder { public DataValidatorBuilder notNull() { if (value == null && !ignoreNullValue) { - StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter) - .append(".cannot.be.blank"); - StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter).append(" cannot be blank."); + + String realParameterName = this.parameter; + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter); + if (this.arrayIndex != null && StringUtils.isNotBlank(arrayPart)) { + validationErrorCode.append(".").append(this.arrayPart); + realParameterName = new StringBuilder(parameter).append('[').append(this.arrayIndex).append("][").append(arrayPart).append(']') + .toString(); + } + + validationErrorCode.append(".cannot.be.blank"); + StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(realParameterName).append(" is mandatory."); ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), - parameter); + realParameterName, arrayIndex); dataValidationErrors.add(error); } return this; @@ -116,11 +132,18 @@ public class DataValidatorBuilder { if (value == null && ignoreNullValue) { return this; } if (value == null || StringUtils.isBlank(value.toString())) { - StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter) - .append(".cannot.be.blank"); - StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter).append(" cannot be blank."); + String realParameterName = this.parameter; + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter); + if (this.arrayIndex != null && StringUtils.isNotBlank(arrayPart)) { + validationErrorCode.append(".").append(this.arrayPart); + realParameterName = new StringBuilder(parameter).append('[').append(this.arrayIndex).append("][").append(arrayPart).append(']') + .toString(); + } + + validationErrorCode.append(".cannot.be.blank"); + StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(realParameterName).append(" is mandatory."); ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), - parameter); + realParameterName, arrayIndex); dataValidationErrors.add(error); } return this; @@ -247,6 +270,15 @@ public class DataValidatorBuilder { return this; } + public void expectedArrayButIsNot() { + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter) + .append(".is.not.an.array"); + StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter).append(" is not an array."); + ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), + parameter); + dataValidationErrors.add(error); + } + public DataValidatorBuilder anyOfNotNull(Object... object) { boolean hasData = false; for (Object obj : object) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/FromJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/FromJsonHelper.java index 928a733fa..6be723ef2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/FromJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/FromJsonHelper.java @@ -36,7 +36,7 @@ public class FromJsonHelper { public Map extractMap(final Type typeOfMap, final String json) { return this.gsonConverter.fromJson(json, typeOfMap); } - + public Map extractDataMap(final Type typeOfMap, final String json) { return this.gsonConverter.fromJson(json, typeOfMap); } @@ -45,6 +45,10 @@ public class FromJsonHelper { return this.gsonConverter.fromJson(json, classOfT); } + public String toJson(final JsonElement jsonElement) { + return this.gsonConverter.toJson(jsonElement); + } + public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set supportedParams) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -63,11 +67,11 @@ public class FromJsonHelper { public JsonElement parse(final String json) { return parser.parse(json); } - + public boolean parameterExists(final String parameterName, final JsonElement element) { return helperDelegator.parameterExists(parameterName, element); } - + public String extractStringNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractStringNamed(parameterName, element, new HashSet()); } @@ -79,11 +83,11 @@ public class FromJsonHelper { public Long extractLongNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractLongNamed(parameterName, element, new HashSet()); } - + public Long extractLongNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractLongNamed(parameterName, element, parametersPassedInRequest); } - + public String[] extractArrayNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractArrayNamed(parameterName, element, new HashSet()); } @@ -91,7 +95,7 @@ public class FromJsonHelper { public String[] extractArrayNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractArrayNamed(parameterName, element, parametersPassedInRequest); } - + public Boolean extractBooleanNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractBooleanNamed(parameterName, element, new HashSet()); } @@ -99,11 +103,11 @@ public class FromJsonHelper { public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest); } - + public LocalDate extractLocalDateNamed(final String parameterName, JsonElement element) { return helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet()); } - + public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, final String dateFormat, final Locale locale) { return helperDelegator.extractLocalDateNamed(parameterName, element.getAsJsonObject(), dateFormat, locale, new HashSet()); @@ -122,7 +126,7 @@ public class FromJsonHelper { public BigDecimal extractBigDecimalWithLocaleNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, new HashSet()); } - + public BigDecimal extractBigDecimalWithLocaleNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, parametersPassedInRequest); @@ -131,31 +135,30 @@ public class FromJsonHelper { public BigDecimal extractBigDecimalNamed(final String parameterName, final JsonElement element, final Locale locale) { return helperDelegator.extractBigDecimalNamed(parameterName, element.getAsJsonObject(), locale, new HashSet()); } - + public BigDecimal extractBigDecimalNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractBigDecimalNamed(parameterName, element.getAsJsonObject(), Locale.US, parametersPassedInRequest); } - + public Integer extractIntegerWithLocaleNamed(final String parameterName, final JsonElement element) { return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), new HashSet()); } - - public Integer extractIntegerSansLocaleNamed(final String parameterName, final JsonElement element){ - return helperDelegator.extractIntegerSansLocaleNamed(parameterName, element.getAsJsonObject(), new HashSet()); + + public Integer extractIntegerSansLocaleNamed(final String parameterName, final JsonElement element) { + return helperDelegator.extractIntegerSansLocaleNamed(parameterName, element.getAsJsonObject(), new HashSet()); } - + public Integer extractIntegerWithLocaleNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), parametersPassedInRequest); } - + public Integer extractIntegerNamed(final String parameterName, final JsonElement element, final Locale locale) { return helperDelegator.extractIntegerNamed(parameterName, element.getAsJsonObject(), locale, new HashSet()); } - public Integer extractIntegerNamed(final String parameterName, final JsonElement element, - final Set parametersPassedInRequest) { + public Integer extractIntegerNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { return helperDelegator.extractIntegerNamed(parameterName, element.getAsJsonObject(), Locale.US, parametersPassedInRequest); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanChargeNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanChargeNotFoundException.java index 27dd6ec35..18d664c02 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanChargeNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanChargeNotFoundException.java @@ -4,7 +4,8 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRul import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; /** - * {@link AbstractPlatformDomainRuleException} thrown when loan charge does not exist. + * {@link AbstractPlatformDomainRuleException} thrown when loan charge does not + * exist. */ public class LoanChargeNotFoundException extends AbstractPlatformResourceNotFoundException { @@ -12,7 +13,8 @@ public class LoanChargeNotFoundException extends AbstractPlatformResourceNotFoun super("error.msg.loanCharge.id.invalid", "Loan charge with identifier " + id + " does not exist", id); } - public LoanChargeNotFoundException(final Long id, final Long loanId) { - super("error.msg.loanCharge.id.invalid.for.given.loan", "Loan charge with identifier " + id + " does not exist for loan " + loanId, id, loanId); - } -} + public LoanChargeNotFoundException(final Long id, final Long loanId) { + super("error.msg.loanCharge.id.invalid.for.given.loan", "Loan charge with identifier " + id + " does not exist for loan " + loanId, + id, loanId); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanCollateralNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanCollateralNotFoundException.java new file mode 100644 index 000000000..8619c87bd --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/exception/LoanCollateralNotFoundException.java @@ -0,0 +1,20 @@ +package org.mifosplatform.portfolio.charge.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + +/** + * {@link AbstractPlatformDomainRuleException} thrown when loan collateral does + * not exist. + */ +public class LoanCollateralNotFoundException extends AbstractPlatformResourceNotFoundException { + + public LoanCollateralNotFoundException(final Long id) { + super("error.msg.loanCollateral.id.invalid", "Loan collateral with identifier " + id + " does not exist", id); + } + + public LoanCollateralNotFoundException(final Long id, final Long loanId) { + super("error.msg.loanCollateral.id.invalid.for.given.loan", "Loan collateral with identifier " + id + " does not exist for loan " + + loanId, id, loanId); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java index 33528b53d..fd2eeb4c3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientIdentifiersApiResource.java @@ -87,7 +87,7 @@ public class ClientIdentifiersApiResource { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); - final Collection codeValues = codeValueReadPlatformService.retrieveCustomIdentifierCodeValues(); + final Collection codeValues = codeValueReadPlatformService.retrieveCodeValuesByCode("Customer Identifier"); final ClientIdentifierData clientIdentifierData = ClientIdentifierData.template(codeValues); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); @@ -132,7 +132,8 @@ public class ClientIdentifiersApiResource { ClientIdentifierData clientIdentifierData = this.clientReadPlatformService.retrieveClientIdentifier(clientId, clientIdentifierId); if (settings.isTemplate()) { - final Collection codeValues = codeValueReadPlatformService.retrieveCustomIdentifierCodeValues(); + final Collection codeValues = codeValueReadPlatformService + .retrieveCodeValuesByCode("Customer Identifier"); clientIdentifierData = ClientIdentifierData.template(clientIdentifierData, codeValues); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 79f85b3eb..d11fd2a99 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -7,7 +7,7 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.codes.domain.CodeValue; -import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; @@ -22,8 +22,8 @@ import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientNoteCommand; -import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; +import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; @@ -54,7 +54,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP private final ClientIdentifierRepository clientIdentifierRepository; private final OfficeRepository officeRepository; private final NoteRepository noteRepository; - private final CodeValueRepository codeValueRepository; + private final CodeValueRepositoryWrapper codeValueRepository; private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer; private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; @@ -63,7 +63,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP @Autowired public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository, final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository, - final NoteRepository noteRepository, final CodeValueRepository codeValueRepository, + final NoteRepository noteRepository, final CodeValueRepositoryWrapper codeValueRepository, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer, final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer, @@ -254,9 +254,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP final Client client = this.clientRepository.findOne(clientId); if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } - final CodeValue documentType = this.codeValueRepository.findOne(clientIdentifierCommand.getDocumentTypeId()); - if (documentType == null) { throw new CodeValueNotFoundException(clientIdentifierCommand.getDocumentTypeId()); } - + final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand.getDocumentTypeId()); documentTypeId = documentType.getId(); documentTypeLabel = documentType.label(); @@ -297,7 +295,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP final Map changes = clientIdentifierForUpdate.update(command); if (changes.containsKey("documentTypeId")) { - documentType = this.codeValueRepository.findOne(documentTypeId); + documentType = this.codeValueRepository.findOneWithNotFoundDetection(documentTypeId); if (documentType == null) { throw new CodeValueNotFoundException(documentTypeId); } documentTypeId = documentType.getId(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java index 0330b0b09..9241ded64 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java @@ -23,6 +23,8 @@ import org.joda.time.LocalDate; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.JsonQuery; @@ -46,6 +48,7 @@ import org.mifosplatform.portfolio.loanaccount.data.DisbursementData; import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData; import org.mifosplatform.portfolio.loanaccount.data.LoanBasicDetailsData; import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData; +import org.mifosplatform.portfolio.loanaccount.data.LoanCollateralData; import org.mifosplatform.portfolio.loanaccount.data.LoanPermissionData; import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorData; @@ -53,6 +56,7 @@ import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorReadPl import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService; import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService; +import org.mifosplatform.portfolio.loanaccount.service.LoanCollateralReadPlatformService; import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData; @@ -71,16 +75,17 @@ import com.google.gson.JsonElement; public class LoansApiResource { private final Set LOAN_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "accountNo", "externalId", "clientId", - "groupId", "clientName", "groupName", "fundId", "fundName", "loanProductId", "loanProductName", "loanProductDescription", - "currency", "principal", "inArrearsTolerance", "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod", - "annualInterestRate", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", - "interestCalculationPeriodType", "submittedOnDate", "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate", - "expectedFirstRepaymentOnDate", "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status", - "lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "guarantor", "productOptions", + "groupId", "clientName", "groupName", "fundId", "fundName", "loanPurposeId", "loanOfficerId", "loanOfficerName", + "loanPurposeName", "loanProductId", "loanProductName", "loanProductDescription", "currency", "principal", "inArrearsTolerance", + "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod", "annualInterestRate", "repaymentFrequencyType", + "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "submittedOnDate", + "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate", "expectedFirstRepaymentOnDate", + "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status", "lifeCycleStatusDate", "repaymentSchedule", + "transactions", "permissions", "convenienceData", "charges", "guarantor", "collateral", "productOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions", - "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "loanOfficerId", - "loanOfficerName", "loanOfficerOptions", "chargeTemplate", "transactionProcessingStrategyId", - "termFrequency", "termPeriodFrequencyType")); + "termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", + "loanOfficerOptions", "chargeTemplate", "transactionProcessingStrategyId", "termFrequency", "termPeriodFrequencyType", + "loanPurposeOptions", "loanCollateralOptions")); private final String resourceNameForPermissions = "LOAN"; @@ -91,9 +96,11 @@ public class LoansApiResource { private final FundReadPlatformService fundReadPlatformService; private final ChargeReadPlatformService chargeReadPlatformService; private final LoanChargeReadPlatformService loanChargeReadPlatformService; + private final LoanCollateralReadPlatformService loanCollateralReadPlatformService; private final LoanScheduleCalculationPlatformService calculationPlatformService; private final StaffReadPlatformService staffReadPlatformService; private final GuarantorReadPlatformService guarantorReadPlatformService; + private final CodeValueReadPlatformService codeValueReadPlatformService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final DefaultToApiJsonSerializer loanScheduleToApiJsonSerializer; private final DefaultToApiJsonSerializer loanOfficeTransferToApiJsonSerializer; @@ -106,8 +113,10 @@ public class LoansApiResource { final LoanProductReadPlatformService loanProductReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService, final LoanChargeReadPlatformService loanChargeReadPlatformService, + final LoanCollateralReadPlatformService loanCollateralReadPlatformService, final LoanScheduleCalculationPlatformService calculationPlatformService, final StaffReadPlatformService staffReadPlatformService, final GuarantorReadPlatformService guarantorReadPlatformService, + final CodeValueReadPlatformService codeValueReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final DefaultToApiJsonSerializer loanScheduleToApiJsonSerializer, final DefaultToApiJsonSerializer loanOfficeTransferToApiJsonSerializer, @@ -120,9 +129,11 @@ public class LoansApiResource { this.fundReadPlatformService = fundReadPlatformService; this.chargeReadPlatformService = chargeReadPlatformService; this.loanChargeReadPlatformService = loanChargeReadPlatformService; + this.loanCollateralReadPlatformService = loanCollateralReadPlatformService; this.calculationPlatformService = calculationPlatformService; this.staffReadPlatformService = staffReadPlatformService; this.guarantorReadPlatformService = guarantorReadPlatformService; + this.codeValueReadPlatformService = codeValueReadPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; this.loanScheduleToApiJsonSerializer = loanScheduleToApiJsonSerializer; this.loanOfficeTransferToApiJsonSerializer = loanOfficeTransferToApiJsonSerializer; @@ -135,12 +146,11 @@ public class LoansApiResource { @Path("template") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveDetailsForNewLoanApplicationStepOne(@QueryParam("clientId") final Long clientId, - @QueryParam("groupId") final Long groupId, @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { + public String templateForNewLoanApplication(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId, + @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); - // tempate related Collection productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup(); Collection loanTermFrequencyTypeOptions = dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions(); Collection repaymentFrequencyTypeOptions = dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions(); @@ -160,26 +170,34 @@ public class LoansApiResource { Collection chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly); ChargeData chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate(); - LoanBasicDetailsData loanBasicDetails; - Long officeId; + LoanBasicDetailsData loanBasicDetails = null; + Collection charges = null; + Collection collateral = null; + Collection guarantors = null; + Collection allowedLoanOfficers = null; if (clientId != null) { loanBasicDetails = this.loanReadPlatformService.retrieveClientAndProductDetails(clientId, productId); - officeId = loanBasicDetails.getClientOfficeId(); - } else { + charges = loanBasicDetails.getCharges(); + final Long officeId = loanBasicDetails.getClientOfficeId(); + allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); + } else if (groupId != null) { loanBasicDetails = this.loanReadPlatformService.retrieveGroupAndProductDetails(groupId, productId); - officeId = loanBasicDetails.getGroupOfficeId(); + charges = loanBasicDetails.getCharges(); + final Long officeId = loanBasicDetails.getGroupOfficeId(); + allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); } + final Collection loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose"); + final Collection loanCollateralOptions = this.codeValueReadPlatformService + .retrieveCodeValuesByCode("LoanCollateral"); + final boolean convenienceDataRequired = false; - Collection charges = loanBasicDetails.getCharges(); - - Collection allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); - final LoanAccountData newLoanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, null, null, null, charges, - productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions, - interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, - fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, null); + collateral, guarantors, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, + repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, + interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, + loanCollateralOptions); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.toApiJsonSerializer.serialize(settings, newLoanAccount, LOAN_DATA_PARAMETERS); @@ -201,6 +219,7 @@ public class LoansApiResource { LoanPermissionData permissions = null; Collection charges = null; Collection guarantors = null; + Collection collateral = null; final Set mandatoryResponseParameters = new HashSet(); boolean convenienceDataRequired = false; @@ -209,14 +228,14 @@ public class LoansApiResource { if (associationParameters.contains("all")) { associationParameters.addAll(Arrays.asList("repaymentSchedule", "transactions", "permissions", "convenienceData", - "charges", "guarantor")); + "charges", "guarantor", "collateral")); } if (associationParameters.contains("guarantor")) { mandatoryResponseParameters.add("guarantor"); guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId); if (CollectionUtils.isEmpty(guarantors)) { - guarantors = null; // set back to null so doesn't appear in JSON + guarantors = null; } } @@ -233,7 +252,7 @@ public class LoansApiResource { if (associationParameters.contains("repaymentSchedule")) { mandatoryResponseParameters.add("repaymentSchedule"); } - + DisbursementData singleDisbursement = loanBasicDetails.toDisburementData(); repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(), singleDisbursement, loanBasicDetails.getTotalDisbursementCharges(), loanBasicDetails.getInArrearsTolerance()); @@ -245,7 +264,7 @@ public class LoansApiResource { if (repaymentSchedule == null) { throw new IllegalStateException(); } mandatoryResponseParameters.add("permissions"); - + // FIXME - KW - Waive feature was changed to waive interest at // anytime so this permission checking is probably not needed - // look into. @@ -271,8 +290,15 @@ public class LoansApiResource { mandatoryResponseParameters.add("charges"); charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId); if (CollectionUtils.isEmpty(charges)) { - charges = null; // set back to null so doesnt appear in JSON - // is no charges exist. + charges = null; + } + } + + if (associationParameters.contains("collateral")) { + mandatoryResponseParameters.add("collateral"); + collateral = this.loanCollateralReadPlatformService.retrieveLoanCollateral(loanId); + if (CollectionUtils.isEmpty(collateral)) { + collateral = null; } } } @@ -286,8 +312,11 @@ public class LoansApiResource { Collection interestTypeOptions = null; Collection interestCalculationPeriodTypeOptions = null; Collection fundOptions = null; + Collection allowedLoanOfficers = null; Collection chargeOptions = null; ChargeData chargeTemplate = null; + Collection loanPurposeOptions = null; + Collection loanCollateralOptions = null; final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); if (template) { @@ -305,14 +334,19 @@ public class LoansApiResource { final boolean feeChargesOnly = false; chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly); chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate(); + allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getOfficeId()); + loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose"); + loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral"); } final LoanAccountData loanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, repaymentSchedule, - loanRepayments, permissions, charges, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, - repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, - interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, null, guarantors); + loanRepayments, permissions, charges, collateral, guarantors, productOptions, loanTermFrequencyTypeOptions, + repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, + interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, + loanPurposeOptions, loanCollateralOptions); - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(), mandatoryResponseParameters); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(), + mandatoryResponseParameters); return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS); } @@ -413,7 +447,7 @@ public class LoansApiResource { final CommandWrapper commandRequest = builder.undoLoanApplicationDisbursal(loanId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } - + if (is(commandParam, "assignloanofficer")) { final CommandWrapper commandRequest = builder.assignLoanOfficer(loanId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanChargeCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanChargeCommand.java index ecc5673da..e2dec0924 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanChargeCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanChargeCommand.java @@ -14,14 +14,18 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation */ public class LoanChargeCommand implements Comparable { + @SuppressWarnings("unused") + private final Long id; private final Long chargeId; private final BigDecimal amount; private final Integer chargeTimeType; - private final LocalDate specifiedDueDate; private final Integer chargeCalculationType; + @SuppressWarnings("unused") + private final LocalDate specifiedDueDate; - public LoanChargeCommand(final Long chargeId, final BigDecimal amount, final Integer chargeTimeType, + public LoanChargeCommand(final Long id, final Long chargeId, final BigDecimal amount, final Integer chargeTimeType, final Integer chargeCalculationType, final LocalDate specifiedDueDate) { + this.id = id; this.chargeId = chargeId; this.amount = amount; this.chargeTimeType = chargeTimeType; @@ -38,28 +42,7 @@ public class LoanChargeCommand implements Comparable { return comparison; } - public void validateForCreate() { - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge"); - - baseDataValidator.reset().parameter("chargeId").value(this.chargeId).notNull().longGreaterThanZero(); - baseDataValidator.reset().parameter("amount").value(this.amount).notNull().positiveAmount(); - // baseDataValidator.reset().parameter("chargeTimeType").value(command.getChargeTimeType()).ignoreIfNull().inMinMaxRange(1, - // 2); - // - // if (command.getChargeTimeType().equals(Integer.valueOf(2))) { - // // date must be provided - // baseDataValidator.reset().parameter("specifiedDueDate").value(command.getSpecifiedDueDate()).notNull(); - // } - // - // baseDataValidator.reset().parameter("chargeCalculationType").value(command.getChargeCalculationType()).ignoreIfNull().inMinMaxRange(1, - // 4); - - if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); } - } - + @Deprecated public void validateForUpdate() { List dataValidationErrors = new ArrayList(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java index 3fe9c16f7..785d39c5f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import java.util.Collection; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.staff.data.StaffData; @@ -34,6 +35,8 @@ public class LoanAccountData { private final EnumOptionData status; private final Long fundId; private final String fundName; + private final Long loanPurposeId; + private final String loanPurposeName; private final Long loanOfficerId; private final String loanOfficerName; private final CurrencyData currency; @@ -67,9 +70,10 @@ public class LoanAccountData { private final LoanScheduleData repaymentSchedule; private final Collection transactions; private final Collection charges; + private final Collection collateral; + private final Collection guarantors; private final LoanPermissionData permissions; private final LoanConvenienceData convenienceData; - private final Collection guarantors; // template private final Collection loanOfficerOptions; @@ -84,21 +88,27 @@ public class LoanAccountData { private final Collection fundOptions; private final Collection chargeOptions; private final ChargeData chargeTemplate; + private final Collection loanPurposeOptions; + private final Collection loanCollateralOptions; public LoanAccountData(final LoanBasicDetailsData basicDetails, final boolean convenienceDataRequired, final LoanScheduleData repaymentSchedule, final Collection transactions, final LoanPermissionData permissions, final Collection charges, + final Collection collateral, final Collection guarantors, final Collection productOptions, final Collection termFrequencyTypeOptions, final Collection repaymentFrequencyTypeOptions, final Collection repaymentStrategyOptions, final Collection interestRateFrequencyTypeOptions, final Collection amortizationTypeOptions, final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, final Collection fundOptions, final Collection chargeOptions, final ChargeData chargeTemplate, - final Collection loanOfficerOptions, final Collection guarantors) { + final Collection loanOfficerOptions, final Collection loanPurposeOptions, + final Collection loanCollateralOptions) { this.repaymentSchedule = repaymentSchedule; this.transactions = transactions; this.permissions = permissions; this.charges = charges; + this.collateral = collateral; + this.guarantors = guarantors; this.productOptions = productOptions; this.termFrequencyTypeOptions = termFrequencyTypeOptions; this.repaymentFrequencyTypeOptions = repaymentFrequencyTypeOptions; @@ -111,7 +121,8 @@ public class LoanAccountData { this.chargeOptions = chargeOptions; this.chargeTemplate = chargeTemplate; this.loanOfficerOptions = loanOfficerOptions; - this.guarantors = guarantors; + this.loanPurposeOptions = loanPurposeOptions; + this.loanCollateralOptions = loanCollateralOptions; if (convenienceDataRequired) { int maxSubmittedOnOffsetFromToday = basicDetails.getMaxSubmittedOnOffsetFromToday(); @@ -129,48 +140,98 @@ public class LoanAccountData { this.convenienceData = null; } - this.id = basicDetails.getId(); - this.accountNo = basicDetails.getAccountNo(); - this.externalId = basicDetails.getExternalId(); - this.clientId = basicDetails.getClientId(); - this.clientName = basicDetails.getClientName(); - this.groupId = basicDetails.getGroupId(); - this.groupName = basicDetails.getGroupName(); - this.loanProductId = basicDetails.getLoanProductId(); - this.loanProductName = basicDetails.getLoanProductName(); - this.loanProductDescription = basicDetails.getLoanProductDescription(); - this.fundId = basicDetails.getFundId(); - this.fundName = basicDetails.getFundName(); - this.loanOfficerId = basicDetails.getLoanOfficerId(); - this.loanOfficerName = basicDetails.getLoanOfficerName(); + if (basicDetails != null) { + this.id = basicDetails.getId(); + this.accountNo = basicDetails.getAccountNo(); + this.externalId = basicDetails.getExternalId(); + this.clientId = basicDetails.getClientId(); + this.clientName = basicDetails.getClientName(); + this.groupId = basicDetails.getGroupId(); + this.groupName = basicDetails.getGroupName(); + this.loanProductId = basicDetails.getLoanProductId(); + this.loanProductName = basicDetails.getLoanProductName(); + this.loanProductDescription = basicDetails.getLoanProductDescription(); + this.fundId = basicDetails.getFundId(); + this.fundName = basicDetails.getFundName(); + this.loanPurposeId = basicDetails.getLoanPurposeId(); + this.loanPurposeName = basicDetails.getLoanPurposeName(); + this.loanOfficerId = basicDetails.getLoanOfficerId(); + this.loanOfficerName = basicDetails.getLoanOfficerName(); - this.submittedOnDate = basicDetails.getSubmittedOnDate(); - this.approvedOnDate = basicDetails.getApprovedOnDate(); - this.expectedDisbursementDate = basicDetails.getExpectedDisbursementDate(); - this.actualDisbursementDate = basicDetails.getActualDisbursementDate(); - this.closedOnDate = basicDetails.getClosedOnDate(); - this.expectedMaturityDate = basicDetails.getExpectedMaturityDate(); - this.repaymentsStartingFromDate = basicDetails.getRepaymentsStartingFromDate(); - this.interestChargedFromDate = basicDetails.getInterestChargedFromDate(); + this.submittedOnDate = basicDetails.getSubmittedOnDate(); + this.approvedOnDate = basicDetails.getApprovedOnDate(); + this.expectedDisbursementDate = basicDetails.getExpectedDisbursementDate(); + this.actualDisbursementDate = basicDetails.getActualDisbursementDate(); + this.closedOnDate = basicDetails.getClosedOnDate(); + this.expectedMaturityDate = basicDetails.getExpectedMaturityDate(); + this.repaymentsStartingFromDate = basicDetails.getRepaymentsStartingFromDate(); + this.interestChargedFromDate = basicDetails.getInterestChargedFromDate(); - this.currency = basicDetails.getCurrency(); - this.principal = basicDetails.getPrincipal(); - this.inArrearsTolerance = basicDetails.getInArrearsTolerance(); + this.currency = basicDetails.getCurrency(); + this.principal = basicDetails.getPrincipal(); + this.inArrearsTolerance = basicDetails.getInArrearsTolerance(); - this.termFrequency = basicDetails.getTermFrequency(); - this.termPeriodFrequencyType = basicDetails.getTermPeriodFrequencyType(); - this.numberOfRepayments = basicDetails.getNumberOfRepayments(); - this.repaymentEvery = basicDetails.getRepaymentEvery(); - this.transactionProcessingStrategyId = basicDetails.getTransactionStrategyId(); - this.interestRatePerPeriod = basicDetails.getInterestRatePerPeriod(); - this.annualInterestRate = basicDetails.getAnnualInterestRate(); - this.repaymentFrequencyType = basicDetails.getRepaymentFrequencyType(); - this.interestRateFrequencyType = basicDetails.getInterestRateFrequencyType(); - this.amortizationType = basicDetails.getAmortizationType(); - this.interestType = basicDetails.getInterestType(); - this.interestCalculationPeriodType = basicDetails.getInterestCalculationPeriodType(); + this.termFrequency = basicDetails.getTermFrequency(); + this.termPeriodFrequencyType = basicDetails.getTermPeriodFrequencyType(); + this.numberOfRepayments = basicDetails.getNumberOfRepayments(); + this.repaymentEvery = basicDetails.getRepaymentEvery(); + this.transactionProcessingStrategyId = basicDetails.getTransactionStrategyId(); + this.interestRatePerPeriod = basicDetails.getInterestRatePerPeriod(); + this.annualInterestRate = basicDetails.getAnnualInterestRate(); + this.repaymentFrequencyType = basicDetails.getRepaymentFrequencyType(); + this.interestRateFrequencyType = basicDetails.getInterestRateFrequencyType(); + this.amortizationType = basicDetails.getAmortizationType(); + this.interestType = basicDetails.getInterestType(); + this.interestCalculationPeriodType = basicDetails.getInterestCalculationPeriodType(); - this.status = basicDetails.getStatus(); - this.lifeCycleStatusDate = basicDetails.getLifeCycleStatusDate(); + this.status = basicDetails.getStatus(); + this.lifeCycleStatusDate = basicDetails.getLifeCycleStatusDate(); + } else { + this.id = null; + this.accountNo = null; + this.externalId = null; + this.clientId = null; + this.clientName = null; + this.groupId = null; + this.groupName = null; + this.loanProductId = null; + this.loanProductName = null; + this.loanProductDescription = null; + this.fundId = null; + this.fundName = null; + this.loanPurposeId = null; + this.loanPurposeName = null; + this.loanOfficerId = null; + this.loanOfficerName = null; + + this.submittedOnDate = null; + this.approvedOnDate = null; + this.expectedDisbursementDate = null; + this.actualDisbursementDate = null; + this.closedOnDate = null; + this.expectedMaturityDate = null; + this.repaymentsStartingFromDate = null; + this.interestChargedFromDate = null; + + this.currency = null; + this.principal = null; + this.inArrearsTolerance = null; + + this.termFrequency = null; + this.termPeriodFrequencyType = null; + this.numberOfRepayments = null; + this.repaymentEvery = null; + this.transactionProcessingStrategyId = null; + this.interestRatePerPeriod = null; + this.annualInterestRate = null; + this.repaymentFrequencyType = null; + this.interestRateFrequencyType = null; + this.amortizationType = null; + this.interestType = null; + this.interestCalculationPeriodType = null; + + this.status = null; + this.lifeCycleStatusDate = null; + } } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanBasicDetailsData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanBasicDetailsData.java index 3e66f5f7a..4e5fa216e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanBasicDetailsData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanBasicDetailsData.java @@ -34,6 +34,8 @@ public class LoanBasicDetailsData { private final EnumOptionData status; private final Long fundId; private final String fundName; + private final Long loanPurposeId; + private final String loanPurposeName; private final Long loanOfficerId; private final String loanOfficerName; private final CurrencyData currency; @@ -120,6 +122,8 @@ public class LoanBasicDetailsData { this.status = null; this.fundId = fundId; this.fundName = fundName; + this.loanPurposeId = null; + this.loanPurposeName = null; this.loanOfficerId = null; this.loanOfficerName = null; this.currency = currency; @@ -179,6 +183,8 @@ public class LoanBasicDetailsData { this.status = null; this.fundId = null; this.fundName = null; + this.loanPurposeId = null; + this.loanPurposeName = null; this.loanOfficerId = null; this.loanOfficerName = null; this.currency = null; @@ -216,16 +222,17 @@ public class LoanBasicDetailsData { public LoanBasicDetailsData(final Long id, final String accountNo, final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final Long groupId, final String groupName, final Long groupOfficeId, final Long loanProductId, final String loanProductName, final String loanProductDescription, final Long fundId, - String fundName, final LocalDate closedOnDate, final LocalDate submittedOnDate, final LocalDate approvedOnDate, - final LocalDate expectedDisbursementDate, final LocalDate actualDisbursementDate, final LocalDate expectedMaturityDate, - final LocalDate repaymentsStartingFromDate, final LocalDate interestChargedFromDate, final CurrencyData currency, - final BigDecimal principal, final BigDecimal inArrearsTolerance, final Integer numberOfRepayments, - final Integer repaymentEvery, final BigDecimal interestRatePerPeriod, final BigDecimal annualInterestRate, - final EnumOptionData repaymentFrequencyType, final EnumOptionData interestRateFrequencyType, - final EnumOptionData amortizationType, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType, - final EnumOptionData status, final LocalDate lifeCycleStatusDate, final Integer termFrequency, - final EnumOptionData termPeriodFrequencyType, final Integer transactionStrategyId, final Collection charges, - final Long loanOfficerId, String loanOfficerName, final BigDecimal totalDisbursementCharges) { + final String fundName, final Long loanPurposeId, final String loanPurposeName, final LocalDate closedOnDate, + final LocalDate submittedOnDate, final LocalDate approvedOnDate, final LocalDate expectedDisbursementDate, + final LocalDate actualDisbursementDate, final LocalDate expectedMaturityDate, final LocalDate repaymentsStartingFromDate, + final LocalDate interestChargedFromDate, final CurrencyData currency, final BigDecimal principal, + final BigDecimal inArrearsTolerance, final Integer numberOfRepayments, final Integer repaymentEvery, + final BigDecimal interestRatePerPeriod, final BigDecimal annualInterestRate, final EnumOptionData repaymentFrequencyType, + final EnumOptionData interestRateFrequencyType, final EnumOptionData amortizationType, final EnumOptionData interestType, + final EnumOptionData interestCalculationPeriodType, final EnumOptionData status, final LocalDate lifeCycleStatusDate, + final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer transactionStrategyId, + final Collection charges, final Long loanOfficerId, String loanOfficerName, + final BigDecimal totalDisbursementCharges) { this.id = id; this.accountNo = accountNo; this.externalId = externalId; @@ -240,6 +247,8 @@ public class LoanBasicDetailsData { this.loanProductDescription = loanProductDescription; this.fundId = fundId; this.fundName = fundName; + this.loanPurposeId = loanPurposeId; + this.loanPurposeName = loanPurposeName; this.loanOfficerId = loanOfficerId; this.loanOfficerName = loanOfficerName; this.closedOnDate = closedOnDate; @@ -393,6 +402,14 @@ public class LoanBasicDetailsData { return fundName; } + public Long getLoanPurposeId() { + return this.loanPurposeId; + } + + public String getLoanPurposeName() { + return this.loanPurposeName; + } + public Long getLoanProductId() { return loanProductId; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanCollateralData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanCollateralData.java new file mode 100644 index 000000000..b21b85ee4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanCollateralData.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.loanaccount.data; + +import org.mifosplatform.infrastructure.codes.data.CodeValueData; + +/** + * Immutable data object for loan collateral data. + */ +public class LoanCollateralData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final CodeValueData type; + @SuppressWarnings("unused") + private final String description; + + public static LoanCollateralData instance(final Long id, final CodeValueData type, final String description) { + return new LoanCollateralData(id, type, description); + } + + private LoanCollateralData(final Long id, final CodeValueData type, final String description) { + this.id = id; + this.type = type; + this.description = description; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 8ae52488e..645e3ffb8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -2,7 +2,6 @@ package org.mifosplatform.portfolio.loanaccount.domain; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -33,6 +32,7 @@ import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.core.service.DateUtils; @@ -46,6 +46,7 @@ import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand; +import org.mifosplatform.portfolio.loanaccount.data.LoanCollateralData; import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanStateTransitionException; import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanTransactionTypeException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException; @@ -67,8 +68,7 @@ import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; import org.mifosplatform.useradministration.domain.AppUser; @Entity -@Table(name = "m_loan", uniqueConstraints = { - @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"), +@Table(name = "m_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"), @UniqueConstraint(columnNames = { "external_id" }, name = "loan_externalid_UNIQUE") }) public class Loan extends AbstractAuditableCustom { @@ -77,7 +77,7 @@ public class Loan extends AbstractAuditableCustom { @Column(name = "external_id") private String externalId; - + @ManyToOne(optional = true) @JoinColumn(name = "client_id") private Client client; @@ -96,7 +96,11 @@ public class Loan extends AbstractAuditableCustom { @ManyToOne @JoinColumn(name = "loan_officer_id", nullable = true) - private Staff loanofficer; + private Staff loanOfficer; + + @ManyToOne + @JoinColumn(name = "loanpurpose_cv_id", nullable = true) + private CodeValue loanPurpose; @ManyToOne @JoinColumn(name = "loan_transaction_strategy_id", nullable = true) @@ -171,6 +175,10 @@ public class Loan extends AbstractAuditableCustom { @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) private Set charges = new HashSet(); + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + private Set collateral = null; + @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) private Set loanOfficerHistory; @@ -198,21 +206,24 @@ public class Loan extends AbstractAuditableCustom { private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessor = new LoanRepaymentScheduleTransactionProcessorFactory(); public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final LoanProduct loanProduct, - final Fund fund, final Staff officer, final LoanTransactionProcessingStrategy transactionProcessingStrategy, - final LoanSchedule loanSchedule, final Set loanCharges) { + final Fund fund, final Staff officer, final CodeValue loanPurpose, + final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule, + final Set loanCharges, final Set collateral) { final LoanStatus status = null; LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); - return new Loan(accountNo, client, null, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, - status, loanCharges); + return new Loan(accountNo, client, null, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct, + loanRepaymentScheduleDetail, status, loanCharges, collateral); } public static Loan newGroupLoanApplication(final String accountNo, final Group group, final LoanProduct loanProduct, final Fund fund, final Staff officer, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule, final Set loanCharges) { final LoanStatus status = null; - LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); - return new Loan(accountNo, null, group, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, - status, loanCharges); + final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); + final CodeValue loanPurpose = null; + final Set collateral = null; + return new Loan(accountNo, null, group, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct, + loanRepaymentScheduleDetail, status, loanCharges, collateral); } public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group, @@ -220,19 +231,21 @@ public class Loan extends AbstractAuditableCustom { final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule, final Set loanCharges) { final LoanStatus status = null; - LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); - return new Loan(accountNo, client, group, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, - status, loanCharges); + final LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail(); + final CodeValue loanPurpose = null; + final Set collateral = null; + return new Loan(accountNo, client, group, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct, + loanRepaymentScheduleDetail, status, loanCharges, collateral); } protected Loan() { // } - private Loan(final String accountNo, final Client client, final Group group, Fund fund, Staff loanOfficer, - final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, - final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus, final Set loanCharges) { - + private Loan(final String accountNo, final Client client, final Group group, final Fund fund, final Staff loanOfficer, + final CodeValue loanPurpose, final LoanTransactionProcessingStrategy transactionProcessingStrategy, + final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus, + final Set loanCharges, final Set collateral) { if (StringUtils.isBlank(accountNo)) { this.accountNumber = new RandomPasswordGenerator(19).generate(); this.accountNumberRequiresAutoGeneration = true; @@ -242,7 +255,9 @@ public class Loan extends AbstractAuditableCustom { this.client = client; this.group = group; this.fund = fund; - this.loanofficer = loanOfficer; + this.loanOfficer = loanOfficer; + this.loanPurpose = loanPurpose; + this.transactionProcessingStrategy = transactionProcessingStrategy; this.loanProduct = loanProduct; this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail; @@ -257,6 +272,11 @@ public class Loan extends AbstractAuditableCustom { } else { this.charges = null; } + if (collateral != null && !collateral.isEmpty()) { + this.collateral = associateWithThisLoan(collateral); + } else { + this.collateral = null; + } this.loanOfficerHistory = null; } @@ -280,14 +300,21 @@ public class Loan extends AbstractAuditableCustom { return loanCharges; } + private Set associateWithThisLoan(final Set collateral) { + for (LoanCollateral item : collateral) { + item.associateWith(this); + } + return collateral; + } + private void updateTotalChargesDueAtDisbursement() { this.totalChargesDueAtDisbursement = deriveSumTotalOfChargesDueAtDisbursement(); } - + public boolean isAccountNumberRequiresAutoGeneration() { return this.accountNumberRequiresAutoGeneration; } - + public void setAccountNumberRequiresAutoGeneration(boolean accountNumberRequiresAutoGeneration) { this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration; } @@ -354,7 +381,8 @@ public class Loan extends AbstractAuditableCustom { private void validateChargeHasValidSpecifiedDateIfApplicable(final LoanCharge loanCharge, final LocalDate disbursementDate, final LocalDate lastRepaymentPeriodDueDate) { - if (loanCharge.isSpecifiedDueDate() && !loanCharge.isDueForCollectionBetween(disbursementDate, lastRepaymentPeriodDueDate)) { + if (loanCharge.isSpecifiedDueDate() + && !loanCharge.isDueForCollectionFromAndUpToAndIncluding(disbursementDate, lastRepaymentPeriodDueDate)) { final String defaultUserMessage = "This charge which is due at disbursement cannot be added as the loan is already disbursed."; throw new LoanChargeCannotBeAddedException("loanCharge", "specified.due.date.outside.range", defaultUserMessage, getDisbursementDate(), getLastRepaymentPeriodDueDate(), loanCharge.name()); @@ -505,10 +533,30 @@ public class Loan extends AbstractAuditableCustom { this.loanProduct = loanProduct; } + public void updateAccountNo(final String newAccountNo) { + this.accountNumber = newAccountNo; + this.accountNumberRequiresAutoGeneration = false; + } + public void updateFund(final Fund fund) { this.fund = fund; } + public void updateLoanPurpose(final CodeValue loanPurpose) { + this.loanPurpose = loanPurpose; + } + + public void updateLoanOfficerOnLoanApplication(final Staff newLoanOfficer) { + if (!this.isSubmittedAndPendingApproval()) { + Long loanOfficerId = null; + if (this.loanOfficer != null) { + loanOfficerId = this.loanOfficer.getId(); + } + throw new LoanOfficerAssignmentException(this.getId(), loanOfficerId); + } + this.loanOfficer = newLoanOfficer; + } + public void updateTransactionProcessingStrategy(final LoanTransactionProcessingStrategy strategy) { this.transactionProcessingStrategy = strategy; } @@ -519,6 +567,14 @@ public class Loan extends AbstractAuditableCustom { this.totalChargesDueAtDisbursement = deriveSumTotalOfChargesDueAtDisbursement(); } + public void updateLoanCollateral(final Set loanCollateral) { + if (this.collateral == null) { + this.collateral = new HashSet(); + } + this.collateral.clear(); + this.collateral.addAll(associateWithThisLoan(loanCollateral)); + } + public void updateLoanSchedule(final LoanScheduleData modifiedLoanSchedule) { this.repaymentScheduleInstallments.clear(); @@ -548,8 +604,8 @@ public class Loan extends AbstractAuditableCustom { this.expectedMaturityDate = determineExpectedMaturityDate().toDate(); } - public Map loanApplicationModification(final JsonCommand command, final LoanChargeCommand[] loanChargeCommands, - final AprCalculator aprCalculator) { + public Map loanApplicationModification(final JsonCommand command, final Set possiblyModifedLoanCharges, + final Set possiblyModifedLoanCollateralItems, final AprCalculator aprCalculator) { final Map actualChanges = this.loanRepaymentScheduleDetail.updateLoanApplicationAttributes(command, aprCalculator); if (!actualChanges.isEmpty()) { @@ -566,7 +622,7 @@ public class Loan extends AbstractAuditableCustom { actualChanges.put(accountNoParamName, newValue); this.accountNumber = StringUtils.defaultIfEmpty(newValue, null); } - + final String externalIdParamName = "externalId"; if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) { final String newValue = command.stringValueOfParameterNamed(externalIdParamName); @@ -597,21 +653,32 @@ public class Loan extends AbstractAuditableCustom { actualChanges.put(fundIdParamName, newValue); } + Long existingLoanOfficerId = null; + if (this.loanOfficer != null) { + existingLoanOfficerId = this.loanOfficer.getId(); + } + final String loanOfficerIdParamName = "loanOfficerId"; + if (command.isChangeInLongParameterNamed(loanOfficerIdParamName, existingLoanOfficerId)) { + final Long newValue = command.longValueOfParameterNamed(loanOfficerIdParamName); + actualChanges.put(loanOfficerIdParamName, newValue); + } + + Long existingLoanPurposeId = null; + if (this.loanPurpose != null) { + existingLoanPurposeId = this.loanPurpose.getId(); + } + final String loanPurposeIdParamName = "loanPurposeId"; + if (command.isChangeInLongParameterNamed(loanPurposeIdParamName, existingLoanPurposeId)) { + final Long newValue = command.longValueOfParameterNamed(loanPurposeIdParamName); + actualChanges.put(loanPurposeIdParamName, newValue); + } + final String strategyIdParamName = "transactionProcessingStrategyId"; if (command.isChangeInLongParameterNamed(strategyIdParamName, this.transactionProcessingStrategy.getId())) { final Long newValue = command.longValueOfParameterNamed(strategyIdParamName); actualChanges.put(strategyIdParamName, newValue); } - final String chargesParamName = "charges"; - if (command.parameterExists(chargesParamName)) { - LoanChargeCommand[] existingLoanChargeData = getLoanCharges(); - if (differenceExistsBetween(existingLoanChargeData, loanChargeCommands)) { - actualChanges.put(chargesParamName, loanChargeCommands); - actualChanges.put("recalculateLoanSchedule", true); - } - } - final String submittedOnDateParamName = "submittedOnDate"; if (command.isChangeInLocalDateParameterNamed(submittedOnDateParamName, getSubmittedOnDate())) { final String valueAsInput = command.stringValueOfParameterNamed(submittedOnDateParamName); @@ -668,7 +735,7 @@ public class Loan extends AbstractAuditableCustom { this.interestChargedFromDate = null; } } - + if (getSubmittedOnDate().isAfter(new LocalDate())) { final String errorMessage = "The date on which a loan is submitted cannot be in the future."; throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, getSubmittedOnDate()); @@ -680,33 +747,59 @@ public class Loan extends AbstractAuditableCustom { throw new InvalidLoanStateTransitionException("submittal", "cannot.be.after.expected.disbursement.date", errorMessage, getSubmittedOnDate(), getExpectedDisbursedOnLocalDate()); } - - // FIXME - this constraint doesnt really need to be here. should be - // possible to express loan term as say 12 months whilst also saying - // - that the repayment structure is 6 repayments every bi-monthly. -// validateSelectedPeriodFrequencyTypeIsTheSame(dataValidationErrors, loanTermFrequency, loanTermFrequencyType, numberOfRepayments, -// repaymentEvery, repaymentEveryType); -// -// validateRepaymentsStartingFromDateIsAfterDisbursementDate(dataValidationErrors, expectedDisbursementDate, -// repaymentsStartingFromDate); -// -// validateRepaymentsStartingFromDateAndInterestChargedFromDate(dataValidationErrors, expectedDisbursementDate, -// repaymentsStartingFromDate, interestChargedFromDate); - // charges are optional - for (LoanCharge loanCharge : getNullPointerSafeLoanCharges()) { - validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate()); + final String chargesParamName = "charges"; + if (command.parameterExists(chargesParamName)) { + + final Set existingLoanCharges = getNullPointerSafeLoanCharges(); + + if (!possiblyModifedLoanCharges.equals(existingLoanCharges)) { + actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges)); + + actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges)); + actualChanges.put("recalculateLoanSchedule", true); + + for (LoanCharge loanCharge : possiblyModifedLoanCharges) { + validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate()); + } + } + + // final ImmutableSet difference = + // Sets.symmetricDifference(existingLoanCharges, + // possiblyModifedLoanCharges) + // .immutableCopy(); + // if (!difference.isEmpty()) { + // actualChanges.put(chargesParamName, getLoanCharges(difference)); + // actualChanges.put("recalculateLoanSchedule", true); + // + // for (LoanCharge loanCharge : possiblyModifedLoanCharges) { + // validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, + // getDisbursementDate(), getLastRepaymentPeriodDueDate()); + // } + // } + } + + final String collateralParamName = "collateral"; + if (command.parameterExists(collateralParamName)) { + + if (!possiblyModifedLoanCollateralItems.equals(this.collateral)) { + actualChanges.put(collateralParamName, listOfLoanCollateralData(possiblyModifedLoanCollateralItems)); + } + + // + // final ImmutableSet difference = + // Sets.symmetricDifference(this.collateral, + // possiblyModifedLoanCollateralItems) + // .immutableCopy(); + // if (!difference.isEmpty()) { + // actualChanges.put(collateralParamName, + // listOfLoanCollateralData(difference)); + // } } return actualChanges; } - private boolean differenceExistsBetween(final LoanChargeCommand[] existingLoanChargeData, final LoanChargeCommand[] newLoanChargeData) { - Arrays.sort(existingLoanChargeData); - Arrays.sort(newLoanChargeData); - return !Arrays.equals(existingLoanChargeData, newLoanChargeData); - } - private Set getNullPointerSafeLoanCharges() { Set loanCharges = this.charges; if (this.charges == null) { @@ -715,19 +808,34 @@ public class Loan extends AbstractAuditableCustom { return loanCharges; } - private LoanChargeCommand[] getLoanCharges() { + private LoanCollateralData[] listOfLoanCollateralData(final Set setOfLoanCollateral) { + + LoanCollateralData[] existingLoanCollateral = null; + + List loanCollateralList = new ArrayList(); + for (LoanCollateral loanCollateral : setOfLoanCollateral) { + + LoanCollateralData data = loanCollateral.toData(); + + loanCollateralList.add(data); + } + + existingLoanCollateral = loanCollateralList.toArray(new LoanCollateralData[loanCollateralList.size()]); + + return existingLoanCollateral; + } + + private LoanChargeCommand[] getLoanCharges(Set setOfLoanCharges) { LoanChargeCommand[] existingLoanCharges = null; - if (!getNullPointerSafeLoanCharges().isEmpty()) { - List loanChargesList = new ArrayList(); - for (LoanCharge loanCharge : getNullPointerSafeLoanCharges()) { - loanChargesList.add(loanCharge.toCommand()); - } - - existingLoanCharges = loanChargesList.toArray(new LoanChargeCommand[loanChargesList.size()]); + List loanChargesList = new ArrayList(); + for (LoanCharge loanCharge : setOfLoanCharges) { + loanChargesList.add(loanCharge.toCommand()); } + existingLoanCharges = loanChargesList.toArray(new LoanChargeCommand[loanChargesList.size()]); + return existingLoanCharges; } @@ -744,12 +852,13 @@ public class Loan extends AbstractAuditableCustom { final LocalDate submittedOn, final String externalId) { final LoanScheduleData loanScheduleData = loanSchedule.generate(); - - // Have to set expectedDisbursementDate to avoid nullPointer so should be passed down to updateLoanSchedule method + + // Have to set expectedDisbursementDate to avoid nullPointer so should + // be passed down to updateLoanSchedule method if (loanSchedule.getDisbursementDate() != null) { this.expectedDisbursedOnDate = loanSchedule.getDisbursementDate().toDate(); - } - + } + updateLoanSchedule(loanScheduleData); LoanStatus from = null; @@ -761,7 +870,7 @@ public class Loan extends AbstractAuditableCustom { this.loanStatus = statusEnum.getValue(); this.externalId = externalId; - + this.termFrequency = loanSchedule.getLoanTermFrequency(); this.termPeriodFrequencyType = loanSchedule.getLoanTermPeriodFrequencyType().getValue(); @@ -807,7 +916,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate"); if (rejectedOn == null) { rejectedOn = command.localDateValueOfParameterNamed("eventDate"); @@ -847,7 +956,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate"); if (withdrawnOn == null) { withdrawnOn = command.localDateValueOfParameterNamed("eventDate"); @@ -887,7 +996,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + // only do below if status has changed in the 'approval' case LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate"); String approvedOnDateChange = command.stringValueOfParameterNamed("approvedOnDate"); @@ -905,17 +1014,17 @@ public class Loan extends AbstractAuditableCustom { if (approvedOn.isBefore(submittalDate)) { final String errorMessage = "The date on which a loan is approved cannot be before its submittal date: " + submittalDate.toString(); - throw new InvalidLoanStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, getApprovedOnDate(), - submittalDate); + throw new InvalidLoanStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, + getApprovedOnDate(), submittalDate); } if (approvedOn.isAfter(new LocalDate())) { final String errorMessage = "The date on which a loan is approved cannot be in the future."; throw new InvalidLoanStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getApprovedOnDate()); } - if (this.loanofficer != null) { + if (this.loanOfficer != null) { final LoanOfficerAssignmentHistory loanOfficerAssignmentHistory = LoanOfficerAssignmentHistory.createNew(this, - this.loanofficer, approvedOn); + this.loanOfficer, approvedOn); this.loanOfficerHistory.add(loanOfficerAssignmentHistory); } } @@ -932,7 +1041,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(currentStatus)) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + this.approvedOnDate = null; actualChanges.put("approvedOnDate", ""); @@ -959,7 +1068,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate"); if (disbursedOn == null) { disbursedOn = command.localDateValueOfParameterNamed("eventDate"); @@ -1074,7 +1183,7 @@ public class Loan extends AbstractAuditableCustom { if (!statusEnum.hasStateOf(currentStatus)) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); - + this.approvedOnDate = null; actualChanges.put("disbursedOnDate", ""); @@ -1861,8 +1970,8 @@ public class Loan extends AbstractAuditableCustom { public boolean hasLoanOfficer(final Staff fromLoanOfficer) { boolean matchesCurrentLoanOfficer = false; - if (this.loanofficer != null) { - matchesCurrentLoanOfficer = this.loanofficer.identifiedBy(fromLoanOfficer); + if (this.loanOfficer != null) { + matchesCurrentLoanOfficer = this.loanOfficer.identifiedBy(fromLoanOfficer); } else { matchesCurrentLoanOfficer = fromLoanOfficer == null; } @@ -1920,11 +2029,11 @@ public class Loan extends AbstractAuditableCustom { final LoanOfficerAssignmentHistory latestHistoryRecord = findLatestIncompleteHistoryRecord(); - if (latestHistoryRecord != null && this.loanofficer.identifiedBy(newLoanOfficer)) { + if (latestHistoryRecord != null && this.loanOfficer.identifiedBy(newLoanOfficer)) { latestHistoryRecord.updateStartDate(assignmentDate); } else if (latestHistoryRecord != null && latestHistoryRecord.matchesStartDateOf(assignmentDate)) { latestHistoryRecord.updateLoanOfficer(newLoanOfficer); - this.loanofficer = newLoanOfficer; + this.loanOfficer = newLoanOfficer; } else if (latestHistoryRecord != null && latestHistoryRecord.hasStartDateBefore(assignmentDate)) { throw new LoanOfficerAssignmentException(this.getId(), assignmentDate); } else { @@ -1934,16 +2043,15 @@ public class Loan extends AbstractAuditableCustom { latestHistoryRecord.updateEndDate(assignmentDate); } - this.loanofficer = newLoanOfficer; + this.loanOfficer = newLoanOfficer; if (this.isNotSubmittedAndPendingApproval()) { final LoanOfficerAssignmentHistory loanOfficerAssignmentHistory = LoanOfficerAssignmentHistory.createNew(this, - this.loanofficer, assignmentDate); + this.loanOfficer, assignmentDate); this.loanOfficerHistory.add(loanOfficerAssignmentHistory); } } } - public void removeLoanOfficer(final LocalDate unassignDate) { final LoanOfficerAssignmentHistory latestHistoryRecord = findLatestIncompleteHistoryRecord(); @@ -1953,7 +2061,7 @@ public class Loan extends AbstractAuditableCustom { latestHistoryRecord.updateEndDate(unassignDate); } - this.loanofficer = null; + this.loanOfficer = null; } private void validateUnassignDate(final LoanOfficerAssignmentHistory latestHistoryRecord, final LocalDate unassignDate) { @@ -1963,8 +2071,7 @@ public class Loan extends AbstractAuditableCustom { if (latestHistoryRecord.getStartDate().isAfter(unassignDate)) { throw new LoanOfficerUnassignmentDateException(this.getId(), this.getLoanOfficer().getId(), latestHistoryRecord.getStartDate(), unassignDate); - } else if (unassignDate.isAfter(today)) { throw new LoanOfficerUnassignmentDateException( - this.getId()); } + } else if (unassignDate.isAfter(today)) { throw new LoanOfficerUnassignmentDateException(this.getId()); } } private LoanOfficerAssignmentHistory findLatestIncompleteHistoryRecord() { @@ -2008,11 +2115,6 @@ public class Loan extends AbstractAuditableCustom { return officeId; } - public void updateAccountNo(final String newAccountNo) { - this.accountNumber = newAccountNo; - this.accountNumberRequiresAutoGeneration=false; - } - public List getLoanTransactions() { return this.loanTransactions; } @@ -2020,21 +2122,20 @@ public class Loan extends AbstractAuditableCustom { public boolean isAccountingEnabledOnLoanProduct() { return this.loanProduct.isAccountingEnabled(); } - - public boolean isCashBasedAccountingEnabledOnLoanProduct(){ + + public boolean isCashBasedAccountingEnabledOnLoanProduct() { return this.loanProduct.isCashBasedAccountingEnabled(); } - - public boolean isAccrualBasedAccountingEnabledOnLoanProduct(){ + + public boolean isAccrualBasedAccountingEnabledOnLoanProduct() { return this.loanProduct.isAccrualBasedAccountingEnabled(); } public Long productId() { return this.loanProduct.getId(); } - - public Staff getLoanOfficer() { - return this.loanofficer; - } + public Staff getLoanOfficer() { + return this.loanOfficer; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java index 06aaeb05f..59f8c04a8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java @@ -15,6 +15,8 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.joda.time.LocalDate; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; @@ -347,9 +349,8 @@ public class LoanCharge extends AbstractPersistable { } public LoanChargeCommand toCommand() { - - final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate(); - return new LoanChargeCommand(this.charge.getId(), this.amount, this.chargeTime, this.chargeCalculation, specifiedDueDate); + return new LoanChargeCommand(this.getId(), this.charge.getId(), this.amount, this.chargeTime, this.chargeCalculation, + getDueForCollectionAsOfLocalDate()); } public LocalDate getDueForCollectionAsOfLocalDate() { @@ -411,16 +412,14 @@ public class LoanCharge extends AbstractPersistable { return this.loan.hasIdentifyOf(loanId); } - public boolean isDueForCollectionBetween(final LocalDate fromNotInclusive, final LocalDate toInclusive) { + public boolean isDueForCollectionFromAndUpToAndIncluding(final LocalDate fromNotInclusive, final LocalDate upToAndInclusive) { final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate(); - - return specifiedDueDateFallsWithinPeriod(fromNotInclusive, toInclusive, specifiedDueDate); + return occursOnDayFromAndUpToAndIncluding(fromNotInclusive, upToAndInclusive, specifiedDueDate); } - private boolean specifiedDueDateFallsWithinPeriod(final LocalDate fromNotInclusive, final LocalDate toInclusive, - final LocalDate specifiedDueDate) { - return specifiedDueDate != null && fromNotInclusive.isBefore(specifiedDueDate) - && (toInclusive.isAfter(specifiedDueDate) || toInclusive.isEqual(specifiedDueDate)); + private boolean occursOnDayFromAndUpToAndIncluding(final LocalDate fromNotInclusive, final LocalDate upToAndInclusive, + final LocalDate target) { + return target != null && target.isAfter(fromNotInclusive) && !target.isAfter(upToAndInclusive); } public boolean isFeeCharge() { @@ -493,4 +492,27 @@ public class LoanCharge extends AbstractPersistable { public String name() { return this.charge.getName(); } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { return false; } + if (obj == this) { return true; } + if (obj.getClass() != getClass()) { return false; } + LoanCharge rhs = (LoanCharge) obj; + return new EqualsBuilder().appendSuper(super.equals(obj)) // + .append(this.getId(), rhs.getId()) // + .append(this.charge.getId(), rhs.charge.getId()) // + .append(this.amount, rhs.amount) // + .append(this.getDueForCollectionAsOfLocalDate(), rhs.getDueForCollectionAsOfLocalDate()) // + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(3, 5) // + .append(this.getId()) // + .append(this.charge.getId()) // + .append(this.amount).append(this.getDueForCollectionAsOfLocalDate()) // + .toHashCode(); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateral.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateral.java new file mode 100644 index 000000000..25391bf78 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateral.java @@ -0,0 +1,106 @@ +package org.mifosplatform.portfolio.loanaccount.domain; + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.portfolio.loanaccount.data.LoanCollateralData; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_loan_collateral") +public class LoanCollateral extends AbstractPersistable { + + @SuppressWarnings("unused") + @ManyToOne(optional = false) + @JoinColumn(name = "loan_id", nullable = false) + private Loan loan; + + @ManyToOne + @JoinColumn(name = "type_cv_id", nullable = false) + private CodeValue type; + + @Column(name = "description", length = 500) + private String description; + + public static LoanCollateral from(final CodeValue collateralType, final String description) { + return new LoanCollateral(null, collateralType, description); + } + + protected LoanCollateral() { + // + } + + private LoanCollateral(final Loan loan, final CodeValue collateralType, final String description) { + this.loan = loan; + this.type = collateralType; + this.description = StringUtils.defaultIfEmpty(description, null); + } + + public void assembleFrom(final CodeValue collateralType, final String description) { + this.type = collateralType; + this.description = description; + } + + public void associateWith(final Loan loan) { + this.loan = loan; + } + + public Map update(final JsonCommand command) { + + final Map actualChanges = new LinkedHashMap(7); + + final String collateralTypeIdParamName = "type"; + if (command.isChangeInLongParameterNamed(collateralTypeIdParamName, this.type.getId())) { + final Long newValue = command.longValueOfParameterNamed(collateralTypeIdParamName); + actualChanges.put(collateralTypeIdParamName, newValue); + } + + final String descriptionParamName = "description"; + if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { + final String newValue = command.stringValueOfParameterNamed(descriptionParamName); + actualChanges.put(descriptionParamName, newValue); + this.description = StringUtils.defaultIfEmpty(newValue, null); + } + + return actualChanges; + } + + public LoanCollateralData toData() { + final CodeValueData typeData = this.type.toData(); + return LoanCollateralData.instance(this.getId(), typeData, this.description); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { return false; } + if (obj == this) { return true; } + if (obj.getClass() != getClass()) { return false; } + LoanCollateral rhs = (LoanCollateral) obj; + return new EqualsBuilder().appendSuper(super.equals(obj)) // + .append(this.getId(), rhs.getId()) // + .append(this.type.getId(), rhs.type.getId()) // + .append(this.description, rhs.description) // + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(3, 5) // + .append(this.getId()) // + .append(this.type.getId()) // + .append(this.description) // + .toHashCode(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateralRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateralRepository.java new file mode 100644 index 000000000..6673435a9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCollateralRepository.java @@ -0,0 +1,8 @@ +package org.mifosplatform.portfolio.loanaccount.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface LoanCollateralRepository extends JpaRepository, JpaSpecificationExecutor { + // no added behaviour +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanScheduleWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanScheduleWrapper.java index 855787efb..bffd73f06 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanScheduleWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanScheduleWrapper.java @@ -65,7 +65,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(monetaryCurrency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isFeeCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isFeeCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } @@ -79,7 +79,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(currency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isFeeCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isFeeCharge()) { cumulative = cumulative.plus(loanCharge.getAmountWaived(currency)); } } @@ -93,7 +93,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(currency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isFeeCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isFeeCharge()) { cumulative = cumulative.plus(loanCharge.getAmountWrittenOff(currency)); } } @@ -107,7 +107,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(currency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } @@ -121,7 +121,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(currency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { cumulative = cumulative.plus(loanCharge.getAmountWaived(currency)); } } @@ -135,7 +135,7 @@ public class LoanScheduleWrapper { Money cumulative = Money.zero(currency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { cumulative = cumulative.plus(loanCharge.getAmountWrittenOff(currency)); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java new file mode 100644 index 000000000..00758b8e0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java @@ -0,0 +1,16 @@ +package org.mifosplatform.portfolio.loanaccount.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +/** + * {@link AbstractPlatformDomainRuleException} thrown when trying to delete a + * loan in an invalid state. + */ +public class LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted extends AbstractPlatformDomainRuleException { + + public LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(final Long id) { + super("error.msg.loan.cannot.delete.loan.in.its.present.state", "Loan with identifier " + id + + " cannot be deleted in its current state.", id); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified.java new file mode 100644 index 000000000..e4d444288 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified.java @@ -0,0 +1,16 @@ +package org.mifosplatform.portfolio.loanaccount.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +/** + * {@link AbstractPlatformDomainRuleException} thrown when trying to modify a + * loan in an invalid state. + */ +public class LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified extends AbstractPlatformDomainRuleException { + + public LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified(final Long id) { + super("error.msg.loan.cannot.modify.loan.in.its.present.state", "Loan application with identifier " + id + + " cannot be modified in its current state.", id); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java deleted file mode 100644 index e9398fb5d..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mifosplatform.portfolio.loanaccount.exception; - -import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; - -/** - * {@link AbstractPlatformDomainRuleException} thrown when trying to delete a loan in an invalid state. - */ -public class LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted extends - AbstractPlatformDomainRuleException { - - public LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted(final Long id) { - super("error.msg.loan.cannot.delete.loan.in.its.present.state", "Loan with identifier " + id + " cannot be deleted in its current state.", id); - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java index 8a6cca873..c35ed6503 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java @@ -156,7 +156,7 @@ public class EqualInstallmentsAmortizationLoanScheduleGenerator implements Amort Money cumulative = Money.zero(monetaryCurrency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isFeeCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isFeeCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } @@ -170,7 +170,7 @@ public class EqualInstallmentsAmortizationLoanScheduleGenerator implements Amort Money cumulative = Money.zero(monetaryCurrency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/FlatMethodLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/FlatMethodLoanScheduleGenerator.java index b2c6b715f..d1355839c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/FlatMethodLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/FlatMethodLoanScheduleGenerator.java @@ -146,7 +146,7 @@ public class FlatMethodLoanScheduleGenerator implements LoanScheduleGenerator { Money cumulative = Money.zero(monetaryCurrency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isFeeCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isFeeCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } @@ -160,7 +160,7 @@ public class FlatMethodLoanScheduleGenerator implements LoanScheduleGenerator { Money cumulative = Money.zero(monetaryCurrency); for (LoanCharge loanCharge : loanCharges) { - if (loanCharge.isDueForCollectionBetween(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { + if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(periodStart, periodEnd) && loanCharge.isPenaltyCharge()) { cumulative = cumulative.plus(loanCharge.amount()); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java index 215572dde..3db68bc64 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java @@ -17,7 +17,6 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; -import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -32,12 +31,12 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { /** * The parameters supported for this command. */ - final Set supportedParameters = new HashSet(Arrays.asList("clientId", "groupId", "productId", "accountNo", - "externalId", "fundId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance", "interestRatePerPeriod", - "repaymentEvery", "numberOfRepayments", "loanTermFrequency", "loanTermFrequencyType", "charges", "repaymentFrequencyType", - "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "expectedDisbursementDate", - "repaymentsStartingFromDate", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", "locale", "dateFormat", - "loanOfficerId", "id")); + final Set supportedParameters = new HashSet(Arrays.asList("id", "clientId", "groupId", "productId", "accountNo", + "externalId", "fundId", "loanOfficerId", "loanPurposeId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance", + "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "loanTermFrequency", "loanTermFrequencyType", + "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", + "expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", + "locale", "dateFormat", "charges", "collateral")); private final FromJsonHelper fromApiJsonHelper; @@ -124,14 +123,16 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { final String repaymentsStartingFromDateParameterName = "repaymentsStartingFromDate"; if (fromApiJsonHelper.parameterExists(repaymentsStartingFromDateParameterName, element)) { repaymentsStartingFromDate = fromApiJsonHelper.extractLocalDateNamed(repaymentsStartingFromDateParameterName, element); - baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull() + .notNull(); } LocalDate interestChargedFromDate = null; final String interestChargedFromDateParameterName = "interestChargedFromDate"; if (fromApiJsonHelper.parameterExists(interestChargedFromDateParameterName, element)) { interestChargedFromDate = fromApiJsonHelper.extractLocalDateNamed(interestChargedFromDateParameterName, element); - baseDataValidator.reset().parameter(interestChargedFromDateParameterName).value(interestChargedFromDate).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter(interestChargedFromDateParameterName).value(interestChargedFromDate).ignoreIfNull() + .notNull(); } validateRepaymentsStartingFromDateIsAfterDisbursementDate(dataValidationErrors, expectedDisbursementDate, @@ -140,13 +141,34 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { validateRepaymentsStartingFromDateAndInterestChargedFromDate(dataValidationErrors, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate); - final LoanChargeCommand[] charges = extractInToLoanChargeCommands(element); - if (charges != null) { - for (LoanChargeCommand loanChargeCommand : charges) { - try { - loanChargeCommand.validateForCreate(); - } catch (PlatformApiDataValidationException e) { - dataValidationErrors.addAll(e.getErrors()); + // charges + final String chargesParameterName = "charges"; + if (element.isJsonObject() && fromApiJsonHelper.parameterExists(chargesParameterName, element)) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + final String dateFormat = fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + final Locale locale = fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + + if (topLevelJsonElement.get(chargesParameterName).isJsonArray()) { + final Type arrayObjectParameterTypeOfMap = new TypeToken>() {}.getType(); + final Set supportedParameters = new HashSet(Arrays.asList("id", "chargeId", "amount", "chargeTimeType", + "chargeCalculationType", "specifiedDueDate")); + + final JsonArray array = topLevelJsonElement.get("charges").getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + + final JsonObject loanChargeElement = array.get(i - 1).getAsJsonObject(); + final String arrayObjectJson = this.fromApiJsonHelper.toJson(loanChargeElement); + fromApiJsonHelper.checkForUnsupportedParameters(arrayObjectParameterTypeOfMap, arrayObjectJson, supportedParameters); + + final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", loanChargeElement); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("chargeId", i).value(chargeId).notNull() + .integerGreaterThanZero(); + + final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, locale); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("amount", i).value(amount).notNull() + .positiveAmount(); + + fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", loanChargeElement, dateFormat, locale); } } } @@ -213,32 +235,47 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { } } - private LoanChargeCommand[] extractInToLoanChargeCommands(final JsonElement element) { - LoanChargeCommand[] charges = null; - if (element.isJsonObject()) { - final JsonObject topLevelJsonElement = element.getAsJsonObject(); - final String dateFormat = fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); - final Locale locale = fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); - if (topLevelJsonElement.has("charges") && topLevelJsonElement.get("charges").isJsonArray()) { - - final JsonArray array = topLevelJsonElement.get("charges").getAsJsonArray(); - charges = new LoanChargeCommand[array.size()]; - for (int i = 0; i < array.size(); i++) { - - final JsonObject loanChargeElement = array.get(i).getAsJsonObject(); - - final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", loanChargeElement); - final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, locale); - final Integer chargeTimeType = fromApiJsonHelper.extractIntegerNamed("chargeTimeType", loanChargeElement, locale); - final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerNamed("chargeCalculationType", loanChargeElement, - locale); - final LocalDate specifiedDueDate = fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", loanChargeElement, - dateFormat, locale); - - charges[i] = new LoanChargeCommand(chargeId, amount, chargeTimeType, chargeCalculationType, specifiedDueDate); - } - } - } - return charges; - } + // private LoanChargeCommand[] extractInToLoanChargeCommands(final + // JsonElement element) { + // LoanChargeCommand[] charges = null; + // if (element.isJsonObject()) { + // final JsonObject topLevelJsonElement = element.getAsJsonObject(); + // final String dateFormat = + // fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + // final Locale locale = + // fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + // if (topLevelJsonElement.has("charges") && + // topLevelJsonElement.get("charges").isJsonArray()) { + // + // final JsonArray array = + // topLevelJsonElement.get("charges").getAsJsonArray(); + // charges = new LoanChargeCommand[array.size()]; + // for (int i = 0; i < array.size(); i++) { + // + // final JsonObject loanChargeElement = array.get(i).getAsJsonObject(); + // + // final Long id = fromApiJsonHelper.extractLongNamed("id", + // loanChargeElement); + // final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", + // loanChargeElement); + // final BigDecimal amount = + // fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, + // locale); + // final Integer chargeTimeType = + // fromApiJsonHelper.extractIntegerNamed("chargeTimeType", + // loanChargeElement, locale); + // final Integer chargeCalculationType = + // fromApiJsonHelper.extractIntegerNamed("chargeCalculationType", + // loanChargeElement, + // locale); + // fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", + // loanChargeElement, dateFormat, locale); + // + // charges[i] = new LoanChargeCommand(id, chargeId, amount, chargeTimeType, + // chargeCalculationType); + // } + // } + // } + // return charges; + // } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index aee8bfb68..5abceead6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -17,7 +17,6 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; -import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -32,12 +31,15 @@ public final class LoanApplicationCommandFromApiJsonHelper { /** * The parameters supported for this command. */ - final Set supportedParameters = new HashSet(Arrays.asList("id", "clientId", "groupId", "productId", "accountNo", - "externalId", "fundId", "loanOfficerId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance", - "repaymentEvery", "numberOfRepayments", "loanTermFrequency", "loanTermFrequencyType", "charges", "repaymentFrequencyType", - "interestRatePerPeriod", "interestRateFrequencyType", "interestType", "interestCalculationPeriodType", "amortizationType", - "expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", - "locale", "dateFormat")); + final Set supportedParameters = new HashSet(Arrays.asList("dateFormat", "locale", "id", "clientId", "groupId", + "productId", "principal", "loanTermFrequency", "loanTermFrequencyType", "numberOfRepayments", "repaymentEvery", + "repaymentFrequencyType", "interestRatePerPeriod", "interestRateFrequencyType", "amortizationType", "interestType", + "interestCalculationPeriodType", "expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate", + "submittedOnDate", "submittedOnNote", // + "accountNo", "externalId", "fundId", "loanOfficerId", // optional + "loanPurposeId", "inArrearsTolerance", "charges", "collateral", // optional + "transactionProcessingStrategyId" // settings + )); private final FromJsonHelper fromApiJsonHelper; @@ -97,6 +99,12 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter(loanOfficerIdParameterName).value(loanOfficerId).ignoreIfNull().integerGreaterThanZero(); } + final String loanPurposeIdParameterName = "loanPurposeId"; + if (fromApiJsonHelper.parameterExists(loanPurposeIdParameterName, element)) { + final Long loanPurposeId = fromApiJsonHelper.extractLongNamed(loanPurposeIdParameterName, element); + baseDataValidator.reset().parameter(loanPurposeIdParameterName).value(loanPurposeId).ignoreIfNull().integerGreaterThanZero(); + } + final BigDecimal principal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("principal", element); baseDataValidator.reset().parameter("principal").value(principal).notNull().positiveAmount(); @@ -105,7 +113,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter(loanTermFrequencyParameterName).value(loanTermFrequency).notNull().integerGreaterThanZero(); final String loanTermFrequencyTypeParameterName = "loanTermFrequencyType"; - final Integer loanTermFrequencyType = fromApiJsonHelper.extractIntegerWithLocaleNamed(loanTermFrequencyTypeParameterName, element); + final Integer loanTermFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(loanTermFrequencyTypeParameterName, element); baseDataValidator.reset().parameter(loanTermFrequencyTypeParameterName).value(loanTermFrequencyType).notNull().inMinMaxRange(0, 3); final String numberOfRepaymentsParameterName = "numberOfRepayments"; @@ -117,7 +125,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter(repaymentEveryParameterName).value(repaymentEvery).notNull().integerGreaterThanZero(); final String repaymentEveryFrequencyTypeParameterName = "repaymentFrequencyType"; - final Integer repaymentEveryType = fromApiJsonHelper.extractIntegerWithLocaleNamed(repaymentEveryFrequencyTypeParameterName, + final Integer repaymentEveryType = fromApiJsonHelper.extractIntegerSansLocaleNamed(repaymentEveryFrequencyTypeParameterName, element); baseDataValidator.reset().parameter(repaymentEveryFrequencyTypeParameterName).value(repaymentEveryType).notNull() .inMinMaxRange(0, 3); @@ -128,23 +136,23 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter(interestRatePerPeriodParameterName).value(interestRatePerPeriod).notNull().positiveAmount(); final String interestRateFrequencyTypeParameterName = "interestRateFrequencyType"; - final Integer interestRateFrequencyType = fromApiJsonHelper.extractIntegerWithLocaleNamed(interestRateFrequencyTypeParameterName, + final Integer interestRateFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestRateFrequencyTypeParameterName, element); baseDataValidator.reset().parameter(interestRateFrequencyTypeParameterName).value(interestRateFrequencyType).notNull() .inMinMaxRange(0, 3); final String interestTypeParameterName = "interestType"; - final Integer interestType = fromApiJsonHelper.extractIntegerWithLocaleNamed(interestTypeParameterName, element); + final Integer interestType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestTypeParameterName, element); baseDataValidator.reset().parameter(interestTypeParameterName).value(interestType).notNull().inMinMaxRange(0, 1); final String interestCalculationPeriodTypeParameterName = "interestCalculationPeriodType"; - final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerWithLocaleNamed( + final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed( interestCalculationPeriodTypeParameterName, element); baseDataValidator.reset().parameter(interestCalculationPeriodTypeParameterName).value(interestCalculationPeriodType).notNull() .inMinMaxRange(0, 1); final String amortizationTypeParameterName = "amortizationType"; - final Integer amortizationType = fromApiJsonHelper.extractIntegerWithLocaleNamed(amortizationTypeParameterName, element); + final Integer amortizationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(amortizationTypeParameterName, element); baseDataValidator.reset().parameter(amortizationTypeParameterName).value(amortizationType).notNull().inMinMaxRange(0, 1); final String expectedDisbursementDateParameterName = "expectedDisbursementDate"; @@ -155,21 +163,24 @@ public final class LoanApplicationCommandFromApiJsonHelper { if (fromApiJsonHelper.parameterExists(repaymentsStartingFromDateParameterName, element)) { final LocalDate repaymentsStartingFromDate = fromApiJsonHelper.extractLocalDateNamed(repaymentsStartingFromDateParameterName, element); - baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull() + .notNull(); } final String interestChargedFromDateParameterName = "interestChargedFromDate"; if (fromApiJsonHelper.parameterExists(interestChargedFromDateParameterName, element)) { final LocalDate interestChargedFromDate = fromApiJsonHelper .extractLocalDateNamed(interestChargedFromDateParameterName, element); - baseDataValidator.reset().parameter(interestChargedFromDateParameterName).value(interestChargedFromDate).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter(interestChargedFromDateParameterName).value(interestChargedFromDate).ignoreIfNull() + .notNull(); } final String inArrearsToleranceParameterName = "inArrearsTolerance"; if (fromApiJsonHelper.parameterExists(inArrearsToleranceParameterName, element)) { final BigDecimal inArrearsTolerance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(inArrearsToleranceParameterName, element); - baseDataValidator.reset().parameter(inArrearsToleranceParameterName).value(inArrearsTolerance).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter(inArrearsToleranceParameterName).value(inArrearsTolerance).ignoreIfNull() + .zeroOrPositiveAmount(); } final String submittedOnDateParameterName = "submittedOnDate"; @@ -181,7 +192,8 @@ public final class LoanApplicationCommandFromApiJsonHelper { final String submittedOnNoteParameterName = "submittedOnNote"; if (fromApiJsonHelper.parameterExists(submittedOnNoteParameterName, element)) { final String submittedOnNote = fromApiJsonHelper.extractStringNamed(submittedOnNoteParameterName, element); - baseDataValidator.reset().parameter(submittedOnNoteParameterName).value(submittedOnNote).ignoreIfNull().notExceedingLengthOf(500); + baseDataValidator.reset().parameter(submittedOnNoteParameterName).value(submittedOnNote).ignoreIfNull() + .notExceedingLengthOf(500); } // not optional at present but might make it so to allow it to pick up @@ -193,17 +205,67 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter(transactionProcessingStrategyIdParameterName).value(transactionProcessingStrategyId).notNull() .integerGreaterThanZero(); - final LoanChargeCommand[] charges = extractInToLoanChargeCommands(element); - if (charges != null) { - for (LoanChargeCommand loanChargeCommand : charges) { - try { - loanChargeCommand.validateForCreate(); - } catch (PlatformApiDataValidationException e) { - dataValidationErrors.addAll(e.getErrors()); + // charges + final String chargesParameterName = "charges"; + if (element.isJsonObject() && fromApiJsonHelper.parameterExists(chargesParameterName, element)) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + final String dateFormat = fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + final Locale locale = fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + + if (topLevelJsonElement.get(chargesParameterName).isJsonArray()) { + final Type arrayObjectParameterTypeOfMap = new TypeToken>() {}.getType(); + final Set supportedParameters = new HashSet(Arrays.asList("id", "chargeId", "amount", "chargeTimeType", + "chargeCalculationType", "specifiedDueDate")); + + final JsonArray array = topLevelJsonElement.get("charges").getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + + final JsonObject loanChargeElement = array.get(i - 1).getAsJsonObject(); + final String arrayObjectJson = this.fromApiJsonHelper.toJson(loanChargeElement); + fromApiJsonHelper.checkForUnsupportedParameters(arrayObjectParameterTypeOfMap, arrayObjectJson, supportedParameters); + + final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", loanChargeElement); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("chargeId", i).value(chargeId).notNull() + .integerGreaterThanZero(); + + final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, locale); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("amount", i).value(amount).notNull() + .positiveAmount(); + + fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", loanChargeElement, dateFormat, locale); } } } + // collateral + final String collateralParameterName = "collateral"; + if (element.isJsonObject() && fromApiJsonHelper.parameterExists(collateralParameterName, element)) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + if (topLevelJsonElement.get("collateral").isJsonArray()) { + + final Type collateralParameterTypeOfMap = new TypeToken>() {}.getType(); + final Set supportedParameters = new HashSet(Arrays.asList("id", "type", "description")); + final JsonArray array = topLevelJsonElement.get("collateral").getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + final JsonObject collateralItemElement = array.get(i - 1).getAsJsonObject(); + + final String collateralJson = this.fromApiJsonHelper.toJson(collateralItemElement); + fromApiJsonHelper.checkForUnsupportedParameters(collateralParameterTypeOfMap, collateralJson, supportedParameters); + + final Long collateralTypeId = fromApiJsonHelper.extractLongNamed("type", collateralItemElement); + baseDataValidator.reset().parameter("collateral").parameterAtIndexArray("type", i).value(collateralTypeId).notNull() + .integerGreaterThanZero(); + + final String description = fromApiJsonHelper.extractStringNamed("description", collateralItemElement); + baseDataValidator.reset().parameter("collateral").parameterAtIndexArray("description", i).value(description).notBlank() + .notExceedingLengthOf(500); + + } + } else { + baseDataValidator.reset().parameter(collateralParameterName).expectedArrayButIsNot(); + } + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } } @@ -328,7 +390,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { final Integer repaymentEveryType = fromApiJsonHelper.extractIntegerWithLocaleNamed(repaymentEveryTypeParameterName, element); baseDataValidator.reset().parameter(repaymentEveryTypeParameterName).value(repaymentEveryType).notNull().inMinMaxRange(0, 3); } - + final String interestRatePerPeriodParameterName = "interestRatePerPeriod"; if (fromApiJsonHelper.parameterExists(interestRatePerPeriodParameterName, element)) { atLeastOneParameterPassedForUpdate = true; @@ -412,6 +474,69 @@ public final class LoanApplicationCommandFromApiJsonHelper { .notExceedingLengthOf(500); } + // charges + final String chargesParameterName = "charges"; + if (element.isJsonObject() && fromApiJsonHelper.parameterExists(chargesParameterName, element)) { + atLeastOneParameterPassedForUpdate = true; + + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + final String dateFormat = fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + final Locale locale = fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + + if (topLevelJsonElement.get(chargesParameterName).isJsonArray()) { + final Type arrayObjectParameterTypeOfMap = new TypeToken>() {}.getType(); + final Set supportedParameters = new HashSet(Arrays.asList("id", "chargeId", "amount", "chargeTimeType", + "chargeCalculationType", "specifiedDueDate")); + + final JsonArray array = topLevelJsonElement.get("charges").getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + + final JsonObject loanChargeElement = array.get(i - 1).getAsJsonObject(); + final String arrayObjectJson = this.fromApiJsonHelper.toJson(loanChargeElement); + fromApiJsonHelper.checkForUnsupportedParameters(arrayObjectParameterTypeOfMap, arrayObjectJson, supportedParameters); + + final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", loanChargeElement); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("chargeId", i).value(chargeId).notNull() + .integerGreaterThanZero(); + + final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, locale); + baseDataValidator.reset().parameter("charges").parameterAtIndexArray("amount", i).value(amount).notNull() + .positiveAmount(); + + fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", loanChargeElement, dateFormat, locale); + } + } + } + + // collateral + final String collateralParameterName = "collateral"; + if (element.isJsonObject() && fromApiJsonHelper.parameterExists(collateralParameterName, element)) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + if (topLevelJsonElement.get("collateral").isJsonArray()) { + + final Type collateralParameterTypeOfMap = new TypeToken>() {}.getType(); + final Set supportedParameters = new HashSet(Arrays.asList("id", "type", "description")); + final JsonArray array = topLevelJsonElement.get("collateral").getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + final JsonObject collateralItemElement = array.get(i - 1).getAsJsonObject(); + + final String collateralJson = this.fromApiJsonHelper.toJson(collateralItemElement); + fromApiJsonHelper.checkForUnsupportedParameters(collateralParameterTypeOfMap, collateralJson, supportedParameters); + + final Long collateralTypeId = fromApiJsonHelper.extractLongNamed("type", collateralItemElement); + baseDataValidator.reset().parameter("collateral").parameterAtIndexArray("type", i).value(collateralTypeId).notNull() + .integerGreaterThanZero(); + + final String description = fromApiJsonHelper.extractStringNamed("description", collateralItemElement); + baseDataValidator.reset().parameter("collateral").parameterAtIndexArray("description", i).value(description).notBlank() + .notExceedingLengthOf(500); + + } + } else { + baseDataValidator.reset().parameter(collateralParameterName).expectedArrayButIsNot(); + } + } + if (!atLeastOneParameterPassedForUpdate) { final Object forceError = null; baseDataValidator.reset().anyOfNotNull(forceError); @@ -420,38 +545,4 @@ public final class LoanApplicationCommandFromApiJsonHelper { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } } - - public LoanChargeCommand[] extractLoanCharges(final String json) { - final JsonElement element = fromApiJsonHelper.parse(json); - return extractInToLoanChargeCommands(element); - } - - private LoanChargeCommand[] extractInToLoanChargeCommands(final JsonElement element) { - LoanChargeCommand[] charges = null; - if (element.isJsonObject()) { - final JsonObject topLevelJsonElement = element.getAsJsonObject(); - final String dateFormat = fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); - final Locale locale = fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); - if (topLevelJsonElement.has("charges") && topLevelJsonElement.get("charges").isJsonArray()) { - - final JsonArray array = topLevelJsonElement.get("charges").getAsJsonArray(); - charges = new LoanChargeCommand[array.size()]; - for (int i = 0; i < array.size(); i++) { - - final JsonObject loanChargeElement = array.get(i).getAsJsonObject(); - - final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", loanChargeElement); - final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed("amount", loanChargeElement, locale); - final Integer chargeTimeType = fromApiJsonHelper.extractIntegerNamed("chargeTimeType", loanChargeElement, locale); - final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerNamed("chargeCalculationType", loanChargeElement, - locale); - final LocalDate specifiedDueDate = fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", loanChargeElement, - dateFormat, locale); - - charges[i] = new LoanChargeCommand(chargeId, amount, chargeTimeType, chargeCalculationType, specifiedDueDate); - } - } - } - return charges; - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanChargeCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanChargeCommandFromApiJsonDeserializer.java index 39189f279..ae954fc6e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanChargeCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanChargeCommandFromApiJsonDeserializer.java @@ -30,7 +30,7 @@ public final class LoanChargeCommandFromApiJsonDeserializer extends AbstractFrom /** * The parameters supported for this command. */ - final Set supportedParameters = new HashSet(Arrays.asList("chargeId", "amount", "chargeTimeType", + final Set supportedParameters = new HashSet(Arrays.asList("id", "chargeId", "amount", "chargeTimeType", "chargeCalculationType", "specifiedDueDate", "locale", "dateFormat")); private final FromJsonHelper fromApiJsonHelper; @@ -49,12 +49,13 @@ public final class LoanChargeCommandFromApiJsonDeserializer extends AbstractFrom fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); final JsonElement element = fromApiJsonHelper.parse(json); + final Long id = fromApiJsonHelper.extractLongNamed("id", element); final Long chargeId = fromApiJsonHelper.extractLongNamed("chargeId", element); final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element); final Integer chargeTimeType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeTimeType", element); final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element); - final LocalDate specifiedDueDate = fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", element); + final LocalDate dueAsOfDate = fromApiJsonHelper.extractLocalDateNamed("specifiedDueDate", element); - return new LoanChargeCommand(chargeId, amount, chargeTimeType, chargeCalculationType, specifiedDueDate); + return new LoanChargeCommand(id, chargeId, amount, chargeTimeType, chargeCalculationType, dueAsOfDate); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 3cc0e7db8..bc44530ae 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -7,6 +7,7 @@ import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonQuery; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; @@ -15,6 +16,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityExce import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; @@ -23,16 +25,17 @@ import org.mifosplatform.portfolio.client.domain.Note; import org.mifosplatform.portfolio.client.domain.NoteRepository; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.fund.domain.Fund; -import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand; import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionCommand; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge; +import org.mifosplatform.portfolio.loanaccount.domain.LoanCollateral; import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus; +import org.mifosplatform.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted; +import org.mifosplatform.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified; import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; -import org.mifosplatform.portfolio.loanaccount.exception.LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted; import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator; import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService; @@ -56,7 +59,7 @@ import com.google.gson.JsonElement; public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService { private final static Logger logger = LoggerFactory.getLogger(LoanApplicationWritePlatformServiceJpaRepositoryImpl.class); - + private final PlatformSecurityContext context; private final FromJsonHelper fromJsonHelper; private final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer; @@ -68,6 +71,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private final ClientRepository clientRepository; private final LoanProductRepository loanProductRepository; private final LoanChargeAssembler loanChargeAssembler; + private final LoanCollateralAssembler loanCollateralAssembler; private final AprCalculator aprCalculator; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; @@ -76,9 +80,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer, final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer, final AprCalculator aprCalculator, final LoanAssembler loanAssembler, final LoanChargeAssembler loanChargeAssembler, - final LoanRepository loanRepository, final NoteRepository noteRepository, - final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepository clientRepository, - final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory) { + final LoanCollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, + final NoteRepository noteRepository, final LoanScheduleCalculationPlatformService calculationPlatformService, + final ClientRepository clientRepository, final LoanProductRepository loanProductRepository, + final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory) { this.context = context; this.fromJsonHelper = fromJsonHelper; this.fromApiJsonDeserializer = fromApiJsonDeserializer; @@ -86,6 +91,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.aprCalculator = aprCalculator; this.loanAssembler = loanAssembler; this.loanChargeAssembler = loanChargeAssembler; + this.loanCollateralAssembler = loanCollateralAssembler; this.loanRepository = loanRepository; this.noteRepository = noteRepository; this.calculationPlatformService = calculationPlatformService; @@ -149,9 +155,15 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Loan existingLoanApplication = retrieveLoanBy(loanId); - final LoanChargeCommand[] charges = this.fromApiJsonDeserializer.extractLoanCharges(command.json()); + if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified( + loanId); } - final Map changes = existingLoanApplication.loanApplicationModification(command, charges, this.aprCalculator); + final Set possiblyModifedLoanCharges = this.loanChargeAssembler.fromParsedJson(command.parsedJson()); + final Set possiblyModifedLoanCollateralItems = this.loanCollateralAssembler + .fromParsedJson(command.parsedJson()); + + final Map changes = existingLoanApplication.loanApplicationModification(command, possiblyModifedLoanCharges, + possiblyModifedLoanCollateralItems, this.aprCalculator); final String clientIdParamName = "clientId"; if (changes.containsKey(clientIdParamName)) { @@ -179,6 +191,20 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa existingLoanApplication.updateFund(fund); } + final String loanPurposeIdParamName = "loanPurposeId"; + if (changes.containsKey(loanPurposeIdParamName)) { + final Long loanPurposeId = command.longValueOfParameterNamed(loanPurposeIdParamName); + final CodeValue loanPurpose = this.loanAssembler.findCodeValueByIdIfProvided(loanPurposeId); + existingLoanApplication.updateLoanPurpose(loanPurpose); + } + + final String loanOfficerIdParamName = "loanOfficerId"; + if (changes.containsKey(loanOfficerIdParamName)) { + final Long loanOfficerId = command.longValueOfParameterNamed(loanOfficerIdParamName); + final Staff newValue = this.loanAssembler.findLoanOfficerByIdIfProvided(loanOfficerId); + existingLoanApplication.updateLoanOfficerOnLoanApplication(newValue); + } + final String strategyIdParamName = "transactionProcessingStrategyId"; if (changes.containsKey(strategyIdParamName)) { final Long strategyId = command.longValueOfParameterNamed(strategyIdParamName); @@ -193,6 +219,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa existingLoanApplication.updateLoanCharges(loanCharges); } + final String collateralParamName = "collateral"; + if (changes.containsKey(collateralParamName)) { + final Set loanCollateral = this.loanCollateralAssembler.fromParsedJson(command.parsedJson()); + existingLoanApplication.updateLoanCollateral(loanCollateral); + } + if (changes.containsKey("recalculateLoanSchedule")) { changes.remove("recalculateLoanSchedule"); @@ -224,7 +256,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa return CommandProcessingResult.empty(); } } - + /* * Guaranteed to throw an exception no matter what the data integrity issue * is. @@ -245,10 +277,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa } logAsErrorUnexpectedDataIntegrityException(dve); - throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); } - + private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { logger.error(dve.getMessage(), dve); } @@ -261,7 +292,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Loan loan = retrieveLoanBy(loanId); - if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); } + if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); } List relatedNotes = this.noteRepository.findByLoanId(loan.getId()); this.noteRepository.deleteInBatch(relatedNotes); @@ -296,7 +327,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Map changes = loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { this.loanRepository.save(loan); - + final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); @@ -327,7 +358,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Map changes = loan.undoApproval(defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { this.loanRepository.save(loan); - + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); @@ -365,7 +396,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Map changes = loan.loanApplicationRejection(command, defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { this.loanRepository.save(loan); - + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); @@ -403,7 +434,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Map changes = loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { this.loanRepository.save(loan); - + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index fcce0e3c1..9f1452448 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Set; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.organisation.staff.domain.Staff; @@ -25,6 +27,7 @@ import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge; +import org.mifosplatform.portfolio.loanaccount.domain.LoanCollateral; import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository; @@ -49,16 +52,18 @@ public class LoanAssembler { private final FundRepository fundRepository; private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository; private final StaffRepository staffRepository; - private final LoanChargeAssembler loanChargeAssembler; + private final CodeValueRepositoryWrapper codeValueRepository; private final LoanScheduleAssembler loanScheduleAssembler; + private final LoanChargeAssembler loanChargeAssembler; + private final LoanCollateralAssembler loanCollateralAssembler; private final FromJsonHelper fromApiJsonHelper; @Autowired public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanProductRepository loanProductRepository, final ClientRepository clientRepository, final GroupRepository groupRepository, final FundRepository fundRepository, final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository, - final StaffRepository staffRepository, final LoanScheduleAssembler loanScheduleAssembler, - final LoanChargeAssembler loanChargeAssembler) { + final StaffRepository staffRepository, final CodeValueRepositoryWrapper codeValueRepository, + final LoanScheduleAssembler loanScheduleAssembler, final LoanChargeAssembler loanChargeAssembler, final LoanCollateralAssembler loanCollateralAssembler) { this.fromApiJsonHelper = fromApiJsonHelper; this.loanProductRepository = loanProductRepository; this.clientRepository = clientRepository; @@ -66,8 +71,10 @@ public class LoanAssembler { this.fundRepository = fundRepository; this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository; this.staffRepository = staffRepository; + this.codeValueRepository = codeValueRepository; this.loanScheduleAssembler = loanScheduleAssembler; this.loanChargeAssembler = loanChargeAssembler; + this.loanCollateralAssembler = loanCollateralAssembler; } public Loan assembleFrom(final JsonCommand command) { @@ -86,6 +93,7 @@ public class LoanAssembler { final Long fundId = fromApiJsonHelper.extractLongNamed("fundId", element); final Long loanOfficerId = fromApiJsonHelper.extractLongNamed("loanOfficerId", element); final Long transactionProcessingStrategyId = fromApiJsonHelper.extractLongNamed("transactionProcessingStrategyId", element); + final Long loanPurposeId = fromApiJsonHelper.extractLongNamed("loanPurposeId", element); final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } @@ -93,7 +101,11 @@ public class LoanAssembler { final Fund fund = findFundByIdIfProvided(fundId); final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId); final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(transactionProcessingStrategyId); - + CodeValue loanPurpose = null; + if (loanPurposeId != null) { + loanPurpose = codeValueRepository.findOneWithNotFoundDetection(loanPurposeId); + } + final Set collateral = this.loanCollateralAssembler.fromParsedJson(element); final Set loanCharges = this.loanChargeAssembler.fromParsedJson(element); final BigDecimal inArrearsTolerance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("inArrearsTolerance", element); @@ -106,24 +118,24 @@ public class LoanAssembler { client = this.clientRepository.findOne(clientId); if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } - loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy, - loanSchedule, loanCharges); + loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanPurpose, + loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral); } if (groupId != null) { group = this.groupRepository.findOne(groupId); if (group == null || group.isDeleted()) { throw new GroupNotFoundException(groupId); } - loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy, - loanSchedule, loanCharges); + loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanProduct, fund, loanOfficer, + loanTransactionProcessingStrategy, loanSchedule, loanCharges); } - if (client != null && group != null){ - + if (client != null && group != null) { + if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); } - - loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy, - loanSchedule, loanCharges); + + loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanProduct, fund, loanOfficer, + loanTransactionProcessingStrategy, loanSchedule, loanCharges); } final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); @@ -140,6 +152,14 @@ public class LoanAssembler { List allowedLoanStatuses = Arrays.asList(LoanStatus.values()); return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses); } + + public CodeValue findCodeValueByIdIfProvided(final Long codeValueId) { + CodeValue codeValue = null; + if (codeValueId != null) { + codeValue = this.codeValueRepository.findOneWithNotFoundDetection(codeValueId); + } + return codeValue; + } public Fund findFundByIdIfProvided(final Long fundId) { Fund fund = null; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeAssembler.java index eaa718934..f2dffd7c1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeAssembler.java @@ -89,10 +89,7 @@ public class LoanChargeAssembler { loanCharges.add(loanCharge); } } - } else { - // no charges passed, use existing ones against loan } - } return loanCharges; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralAssembler.java new file mode 100644 index 000000000..760379f88 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralAssembler.java @@ -0,0 +1,71 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import java.util.HashSet; +import java.util.Set; + +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.portfolio.charge.exception.LoanCollateralNotFoundException; +import org.mifosplatform.portfolio.loanaccount.domain.LoanCollateral; +import org.mifosplatform.portfolio.loanaccount.domain.LoanCollateralRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +@Service +public class LoanCollateralAssembler { + + private final FromJsonHelper fromApiJsonHelper; + private final CodeValueRepositoryWrapper codeValueRepository; + private final LoanCollateralRepository loanCollateralRepository; + + @Autowired + public LoanCollateralAssembler(final FromJsonHelper fromApiJsonHelper, final CodeValueRepositoryWrapper codeValueRepository, + final LoanCollateralRepository loanCollateralRepository) { + this.fromApiJsonHelper = fromApiJsonHelper; + this.codeValueRepository = codeValueRepository; + this.loanCollateralRepository = loanCollateralRepository; + } + + public Set fromParsedJson(final JsonElement element) { + + final Set collateralItems = new HashSet(); + + if (element.isJsonObject()) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + + if (topLevelJsonElement.has("collateral") && topLevelJsonElement.get("collateral").isJsonArray()) { + final JsonArray array = topLevelJsonElement.get("collateral").getAsJsonArray(); + for (int i = 0; i < array.size(); i++) { + + final JsonObject collateralItemElement = array.get(i).getAsJsonObject(); + + final Long id = fromApiJsonHelper.extractLongNamed("id", collateralItemElement); + final Long collateralTypeId = fromApiJsonHelper.extractLongNamed("type", collateralItemElement); + final CodeValue collateralType = this.codeValueRepository.findOneWithNotFoundDetection(collateralTypeId); + final String description = fromApiJsonHelper.extractStringNamed("description", collateralItemElement); + + if (id == null) { + collateralItems.add(LoanCollateral.from(collateralType, description)); + } else { + LoanCollateral loanCollateralItem = this.loanCollateralRepository.findOne(id); + if (loanCollateralItem == null) { throw new LoanCollateralNotFoundException(id); } + + loanCollateralItem.assembleFrom(collateralType, description); + + collateralItems.add(loanCollateralItem); + } + } + } else { + // no charges passed, use existing ones against loan + } + + } + + return collateralItems; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformService.java new file mode 100644 index 000000000..3efd11244 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformService.java @@ -0,0 +1,10 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.loanaccount.data.LoanCollateralData; + +public interface LoanCollateralReadPlatformService { + + Collection retrieveLoanCollateral(Long loanId); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformServiceImpl.java new file mode 100644 index 000000000..9513f6720 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanCollateralReadPlatformServiceImpl.java @@ -0,0 +1,63 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.loanaccount.data.LoanCollateralData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class LoanCollateralReadPlatformServiceImpl implements LoanCollateralReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + + @Autowired + public LoanCollateralReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private static final class LoanCollateralMapper implements RowMapper { + + private StringBuilder sqlBuilder = new StringBuilder( + "lc.id as id, lc.description as description, cv.id as typeId, cv.code_value as typeName") // + .append(" FROM m_loan_collateral lc") // + .append(" JOIN m_code_value cv on lc.type_cv_id = cv.id"); + + public String schema() { + return sqlBuilder.toString(); + } + + @Override + public LoanCollateralData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String name = rs.getString("description"); + final Long typeId = rs.getLong("typeId"); + final String typeName = rs.getString("typeName"); + + final CodeValueData type = CodeValueData.instance(typeId, typeName); + + return LoanCollateralData.instance(id, type, name); + } + } + + @Override + public Collection retrieveLoanCollateral(final Long loanId) { + this.context.authenticatedUser(); + + final LoanCollateralMapper rm = new LoanCollateralMapper(); + + final String sql = "select " + rm.schema() + " where lc.loan_id=? order by id ASC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 4f7f9d2f7..eeb575df7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -362,9 +362,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { private static final class LoanMapper implements RowMapper { public String loanSchema() { - return "l.id as id, l.account_no as accountNo, l.external_id as externalId, l.fund_id as fundId, f.name as fundName, " - + " lp.id as loanProductId, lp.name as loanProductName, lp.description as loanProductDescription, c.id as clientId, c.display_name as clientName, " - + " c.office_id as clientOfficeId, g.id as groupId, g.name as groupName, g.office_id as groupOfficeId," + return "l.id as id, l.account_no as accountNo, l.external_id as externalId, l.fund_id as fundId, f.name as fundName," + + " l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName," + + " lp.id as loanProductId, lp.name as loanProductName, lp.description as loanProductDescription," + + " c.id as clientId, c.display_name as clientName, c.office_id as clientOfficeId," + + " g.id as groupId, g.name as groupName, g.office_id as groupOfficeId," + " l.submittedon_date as submittedOnDate," + " l.total_charges_due_at_disbursement_derived as totalDisbursementCharges," + " l.approvedon_date as approvedOnDate, l.expected_disbursedon_date as expectedDisbursementDate, l.disbursedon_date as actualDisbursementDate, l.expected_firstrepaymenton_date as expectedFirstRepaymentOnDate," @@ -379,7 +381,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.loan_officer_id as loanOfficerId, s.display_name as loanOfficerName" + " from m_loan l" + " left join m_client c on c.id = l.client_id" + " left join m_group g on g.id = l.group_id" + " join m_product_loan lp on lp.id = l.product_id" + " join m_currency rc on rc.`code` = l.currency_code" - + " left join m_fund f on f.id = l.fund_id" + " left join m_staff s on s.id = l.loan_officer_id"; + + " left join m_fund f on f.id = l.fund_id" + " left join m_staff s on s.id = l.loan_officer_id" + + " left join m_code_value cv on cv.id = l.loanpurpose_cv_id"; } @Override @@ -407,8 +410,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Long fundId = JdbcSupport.getLong(rs, "fundId"); final String fundName = rs.getString("fundName"); + final Long loanOfficerId = JdbcSupport.getLong(rs, "loanOfficerId"); final String loanOfficerName = rs.getString("loanOfficerName"); + + final Long loanPurposeId = JdbcSupport.getLong(rs, "loanPurposeId"); + final String loanPurposeName = rs.getString("loanPurposeName"); + final Long loanProductId = JdbcSupport.getLong(rs, "loanProductId"); final String loanProductName = rs.getString("loanProductName"); final String loanProductDescription = rs.getString("loanProductDescription"); @@ -468,12 +476,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { Collection charges = null; return new LoanBasicDetailsData(id, accountNo, externalId, clientId, clientName, clientOfficeId, groupId, groupName, - groupOfficeId, loanProductId, loanProductName, loanProductDescription, fundId, fundName, closedOnDate, submittedOnDate, - approvedOnDate, expectedDisbursementDate, actualDisbursementDate, expectedMaturityDate, expectedFirstRepaymentOnDate, - interestChargedFromDate, currencyData, principal, inArrearsTolerance, numberOfRepayments, repaymentEvery, - interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType, - interestType, interestCalculationPeriodType, status, lifeCycleStatusDate, termFrequency, termPeriodFrequencyType, - transactionStrategyId, charges, loanOfficerId, loanOfficerName, totalDisbursementCharges); + groupOfficeId, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, + loanPurposeName, closedOnDate, submittedOnDate, approvedOnDate, expectedDisbursementDate, actualDisbursementDate, + expectedMaturityDate, expectedFirstRepaymentOnDate, interestChargedFromDate, currencyData, principal, + inArrearsTolerance, numberOfRepayments, repaymentEvery, interestRatePerPeriod, annualInterestRate, + repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, + status, lifeCycleStatusDate, termFrequency, termPeriodFrequencyType, transactionStrategyId, charges, loanOfficerId, + loanOfficerName, totalDisbursementCharges); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index d1537e58f..f27aca016 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -44,8 +44,8 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository; import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException; -import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException; +import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException; import org.mifosplatform.portfolio.loanaccount.serialization.LoanChargeCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanaccount.serialization.LoanStateTransitionCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanaccount.serialization.LoanTransactionCommandFromApiJsonDeserializer; @@ -78,8 +78,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer, final LoanTransactionCommandFromApiJsonDeserializer loanTransactionCommandFromApiJsonDeserializer, final LoanChargeCommandFromApiJsonDeserializer loanChargeCommandFromApiJsonDeserializer, - final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer, - final LoanAssembler loanAssembler, + final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer, final LoanAssembler loanAssembler, final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository, final NoteRepository noteRepository, final ChargeRepository chargeRepository, final LoanChargeRepository loanChargeRepository, final ApplicationCurrencyRepository applicationCurrencyRepository, @@ -96,7 +95,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanChargeRepository = loanChargeRepository; this.applicationCurrencyRepository = applicationCurrencyRepository; this.journalEntryWritePlatformService = journalEntryWritePlatformService; - this.loanUpdateCommandFromApiJsonDeserializer = loanUpdateCommandFromApiJsonDeserializer; + this.loanUpdateCommandFromApiJsonDeserializer = loanUpdateCommandFromApiJsonDeserializer; } private boolean isBeforeToday(final LocalDate date) { @@ -129,26 +128,27 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Map changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency); if (!changes.isEmpty()) { - // variable stores Id's of all existing loan transactions (newly created + // variable stores Id's of all existing loan transactions (newly + // created // loan transactions would not have an Id before save) final Set existingLoanTransactionIds = new HashSet(); - for(LoanTransaction loanTransaction:loan.getLoanTransactions()){ - if(!(loanTransaction.getId()==null)){ + for (LoanTransaction loanTransaction : loan.getLoanTransactions()) { + if (!(loanTransaction.getId() == null)) { existingLoanTransactionIds.add(loanTransaction.getId()); } } this.loanRepository.save(loan); - + if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } - + // make a call to accounting if (loan.isAccountingEnabledOnLoanProduct()) { /*** - * Variable holds list of all newly created loan transactions during - * this disbursal + * Variable holds list of all newly created loan transactions + * during this disbursal **/ List newLoanTransactions = new ArrayList(); for (LoanTransaction loanTransaction : loan.getLoanTransactions()) { @@ -183,7 +183,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Map changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { this.loanRepository.save(loan); - + final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); @@ -276,15 +276,15 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Map changes = new LinkedHashMap(); changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate")); changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount")); - - boolean transactionIsRepayment= transactionToAdjust.isRepayment(); + + boolean transactionIsRepayment = transactionToAdjust.isRepayment(); final LoanTransaction newTransactionDetail = loan.adjustExistingTransaction(transactionDate, transactionAmount, defaultLoanLifecycleStateMachine(), transactionToAdjust); if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) { this.loanTransactionRepository.save(newTransactionDetail); } - + this.loanRepository.save(loan); final String noteText = command.stringValueOfParameterNamed("note"); @@ -296,8 +296,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf changes.put("locale", command.locale()); changes.put("dateFormat", command.dateFormat()); - - // make a call to accounting only if transaction being adjusted is a repayment (not waiver) + + // make a call to accounting only if transaction being adjusted is a + // repayment (not waiver) if (loan.isAccountingEnabledOnLoanProduct() && transactionIsRepayment) { List newLoanTransactions = new ArrayList(); if (newTransactionDetail.getId() != null) { @@ -307,7 +308,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions); journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO); } - + return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(transactionId) // @@ -389,7 +390,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf changes.put("locale", command.locale()); changes.put("dateFormat", command.dateFormat()); - + // make a call to accounting if (loan.isAccountingEnabledOnLoanProduct()) { LoanDTO loanDTO = populateLoanData(loan, writeoff); @@ -509,8 +510,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf public CommandProcessingResult addLoanCharge(final Long loanId, final JsonCommand command) { this.context.authenticatedUser(); + // FIXME - KW - update loan charge api validation final LoanChargeCommand loanChargeCommand = this.loanChargeCommandFromApiJsonDeserializer.commandFromApiJson(command.json()); - loanChargeCommand.validateForCreate(); + // loanChargeCommand.validateForCreate(); final Loan loan = retrieveLoanBy(loanId); @@ -709,12 +711,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.context.authenticatedUser(); - final LoanUpdateCommand loanUpdateCommand = this.loanUpdateCommandFromApiJsonDeserializer.commandFromApiJson(command - .json()); - + final LoanUpdateCommand loanUpdateCommand = this.loanUpdateCommandFromApiJsonDeserializer.commandFromApiJson(command.json()); + loanUpdateCommand.validate(); - final LocalDate dateOfLoanOfficerunAssigned = command.localDateValueOfParameterNamed("unassignedDate"); final Loan loan = retrieveLoanBy(loanId); @@ -738,11 +738,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private LoanDTO populateLoanDTO(Loan loan, List loanTransactions) { List loanTransactionDTOs = new ArrayList(); for (LoanTransaction loanTransaction : loanTransactions) { - LoanTransactionDTO loanTransactionDTO = new LoanTransactionDTO(loanTransaction.getId().toString(), - loanTransaction.getDateOf(), loanTransaction.getAmount(), loanTransaction.getPrincipalPortion(), - loanTransaction.getInterestPortion(), loanTransaction.getFeePortion(), loanTransaction.getPenaltyChargesPortion(), - loanTransaction.isDisbursement(), loanTransaction.isRepayment(), loanTransaction.isRepaymentAtDisbursement(), - loanTransaction.isContra(), loanTransaction.isWriteOff()); + LoanTransactionDTO loanTransactionDTO = new LoanTransactionDTO(loanTransaction.getId().toString(), loanTransaction.getDateOf(), + loanTransaction.getAmount(), loanTransaction.getPrincipalPortion(), loanTransaction.getInterestPortion(), + loanTransaction.getFeePortion(), loanTransaction.getPenaltyChargesPortion(), loanTransaction.isDisbursement(), + loanTransaction.isRepayment(), loanTransaction.isRepaymentAtDisbursement(), loanTransaction.isContra(), + loanTransaction.isWriteOff()); loanTransactionDTOs.add(loanTransactionDTO); } return new LoanDTO(loan.getId(), loan.productId(), loan.getOfficeId(), loan.isCashBasedAccountingEnabledOnLoanProduct(),