diff --git a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql b/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql index c436784b4..27b783100 100644 --- a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql +++ b/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql @@ -193,10 +193,11 @@ CREATE TABLE `m_office_transaction` ( CREATE TABLE `m_permission` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `grouping` varchar(45) DEFAULT NULL, - `order_in_grouping` int(11) DEFAULT NULL, `code` varchar(100) NOT NULL, `default_description` varchar(500) NOT NULL, `default_name` varchar(100) NOT NULL, + `entity_name` varchar(100) DEFAULT NULL, + `action_name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `code` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/mifosng-db/0002-mifosng-base-reference-data.sql b/mifosng-db/0002-mifosng-base-reference-data.sql index 702190e10..45f7e2607 100644 --- a/mifosng-db/0002-mifosng-base-reference-data.sql +++ b/mifosng-db/0002-mifosng-base-reference-data.sql @@ -157,167 +157,58 @@ VALUES -- ========= roles and permissions ========= -- === System Supplied Permissons == +/* +this scripts removes all current m_role_permission and m_permission entries +and then inserts new m_permission entries and just one m_role_permission entry +which gives the role (id 1 - super user) an ALL_FUNCTIONS permission + +If you had other roles set up with specific permissions you will have to set up their permissions again. +*/ + delete from m_role_permission; delete from m_permission; -INSERT INTO m_permission VALUES -(1,'special',5,'USER_ADMINISTRATION_SUPER_USER','An application user will have permission to execute all tasks related to user administration.','User administration -ALL'), -(2,'special',4,'ORGANISATION_ADMINISTRATION_SUPER_USER','An application user will have permission to execute all tasks related to organisation -administration.','Organisation adminsitration ALL'), -(3,'special',3,'PORTFOLIO_MANAGEMENT_SUPER_USER','An application user will have permission to execute all tasks related to portfolio management.','Portfolio management -ALL'), -(4,'special',6,'REPORTING_SUPER_USER','An application user will have permission to execute and view all reports.','Reporting ALL'), - -(5,'portfolio',NULL,'CREATE_LOAN','Allows an application user to sumit new loan application.','Can submit new loan application'), - -(6,'portfolio',NULL,'CREATEHISTORIC_LOAN','Allows an application user to sumit new loan application where the submitted on date is in the past.','Can submit historic - -loan application'), -(7,'portfolio',NULL,'APPROVE_LOAN','Allows an application user to approve a loan application.','Can approve loan application'), - -(8,'portfolio',NULL,'APPROVEINPAST_LOAN','Allows an application user to approve a loan application where the approval date is in the past.','Can approve loan - -application in the past'), -(9,'portfolio',NULL,'REJECT_LOAN','Allows an application user to reject a loan application.','Can reject loan application'), - -(10,'portfolio',NULL,'REJECTINPAST_LOAN','Allows an application user to reject a loan application where the rejected date is in the past.','Can reject loan application - -in the past'), -(11,'portfolio',NULL,'WITHDRAW_LOAN','Allows an application user to mark loan application as withdrawn by client.','Can withdraw loan application'), - -(12,'portfolio',NULL,'WITHDRAWINPAST_LOAN','Allows an application user to mark loan application as withdrawn by client where the withdran on date is in the past.','Can - -withdraw loan application in the past'),(13,'portfolio',NULL,'DELETE_LOAN','Allows an application user to complete delete the loan application if it is submitted but - -not approved.','Can delete submitted loan application'),(14,'portfolio',NULL,'APPROVALUNDO_LOAN','Allows an application user to undo a loan approval.','Can undo loan - -approval'),(15,'portfolio',NULL,'DISBURSE_LOAN','Allows an application user to disburse a loan application.','Can disburse loan'), - -(16,'portfolio',NULL,'DISBURSEINPAST_LOAN','Allows an application user to disburse a loan where the disbursement date is in the past.','Can disburse loan in the - -past'),(17,'portfolio',NULL,'DISBURSALUNDO_LOAN','Allows an application user to undo a loan disbursal if not payments already made.','Can undo loan disbursal'), - -(18,'portfolio',NULL,'REPAYMENT_LOAN','Allows an application user to enter a repayment on the loan.','Can enter a repayment against a loan'), - -(19,'portfolio',NULL,'REPAYMENTINPAST_LOAN','Allows an application user to enter a repayment on the loan where the repayment date is in the past.','Can enter a - -repayment against a loan in the past'), -(20,'portfolio',NULL,'CREATE_CLIENT','Allows an application user to add a new client.','Can add a new client.'), -(42,'special',1,'ALL_FUNCTIONS','An application user will have permission to execute all tasks.','ALL'), -(43,'special',2,'ALL_FUNCTIONS_READ','An application user will have permission to execute all read tasks.','ALL READ'), -(112,'organisation',NULL,'CREATE_CHARGE','Create a Charge','Create a Charge'),(113,'organisation',NULL,'READ_CHARGE','Read Charges','Read Charges'), - -(114,'organisation',NULL,'UPDATE_CHARGE','Update a Charge','Update a Charge'),(115,'organisation',NULL,'DELETE_CHARGE','Delete a Charge','Delete a Charge'), -(120,'portfolio',NULL,'READ_CLIENT','Read Clients','Read Clients'),(121,'portfolio',NULL,'UPDATE_CLIENT','Update a Client','Update a Client'), - -(122,'portfolio',NULL,'DELETE_CLIENT','Delete a Client','Delete a Client'),(123,'portfolio',NULL,'CREATE_CLIENTIMAGE','Create/Update Client Image','Create/Update - -Client Image'),(124,'portfolio',NULL,'READ_CLIENTIMAGE','Read Client Images','Read Client Images'),(126,'portfolio',NULL,'DELETE_CLIENTIMAGE','Delete Client - -Image','Delete Client Image'),(127,'portfolio',NULL,'CREATE_CLIENTNOTE','Create a Client Note','Create a Client Note'),(128,'portfolio',NULL,'READ_CLIENTNOTE','Read - -Client Notes','Read Client Notes'),(129,'portfolio',NULL,'UPDATE_CLIENTNOTE','Update a Client Note','Update a Client Note'), - -(130,'portfolio',NULL,'DELETE_CLIENTNOTE','Delete a Client Note','Delete a Client Note'),(131,'portfolio',NULL,'CREATE_CLIENTIDENTIFIER','Create a Client - -Identifier','Create a Client Identifier'),(132,'portfolio',NULL,'READ_CLIENTIDENTIFIER','Read Client Identifiers','Read Client Identifiers'), - -(133,'portfolio',NULL,'UPDATE_CLIENTIDENTIFIER','Update a Client Identifier','Update a Client Identifier'),(134,'portfolio',NULL,'DELETE_CLIENTIDENTIFIER','Delete a - -Client Identifier','Delete a Client Identifier'),(135,'configuration',NULL,'CREATE_CODE','Create a Code','Create a Code'),(136,'configuration',NULL,'READ_CODE','Read - -Codes','Read Codes'),(137,'configuration',NULL,'UPDATE_CODE','Update a Code','Update a Code'),(138,'configuration',NULL,'DELETE_CODE','Delete a Code','Delete a - -Code'),(139,'configuration',NULL,'READ_CURRENCY','Read Currencies','Read Currencies'),(140,'configuration',NULL,'UPDATE_CURRENCY','Update Currencies','Update - -Currencies'),(141,'portfolio',NULL,'CREATE_DOCUMENT','Create and Upload a Document','Create and Upload a Document'),(142,'portfolio',NULL,'READ_DOCUMENT','Read - -Documents','Read Documents'),(143,'portfolio',NULL,'UPDATE_DOCUMENT','Update and Upload a Document','Update and Upload a Document'), - -(144,'portfolio',NULL,'DELETE_DOCUMENT','Delete a Document','Delete a Document'),(145,'organisation',NULL,'CREATE_FUND','Create a Fund','Create a Fund'), - -(146,'organisation',NULL,'READ_FUND','Read Funds','Read Funds'),(147,'organisation',NULL,'UPDATE_FUND','Update a Fund','Update a Fund'), - -(148,'organisation',NULL,'DELETE_FUND','Delete Fund','Delete Fund'),(149,'portfolio',NULL,'CREATE_GROUP','Create a Group','Create a Group'), - -(150,'portfolio',NULL,'READ_GROUP','Read Groups','Read Groups'),(151,'portfolio',NULL,'UPDATE_GROUP','Update a Group','Update a Group'), - -(152,'portfolio',NULL,'DELETE_GROUP','Delete a Group','Delete a Group'),(153,'organisation',NULL,'CREATE_LOANPRODUCT','Create a Loan Product','Create a Loan - -Product'),(154,'organisation',NULL,'READ_LOANPRODUCT','Read Loan Products','Read Loan Products'),(155,'organisation',NULL,'UPDATE_LOANPRODUCT','Update a Loan - -Product','Update a Loan Product'),(156,'organisation',NULL,'DELETE_LOANPRODUCT','Delete a Loan Product','Delete a Loan Product'), - -(157,'portfolio',NULL,'READ_LOAN','Read Loans','Read Loans'),(158,'portfolio',NULL,'UPDATE_LOAN','Update a Loan','Update a Loan'), - -(159,'portfolio',NULL,'UPDATEHISTORIC_LOAN','Update a Loan that was Created Historically','Update a Loan that was Created Historically'), - -(160,'portfolio',NULL,'CREATE_LOANCHARGE','Create a Loan Charge','Create a Loan Charge'),(161,'portfolio',NULL,'UPDATE_LOANCHARGE','Update a Loan Charge','Update a - -Loan Charge'),(162,'portfolio',NULL,'DELETE_LOANCHARGE','Delete a Loan Charge','Delete a Loan Charge'),(163,'portfolio',NULL,'WAIVE_LOANCHARGE','Waive a Loan - -Charge','Waive a Loan Charge'),(164,'portfolio',NULL,'BULKREASSIGN_LOAN','Bulk Reassign Loans','Bulk Reassign Loans'), -(165,'portfolio',NULL,'ADJUST_LOAN','Adjust a Loan Transaction','Adjust a Loan Transaction'),(166,'portfolio',NULL,'WAIVEINTERESTPORTION_LOAN','Waive Portion of Loan - -Interest','Waive Portion of Loan Interest'),(167,'portfolio',NULL,'WRITEOFF_LOAN','Write-Off a Loan','Write-Off a Loan'),(168,'portfolio',NULL,'CLOSE_LOAN','Close a - -Loan','Close a Loan'),(169,'portfolio',NULL,'CLOSEASRESCHEDULED_LOAN','Close a Loan (having been Rescheduled (Mifos Legacy Need)','Close a Loan (having been - -Rescheduled (Mifos Legacy Need)'),(170,'organisation',NULL,'READ_MAKERCHECKER','Read Maker-Checker Entries','Read Maker-Checker Entries'), - -(171,'organisation',NULL,'CREATE_OFFICE','Create an Office','Create an Office'),(172,'organisation',NULL,'READ_OFFICE','Read Offices','Read Offices'), - -(173,'organisation',NULL,'UPDATE_OFFICE','Update an Office','Update an Office'),(174,'organisation',NULL,'DELETE_OFFICE','Delete an Office','Delete an Office'), - -(175,'organisation',NULL,'READ_OFFICETRANSACTION','Read Office Transactions','Read Office Transactions'), -(176,'organisation',NULL,'CREATE_OFFICETRANSACTION','Create an Office Transaction','Create an Office Transaction'), -(177,'authorisation',NULL,'READ_PERMISSION','Read Permissions','Read Permissions'), -(178,'authorisation',NULL,'CREATE_ROLE','Create a Role','Create a Role'), -(179,'authorisation',NULL,'READ_ROLE','Read Roles','Read Roles'), -(180,'authorisation',NULL,'UPDATE_ROLE','Update a Role','Update a Role'), -(181,'authorisation',NULL,'DELETE_ROLE','Delete a Role','Delete a Role'), -(182,'authorisation',NULL,'CREATE_USER','Create a User','Create a User'), -(183,'authorisation',NULL,'READ_USER','Read Users','Read Users'), -(184,'authorisation',NULL,'UPDATE_USER','Update a User','Update a User'), -(185,'authorisation',NULL,'DELETE_USER','Create a User','Create a User'), -(186,'organisation',NULL,'CREATE_STAFF','Create a Staff Member','Create a Staff Member'), -(187,'organisation',NULL,'READ_STAFF','Read Staff','Read Staff'), -(188,'organisation',NULL,'UPDATE_STAFF','Update a Staff Member','Update a Staff Member'), -(189,'organisation',NULL,'DELETE_STAFF','Delete a Staff Member','Delete a Staff Member'), -(190,'organisation',NULL,'CREATE_SAVINGSPRODUCT','Create a Savings Product','Create a Savings Product'), -(191,'organisation',NULL,'READ_SAVINGSPRODUCT','Read Savings Products','Read Savings Products'), -(192,'organisation',NULL,'UPDATE_SAVINGSPRODUCT','Update a Savings Product','Update a Savings Product'), -(193,'organisation',NULL,'DELETE_SAVINGSPRODUCT','Delete a Savings Product','Delete a Savings Product'), -(194,'organisation',NULL,'CREATE_DEPOSITPRODUCT','Create a Deposit Product','Create a Deposit Product'), -(195,'organisation',NULL,'READ_DEPOSITPRODUCT','Read Deposit Products','Read Deposit Products'), -(196,'organisation',NULL,'UPDATE_DEPOSITPRODUCT','Update a Deposit Product','Update a Deposit Product'), -(197,'organisation',NULL,'DELETE_DEPOSITPRODUCT','Delete a Deposit Product','Delete a Deposit Product'), -(198,'portfolio',NULL,'CREATE_DEPOSITACCOUNT','Create a Deposit Account','Create a Deposit Account'), -(199,'portfolio',NULL,'READ_DEPOSITACCOUNT','Read Deposit Accounts','Read Deposit Accounts'), -(200,'portfolio',NULL,'UPDATE_DEPOSITACCOUNT','Update a Deposit Account','Update a Deposit Account'), -(201,'portfolio',NULL,'DELETE_DEPOSITACCOUNT','Delete a Deposit Account','Delete a Deposit Account'), -(202,'portfolio',NULL,'APPROVE_DEPOSITACCOUNT','Approve a Deposit Account','Approve a Deposit Account'), -(203,'portfolio',NULL,'REJECT_DEPOSITACCOUNT','Reject Deposit Account','Reject Deposit Account'), -(204,'portfolio',NULL,'WITHDRAW_DEPOSITACCOUNT','Withdraw Deposit Account','Withdraw Deposit Account'), -(205,'portfolio',NULL,'APPROVALUNDO_DEPOSITACCOUNT','Undo Approval of Deposit Account','Undo Approval of Deposit Account'), -(206,'portfolio',NULL,'WITHDRAWAL_DEPOSITACCOUNT','Make a Withdrawal From Deposit Account','Make a Withdrawal From Deposit Account'), -(207,'portfolio',NULL,'INTEREST_DEPOSITACCOUNT','Apply Interest to Deposit Accounts','Apply Interest to Deposit Accounts'), -(208,'portfolio',NULL,'RENEW_DEPOSITACCOUNT','Renew Deposit Account','Renew Deposit Account'), -(209,'portfolio',NULL,'CREATE_SAVINGSACCOUNT','Create a Savings Account','Create a Savings Account'), -(210,'portfolio',NULL,'READ_SAVINGSACCOUNT','Read Savings Accounts','Read Savings Accounts'), -(211,'portfolio',NULL,'UPDATE_SAVINGSACCOUNT','Update a Savings Account','Update a Savings Account'), -(212,'portfolio',NULL,'DELETE_SAVINGSACCOUNT','Delete a Savings Account','Delete a Savings Account'); +/* System Supplied Permissons */ +INSERT INTO `m_permission` VALUES (1,'special','USER_ADMINISTRATION_SUPER_USER','An application user will have permission to execute all tasks related to user administration.','User administration ALL',NULL,NULL),(2,'special','ORGANISATION_ADMINISTRATION_SUPER_USER','An application user will have permission to execute all tasks related to organisation administration.','Organisation adminsitration ALL',NULL,NULL),(3,'special','PORTFOLIO_MANAGEMENT_SUPER_USER','An application user will have permission to execute all tasks related to portfolio management.','Portfolio management ALL',NULL,NULL),(4,'special','REPORTING_SUPER_USER','An application user will have permission to execute and view all reports.','Reporting ALL',NULL,NULL),(5,'portfolio','CREATE_LOAN','Allows an application user to sumit new loan application.','Can submit new loan application','LOAN','CREATE'),(6,'portfolio','CREATEHISTORIC_LOAN','Allows an application user to sumit new loan application where the submitted on date is in the past.','Can submit historic loan application','LOAN','CREATEHISTORIC'),(7,'transaction_loan','APPROVE_LOAN','Allows an application user to approve a loan application.','Can approve loan application','LOAN','APPROVE'),(8,'transaction_loan','APPROVEINPAST_LOAN','Allows an application user to approve a loan application where the approval date is in the past.','Can approve loan application in the past','LOAN','APPROVEINPAST'),(9,'transaction_loan','REJECT_LOAN','Allows an application user to reject a loan application.','Can reject loan application','LOAN','REJECT'),(10,'transaction_loan','REJECTINPAST_LOAN','Allows an application user to reject a loan application where the rejected date is in the past.','Can reject loan application in the past','LOAN','REJECTINPAST'), +(11,'transaction_loan','WITHDRAW_LOAN','Allows an application user to mark loan application as withdrawn by client.','Can withdraw loan application','LOAN','WITHDRAW'),(12,'transaction_loan','WITHDRAWINPAST_LOAN','Allows an application user to mark loan application as withdrawn by client where the withdran on date is in the past.','Can withdraw loan application in the past','LOAN','WITHDRAWINPAST'),(13,'portfolio','DELETE_LOAN','Allows an application user to complete delete the loan application if it is submitted but not approved.','Can delete submitted loan application','LOAN','DELETE'),(14,'transaction_loan','APPROVALUNDO_LOAN','Allows an application user to undo a loan approval.','Can undo loan approval','LOAN','APPROVALUNDO'),(15,'transaction_loan','DISBURSE_LOAN','Allows an application user to disburse a loan application.','Can disburse loan','LOAN','DISBURSE'),(16,'transaction_loan','DISBURSEINPAST_LOAN','Allows an application user to disburse a loan where the disbursement date is in the past.','Can disburse loan in the past','LOAN','DISBURSEINPAST'),(17,'transaction_loan','DISBURSALUNDO_LOAN','Allows an application user to undo a loan disbursal if not payments already made.','Can undo loan disbursal','LOAN','DISBURSALUNDO'),(18,'transaction_loan','REPAYMENT_LOAN','Allows an application user to enter a repayment on the loan.','Can enter a repayment against a loan','LOAN','REPAYMENT'),(19,'transaction_loan','REPAYMENTINPAST_LOAN','Allows an application user to enter a repayment on the loan where the repayment date is in the past.','Can enter a repayment against a loan in the past','LOAN','REPAYMENTINPAST'),(20,'portfolio','CREATE_CLIENT','Allows an application user to add a new client.','Can add a new client.','CLIENT','CREATE'), +(42,'special','ALL_FUNCTIONS','An application user will have permission to execute all tasks.','ALL',NULL,NULL),(43,'special','ALL_FUNCTIONS_READ','An application user will have permission to execute all read tasks.','ALL READ',NULL,NULL),(112,'organisation','CREATE_CHARGE','Create a Charge','Create a Charge','CHARGE','CREATE'),(113,'organisation','READ_CHARGE','Read Charges','Read Charges','CHARGE','READ'),(114,'organisation','UPDATE_CHARGE','Update a Charge','Update a Charge','CHARGE','UPDATE'),(115,'organisation','DELETE_CHARGE','Delete a Charge','Delete a Charge','CHARGE','DELETE'),(120,'portfolio','READ_CLIENT','Read Clients','Read Clients','CLIENT','READ'),(121,'portfolio','UPDATE_CLIENT','Update a Client','Update a Client','CLIENT','UPDATE'),(122,'portfolio','DELETE_CLIENT','Delete a Client','Delete a Client','CLIENT','DELETE'),(123,'portfolio','CREATE_CLIENTIMAGE','Create/Update Client Image','Create/Update Client Image','CLIENTIMAGE','CREATE'),(124,'portfolio','READ_CLIENTIMAGE','Read Client Images','Read Client Images','CLIENTIMAGE','READ'),(126,'portfolio','DELETE_CLIENTIMAGE','Delete Client Image','Delete Client Image','CLIENTIMAGE','DELETE'),(127,'portfolio','CREATE_CLIENTNOTE','Create a Client Note','Create a Client Note','CLIENTNOTE','CREATE'),(128,'portfolio','READ_CLIENTNOTE','Read Client Notes','Read Client Notes','CLIENTNOTE','READ'),(129,'portfolio','UPDATE_CLIENTNOTE','Update a Client Note','Update a Client Note','CLIENTNOTE','UPDATE'),(130,'portfolio','DELETE_CLIENTNOTE','Delete a Client Note','Delete a Client Note','CLIENTNOTE','DELETE'),(131,'portfolio','CREATE_CLIENTIDENTIFIER','Create a Client Identifier','Create a Client Identifier','CLIENTIDENTIFIER','CREATE'), +(132,'portfolio','READ_CLIENTIDENTIFIER','Read Client Identifiers','Read Client Identifiers','CLIENTIDENTIFIER','READ'),(133,'portfolio','UPDATE_CLIENTIDENTIFIER','Update a Client Identifier','Update a Client Identifier','CLIENTIDENTIFIER','UPDATE'),(134,'portfolio','DELETE_CLIENTIDENTIFIER','Delete a Client Identifier','Delete a Client Identifier','CLIENTIDENTIFIER','DELETE'),(135,'configuration','CREATE_CODE','Create a Code','Create a Code','CODE','CREATE'),(136,'configuration','READ_CODE','Read Codes','Read Codes','CODE','READ'),(137,'configuration','UPDATE_CODE','Update a Code','Update a Code','CODE','UPDATE'),(138,'configuration','DELETE_CODE','Delete a Code','Delete a Code','CODE','DELETE'),(139,'configuration','READ_CURRENCY','Read Currencies','Read Currencies','CURRENCY','READ'),(140,'configuration','UPDATE_CURRENCY','Update Currencies','Update Currencies','CURRENCY','UPDATE'),(141,'portfolio','CREATE_DOCUMENT','Create and Upload a Document','Create and Upload a Document','DOCUMENT','CREATE'),(142,'portfolio','READ_DOCUMENT','Read Documents','Read Documents','DOCUMENT','READ'),(143,'portfolio','UPDATE_DOCUMENT','Update and Upload a Document','Update and Upload a Document','DOCUMENT','UPDATE'),(144,'portfolio','DELETE_DOCUMENT','Delete a Document','Delete a Document','DOCUMENT','DELETE'),(145,'organisation','CREATE_FUND','Create a Fund','Create a Fund','FUND','CREATE'),(146,'organisation','READ_FUND','Read Funds','Read Funds','FUND','READ'),(147,'organisation','UPDATE_FUND','Update a Fund','Update a Fund','FUND','UPDATE'),(148,'organisation','DELETE_FUND','Delete Fund','Delete Fund','FUND','DELETE'),(149,'portfolio','CREATE_GROUP','Create a Group','Create a Group','GROUP','CREATE'), +(150,'portfolio','READ_GROUP','Read Groups','Read Groups','GROUP','READ'),(151,'portfolio','UPDATE_GROUP','Update a Group','Update a Group','GROUP','UPDATE'),(152,'portfolio','DELETE_GROUP','Delete a Group','Delete a Group','GROUP','DELETE'),(153,'organisation','CREATE_LOANPRODUCT','Create a Loan Product','Create a Loan Product','LOANPRODUCT','CREATE'),(154,'organisation','READ_LOANPRODUCT','Read Loan Products','Read Loan Products','LOANPRODUCT','READ'),(155,'organisation','UPDATE_LOANPRODUCT','Update a Loan Product','Update a Loan Product','LOANPRODUCT','UPDATE'),(156,'organisation','DELETE_LOANPRODUCT','Delete a Loan Product','Delete a Loan Product','LOANPRODUCT','DELETE'),(157,'portfolio','READ_LOAN','Read Loans','Read Loans','LOAN','READ'),(158,'portfolio','UPDATE_LOAN','Update a Loan','Update a Loan','LOAN','UPDATE'),(159,'portfolio','UPDATEHISTORIC_LOAN','Update a Loan that was Created Historically','Update a Loan that was Created Historically','LOAN','UPDATEHISTORIC'),(160,'portfolio','CREATE_LOANCHARGE','Create a Loan Charge','Create a Loan Charge','LOANCHARGE','CREATE'),(161,'portfolio','UPDATE_LOANCHARGE','Update a Loan Charge','Update a Loan Charge','LOANCHARGE','UPDATE'),(162,'portfolio','DELETE_LOANCHARGE','Delete a Loan Charge','Delete a Loan Charge','LOANCHARGE','DELETE'),(163,'portfolio','WAIVE_LOANCHARGE','Waive a Loan Charge','Waive a Loan Charge','LOANCHARGE','WAIVE'),(164,'transaction_loan','BULKREASSIGN_LOAN','Bulk Reassign Loans','Bulk Reassign Loans','LOAN','BULKREASSIGN'),(165,'transaction_loan','ADJUST_LOAN','Adjust a Loan Transaction','Adjust a Loan Transaction','LOAN','ADJUST'),(166,'transaction_loan','WAIVEINTERESTPORTION_LOAN','Waive Portion of Loan Interest','Waive Portion of Loan Interest','LOAN','WAIVEINTERESTPORTION'), +(167,'transaction_loan','WRITEOFF_LOAN','Write-Off a Loan','Write-Off a Loan','LOAN','WRITEOFF'),(168,'transaction_loan','CLOSE_LOAN','Close a Loan','Close a Loan','LOAN','CLOSE'),(169,'transaction_loan','CLOSEASRESCHEDULED_LOAN','Close a Loan (having been Rescheduled (Mifos Legacy Need)','Close a Loan (having been Rescheduled (Mifos Legacy Need)','LOAN','CLOSEASRESCHEDULED'),(170,'organisation','READ_MAKERCHECKER','Read Maker-Checker Entries','Read Maker-Checker Entries','MAKERCHECKER','READ'),(171,'organisation','CREATE_OFFICE','Create an Office','Create an Office','OFFICE','CREATE'),(172,'organisation','READ_OFFICE','Read Offices','Read Offices','OFFICE','READ'),(173,'organisation','UPDATE_OFFICE','Update an Office','Update an Office','OFFICE','UPDATE'),(174,'organisation','DELETE_OFFICE','Delete an Office','Delete an Office','OFFICE','DELETE'),(175,'organisation','READ_OFFICETRANSACTION','Read Office Transactions','Read Office Transactions','OFFICETRANSACTION','READ'),(176,'organisation','CREATE_OFFICETRANSACTION','Create an Office Transaction','Create an Office Transaction','OFFICETRANSACTION','CREATE'),(177,'authorisation','READ_PERMISSION','Read Permissions','Read Permissions','PERMISSION','READ'),(178,'authorisation','CREATE_ROLE','Create a Role','Create a Role','ROLE','CREATE'),(179,'authorisation','READ_ROLE','Read Roles','Read Roles','ROLE','READ'),(180,'authorisation','UPDATE_ROLE','Update a Role','Update a Role','ROLE','UPDATE'),(181,'authorisation','DELETE_ROLE','Delete a Role','Delete a Role','ROLE','DELETE'),(182,'authorisation','CREATE_USER','Create a User','Create a User','USER','CREATE'),(183,'authorisation','READ_USER','Read Users','Read Users','USER','READ'),(184,'authorisation','UPDATE_USER','Update a User','Update a User','USER','UPDATE'), +(185,'authorisation','DELETE_USER','Create a User','Create a User','USER','DELETE'),(186,'organisation','CREATE_STAFF','Create a Staff Member','Create a Staff Member','STAFF','CREATE'),(187,'organisation','READ_STAFF','Read Staff','Read Staff','STAFF','READ'),(188,'organisation','UPDATE_STAFF','Update a Staff Member','Update a Staff Member','STAFF','UPDATE'),(189,'organisation','DELETE_STAFF','Delete a Staff Member','Delete a Staff Member','STAFF','DELETE'),(190,'organisation','CREATE_SAVINGSPRODUCT','Create a Savings Product','Create a Savings Product','SAVINGSPRODUCT','CREATE'),(191,'organisation','READ_SAVINGSPRODUCT','Read Savings Products','Read Savings Products','SAVINGSPRODUCT','READ'),(192,'organisation','UPDATE_SAVINGSPRODUCT','Update a Savings Product','Update a Savings Product','SAVINGSPRODUCT','UPDATE'),(193,'organisation','DELETE_SAVINGSPRODUCT','Delete a Savings Product','Delete a Savings Product','SAVINGSPRODUCT','DELETE'),(194,'organisation','CREATE_DEPOSITPRODUCT','Create a Deposit Product','Create a Deposit Product','DEPOSITPRODUCT','CREATE'),(195,'organisation','READ_DEPOSITPRODUCT','Read Deposit Products','Read Deposit Products','DEPOSITPRODUCT','READ'),(196,'organisation','UPDATE_DEPOSITPRODUCT','Update a Deposit Product','Update a Deposit Product','DEPOSITPRODUCT','UPDATE'),(197,'organisation','DELETE_DEPOSITPRODUCT','Delete a Deposit Product','Delete a Deposit Product','DEPOSITPRODUCT','DELETE'),(198,'portfolio','CREATE_DEPOSITACCOUNT','Create a Deposit Account','Create a Deposit Account','DEPOSITACCOUNT','CREATE'),(199,'portfolio','READ_DEPOSITACCOUNT','Read Deposit Accounts','Read Deposit Accounts','DEPOSITACCOUNT','READ'),(200,'portfolio','UPDATE_DEPOSITACCOUNT','Update a Deposit Account','Update a Deposit Account','DEPOSITACCOUNT','UPDATE'), +(201,'portfolio','DELETE_DEPOSITACCOUNT','Delete a Deposit Account','Delete a Deposit Account','DEPOSITACCOUNT','DELETE'),(202,'transaction_deposit','APPROVE_DEPOSITACCOUNT','Approve a Deposit Account','Approve a Deposit Account','DEPOSITACCOUNT','APPROVE'),(203,'transaction_deposit','REJECT_DEPOSITACCOUNT','Reject Deposit Account','Reject Deposit Account','DEPOSITACCOUNT','REJECT'),(204,'transaction_deposit','WITHDRAW_DEPOSITACCOUNT','Withdraw Deposit Account','Withdraw Deposit Account','DEPOSITACCOUNT','WITHDRAW'),(205,'transaction_deposit','APPROVALUNDO_DEPOSITACCOUNT','Undo Approval of Deposit Account','Undo Approval of Deposit Account','DEPOSITACCOUNT','APPROVALUNDO'),(206,'transaction_deposit','WITHDRAWAL_DEPOSITACCOUNT','Make a Withdrawal From Deposit Account','Make a Withdrawal From Deposit Account','DEPOSITACCOUNT','WITHDRAWAL'),(207,'transaction_deposit','INTEREST_DEPOSITACCOUNT','Apply Interest to Deposit Accounts','Apply Interest to Deposit Accounts','DEPOSITACCOUNT','INTEREST'),(208,'transaction_deposit','RENEW_DEPOSITACCOUNT','Renew Deposit Account','Renew Deposit Account','DEPOSITACCOUNT','RENEW'),(209,'portfolio','CREATE_SAVINGSACCOUNT','Create a Savings Account','Create a Savings Account','SAVINGSACCOUNT','CREATE'),(210,'portfolio','READ_SAVINGSACCOUNT','Read Savings Accounts','Read Savings Accounts','SAVINGSACCOUNT','READ'),(211,'portfolio','UPDATE_SAVINGSACCOUNT','Update a Savings Account','Update a Savings Account','SAVINGSACCOUNT','UPDATE'),(212,'portfolio','DELETE_SAVINGSACCOUNT','Delete a Savings Account','Delete a Savings Account','SAVINGSACCOUNT','DELETE'); INSERT INTO `m_role` (`id`, `name`, `description`, `createdby_id`, `created_date`, `lastmodified_date`, `lastmodifiedby_id`) VALUES -(1,'Super user','This role provides all application permissions.',NULL,NULL,NULL,NULL), -(2,'Read Only user','This role provides read only application permissions.',NULL,NULL,NULL,NULL); +(1,'Super user','This role provides all application permissions.',NULL,NULL,NULL,NULL); +/* role 1 is super user, give it ALL_FUNCTIONS */ +INSERT INTO m_role_permission(role_id, permission_id) +select 1, id +from m_permission +where code = 'ALL_FUNCTIONS'; -INSERT INTO `m_role_permission` (`role_id`, `permission_id`) -VALUES -(1,42), (2,43); +/* add a read permission for each defined report */ +insert into m_permission(grouping, `code`, default_description, default_name, entity_name, action_name) +select 'report', concat('READ_', sr.report_name), concat('READ_', sr.report_name), concat('READ_', sr.report_name), sr.report_name, 'READ' +from stretchy_report sr; + +/* add a create, read, update and delete permission for each registered datatable */ +insert into m_permission(grouping, `code`, default_description, default_name, entity_name, action_name) +select 'datatable', concat('CREATE_', r.registered_table_name), concat('CREATE_', r.registered_table_name), concat('CREATE_', r.registered_table_name), r.registered_table_name, 'CREATE' +from x_registered_table r; + +insert into m_permission(grouping, `code`, default_description, default_name, entity_name, action_name) +select 'datatable', concat('READ_', r.registered_table_name), concat('READ_', r.registered_table_name), concat('READ_', r.registered_table_name), r.registered_table_name, 'READ' +from x_registered_table r; + +insert into m_permission(grouping, `code`, default_description, default_name, entity_name, action_name) +select 'datatable', concat('UPDATE_', r.registered_table_name), concat('UPDATE_', r.registered_table_name), concat('UPDATE_', r.registered_table_name), r.registered_table_name, 'UPDATE' +from x_registered_table r; + +insert into m_permission(grouping, `code`, default_description, default_name, entity_name, action_name) +select 'datatable', concat('DELETE_', r.registered_table_name), concat('DELETE_', r.registered_table_name), concat('DELETE_', r.registered_table_name), r.registered_table_name, 'DELETE' +from x_registered_table r; INSERT INTO `m_appuser` (`id`, `office_id`, `username`, `firstname`, `lastname`, `password`, `email`, `firsttime_login_remaining`, `nonexpired`, `nonlocked`, `nonexpired_credentials`, `enabled`, @@ -328,7 +219,6 @@ VALUES INSERT INTO `m_appuser_role` (`appuser_id`, `role_id`) VALUES (1,1); - INSERT INTO `stretchy_parameter` VALUES (3,'FullReportList',NULL,'n/a','n/a','n/a','n/a','Y',NULL,NULL,'select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category,\r\nrp.parameter_id, rp.report_parameter_name, p.parameter_name\r\nfrom stretchy_report r\r\nleft join stretchy_report_parameter rp diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index ef58c9227..04c6774b4 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -16,6 +16,14 @@ apply plugin: 'eclipse' apply plugin: 'tomcat' apply plugin: 'project-report' +/* define the valid syntax level for source files */ +sourceCompatibility = JavaVersion.VERSION_1_6 +/* define binary compatiblity version */ +targetCompatibility = JavaVersion.VERSION_1_6 + +// targetCompatibility = 1.6 +// sourceCompatibility = 1.6 + project.ext.springVersion = '3.1.1.RELEASE' project.ext.springSecurityVersion = '3.1.0.RELEASE' project.ext.hibernateValidatorVersion = '4.3.0.Final' diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java index 424213312..e7688f382 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java @@ -24,7 +24,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.NoteCommand; import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData; import org.mifosng.platform.api.data.ClientData; @@ -159,7 +158,7 @@ public class ClientsApiResource { @Path("{clientId}") @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) - public String retrieveClientData( + public String retrieveClient( @PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) { @@ -176,15 +175,46 @@ public class ClientsApiResource { clientData = ClientData.templateOnTop(clientData, allowedOffices); } if (makerCheckerId != null) { - final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId); - final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json(), false); - - clientData = ClientData.integrateChanges(clientData, command); + clientData = handleMakerCheckerRequest(clientId, makerCheckerId, clientData); + } + + boolean retrieveChanges = true; + if (retrieveChanges) { + final Collection dataChanges = retrieveAllUnprocessedDataChanges(clientId); + clientData = ClientData.integrateChanges(clientData, clientData.currentChange(), dataChanges); } return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); } + private ClientData handleMakerCheckerRequest(final Long clientId, final Long makerCheckerId, ClientData clientData) { + final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId); + final ClientData currentChange = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(clientId, entry.json()); + + final Collection dataChanges = retrieveAllUnprocessedDataChanges(clientId); + clientData = ClientData.integrateChanges(clientData, currentChange, dataChanges); + return clientData; + } + + private Collection retrieveAllUnprocessedDataChanges(final Long clientId) { + Collection dataChanges = new ArrayList(); + + boolean retrieveChanges = true; + if (retrieveChanges) { + Collection unprocessedChanges = this.commandSourceReadPlatformService.retrieveUnprocessChangesByResourceId("clients", clientId); + for (CommandSourceData commandSourceData : unprocessedChanges) { + ClientData change = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(clientId, commandSourceData.json()); + dataChanges.add(change); + } + } + + if (dataChanges.isEmpty()) { + dataChanges = null; + } + + return dataChanges; + } + @GET @Path("template") @Consumes({MediaType.APPLICATION_JSON}) @@ -199,10 +229,7 @@ public class ClientsApiResource { ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails(); if (makerCheckerId != null) { - final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId); - final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json(), false); - - clientData = ClientData.integrateChanges(clientData, command); + clientData = handleMakerCheckerRequest(null, makerCheckerId, clientData); } return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ClientCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ClientCommand.java index 625e0df0a..a846f459a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ClientCommand.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ClientCommand.java @@ -9,7 +9,6 @@ import org.joda.time.LocalDate; */ public class ClientCommand { - private final Long id; private final String externalId; private final String firstname; private final String lastname; @@ -18,6 +17,7 @@ public class ClientCommand { private final LocalDate joiningDate; // made transient as dont want them to be serialized/converted to JSON + private final transient Long id; private final transient boolean makerCheckerApproval; private final transient Set parametersPassedInRequest; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java index 9686c8ef8..8fa739717 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java @@ -1,10 +1,10 @@ package org.mifosng.platform.api.data; +import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.ClientCommand; /** * Immutable data object representing client data. @@ -22,13 +22,13 @@ final public class ClientData { private final LocalDate joinedDate; private final String imageKey; @SuppressWarnings("unused") - private final boolean imagePresent; + private final Boolean imagePresent; private final List allowedOffices; - @SuppressWarnings("unused") - private final ClientCommand changes; - + private final ClientData currentChange; + private final Collection allChanges; + private static String buildDisplayNameFrom(final String firstname, final String lastname) { String displayName = null; StringBuilder displayNameBuilder = new StringBuilder(); @@ -43,7 +43,27 @@ final public class ClientData { return displayName; } - public static ClientData integrateChanges(final ClientData clientData, final ClientCommand command) { + public static ClientData dataChangeInstance( + final Long id, + final Long officeId, + final String externalId, + final String firstname, + final String lastname, + final String clientOrBusinessName, + final LocalDate joiningDate) { + + String firstnameValue = firstname; + String lastnameValue = lastname; + if (StringUtils.isNotBlank(clientOrBusinessName)) { + firstnameValue = null; + lastnameValue = clientOrBusinessName; + } + final String displayName = buildDisplayNameFrom(firstnameValue, lastnameValue); + + return new ClientData(officeId, null, id, firstname, lastname, displayName, externalId, joiningDate, null, null, null, null); + } + + public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection allChanges) { String firstname = clientData.firstname; String lastname = clientData.lastname; if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { @@ -52,11 +72,11 @@ final public class ClientData { } final String displayName = buildDisplayNameFrom(firstname, lastname); return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, - clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, command); + clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges); } public static ClientData template(final Long officeId, final LocalDate joinedDate, final List allowedOffices) { - return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null); + return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null); } public static ClientData templateOnTop(final ClientData clientData, final List allowedOffices) { @@ -69,7 +89,7 @@ final public class ClientData { } final String displayName = buildDisplayNameFrom(firstname, lastname); return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, - clientData.externalId, clientData.joinedDate, clientData.imageKey, allowedOffices, null); + clientData.externalId, clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange, clientData.allChanges); } public static ClientData clientIdentifier( @@ -81,7 +101,7 @@ final public class ClientData { final String displayName = buildDisplayNameFrom(firstname, lastname); - return new ClientData(officeId, officeName, id, firstname, lastname, displayName, null, null, null, null, null); + return new ClientData(officeId, officeName, id, firstname, lastname, displayName, null, null, null, null, null, null); } public ClientData( @@ -95,7 +115,8 @@ final public class ClientData { final LocalDate joinedDate, final String imageKey, final List allowedOffices, - final ClientCommand changes) { + final ClientData currentChange, + final Collection allChanges) { this.officeId = officeId; this.officeName = officeName; this.id = id; @@ -113,9 +134,14 @@ final public class ClientData { this.externalId = externalId; this.joinedDate = joinedDate; this.imageKey = imageKey; - this.imagePresent = (imageKey != null); + if (imageKey != null) { + this.imagePresent = Boolean.TRUE; + } else { + this.imagePresent = null; + } this.allowedOffices = allowedOffices; - this.changes = changes; + this.currentChange = currentChange; + this.allChanges = allChanges; } public String displayName() { @@ -145,4 +171,8 @@ final public class ClientData { public Long officeId() { return this.officeId; } + + public ClientData currentChange() { + return this.currentChange; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java index 7e4adc234..43904a1a2 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java @@ -7,6 +7,7 @@ import java.util.Set; import org.mifosng.platform.accounting.api.data.ChartOfAccountsData; import org.mifosng.platform.api.LoanScheduleData; +import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.data.AdditionalFieldsSetData; import org.mifosng.platform.api.data.AppUserData; import org.mifosng.platform.api.data.AuthenticatedUserData; @@ -497,14 +498,15 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi } @Override - public String serializeClientDataToJson(final boolean prettyPrint, - final Set responseParameters, - final Collection clients) { + public String serializeClientCommandToJson(final ClientCommand command) { final Gson gsonDeserializer = helper - .createGsonBuilderWithParameterExclusionSerializationStrategy( - CLIENT_DATA_PARAMETERS, prettyPrint, responseParameters); - return helper.serializedJsonFrom(gsonDeserializer, - clients.toArray(new ClientData[clients.size()])); + .createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeClientDataToJson(final ClientData client) { + return serializeClientDataToJson(false, new HashSet(), client); } @Override @@ -515,6 +517,17 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi CLIENT_DATA_PARAMETERS, prettyPrint, responseParameters); return helper.serializedJsonFrom(gsonDeserializer, client); } + + @Override + public String serializeClientDataToJson(final boolean prettyPrint, + final Set responseParameters, + final Collection clients) { + final Gson gsonDeserializer = helper + .createGsonBuilderWithParameterExclusionSerializationStrategy( + CLIENT_DATA_PARAMETERS, prettyPrint, responseParameters); + return helper.serializedJsonFrom(gsonDeserializer, + clients.toArray(new ClientData[clients.size()])); + } @Override public String serializeClientAccountSummaryCollectionDataToJson( diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java index c43dc6e80..283d31e18 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java @@ -28,6 +28,7 @@ import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosng.platform.api.commands.StaffCommand; import org.mifosng.platform.api.commands.UserCommand; +import org.mifosng.platform.api.data.ClientData; public interface PortfolioApiDataConversionService { @@ -49,7 +50,13 @@ public interface PortfolioApiDataConversionService { DepositProductCommand convertJsonToDepositProductCommand(Long resourceIdentifier, String json); - ClientCommand convertJsonToClientCommand(Long resourceIdentifier, String json, boolean makerCheckerApproval); + ClientCommand convertApiRequestJsonToClientCommand(Long resourceIdentifier, String json); + + ClientCommand convertInternalJsonFormatToClientCommand(Long resourceIdentifier, String json, boolean checkerApproved); + + ClientData convertInternalJsonFormatToClientDataChange(Long clientId, String json); + + ClientCommand detectChanges(Long resourceId, String baseJson, String workingJson); GroupCommand convertJsonToGroupCommand(Long resourceIdentifier, String json); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java index fb9b9062d..3453970df 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java @@ -19,7 +19,6 @@ import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientIdentifierCommand; @@ -35,6 +34,7 @@ import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.LoanProductCommand; +import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.NoteCommand; @@ -46,6 +46,7 @@ import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosng.platform.api.commands.StaffCommand; import org.mifosng.platform.api.commands.UserCommand; import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.infrastructure.api.JsonParserHelper; import org.mifosng.platform.infrastructure.errorhandling.InvalidJsonException; @@ -376,7 +377,96 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public ClientCommand convertJsonToClientCommand(final Long resourceIdentifier, final String json, final boolean makerCheckerApproval) { + public ClientCommand detectChanges(final Long resourceIdentifier, final String baseJson, final String workingJson) { + + final Type typeOfMap = new TypeToken>(){}.getType(); + final Map workingVersion = gsonConverter.fromJson(workingJson, typeOfMap); + + final Set workingParameters = workingVersion.keySet(); + + final JsonParser parser = new JsonParser(); + final JsonElement baseElement = parser.parse(baseJson); + final JsonElement workingElement = parser.parse(workingJson); + + final JsonParserHelper helper = new JsonParserHelper(); + final Set ignoreParameters = new HashSet(); + final Set parametersPassedInRequest = new HashSet(); + + Long officeId = null; + String externalId = null; + String firstname = null; + String lastname = null; + String clientOrBusinessName = null; + LocalDate joiningDate = null; + + for (final String parameter : workingParameters) { + + final String officeIdParameterName = "officeId"; + if (officeIdParameterName.equalsIgnoreCase(parameter)) { + final Long baseOfficeId = helper.extractLongNamed(officeIdParameterName, baseElement, ignoreParameters); + final Long workingOfficeId = helper.extractLongNamed(officeIdParameterName, workingElement, ignoreParameters); + if (!workingOfficeId.equals(baseOfficeId)) { + officeId = workingOfficeId; + parametersPassedInRequest.add(officeIdParameterName); + } + } + + final String externalIdParamName = "externalId"; + if (externalIdParamName.equalsIgnoreCase(parameter)) { + final String baseExternalId = helper.extractStringNamed(externalIdParamName, baseElement, ignoreParameters); + final String workingExternalId = helper.extractStringNamed(externalIdParamName, workingElement, ignoreParameters); + if (!baseExternalId.equals(workingExternalId)) { + externalId = workingExternalId; + parametersPassedInRequest.add(externalIdParamName); + } + } + + final String firstnameParamName = "firstname"; + if (firstnameParamName.equalsIgnoreCase(parameter)) { + final String baseValue = helper.extractStringNamed(firstnameParamName, baseElement, ignoreParameters); + final String workingCopyValue = helper.extractStringNamed(firstnameParamName, workingElement, ignoreParameters); + if (!baseValue.equals(workingCopyValue)) { + firstname = workingCopyValue; + parametersPassedInRequest.add(firstnameParamName); + } + } + + final String lastnameParamName = "lastname"; + if (lastnameParamName.equalsIgnoreCase(parameter)) { + final String baseValue = helper.extractStringNamed(lastnameParamName, baseElement, ignoreParameters); + final String workingCopyValue = helper.extractStringNamed(lastnameParamName, workingElement, ignoreParameters); + if (!baseValue.equals(workingCopyValue)) { + lastname = workingCopyValue; + parametersPassedInRequest.add(lastnameParamName); + } + } + + final String clientOrBusinessNameParamName = "clientOrBusinessName"; + if (clientOrBusinessNameParamName.equalsIgnoreCase(parameter)) { + final String baseValue = helper.extractStringNamed(clientOrBusinessNameParamName, baseElement, ignoreParameters); + final String workingCopyValue = helper.extractStringNamed(clientOrBusinessNameParamName, workingElement, ignoreParameters); + if (!baseValue.equals(workingCopyValue)) { + clientOrBusinessName = workingCopyValue; + parametersPassedInRequest.add(clientOrBusinessNameParamName); + } + } + + final String joinedDateParamName = "joinedDate"; + if (joinedDateParamName.equalsIgnoreCase(parameter)) { + final LocalDate baseValue = helper.extractLocalDateAsArrayNamed(joinedDateParamName, baseElement, ignoreParameters); + final LocalDate workingCopyValue = helper.extractLocalDateAsArrayNamed(joinedDateParamName, workingElement, ignoreParameters); + if (!baseValue.isEqual(workingCopyValue)) { + joiningDate = workingCopyValue; + parametersPassedInRequest.add(joinedDateParamName); + } + } + } + + return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate, false); + } + + @Override + public ClientCommand convertApiRequestJsonToClientCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -385,7 +475,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo final Map requestMap = gsonConverter.fromJson(json, typeOfMap); final Set supportedParams = new HashSet( - Arrays.asList("externalId", "firstname", "lastname", "clientOrBusinessName", "officeId", "joiningDate", "locale", "dateFormat") + Arrays.asList("id", "externalId", "firstname", "lastname", "clientOrBusinessName", "officeId", "joiningDate", "locale", "dateFormat") ); checkForUnsupportedParameters(requestMap, supportedParams); @@ -402,7 +492,46 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo final String clientOrBusinessName = helper.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest); final LocalDate joiningDate = helper.extractLocalDateNamed("joiningDate", element, parametersPassedInRequest); - return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate, makerCheckerApproval); + return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate, false); + } + + @Override + public ClientCommand convertInternalJsonFormatToClientCommand(final Long resourceIdentifier, final String json, final boolean checkerApproved) { + if (StringUtils.isBlank(json)) { + throw new InvalidJsonException(); + } + + final Type typeOfMap = new TypeToken>(){}.getType(); + final Map requestMap = gsonConverter.fromJson(json, typeOfMap); + + final Set supportedParams = new HashSet( + Arrays.asList("id", "externalId", "firstname", "lastname", "clientOrBusinessName", "officeId", "joiningDate") + ); + + checkForUnsupportedParameters(requestMap, supportedParams); + + final JsonParser parser = new JsonParser(); + final JsonElement element = parser.parse(json); + final JsonParserHelper helper = new JsonParserHelper(); + final Set parametersPassedInRequest = new HashSet(); + + final Long officeId = helper.extractLongNamed("officeId", element, parametersPassedInRequest); + final String externalId = helper.extractStringNamed("externalId", element, parametersPassedInRequest); + final String firstname = helper.extractStringNamed("firstname", element, parametersPassedInRequest); + final String lastname = helper.extractStringNamed("lastname", element, parametersPassedInRequest); + final String clientOrBusinessName = helper.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest); + final LocalDate joiningDate = helper.extractLocalDateAsArrayNamed("joiningDate", element, parametersPassedInRequest); + + return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate, checkerApproved); + } + + @Override + public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) { + + final ClientCommand command = convertInternalJsonFormatToClientCommand(resourceIdentifier, json, false); + + return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), + command.getFirstname(), command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate()); } @Override diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java index 6877f5851..b36e48eae 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java @@ -5,6 +5,7 @@ import java.util.Set; import org.mifosng.platform.accounting.api.data.ChartOfAccountsData; import org.mifosng.platform.api.LoanScheduleData; +import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.data.AdditionalFieldsSetData; import org.mifosng.platform.api.data.AppUserData; import org.mifosng.platform.api.data.AuthenticatedUserData; @@ -91,10 +92,14 @@ public interface PortfolioApiJsonSerializerService { String serializeDepositAccountDataToJson(boolean prettyPrint, Set responseParameters, DepositAccountData account); - String serializeClientDataToJson(boolean prettyPrint, Set responseParameters, Collection clients); - + String serializeClientCommandToJson(ClientCommand command); + + String serializeClientDataToJson(ClientData clientData); + String serializeClientDataToJson(boolean prettyPrint, Set responseParameters, ClientData clientData); - + + String serializeClientDataToJson(boolean prettyPrint, Set responseParameters, Collection clients); + String serializeClientAccountSummaryCollectionDataToJson(boolean prettyPrint, Set responseParameters, ClientAccountSummaryCollectionData clientAccount); String serializeGroupAccountSummaryCollectionDataToJson(boolean prettyPrint, Set responseParameters, GroupAccountSummaryCollectionData groupAccount); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java index 6c8a6b0be..c7bd6b21b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java @@ -157,7 +157,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String officeName = rs.getString("officeName"); return new ClientData(officeId, officeName, id, firstname, - lastname, displayName, externalId, joinedDate,imageKey, null, null); + lastname, displayName, externalId, joinedDate,imageKey, null, null, null); } } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java index 6c4b76947..276769923 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java @@ -18,6 +18,7 @@ import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.springframework.format.number.NumberFormatter; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; @@ -176,6 +177,32 @@ public class JsonParserHelper { } return clientApplicationLocale; } + + /** + * Used with the local date is in array format + */ + public LocalDate extractLocalDateAsArrayNamed(final String parameterName, final JsonElement element, final Set parametersPassedInCommand) { + LocalDate value = null; + if (element.isJsonObject()) { + JsonObject object = element.getAsJsonObject(); + + if (object.has(parameterName) && object.get(parameterName).isJsonArray()) { + + parametersPassedInCommand.add(parameterName); + + + final JsonArray dateArray = object.get(parameterName).getAsJsonArray(); + + Integer year = dateArray.get(0).getAsInt(); + Integer month = dateArray.get(1).getAsInt(); + Integer day = dateArray.get(2).getAsInt(); + + value = new LocalDate().withYearOfEra(year).withMonthOfYear(month).withDayOfMonth(day); + } + + } + return value; + } public LocalDate extractLocalDateNamed( final String parameterName, diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java index f63e13366..15ddc902b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java @@ -56,10 +56,9 @@ public class CommandSource extends AbstractPersistable { final String apiOperation, final String resource, final Long resourceId, - final String jsonRequestBody, final AppUser maker, final LocalDate madeOnDate) { - return new CommandSource(apiOperation, resource, resourceId, jsonRequestBody, maker, madeOnDate); + return new CommandSource(apiOperation, resource, resourceId, maker, madeOnDate); } protected CommandSource() { @@ -70,13 +69,11 @@ public class CommandSource extends AbstractPersistable { final String apiOperation, final String resource, final Long resourceId, - final String jsonRequestBody, final AppUser maker, final LocalDate madeOnDate) { this.apiOperation = StringUtils.defaultIfEmpty(apiOperation, null); this.resource = StringUtils.defaultIfEmpty(resource, null); this.resourceId = resourceId; - this.commandAsJson = StringUtils.defaultIfEmpty(jsonRequestBody, null); this.maker = maker; this.madeOnDate = madeOnDate.toDate(); } @@ -90,6 +87,10 @@ public class CommandSource extends AbstractPersistable { this.resourceId = resourceId; } + public void updateJsonTo(final String json) { + this.commandAsJson = json; + } + public Long resourceId() { return this.resourceId; } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java index 51b81ad48..691a9d8a9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java @@ -2,8 +2,11 @@ package org.mifosng.platform.makerchecker.service; import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.ClientCommand; +import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.ClientWritePlatformService; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosng.platform.makerchecker.domain.CommandSource; @@ -14,71 +17,91 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -/** - * - */ @Service public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandSourceWritePlatformService { private final PlatformSecurityContext context; private final CommandSourceRepository commandSourceRepository; private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; private final ClientWritePlatformService clientWritePlatformService; + private final ClientReadPlatformService clientReadPlatformService; @Autowired public PortfolioCommandSourceWriteServiceImpl(final PlatformSecurityContext context, final CommandSourceRepository makerCheckerRepository, final PortfolioApiDataConversionService apiDataConversionService, - final ClientWritePlatformService clientWritePlatformService) { + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final ClientWritePlatformService clientWritePlatformService, + final ClientReadPlatformService clientReadPlatformService) { this.context = context; this.commandSourceRepository = makerCheckerRepository; this.apiDataConversionService = apiDataConversionService; + this.apiJsonSerializerService = apiJsonSerializerService; this.clientWritePlatformService = clientWritePlatformService; + this.clientReadPlatformService = clientReadPlatformService; } // NOT TRANSACTIONAL BY DESIGN FOR NOW @Override - public EntityIdentifier logCommandSource(final String taskOperation, final String taskEntity, final Long entityId, final String taskJson) { + public EntityIdentifier logCommandSource(final String apiOperation, final String resource, final Long resourceId, final String jsonRequestBody) { final AppUser maker = context.authenticatedUser(); final LocalDate asToday = new LocalDate(); - final CommandSource entity = CommandSource.createdBy(taskOperation, taskEntity, entityId, taskJson, maker, asToday); + final CommandSource commandSource = CommandSource.createdBy(apiOperation, resource, resourceId, maker, asToday); - final boolean makerCheckerApproval = false; - Long resourceId = null; - if (entity.isClientResource()) { - final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(entityId, entity.json(), makerCheckerApproval); - if (entity.isCreate()) { + Long newResourceId = null; + if (commandSource.isClientResource()) { + + // translate incoming api request json into java object catering for local and dateFormat parts of api + final ClientCommand command = this.apiDataConversionService.convertApiRequestJsonToClientCommand(resourceId, jsonRequestBody); + // produce serialized json of internal java object representation for persistence. + final String internalCommandSerializedAsJson = this.apiJsonSerializerService.serializeClientCommandToJson(command); + commandSource.updateJsonTo(internalCommandSerializedAsJson); + + if (commandSource.isCreate()) { try { - resourceId = this.clientWritePlatformService.createClient(command); - entity.markAsChecked(maker, asToday); - entity.updateResourceId(resourceId); + newResourceId = this.clientWritePlatformService.createClient(command); + commandSource.markAsChecked(maker, asToday); + commandSource.updateResourceId(newResourceId); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { // swallow this rollback transaction by design } - } else if (entity.isUpdate()) { + } else if (commandSource.isUpdate()) { try { - EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(command); - resourceId = result.getEntityId(); - entity.markAsChecked(maker, asToday); + // useful to employ change detection on update scenario to only store what details have changed + final ClientData originalClient = this.clientReadPlatformService.retrieveIndividualClient(resourceId); + final ClientData changedClient = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(resourceId, internalCommandSerializedAsJson); + + final String baseJson = this.apiJsonSerializerService.serializeClientDataToJson(originalClient); + final String workingJson = this.apiJsonSerializerService.serializeClientDataToJson(changedClient); + final ClientCommand changesOnly = this.apiDataConversionService.detectChanges(resourceId, baseJson, workingJson); + + final String changesOnlyJson = this.apiJsonSerializerService.serializeClientCommandToJson(changesOnly); + commandSource.updateJsonTo(changesOnlyJson); + + EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(changesOnly); + newResourceId = result.getEntityId(); + + commandSource.markAsChecked(maker, asToday); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { // swallow this rollback transaction by design } - } else if (entity.isDelete()) { + } else if (commandSource.isDelete()) { try { EntityIdentifier result = this.clientWritePlatformService.deleteClient(command); - resourceId = result.getEntityId(); - entity.markAsChecked(maker, asToday); + newResourceId = result.getEntityId(); + commandSource.markAsChecked(maker, asToday); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { // swallow this rollback transaction by design } } } - commandSourceRepository.save(entity); + commandSourceRepository.save(commandSource); - return EntityIdentifier.makerChecker(resourceId, entity.getId()); + return EntityIdentifier.makerChecker(newResourceId, commandSource.getId()); } @Transactional @@ -92,7 +115,7 @@ public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandS Long resourceId = null; if (entity.isClientResource()) { - final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(entity.resourceId(), entity.json(), true); + final ClientCommand command = this.apiDataConversionService.convertInternalJsonFormatToClientCommand(entity.resourceId(), entity.json(), true); if (entity.isCreate()) { resourceId = this.clientWritePlatformService.createClient(command); } else if (entity.isUpdate()) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java index 0abd04a4f..ee4f78cd3 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java @@ -10,4 +10,6 @@ public interface PortfolioCommandsReadPlatformService { CommandSourceData retrieveById(Long id); + Collection retrieveUnprocessChangesByResourceId(String apiResource, Long clientId); + } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java index 4dab588e7..f14e69700 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java @@ -69,4 +69,13 @@ public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioComman return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {id}); } + + @Override + public Collection retrieveUnprocessChangesByResourceId(final String apiResource, final Long resourceId) { + + final CommandSourceMapper rm = new CommandSourceMapper(); + final String sql = "select " + rm.schema() + " where mc.api_resource like ? and mc.resource_id = ? and mc.checker_id is null order by mc.made_on_date DESC, mc.api_operation ASC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {apiResource, resourceId}); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java index 80e1d20c8..b47f10c5e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java @@ -12,6 +12,6 @@ public interface CodeWritePlatformService { @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_CODE)") Long updateCode(final CodeCommand command); - @PreAuthorize(value = "hasAnyRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')") + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE', 'DELETE_CODE')") EntityIdentifier deleteCode(Long codeId); } \ No newline at end of file