Merge pull request #861 from ashok-conflux/CONFLUX-39-1

Advanced deposit products and accounts (FD & RD) with interest rate slabs
This commit is contained in:
Vishwas Babu A J
2014-04-15 18:58:00 -07:00
170 changed files with 20697 additions and 380 deletions
@@ -0,0 +1,237 @@
CREATE TABLE IF NOT EXISTS `m_interest_rate_chart` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`description` varchar(200) DEFAULT NULL,
`from_date` date NOT NULL,
`end_date` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_interest_rate_slab` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`interest_rate_chart_id` bigint(20) NOT NULL,
`description` varchar(200) DEFAULT NULL,
`period_type_enum` smallint(5) NOT NULL DEFAULT '1',
`from_period` int(11) NOT NULL DEFAULT '0',
`to_period` int(11) DEFAULT NULL,
`amount_range_from` decimal(19,6) DEFAULT NULL,
`amount_range_to` decimal(19,6) DEFAULT NULL,
`annual_interest_rate` decimal(19,6) NOT NULL,
`currency_code` varchar(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKIRS00000000000001` (`interest_rate_chart_id`),
CONSTRAINT `FKIRS00000000000001` FOREIGN KEY (`interest_rate_chart_id`) REFERENCES `m_interest_rate_chart` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_deposit_product_interest_rate_chart` (
`deposit_product_id` bigint(20) NOT NULL,
`interest_rate_chart_id` bigint(20) NOT NULL,
UNIQUE KEY `deposit_product_id_interest_rate_chart_id` (`deposit_product_id`,`interest_rate_chart_id`),
KEY `FKDPIRC00000000000002` (`interest_rate_chart_id`),
CONSTRAINT `FKDPIRC00000000000001` FOREIGN KEY (`deposit_product_id`) REFERENCES `m_savings_product` (`id`),
CONSTRAINT `FKDPIRC00000000000002` FOREIGN KEY (`interest_rate_chart_id`) REFERENCES `m_interest_rate_chart` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_deposit_product_term_and_preclosure` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_product_id` bigint(20) NOT NULL DEFAULT '0',
`min_deposit_term` int(11) DEFAULT NULL,
`max_deposit_term` int(11) DEFAULT NULL,
`min_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`max_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`in_multiples_of_deposit_term` int(11) DEFAULT NULL,
`in_multiples_of_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`interest_free_period_applicable` smallint(5) DEFAULT NULL,
`interest_free_from_period` int(11) DEFAULT NULL,
`interest_free_to_period` int(11) DEFAULT NULL,
`interest_free_period_frequency_enum` smallint(5) DEFAULT NULL,
`pre_closure_penal_applicable` smallint(5) DEFAULT NULL,
`pre_closure_penal_interest` decimal(19,6) DEFAULT NULL,
`pre_closure_penal_interest_on_enum` smallint(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKDPTP00000000000001` (`savings_product_id`),
CONSTRAINT `FKDPTP00000000000001` FOREIGN KEY (`savings_product_id`) REFERENCES `m_savings_product` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_deposit_product_recurring_detail` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_product_id` bigint(20) NOT NULL DEFAULT '0',
`recurring_deposit_type_enum` smallint(5) DEFAULT NULL,
`recurring_deposit_frequency` int(11) DEFAULT NULL,
`recurring_deposit_frequency_type_enum` smallint(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKDPRD00000000000001` (`savings_product_id`),
CONSTRAINT `FKDPRD00000000000001` FOREIGN KEY (`savings_product_id`) REFERENCES `m_savings_product` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_savings_account_interest_rate_chart` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_account_id` bigint(20) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`description` varchar(200) DEFAULT NULL,
`from_date` date NOT NULL,
`end_date` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKSAIRC00000000000001` (`savings_account_id`),
CONSTRAINT `FKSAIRC00000000000001` FOREIGN KEY (`savings_account_id`) REFERENCES `m_savings_account` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_savings_account_interest_rate_slab` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_account_interest_rate_chart_id` bigint(20) NOT NULL,
`description` varchar(200) DEFAULT NULL,
`period_type_enum` smallint(5) NOT NULL DEFAULT '1',
`from_period` int(11) NOT NULL DEFAULT '0',
`to_period` int(11) DEFAULT NULL,
`amount_range_from` decimal(19,6) DEFAULT NULL,
`amount_range_to` decimal(19,6) DEFAULT NULL,
`annual_interest_rate` decimal(19,6) NOT NULL,
`currency_code` varchar(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKSAIRS00000000000001` (`savings_account_interest_rate_chart_id`),
CONSTRAINT `FKSAIRS00000000000001` FOREIGN KEY (`savings_account_interest_rate_chart_id`) REFERENCES `m_savings_account_interest_rate_chart` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_deposit_account_recurring_detail` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_account_id` bigint(20) NOT NULL DEFAULT '0',
`recurring_deposit_amount` decimal(19,6) DEFAULT NULL,
`recurring_deposit_type_enum` smallint(5) DEFAULT NULL,
`recurring_deposit_frequency` int(11) DEFAULT NULL,
`recurring_deposit_frequency_type_enum` smallint(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKDARD00000000000001` (`savings_account_id`),
CONSTRAINT `FKDARD00000000000001` FOREIGN KEY (`savings_account_id`) REFERENCES `m_savings_account` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `m_deposit_account_term_and_preclosure` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`savings_account_id` bigint(20) NOT NULL DEFAULT '0',
`min_deposit_term` int(11) DEFAULT NULL,
`max_deposit_term` int(11) DEFAULT NULL,
`min_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`max_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`in_multiples_of_deposit_term` int(11) DEFAULT NULL,
`in_multiples_of_deposit_term_type_enum` smallint(5) DEFAULT NULL,
`interest_free_period_applicable` smallint(5) DEFAULT NULL,
`interest_free_from_period` int(11) DEFAULT NULL,
`interest_free_to_period` int(11) DEFAULT NULL,
`interest_free_period_frequency_enum` smallint(5) DEFAULT NULL,
`pre_closure_penal_applicable` smallint(5) DEFAULT NULL,
`pre_closure_penal_interest` decimal(19,6) DEFAULT NULL,
`pre_closure_penal_interest_on_enum` smallint(5) DEFAULT NULL,
`deposit_period` int(11) DEFAULT NULL,
`deposit_period_frequency_enum` smallint(5) DEFAULT NULL,
`deposit_amount` decimal(19,6) DEFAULT NULL,
`maturity_amount` decimal(19,6) DEFAULT NULL,
`maturity_date` date DEFAULT NULL,
`on_account_closure_enum` smallint(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKDATP00000000000001` (`savings_account_id`),
CONSTRAINT `FKDATP00000000000001` FOREIGN KEY (`savings_account_id`) REFERENCES `m_savings_account` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `m_savings_product`
ADD COLUMN `deposit_type_enum` SMALLINT(5) NOT NULL DEFAULT '100' AFTER `description`;
ALTER TABLE `m_savings_account`
ADD COLUMN `deposit_type_enum` SMALLINT(5) NOT NULL DEFAULT '100' AFTER `account_type_enum`;
ALTER TABLE `m_client`
ADD COLUMN `gender_cv_id` INT(11) NULL DEFAULT NULL AFTER `mobile_no`,
ADD COLUMN `date_of_birth` DATE NULL DEFAULT NULL AFTER `gender_cv_id`;
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_INTERESTRATECHART', 'INTERESTRATECHART', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_INTERESTRATECHART_CHECKER', 'INTERESTRATECHART', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_INTERESTRATECHART', 'INTERESTRATECHART', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_INTERESTRATECHART', 'INTERESTRATECHART', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_INTERESTRATECHART_CHECKER', 'INTERESTRATECHART', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_INTERESTRATECHART_CHECKER', 'INTERESTRATECHART', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_CHARTSLAB', 'CHARTSLAB', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_CHARTSLAB_CHECKER', 'CHARTSLAB', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_CHARTSLAB', 'CHARTSLAB', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_CHARTSLAB', 'CHARTSLAB', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_CHARTSLAB_CHECKER', 'CHARTSLAB', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_CHARTSLAB_CHECKER', 'CHARTSLAB', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_FIXEDDEPOSITPRODUCT', 'FIXEDDEPOSITPRODUCT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_FIXEDDEPOSITPRODUCT_CHECKER', 'FIXEDDEPOSITPRODUCT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_FIXEDDEPOSITPRODUCT', 'FIXEDDEPOSITPRODUCT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_FIXEDDEPOSITPRODUCT', 'FIXEDDEPOSITPRODUCT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_FIXEDDEPOSITPRODUCT_CHECKER', 'FIXEDDEPOSITPRODUCT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_FIXEDDEPOSITPRODUCT_CHECKER', 'FIXEDDEPOSITPRODUCT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_RECURRINGDEPOSITPRODUCT', 'RECURRINGDEPOSITPRODUCT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_RECURRINGDEPOSITPRODUCT_CHECKER', 'RECURRINGDEPOSITPRODUCT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_RECURRINGDEPOSITPRODUCT', 'RECURRINGDEPOSITPRODUCT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_RECURRINGDEPOSITPRODUCT', 'RECURRINGDEPOSITPRODUCT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_RECURRINGDEPOSITPRODUCT_CHECKER', 'RECURRINGDEPOSITPRODUCT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_RECURRINGDEPOSITPRODUCT_CHECKER', 'RECURRINGDEPOSITPRODUCT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'READ_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'READ', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'DEPOSIT_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'DEPOSIT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'DEPOSIT_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'DEPOSIT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAWAL_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'WITHDRAWAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAWAL_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'WITHDRAWAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ACTIVATE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'ACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ACTIVATE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'ACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CALCULATEINTEREST_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'CALCULATEINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CALCULATEINTEREST_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'CALCULATEINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'POSTINTEREST_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'POSTINTEREST', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'POSTINTEREST_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'POSTINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'APPROVE', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'REJECT_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'REJECT', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAW_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'WITHDRAW', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVALUNDO_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'APPROVALUNDO', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CLOSE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'CLOSE', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'APPROVE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'REJECT_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'REJECT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAW_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'WITHDRAW', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVALUNDO_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'APPROVALUNDO', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CLOSE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'CLOSE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'UNDOTRANSACTION_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'UNDOTRANSACTION', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'UNDOTRANSACTION_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'UNDOTRANSACTION', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ADJUSTTRANSACTION_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'ADJUSTTRANSACTION', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'READ_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'READ', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'CREATE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'UPDATE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'portfolio', 'DELETE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'DEPOSIT_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'DEPOSIT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'DEPOSIT_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'DEPOSIT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAWAL_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'WITHDRAWAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAWAL_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'WITHDRAWAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ACTIVATE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'ACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ACTIVATE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'ACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CALCULATEINTEREST_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'CALCULATEINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CALCULATEINTEREST_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'CALCULATEINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'POSTINTEREST_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'POSTINTEREST', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'POSTINTEREST_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'POSTINTEREST', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'APPROVE', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'REJECT_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'REJECT', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAW_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'WITHDRAW', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVALUNDO_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'APPROVALUNDO', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CLOSE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'CLOSE', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'APPROVE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'REJECT_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'REJECT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'WITHDRAW_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'WITHDRAW', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'APPROVALUNDO_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'APPROVALUNDO', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'CLOSE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'CLOSE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'UNDOTRANSACTION_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'UNDOTRANSACTION', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'UNDOTRANSACTION_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'UNDOTRANSACTION', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ( 'transaction_savings', 'ADJUSTTRANSACTION_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'ADJUSTTRANSACTION', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('transaction_savings', 'PREMATURECLOSE_FIXEDDEPOSITACCOUNT_CHECKER', 'FIXEDDEPOSITACCOUNT', 'PREMATURECLOSE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`) VALUES ('transaction_savings', 'PREMATURECLOSE_FIXEDDEPOSITACCOUNT', 'FIXEDDEPOSITACCOUNT', 'PREMATURECLOSE');
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('transaction_savings', 'PREMATURECLOSE_RECURRINGDEPOSITACCOUNT_CHECKER', 'RECURRINGDEPOSITACCOUNT', 'PREMATURECLOSE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`) VALUES ('transaction_savings', 'PREMATURECLOSE_RECURRINGDEPOSITACCOUNT', 'RECURRINGDEPOSITACCOUNT', 'PREMATURECLOSE');
@@ -5,6 +5,8 @@
*/
package org.mifosplatform.commands.domain;
import org.mifosplatform.portfolio.savings.DepositAccountType;
public class CommandWrapper {
private final Long commandId;
@@ -23,6 +25,11 @@ public class CommandWrapper {
private final String json;
private final String transactionId;
private final Long productId;
@SuppressWarnings("unused")
private Long templateId;
private Long interestRatechartId;
private DepositAccountType depositAccountType;
public static CommandWrapper wrap(final String actionName, final String entityName, final Long resourceId, final Long subresourceId) {
return new CommandWrapper(null, actionName, entityName, resourceId, subresourceId, null, null);
@@ -61,7 +68,9 @@ public class CommandWrapper {
public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId,
final String actionName, final String entityName, final Long entityId, final Long subentityId, final String href,
final String json, final String transactionId, final Long productId) {
final String json, final String transactionId, final Long productId, final Long templateId, Long interestRatechartId,
DepositAccountType depositAccountType) {
this.commandId = null;
this.officeId = officeId;
this.groupId = groupId;
@@ -77,6 +86,9 @@ public class CommandWrapper {
this.json = json;
this.transactionId = transactionId;
this.productId = productId;
this.templateId = templateId;
this.interestRatechartId = interestRatechartId;
this.depositAccountType = depositAccountType;
}
private CommandWrapper(final Long commandId, final String actionName, final String entityName, final Long resourceId,
@@ -555,6 +567,14 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("PAY") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNTCHARGE");
}
public boolean isInterestRateChartResource() {
return this.entityName.equalsIgnoreCase("INTERESTRATECHART");
}
public boolean isInterestRateChartSlabResource() {
return this.entityName.equalsIgnoreCase("CHARTSLAB");
}
public boolean isCalendarResource() {
return this.entityName.equalsIgnoreCase("CALENDAR");
}
@@ -692,4 +712,84 @@ public class CommandWrapper {
public boolean isCacheResource() {
return this.entityName.equalsIgnoreCase("CACHE");
}
public Long interestRatechartId() {
return this.interestRatechartId;
}
// Begin - Deposit product
public boolean isFixedDepositProductResource() {
return this.entityName.equalsIgnoreCase("FIXEDDEPOSITPRODUCT");
}
public boolean isRecurringDepositProductResource() {
return this.entityName.equalsIgnoreCase("RECURRINGDEPOSITPRODUCT");
}
// End - Deposit product
// Begin - Deposit accounts
public boolean isDepositAccountResource() {
return this.entityName.equalsIgnoreCase("FIXEDDEPOSITACCOUNT") || this.entityName.equalsIgnoreCase("RECURRINGDEPOSITACCOUNT");
}
public boolean isRejectionOfDepositAccountApplication() {
return this.actionName.equalsIgnoreCase("REJECT") && isDepositAccountResource();
}
public boolean isWithdrawFromDepositAccountApplicationByApplicant() {
return this.actionName.equalsIgnoreCase("WITHDRAW") && isDepositAccountResource();
}
public boolean isApprovalOfDepositAccountApplication() {
return this.actionName.equalsIgnoreCase("APPROVE") && isDepositAccountResource();
}
public boolean isUndoApprovalOfDepositAccountApplication() {
return this.actionName.equalsIgnoreCase("APPROVALUNDO") && isDepositAccountResource();
}
//Account transaction actions
public boolean isDepositAccountDeposit() {
return this.actionName.equalsIgnoreCase("DEPOSIT") && isDepositAccountResource();
}
public boolean isDepositAccountWithdrawal() {
return this.actionName.equalsIgnoreCase("WITHDRAWAL") && isDepositAccountResource();
}
public boolean isDepositAccountActivation() {
return this.actionName.equalsIgnoreCase("ACTIVATE") && isDepositAccountResource();
}
public boolean isDepositAccountInterestCalculation() {
return this.actionName.equalsIgnoreCase("CALCULATEINTEREST") && isDepositAccountResource();
}
public boolean isDepositAccountInterestPosting() {
return this.actionName.equalsIgnoreCase("POSTINTEREST") && isDepositAccountResource();
}
public boolean isDepositAccountUndoTransaction() {
return this.actionName.equalsIgnoreCase("UNDOTRANSACTION") && isDepositAccountResource();
}
public boolean isAdjustDeopsitAccountTransaction() {
return this.actionName.equalsIgnoreCase("ADJUSTTRANSACTION") && isDepositAccountResource();
}
public boolean isDepositAccountClose() {
return this.actionName.equalsIgnoreCase("CLOSE") && isDepositAccountResource();
}
public boolean isDepositAccountPrematureClose() {
return this.actionName.equalsIgnoreCase("PREMATURECLOSE") && isDepositAccountResource();
}
// End - Deposit accounts
public DepositAccountType depositAccountType(){
return this.depositAccountType;
}
}
@@ -6,6 +6,7 @@
package org.mifosplatform.commands.service;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.portfolio.savings.DepositAccountType;
public class CommandWrapperBuilder {
@@ -22,10 +23,14 @@ public class CommandWrapperBuilder {
private String json = "{}";
private String transactionId;
private Long productId;
private Long templateId;
private Long interestRatechartId;
private DepositAccountType depositAccountType;
public CommandWrapper build() {
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName,
this.entityName, this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId);
this.entityName, this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId,
this.templateId, this.interestRatechartId, this.depositAccountType);
}
public CommandWrapperBuilder withLoanId(final Long withLoanId) {
@@ -1086,6 +1091,105 @@ public class CommandWrapperBuilder {
return this;
}
public CommandWrapperBuilder createFixedDepositProduct() {
this.actionName = "CREATE";
this.entityName = "FIXEDDEPOSITPRODUCT";
this.entityId = null;
this.href = "/fixeddepositproducts/template";
return this;
}
public CommandWrapperBuilder updateFixedDepositProduct(final Long productId) {
this.actionName = "UPDATE";
this.entityName = "FIXEDDEPOSITPRODUCT";
this.entityId = productId;
this.href = "/fixeddepositproducts/" + productId;
return this;
}
public CommandWrapperBuilder deleteFixedDepositProduct(final Long productId) {
this.actionName = "DELETE";
this.entityName = "FIXEDDEPOSITPRODUCT";
this.entityId = productId;
this.href = "/fixeddepositproducts/" + productId;
return this;
}
public CommandWrapperBuilder createRecurringDepositProduct() {
this.actionName = "CREATE";
this.entityName = "RECURRINGDEPOSITPRODUCT";
this.entityId = null;
this.href = "/recurringdepositproducts/template";
return this;
}
public CommandWrapperBuilder updateRecurringDepositProduct(final Long productId) {
this.actionName = "UPDATE";
this.entityName = "RECURRINGDEPOSITPRODUCT";
this.entityId = productId;
this.href = "/recurringdepositproducts/" + productId;
return this;
}
public CommandWrapperBuilder deleteRecurringDepositProduct(final Long productId) {
this.actionName = "DELETE";
this.entityName = "RECURRINGDEPOSITPRODUCT";
this.entityId = productId;
this.href = "/recurringdepositproducts/" + productId;
return this;
}
public CommandWrapperBuilder createInterestRateChart() {
this.actionName = "CREATE";
this.entityName = "INTERESTRATECHART";
this.entityId = null;
this.href = "/interestratechart/template";
return this;
}
public CommandWrapperBuilder updateInterestRateChart(final Long interestRateChartId) {
this.actionName = "UPDATE";
this.entityName = "INTERESTRATECHART";
this.entityId = interestRateChartId;
this.href = "/interestratechart/" + interestRateChartId;
return this;
}
public CommandWrapperBuilder deleteInterestRateChart(final Long interestRateChartId) {
this.actionName = "DELETE";
this.entityName = "INTERESTRATECHART";
this.entityId = interestRateChartId;
this.href = "/interestratechart/" + interestRateChartId;
return this;
}
public CommandWrapperBuilder createInterestRateChartSlab(final Long chartId) {
this.actionName = "CREATE";
this.entityName = "CHARTSLAB";
this.entityId = null;
this.interestRatechartId = chartId;
this.href = "/interestratechart/" + chartId + "/chartdetails/template";
return this;
}
public CommandWrapperBuilder updateInterestRateChartSlab(final Long chartId, final Long chartSlabId) {
this.actionName = "UPDATE";
this.entityName = "CHARTSLAB";
this.entityId = chartSlabId;
this.interestRatechartId = chartId;
this.href = "/interestratechart/" + chartId + "/chartdetails/" + chartSlabId;
return this;
}
public CommandWrapperBuilder deleteInterestRateChartSlab(final Long chartId, final Long chartSlabId) {
this.actionName = "DELETE";
this.entityName = "CHARTSLAB";
this.entityId = chartSlabId;
this.interestRatechartId = chartId;
this.href = "/interestratechart/" + chartId + "/chartdetails/" + chartSlabId;
return this;
}
public CommandWrapperBuilder createCalendar(final CommandWrapper resourceDetails, final String supportedEntityType,
final Long supportedEntityId) {
this.actionName = "CREATE";
@@ -1567,4 +1671,306 @@ public class CommandWrapperBuilder {
this.href = "/cache";
return this;
}
/**
* Deposit account mappings
*/
public CommandWrapperBuilder createFixedDepositAccount() {
this.actionName = "CREATE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = null;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/template";
return this;
}
public CommandWrapperBuilder updateFixedDepositAccount(final Long accountId) {
this.actionName = "UPDATE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId;
return this;
}
public CommandWrapperBuilder deleteFixedDepositAccount(final Long accountId) {
this.actionName = "DELETE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId;
return this;
}
public CommandWrapperBuilder rejectFixedDepositAccountApplication(final Long accountId) {
this.actionName = "REJECT";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=reject";
return this;
}
public CommandWrapperBuilder withdrawFixedDepositAccountApplication(final Long accountId) {
this.actionName = "WITHDRAW";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=withdrawnByApplicant";
return this;
}
public CommandWrapperBuilder approveFixedDepositAccountApplication(final Long accountId) {
this.actionName = "APPROVE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=approve";
return this;
}
public CommandWrapperBuilder undoFixedDepositAccountApplication(final Long accountId) {
this.actionName = "APPROVALUNDO";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=undoapproval";
return this;
}
public CommandWrapperBuilder fixedDepositAccountActivation(final Long accountId) {
this.actionName = "ACTIVATE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=activate";
return this;
}
public CommandWrapperBuilder closeFixedDepositAccount(final Long accountId) {
this.actionName = "CLOSE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=close";
return this;
}
public CommandWrapperBuilder prematureCloseFixedDepositAccount(final Long accountId) {
this.actionName = "PREMATURECLOSE";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=prematureClose";
return this;
}
public CommandWrapperBuilder fixedDepositAccountInterestCalculation(final Long accountId) {
this.actionName = "CALCULATEINTEREST";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=calculateInterest";
return this;
}
public CommandWrapperBuilder fixedDepositAccountInterestPosting(final Long accountId) {
this.actionName = "POSTINTEREST";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.href = "/fixeddepositaccounts/" + accountId + "?command=postInterest";
return this;
}
public CommandWrapperBuilder fixedDepositAccountDeposit(final Long accountId) {
this.actionName = "DEPOSIT";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.entityId = accountId;
this.href = "/fixeddepositaccounts/" + accountId + "/transactions?command=deposit";
return this;
}
public CommandWrapperBuilder fixedDepositAccountWithdrawal(final Long accountId) {
this.actionName = "WITHDRAWAL";
this.entityName = "FIXEDDEPOSITACCOUNT";
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.FIXED_DEPOSIT;
this.entityId = accountId;
this.href = "/fixeddepositaccounts/" + accountId + "/transactions?command=withdrawal";
return this;
}
public CommandWrapperBuilder createRecurringDepositAccount() {
this.actionName = "CREATE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = null;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/template";
return this;
}
public CommandWrapperBuilder updateRecurringDepositAccount(final Long accountId) {
this.actionName = "UPDATE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId;
return this;
}
public CommandWrapperBuilder recurringAccountDeposit(final Long accountId) {
this.actionName = "DEPOSIT";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.entityId = accountId;
this.href = "/recurringdepositaccounts/" + accountId + "/transactions?command=deposit";
return this;
}
public CommandWrapperBuilder recurringAccountWithdrawal(final Long accountId) {
this.actionName = "WITHDRAWAL";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.entityId = accountId;
this.href = "/recurringdepositaccounts/" + accountId + "/transactions?command=withdrawal";
return this;
}
public CommandWrapperBuilder adjustRecurringAccountTransaction(final Long accountId, final Long transactionId) {
this.actionName = "ADJUSTTRANSACTION";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.subentityId = transactionId;
this.transactionId = transactionId.toString();
this.href = "/recurringdepositaccounts/" + accountId + "/transactions/" + transactionId + "?command=modify";
return this;
}
public CommandWrapperBuilder undoRecurringAccountTransaction(final Long accountId, final Long transactionId) {
this.actionName = "UNDOTRANSACTION";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.subentityId = transactionId;
this.transactionId = transactionId.toString();
this.href = "/recurringdepositaccounts/" + accountId + "/transactions/" + transactionId + "?command=undo";
return this;
}
public CommandWrapperBuilder deleteRecurringDepositAccount(final Long accountId) {
this.actionName = "DELETE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId;
return this;
}
public CommandWrapperBuilder rejectRecurringDepositAccountApplication(final Long accountId) {
this.actionName = "REJECT";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=reject";
return this;
}
public CommandWrapperBuilder withdrawRecurringDepositAccountApplication(final Long accountId) {
this.actionName = "WITHDRAW";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=withdrawnByApplicant";
return this;
}
public CommandWrapperBuilder approveRecurringDepositAccountApplication(final Long accountId) {
this.actionName = "APPROVE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=approve";
return this;
}
public CommandWrapperBuilder undoRecurringDepositAccountApplication(final Long accountId) {
this.actionName = "APPROVALUNDO";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=undoapproval";
return this;
}
public CommandWrapperBuilder recurringDepositAccountActivation(final Long accountId) {
this.actionName = "ACTIVATE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=activate";
return this;
}
public CommandWrapperBuilder closeRecurringDepositAccount(final Long accountId) {
this.actionName = "CLOSE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=close";
return this;
}
public CommandWrapperBuilder prematureCloseRecurringDepositAccount(final Long accountId) {
this.actionName = "PREMATURECLOSE";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=prematureClose";
return this;
}
public CommandWrapperBuilder recurringDepositAccountInterestCalculation(final Long accountId) {
this.actionName = "CALCULATEINTEREST";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=calculateInterest";
return this;
}
public CommandWrapperBuilder recurringDepositAccountInterestPosting(final Long accountId) {
this.actionName = "POSTINTEREST";
this.entityName = "RECURRINGDEPOSITACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
this.href = "/recurringdepositaccounts/" + accountId + "?command=postInterest";
return this;
}
}
@@ -66,7 +66,8 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(),
wrapper.getSavingsId(), wrapper.getTransactionId(), wrapper.getHref(), wrapper.getProductId());
wrapper.getSavingsId(), wrapper.getTransactionId(), wrapper.getHref(), wrapper.getProductId(),
wrapper.interestRatechartId(), wrapper.depositAccountType());
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (final RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -422,6 +422,26 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isFixedDepositProductResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createFixedDepositProductCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("updateFixedDepositProductCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("deleteFixedDepositProductCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isRecurringDepositProductResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createRecurringDepositProductCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("updateRecurringDepositProductCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("deleteRecurringDepositProductCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isSavingsAccountResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext
@@ -479,6 +499,66 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isDepositAccountResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext
.getBean("depositAccountApplicationSubmittalCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("depositAccountApplicationModificationCommandHandler",
NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("depositAccountApplicationDeletionCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isRejectionOfDepositAccountApplication()) {
handler = this.applicationContext.getBean("depositAccountApplicationRejectedCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isWithdrawFromDepositAccountApplicationByApplicant()) {
handler = this.applicationContext.getBean("depositAccountApplicationWithdrawnByApplicantCommandHandler",
NewCommandSourceHandler.class);
} else if (wrapper.isApprovalOfDepositAccountApplication()) {
handler = this.applicationContext.getBean("depositAccountApplicationApprovalCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUndoApprovalOfDepositAccountApplication()) {
handler = this.applicationContext.getBean("depositAccountApplicationApprovalUndoCommandHandler",
NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountDeposit()) {
handler = this.applicationContext.getBean("depositAccountDepositCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountWithdrawal()) {
handler = this.applicationContext.getBean("withdrawDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountActivation()) {
handler = this.applicationContext.getBean("activateDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountInterestCalculation()) {
handler = this.applicationContext.getBean("calculateInterestDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountInterestPosting()) {
handler = this.applicationContext.getBean("postInterestDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountUndoTransaction()) {
handler = this.applicationContext.getBean("undoTransactionDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isAdjustDeopsitAccountTransaction()) {
handler = this.applicationContext.getBean("depositTransactionAdjustmentCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountClose()) {
handler = this.applicationContext.getBean("closeDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDepositAccountPrematureClose()) {
handler = this.applicationContext.getBean("prematureCloseDepositAccountCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isInterestRateChartResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createInterestRateChartCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("updateInterestRateChartCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("deleteInterestRateChartCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isInterestRateChartSlabResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createInterestRateChartSlabCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = this.applicationContext.getBean("updateInterestRateChartSlabCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("deleteInterestRateChartSlabCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isCalendarResource()) {
if (wrapper.isCreate()) {
handler = this.applicationContext.getBean("createCalendarCommandHandler", NewCommandSourceHandler.class);
@@ -21,6 +21,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.domain.BasicPasswordEncodablePlatformUser;
import org.mifosplatform.infrastructure.security.domain.PlatformUser;
import org.mifosplatform.infrastructure.security.service.PlatformPasswordEncoder;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -48,33 +49,50 @@ public final class JsonCommand {
private final String transactionId;
private final String url;
private final Long productId;
private final Long interestRateChartId;
private final DepositAccountType depositAccountType;
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final String entityName, final Long resourceId, final Long subresourceId, final Long groupId, final Long clientId,
final Long loanId, final Long savingsId, final String transactionId, final String url, final Long productId) {
final Long loanId, final Long savingsId, final String transactionId, final String url, final Long productId,
final Long interestRateChartId, final DepositAccountType depositAccountType) {
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, groupId,
clientId, loanId, savingsId, transactionId, url, productId);
clientId, loanId, savingsId, transactionId, url, productId, interestRateChartId, depositAccountType);
}
public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId,
final String url, final Long productId) {
final Long interestRateChartId = null;
final DepositAccountType depositAccountType = null;
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, null, null,
null, null, null, url, productId);
null, null, null, url, productId, interestRateChartId, depositAccountType);
}
public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId,
final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final String transactionId, final String url,
final Long productId) {
final Long interestRateChartId = null;
final DepositAccountType depositAccountType = null;
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, groupId,
clientId, loanId, savingsId, transactionId, url, productId);
clientId, loanId, savingsId, transactionId, url, productId, interestRateChartId, depositAccountType);
}
public static JsonCommand fromExistingCommand(JsonCommand command, final JsonElement parsedCommand) {
final String jsonCommand = command.fromApiJsonHelper.toJson(parsedCommand);
return new JsonCommand(command.commandId, jsonCommand, parsedCommand, command.fromApiJsonHelper, command.entityName,
command.resourceId, command.subresourceId, command.groupId, command.clientId, command.loanId, command.savingsId,
command.transactionId, command.url, command.productId, command.interestRateChartId, command.depositAccountType);
}
public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId,
final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final String transactionId, final String url,
final Long productId) {
final Long productId, final Long interestRateChartId, final DepositAccountType depositAccountType) {
this.commandId = commandId;
this.jsonCommand = jsonCommand;
this.parsedCommand = parsedCommand;
@@ -89,6 +107,8 @@ public final class JsonCommand {
this.transactionId = transactionId;
this.url = url;
this.productId = productId;
this.interestRateChartId = interestRateChartId;
this.depositAccountType = depositAccountType;
}
public String json() {
@@ -483,4 +503,12 @@ public final class JsonCommand {
public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set<String> requestDataParameters) {
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, requestDataParameters);
}
public Long interestRateChartId() {
return this.interestRateChartId;
}
public DepositAccountType depositAccounttype() {
return this.depositAccountType;
}
}
@@ -82,20 +82,20 @@ public class DataValidatorBuilder {
return this;
}
public void failWithCode(final String errorCode) {
public void failWithCode(final String errorCode, final Object... defaultUserMessageArgs) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".").append(errorCode);
final StringBuilder defaultEnglishMessage = new StringBuilder("Failed data validation due to: ").append(errorCode).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, this.value);
this.parameter, this.value, defaultUserMessageArgs);
this.dataValidationErrors.add(error);
}
public void failWithCodeNoParameterAddedToErrorCode(final String errorCode) {
public void failWithCodeNoParameterAddedToErrorCode(final String errorCode, final Object... defaultUserMessageArgs) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".").append(errorCode);
final StringBuilder defaultEnglishMessage = new StringBuilder("Failed data validation due to: ").append(errorCode).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, this.value);
this.parameter, this.value, defaultUserMessageArgs);
this.dataValidationErrors.add(error);
}
@@ -383,7 +383,25 @@ public class DataValidatorBuilder {
}
return this;
}
public DataValidatorBuilder integerEqualToOrGreaterThanNumber(Integer number) {
if (this.value == null && this.ignoreNullValue) { return this; }
if (this.value != null) {
final Integer intValue = Integer.valueOf(this.value.toString());
if (intValue < number) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.equal.to.or.greater.than.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter).append(
" must be equal to or greater than").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, intValue, number);
this.dataValidationErrors.add(error);
}
}
return this;
}
public DataValidatorBuilder integerSameAsNumber(Integer number) {
if (this.value == null && this.ignoreNullValue) { return this; }
@@ -785,5 +803,23 @@ public class DataValidatorBuilder {
}
return this;
}
public DataValidatorBuilder validateDateBefore(final LocalDate date) {
if (this.value == null && this.ignoreNullValue) { return this; }
if (this.value != null && date != null) {
final LocalDate dateVal = (LocalDate) this.value;
if (date.isBefore(dateVal)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.greater.than.date");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be less than provided date").append(date);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
this.dataValidationErrors.add(error);
}
}
return this;
}
}
@@ -14,7 +14,6 @@ public class EnumOptionData {
private final Long id;
private final String code;
@SuppressWarnings("unused")
private final String value;
public EnumOptionData(final Long id, final String code, final String value) {
@@ -30,4 +29,10 @@ public class EnumOptionData {
public String getCode() {
return this.code;
}
public String getValue() {
return this.value;
}
}
@@ -112,4 +112,16 @@ public class PaginationParameters {
}
return sql.toString();
}
public String paginationSql(){
final StringBuilder sqlBuilder = new StringBuilder(50);
if (this.isOrderByRequested()) {
sqlBuilder.append(' ').append(this.orderBySql());
}
if (this.isLimited()) {
sqlBuilder.append(' ').append(this.limitSql());
}
return sqlBuilder.toString();
}
}
@@ -51,6 +51,11 @@ public class JdbcSupport {
final Integer value = (Integer) JdbcUtils.getResultSetValue(rs, rs.findColumn(columnName), Integer.class);
return defaultToNullIfZero(value);
}
public static Long getLongDefaultToNullIfZero(final ResultSet rs, final String columnName) throws SQLException {
final Long value = (Long) JdbcUtils.getResultSetValue(rs, rs.findColumn(columnName), Long.class);
return defaultToNullIfZero(value);
}
private static Integer defaultToNullIfZero(final Integer value) {
Integer result = value;
@@ -59,6 +64,14 @@ public class JdbcSupport {
}
return result;
}
private static Long defaultToNullIfZero(final Long value) {
Long result = value;
if (result != null && Long.valueOf(0).equals(value)) {
result = null;
}
return result;
}
public static BigDecimal getBigDecimalDefaultToZeroIfNull(final ResultSet rs, final String columnName) throws SQLException {
final BigDecimal value = rs.getBigDecimal(columnName);
@@ -14,7 +14,8 @@ public enum JobName {
APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans"),
EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"),
ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"),
UPDATE_NPA("Update Non Performing Assets");
UPDATE_NPA("Update Non Performing Assets"),
UPDATE_DEPOSITS_ACCOUNT_MATURITY_DETAILS("Update Deposit Accounts Maturity details");
private final String name;
@@ -26,12 +26,16 @@ public class SavingsAccountSummaryData {
private final SavingsAccountStatusEnumData status;
private final CurrencyData currency;
private final BigDecimal accountBalance;
//differentiate Individual, JLG or Group account
private final EnumOptionData accountType;
private final SavingsAccountApplicationTimelineData timeline;
//differentiate deposit accounts Savings, FD and RD accounts
private final EnumOptionData depositType;
public SavingsAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
final String productName, final SavingsAccountStatusEnumData status, final CurrencyData currency,
final BigDecimal accountBalance, final EnumOptionData accountType, final SavingsAccountApplicationTimelineData timeline) {
final BigDecimal accountBalance, final EnumOptionData accountType, final SavingsAccountApplicationTimelineData timeline, final EnumOptionData depositType) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
@@ -42,5 +46,6 @@ public class SavingsAccountSummaryData {
this.accountBalance = accountBalance;
this.accountType = accountType;
this.timeline = timeline;
this.depositType = depositType;
}
}
@@ -141,7 +141,8 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, ");
accountsSummary.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
accountsSummary.append("curr.display_symbol as currencyDisplaySymbol, ");
accountsSummary.append("sa.product_id as productId, p.name as productName ");
accountsSummary.append("sa.product_id as productId, p.name as productName, ");
accountsSummary.append("sa.deposit_type_enum as depositType ");
accountsSummary.append("from m_savings_account sa ");
accountsSummary.append("join m_savings_product as p on p.id = sa.product_id ");
accountsSummary.append("join m_currency curr on curr.code = sa.currency_code ");
@@ -172,7 +173,9 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
final SavingsAccountStatusEnumData status = SavingsEnumerations.status(statusId);
final Integer accountType = JdbcSupport.getInteger(rs, "accountType");
final EnumOptionData accountTypeData = AccountEnumerations.loanType(accountType);
final Integer depositTypeId = JdbcSupport.getInteger(rs, "depositType");
final EnumOptionData depositTypeData = SavingsEnumerations.depositType(depositTypeId);
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
@@ -220,7 +223,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
closedByLastname);
return new SavingsAccountSummaryData(id, accountNo, externalId, productId, productName, status, currency, accountBalance,
accountTypeData, timeline);
accountTypeData, timeline, depositTypeData);
}
}
@@ -15,7 +15,7 @@ public class ClientApiConstants {
public static final String CLIENT_RESOURCE_NAME = "client";
public static final String CLIENT_CLOSURE_REASON = "ClientClosureReason";
public static final String GENDER = "Gender";
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
@@ -40,6 +40,9 @@ public class ClientApiConstants {
public static final String submittedOnDateParamName = "submittedOnDate";
public static final String savingsProductIdParamName = "savingsProductId";
public static final String savingsAccountIdParamName = "savingsAccountId";
public static final String dateOfBirthParamName = "dateOfBirth";
public static final String genderIdParamName = "genderId";
public static final String genderParamName = "gender";
// response parameters
public static final String statusParamName = "status";
public static final String hierarchyParamName = "hierarchy";
@@ -64,11 +67,12 @@ public class ClientApiConstants {
public static final Set<String> CLIENT_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, groupIdParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName,
middlenameParamName, lastnameParamName, fullnameParamName, officeIdParamName, activeParamName, activationDateParamName,
staffIdParamName, submittedOnDateParamName, savingsProductIdParamName));
staffIdParamName, submittedOnDateParamName, savingsProductIdParamName, dateOfBirthParamName, genderIdParamName));
public static final Set<String> CLIENT_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName, middlenameParamName,
lastnameParamName, fullnameParamName, activeParamName, activationDateParamName, staffIdParamName, savingsProductIdParamName));
lastnameParamName, fullnameParamName, activeParamName, activationDateParamName, staffIdParamName, savingsProductIdParamName,
dateOfBirthParamName, genderIdParamName));
/**
* These parameters will match the class level parameters of
@@ -79,7 +83,8 @@ public class ClientApiConstants {
externalIdParamName, statusParamName, activeParamName, activationDateParamName, firstnameParamName, middlenameParamName,
lastnameParamName, fullnameParamName, displayNameParamName, mobileNoParamName, officeIdParamName, officeNameParamName,
transferToOfficeIdParamName, transferToOfficeNameParamName, hierarchyParamName, imageIdParamName, imagePresentParamName,
staffIdParamName, staffNameParamName, timelineParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName));
staffIdParamName, staffNameParamName, timelineParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName,
dateOfBirthParamName, genderParamName));
public static final Set<String> ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, activationDateParamName));
@@ -40,6 +40,8 @@ final public class ClientData implements Comparable<ClientData> {
private final String fullname;
private final String displayName;
private final String mobileNo;
private final LocalDate dateOfBirth;
private final CodeValueData gender;
private final Long officeId;
private final String officeName;
@@ -67,12 +69,15 @@ final public class ClientData implements Comparable<ClientData> {
private final Collection<CodeValueData> closureReasons;
private final Collection<SavingsProductData> savingProductOptions;
private final Collection<SavingsAccountData> savingAccountOptions;
@SuppressWarnings("unused")
private final Collection<CodeValueData> genderOptions;
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions,
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons,
final Collection<SavingsProductData> savingProductOptions) {
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, null, null, null, joinedDate, null,
null, null, officeOptions, null, staffOptions, closureReasons, null, savingProductOptions, null, null, null, null);
final Collection<CodeValueData> genderOptions, final Collection<SavingsProductData> savingProductOptions) {
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, null, null, null, null, null,
joinedDate, null, null, null, officeOptions, null, staffOptions, closureReasons, genderOptions, null, savingProductOptions, null, null,
null, null);
}
@@ -81,9 +86,10 @@ final public class ClientData implements Comparable<ClientData> {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName,
clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename,
clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.mobileNo,
clientData.activationDate, clientData.imageId, clientData.staffId, clientData.staffName, templateData.officeOptions,
clientData.groups, templateData.staffOptions, null, null, templateData.savingProductOptions, clientData.savingsProductId,
clientData.savingsProductName, clientData.savingsAccountId, clientData.savingAccountOptions);
clientData.dateOfBirth, clientData.gender, clientData.activationDate, clientData.imageId, clientData.staffId,
clientData.staffName, templateData.officeOptions, clientData.groups, templateData.staffOptions, null, null, null,
templateData.savingProductOptions, clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId,
clientData.savingAccountOptions);
}
@@ -93,9 +99,10 @@ final public class ClientData implements Comparable<ClientData> {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName,
clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename,
clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.mobileNo,
clientData.activationDate, clientData.imageId, clientData.staffId, clientData.staffName, clientData.officeOptions,
clientData.groups, clientData.staffOptions, null, null, clientData.savingProductOptions, clientData.savingsProductId,
clientData.savingsProductName, clientData.savingsAccountId, savingAccountOptions);
clientData.dateOfBirth, clientData.gender, clientData.activationDate, clientData.imageId, clientData.staffId,
clientData.staffName, clientData.officeOptions, clientData.groups, clientData.staffOptions, null, null, null,
clientData.savingProductOptions, clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId,
savingAccountOptions);
}
@@ -103,9 +110,10 @@ final public class ClientData implements Comparable<ClientData> {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName,
clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename,
clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.mobileNo,
clientData.activationDate, clientData.imageId, clientData.staffId, clientData.staffName, clientData.officeOptions,
parentGroups, clientData.staffOptions, null, clientData.timeline, clientData.savingProductOptions,
clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId, clientData.savingAccountOptions);
clientData.dateOfBirth, clientData.gender, clientData.activationDate, clientData.imageId, clientData.staffId,
clientData.staffName, clientData.officeOptions, parentGroups, clientData.staffOptions, null, null, clientData.timeline,
clientData.savingProductOptions, clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId,
clientData.savingAccountOptions);
}
@@ -114,33 +122,35 @@ final public class ClientData implements Comparable<ClientData> {
final String officeName) {
return new ClientData(accountNo, status, officeId, officeName, null, null, id, firstname, middlename, lastname, fullname,
displayName, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
displayName, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
}
public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) {
return new ClientData(null, null, officeId, officeName, null, null, id, null, null, null, null, displayName, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null);
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
}
public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
final Long transferToOfficeId, final String transferToOfficeName, final Long id, final String firstname,
final String middlename, final String lastname, final String fullname, final String displayName, final String externalId,
final String mobileNo, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName,
final ClientTimelineData timeline, final Long savingsProductId, final String savingsProductName, final Long savingsAccountId) {
final String mobileNo, final LocalDate dateOfBirth, final CodeValueData gender, final LocalDate activationDate,
final Long imageId, final Long staffId, final String staffName, final ClientTimelineData timeline, final Long savingsProductId,
final String savingsProductName, final Long savingsAccountId) {
return new ClientData(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname, middlename,
lastname, fullname, displayName, externalId, mobileNo, activationDate, imageId, staffId, staffName, null, null, null, null,
timeline, null, savingsProductId, savingsProductName, savingsAccountId, null);
lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId, staffId, staffName,
null, null, null, null, null, timeline, null, savingsProductId, savingsProductName, savingsAccountId, null);
}
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
final Long transferToOfficeId, final String transferToOfficeName, final Long id, final String firstname,
final String middlename, final String lastname, final String fullname, final String displayName, final String externalId,
final String mobileNo, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName,
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups,
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons, final ClientTimelineData timeline,
final String mobileNo, final LocalDate dateOfBirth, final CodeValueData gender, final LocalDate activationDate,
final Long imageId, final Long staffId, final String staffName, final Collection<OfficeData> allowedOffices,
final Collection<GroupGeneralData> groups, final Collection<StaffData> staffOptions,
final Collection<CodeValueData> closureReasons, final Collection<CodeValueData> genderOptions, final ClientTimelineData timeline,
final Collection<SavingsProductData> savingProductOptions, final Long savingsProductId, final String savingsProductName,
final Long savingsAccountId, final Collection<SavingsAccountData> savingAccountOptions) {
this.accountNo = accountNo;
@@ -163,6 +173,8 @@ final public class ClientData implements Comparable<ClientData> {
this.externalId = StringUtils.defaultIfEmpty(externalId, null);
this.mobileNo = StringUtils.defaultIfEmpty(mobileNo, null);
this.activationDate = activationDate;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
this.imageId = imageId;
if (imageId != null) {
this.imagePresent = Boolean.TRUE;
@@ -179,6 +191,7 @@ final public class ClientData implements Comparable<ClientData> {
this.officeOptions = allowedOffices;
this.staffOptions = staffOptions;
this.closureReasons = closureReasons;
this.genderOptions = genderOptions;
this.timeline = timeline;
this.savingProductOptions = savingProductOptions;
@@ -21,6 +21,7 @@ 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.infrastructure.core.service.DateUtils;
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -144,6 +145,17 @@ public final class ClientDataValidator {
baseDataValidator.reset().parameter(ClientApiConstants.submittedOnDateParamName).value(submittedOnDate).notNull();
}
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.dateOfBirthParamName, element)) {
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
.validateDateBefore(DateUtils.getLocalDateOfTenant());
}
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) {
final Integer genderId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.genderIdParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -318,6 +330,17 @@ public final class ClientDataValidator {
.longGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.dateOfBirthParamName, element)) {
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
.validateDateBefore(DateUtils.getLocalDateOfTenant());
}
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) {
final Integer genderId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.genderIdParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).notNull();
}
if (!atLeastOneParameterPassedForUpdate) {
final Object forceError = null;
baseDataValidator.reset().anyOfNotNull(forceError);
@@ -425,7 +448,7 @@ public final class ClientDataValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForSavingsAccount(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
@@ -450,5 +473,4 @@ public final class ClientDataValidator {
}
}
@@ -105,6 +105,14 @@ public final class Client extends AbstractPersistable<Long> {
@Column(name = "external_id", length = 100, nullable = true, unique = true)
private String externalId;
@Column(name = "date_of_birth", nullable = true)
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "gender_cv_id", nullable = true)
private CodeValue gender;
@ManyToOne
@JoinColumn(name = "staff_id")
private Staff staff;
@@ -144,13 +152,13 @@ public final class Client extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "default_savings_product", nullable = true)
private SavingsProduct savingsProduct;
@ManyToOne
@JoinColumn(name = "default_savings_account", nullable = true)
private SavingsAccount savingsAccount;
public static Client createNew(final AppUser currentUser, final Office clientOffice, final Group clientParentGroup, final Staff staff,
final SavingsProduct savingsProduct, final JsonCommand command) {
final SavingsProduct savingsProduct, final CodeValue gender, final JsonCommand command) {
final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName);
final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName);
@@ -161,6 +169,8 @@ public final class Client extends AbstractPersistable<Long> {
final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
final LocalDate dataOfBirth = command.localDateValueOfParameterNamed(ClientApiConstants.dateOfBirthParamName);
ClientStatus status = ClientStatus.PENDING;
boolean active = false;
if (command.hasParameter("active")) {
@@ -182,9 +192,10 @@ public final class Client extends AbstractPersistable<Long> {
if (command.hasParameter(ClientApiConstants.submittedOnDateParamName)) {
submittedOnDate = command.localDateValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
}
final SavingsAccount account = null;
return new Client(currentUser, status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname,
activationDate, officeJoiningDate, externalId, mobileNo, staff, submittedOnDate, savingsProduct, null);
activationDate, officeJoiningDate, externalId, mobileNo, staff, submittedOnDate, savingsProduct, account, dataOfBirth,
gender);
}
protected Client() {
@@ -194,7 +205,8 @@ public final class Client extends AbstractPersistable<Long> {
private Client(final AppUser currentUser, final ClientStatus status, final Office office, final Group clientParentGroup,
final String accountNo, final String firstname, final String middlename, final String lastname, final String fullname,
final LocalDate activationDate, final LocalDate officeJoiningDate, final String externalId, final String mobileNo,
final Staff staff, final LocalDate submittedOnDate, final SavingsProduct savingsProduct,final SavingsAccount savingsAccount) {
final Staff staff, final LocalDate submittedOnDate, final SavingsProduct savingsProduct, final SavingsAccount savingsAccount,
final LocalDate dateOfBirth, final CodeValue gender) {
if (StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate();
@@ -260,6 +272,13 @@ public final class Client extends AbstractPersistable<Long> {
this.savingsProduct = savingsProduct;
this.savingsAccount = savingsAccount;
if(gender != null){
this.gender = gender;
}
if (dateOfBirth != null) {
this.dateOfBirth = dateOfBirth.toDateTimeAtStartOfDay().toDate();
}
deriveDisplayName();
validate();
}
@@ -666,11 +685,11 @@ public final class Client extends AbstractPersistable<Long> {
return this.activatedBy;
}
public SavingsAccount savingsAccount() {
return this.savingsAccount;
}
public SavingsAccount savingsAccount() {
return this.savingsAccount;
}
public void updateSavingsAccount(SavingsAccount savingsAccount) {
this.savingsAccount = savingsAccount;
}
public void updateSavingsAccount(SavingsAccount savingsAccount) {
this.savingsAccount = savingsAccount;
}
}
@@ -26,6 +26,7 @@ import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.data.ClientTimelineData;
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
@@ -94,8 +95,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
if (CollectionUtils.isEmpty(staffOptions)) {
staffOptions = null;
}
final List<CodeValueData> genderOptions = new ArrayList<CodeValueData>(
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER));
return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions, null, savingsProductDatas);
return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions, null, genderOptions, savingsProductDatas);
}
@Override
@@ -270,6 +273,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, ");
sqlBuilder.append("c.mobile_no as mobileNo, ");
sqlBuilder.append("c.date_of_birth as dateOfBirth, ");
sqlBuilder.append("c.gender_cv_id as genderId, ");
sqlBuilder.append("cv.code_value as genderValue, ");
sqlBuilder.append("c.activation_date as activationDate, c.image_id as imageId, ");
sqlBuilder.append("c.staff_id as staffId, s.display_name as staffName,");
sqlBuilder.append("c.default_savings_product as savingsProductId, sp.name as savingsProductName, ");
@@ -299,6 +305,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
sqlBuilder.append("left join m_appuser sbu on sbu.id = c.submittedon_userid ");
sqlBuilder.append("left join m_appuser acu on acu.id = c.activatedon_userid ");
sqlBuilder.append("left join m_appuser clu on clu.id = c.closedon_userid ");
sqlBuilder.append("left join m_code_value cv on cv.id = c.gender_cv_id ");
this.schema = sqlBuilder.toString();
}
@@ -329,6 +336,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String displayName = rs.getString("displayName");
final String externalId = rs.getString("externalId");
final String mobileNo = rs.getString("mobileNo");
final LocalDate dateOfBirth = JdbcSupport.getLocalDate(rs, "dateOfBirth");
final Long genderId = JdbcSupport.getLong(rs, "genderId");
final String genderValue = rs.getString("genderValue");
final CodeValueData gender = CodeValueData.instance(genderId, genderValue);
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
final Long imageId = JdbcSupport.getLong(rs, "imageId");
@@ -337,9 +348,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final Long savingsProductId = JdbcSupport.getLong(rs, "savingsProductId");
final String savingsProductName = rs.getString("savingsProductName");
final Long savingsAccountId = JdbcSupport.getLong(rs, "savingsAccountId");
final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
final String closedByUsername = rs.getString("closedByUsername");
@@ -360,8 +370,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
closedByUsername, closedByFirstname, closedByLastname);
return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname,
middlename, lastname, fullname, displayName, externalId, mobileNo, activationDate, imageId, staffId, staffName,
timeline, savingsProductId, savingsProductName,savingsAccountId);
middlename, lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId,
staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId);
}
}
@@ -394,6 +404,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
builder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
builder.append("c.fullname as fullname, c.display_name as displayName, ");
builder.append("c.mobile_no as mobileNo, ");
builder.append("c.date_of_birth as dateOfBirth, ");
builder.append("c.gender_cv_id as genderId, ");
builder.append("cv.code_value as genderValue, ");
builder.append("c.submittedon_date as submittedOnDate, ");
builder.append("sbu.username as submittedByUsername, ");
@@ -422,6 +435,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
builder.append("left join m_appuser sbu on sbu.id = c.submittedon_userid ");
builder.append("left join m_appuser acu on acu.id = c.activatedon_userid ");
builder.append("left join m_appuser clu on clu.id = c.closedon_userid ");
builder.append("left join m_code_value cv on cv.id = c.gender_cv_id ");
this.schema = builder.toString();
}
@@ -452,6 +466,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String displayName = rs.getString("displayName");
final String externalId = rs.getString("externalId");
final String mobileNo = rs.getString("mobileNo");
final LocalDate dateOfBirth = JdbcSupport.getLocalDate(rs, "dateOfBirth");
final Long genderId = JdbcSupport.getLong(rs, "genderId");
final String genderValue = rs.getString("genderValue");
final CodeValueData gender = CodeValueData.instance(genderId, genderValue);
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
final Long imageId = JdbcSupport.getLong(rs, "imageId");
final Long staffId = JdbcSupport.getLong(rs, "staffId");
@@ -460,7 +478,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final Long savingsProductId = JdbcSupport.getLong(rs, "savingsProductId");
final String savingsProductName = rs.getString("savingsProductName");
final Long savingsAccountId = JdbcSupport.getLong(rs, "savingsAccountId");
final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
final String closedByUsername = rs.getString("closedByUsername");
@@ -481,8 +498,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
closedByUsername, closedByFirstname, closedByLastname);
return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname,
middlename, lastname, fullname, displayName, externalId, mobileNo, activationDate, imageId, staffId, staffName,
timeline, savingsProductId, savingsProductName,savingsAccountId);
middlename, lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId,
staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId);
}
}
@@ -594,7 +611,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public ClientData retrieveAllClosureReasons(final String clientClosureReason) {
final List<CodeValueData> closureReasons = new ArrayList<CodeValueData>(
this.codeValueReadPlatformService.retrieveCodeValuesByCode(clientClosureReason));
return ClientData.template(null, null, null, null, closureReasons, null);
return ClientData.template(null, null, null, null, closureReasons, null, null);
}
}
@@ -183,6 +183,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
staff = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(staffId, clientOffice.getHierarchy());
}
CodeValue gender = null;
final Long genderId = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
if (genderId != null) {
gender = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.GENDER,
genderId);
}
SavingsProduct savingsProduct = null;
final Long savingsProductId = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName);
if (savingsProductId != null) {
@@ -191,7 +198,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
}
final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProduct, command);
final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProduct, gender, command);
boolean rollbackTransaction = false;
if (newClient.isActive()) {
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build();
@@ -496,7 +503,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
if (savingsId != null) {
savingsAccount = this.savingsRepository.findOne(savingsId);
if (savingsAccount == null) { throw new SavingsAccountNotFoundException(savingsId); }
if(!savingsAccount.getClient().identifiedBy(clientId)){
if (!savingsAccount.getClient().identifiedBy(clientId)) {
String defaultUserMessage = "saving account must belongs to client";
throw new InvalidClientSavingProductException("saving.account", "must.belongs.to.client", defaultUserMessage, savingsId,
clientForUpdate.getId());
@@ -0,0 +1,59 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class InterestRateChartApiConstants {
public static final String INTERESTRATE_CHART_RESOURCE_NAME = "interestchart";
// actions
public static String summitalAction = ".summital";
// command
public static String COMMAND_UNDO_TRANSACTION = "undo";
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
// interest rate chart parameters
public static final String idParamName = "id";
public static final String nameParamName = "name";
public static final String descriptionParamName = "description";
public static final String fromDateParamName = "fromDate";
public static final String endDateParamName = "endDate";
public static final String savingsProductIdParamName = "savingsProductId";
public static final String savingsProductNameParamName = "savingsProductName";
// interest rate chart Slabs parameters
public static final String periodTypeParamName = "periodType";
public static final String fromPeriodParamName = "fromPeriod";
public static final String toPeriodParamName = "toPeriod";
public static final String amountRangeFromParamName = "amountRangeFrom";
public static final String amountRangeToParamName = "amountRangeTo";
public static final String annualInterestRateParamName = "annualInterestRate";
// associations
public static final String chartSlabs = "chartSlabs";
// to delete chart Slabs from chart
public static final String deleteParamName = "delete";
public static final Set<String> INTERESTRATE_CHART_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, nameParamName, descriptionParamName, fromDateParamName, endDateParamName, savingsProductIdParamName,
chartSlabs));
public static final Set<String> INTERESTRATE_CHART_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, idParamName, nameParamName, descriptionParamName, fromDateParamName, endDateParamName, chartSlabs,
deleteParamName));
public static final Set<String> INTERESTRATE_CHART_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, idParamName, nameParamName, descriptionParamName, fromDateParamName, endDateParamName, chartSlabs));
}
@@ -0,0 +1,74 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart;
import java.util.ArrayList;
import java.util.List;
/**
* An enumeration of supported calendar periods used in savings.
*/
public enum InterestRateChartPeriodType {
DAYS(0, "interestChartPeriodType.days"), //
WEEKS(1, "interestChartPeriodType.weeks"), //
MONTHS(2, "interestChartPeriodType.months"), //
YEARS(3, "interestChartPeriodType.years"), //
INVALID(4, "interestChartPeriodType.invalid");
private final Integer value;
private final String code;
private InterestRateChartPeriodType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public static InterestRateChartPeriodType fromInt(final Integer type) {
InterestRateChartPeriodType periodType = InterestRateChartPeriodType.INVALID;
if (type != null) {
switch (type) {
case 0:
periodType = InterestRateChartPeriodType.DAYS;
break;
case 1:
periodType = InterestRateChartPeriodType.WEEKS;
break;
case 2:
periodType = InterestRateChartPeriodType.MONTHS;
break;
case 3:
periodType = InterestRateChartPeriodType.YEARS;
break;
}
}
return periodType;
}
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<Integer>();
for (final InterestRateChartPeriodType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
}
public boolean isInvalid(){
return this.value.equals(InterestRateChartPeriodType.INVALID.value);
}
}
@@ -0,0 +1,48 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class InterestRateChartSlabApiConstants {
public static final String INTERESTRATE_CHART_SLAB_RESOURCE_NAME = "chartslab";
// actions
// command
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
// interest rate chart Slabs parameters
public static final String idParamName = "id";
public static final String descriptionParamName = "description";
public static final String periodTypeParamName = "periodType";
public static final String fromPeriodParamName = "fromPeriod";
public static final String toPeriodParamName = "toPeriod";
public static final String amountRangeFromParamName = "amountRangeFrom";
public static final String amountRangeToParamName = "amountRangeTo";
public static final String annualInterestRateParamName = "annualInterestRate";
public static final String currencyCodeParamName = "currencyCode";
// associations
public static final Set<String> INTERESTRATE_CHART_SLAB_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
localeParamName, idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName,
amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName));
public static final Set<String> INTERESTRATE_CHART_SLAB_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
localeParamName, idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName,
amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName));
public static final Set<String> INTERESTRATE_CHART_SLAB_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName, amountRangeFromParamName,
amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName));
}
@@ -0,0 +1,139 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.api;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESPONSE_DATA_PARAMETERS;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartSlabReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/interestratecharts/{chartId}/chartslabs")
@Component
@Scope("singleton")
public class InterestRateChartSlabsApiResource {
private final InterestRateChartSlabReadPlatformService interestRateChartSlabReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<InterestRateChartSlabData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
@Autowired
public InterestRateChartSlabsApiResource(final InterestRateChartSlabReadPlatformService interestRateChartSlabReadPlatformService,
final PlatformSecurityContext context, final DefaultToApiJsonSerializer<InterestRateChartSlabData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper) {
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.interestRateChartSlabReadPlatformService = interestRateChartSlabReadPlatformService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String template() {
// TODO: implement
return null;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@PathParam("chartId") final Long chartId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
Collection<InterestRateChartSlabData> chartSlabs = this.interestRateChartSlabReadPlatformService.retrieveAll(chartId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, chartSlabs, INTERESTRATE_CHART_SLAB_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{chartSlabId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("chartId") final Long chartId, @PathParam("chartSlabId") final Long chartSlabId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
InterestRateChartSlabData chartSlab = this.interestRateChartSlabReadPlatformService.retrieveOne(chartId, chartSlabId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
chartSlab = this.interestRateChartSlabReadPlatformService.retrieveWithTemplate(chartSlab);
}
return this.toApiJsonSerializer.serialize(settings, chartSlab, INTERESTRATE_CHART_SLAB_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String create(@PathParam("chartId") final Long chartId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createInterestRateChartSlab(chartId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{chartSlabId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("chartId") final Long chartId, @PathParam("chartSlabId") final Long chartSlabId,
final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateInterestRateChartSlab(chartId, chartSlabId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@Path("{chartSlabId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("chartId") final Long chartId, @PathParam("chartSlabId") final Long chartSlabId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteInterestRateChartSlab(chartId, chartSlabId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,143 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.api;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/interestratecharts")
@Component
@Scope("singleton")
public class InterestRateChartsApiResource {
private final InterestRateChartReadPlatformService chartReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<InterestRateChartData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
@Autowired
public InterestRateChartsApiResource(final InterestRateChartReadPlatformService chartReadPlatformService,
final PlatformSecurityContext context, final DefaultToApiJsonSerializer<InterestRateChartData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper) {
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.chartReadPlatformService = chartReadPlatformService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String template(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME);
InterestRateChartData chartData = this.chartReadPlatformService.template();
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, chartData,
InterestRateChartApiConstants.INTERESTRATE_CHART_RESPONSE_DATA_PARAMETERS);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("productId") final Long productId) {
this.context.authenticatedUser().validateHasReadPermission(InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME);
Collection<InterestRateChartData> chartDatas = this.chartReadPlatformService.retrieveAllWithSlabs(productId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, chartDatas,
InterestRateChartApiConstants.INTERESTRATE_CHART_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{chartId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("chartId") final Long chartId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME);
InterestRateChartData chartData = this.chartReadPlatformService.retrieveOneWithSlabs(chartId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
chartData = this.chartReadPlatformService.retrieveWithTemplate(chartData);
}
return this.toApiJsonSerializer.serialize(settings, chartData,
InterestRateChartApiConstants.INTERESTRATE_CHART_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String create(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createInterestRateChart().withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{chartId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("chartId") final Long chartId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateInterestRateChart(chartId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@Path("{chartId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("chartId") final Long chartId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteInterestRateChart(chartId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,116 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
/**
* Immutable data object representing a InterestRateChart.
*/
public class InterestRateChartData {
private final Long id;
private final String name;
private final String description;
private final LocalDate fromDate;
private final LocalDate endDate;
private final Long savingsProductId;
private final String savingsProductName;
// associations
private Set<InterestRateChartSlabData> chartSlabs;
// template
private Collection<EnumOptionData> periodTypes;
public static InterestRateChartData instance(Long id, String name, String description, LocalDate fromDate, LocalDate endDate,
Long savingsProductId, String savingsProductName, Set<InterestRateChartSlabData> chartSlabs) {
Collection<EnumOptionData> periodTypes = null;
return new InterestRateChartData(id, name, description, fromDate, endDate, savingsProductId, savingsProductName, chartSlabs,
periodTypes);
}
public static InterestRateChartData withSlabs(InterestRateChartData interestRateChartData,
Set<InterestRateChartSlabData> chartSlabs) {
return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description,
interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.savingsProductId,
interestRateChartData.savingsProductName, chartSlabs, interestRateChartData.periodTypes);
}
public static InterestRateChartData withTemplate(InterestRateChartData interestRateChartData, Collection<EnumOptionData> periodTypes) {
return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description,
interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.savingsProductId,
interestRateChartData.savingsProductName, interestRateChartData.chartSlabs, periodTypes);
}
public static InterestRateChartData template(Collection<EnumOptionData> periodTypes) {
final Long id = null;
final String name = null;
final String description = null;
final LocalDate fromDate = null;
final LocalDate endDate = null;
final Long savingsProductId = null;
final String savingsProductName = null;
final Set<InterestRateChartSlabData> chartSlabs = null;
return new InterestRateChartData(id, name, description, fromDate, endDate, savingsProductId, savingsProductName, chartSlabs,
periodTypes);
}
private InterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate, Long savingsProductId,
String savingsProductName, Set<InterestRateChartSlabData> chartSlabs, Collection<EnumOptionData> periodTypes) {
this.id = id;
this.name = name;
this.description = description;
this.fromDate = fromDate;
this.endDate = endDate;
this.chartSlabs = chartSlabs;
this.savingsProductId = savingsProductId;
this.savingsProductName = savingsProductName;
this.periodTypes = periodTypes;
}
public void addChartSlab(final InterestRateChartSlabData chartSlab) {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<InterestRateChartSlabData>();
}
this.chartSlabs.add(chartSlab);
}
public boolean isFromDateAfter(final LocalDate compareDate) {
return (compareDate == null) ? false : this.fromDate.isAfter(compareDate);
}
public LocalDate endDate() {
return this.endDate;
}
public LocalDate fromDate() {
return this.fromDate;
}
public String name() {
return this.name;
}
public String description() {
return this.description;
}
public Set<InterestRateChartSlabData> chartSlabs() {
return this.chartSlabs;
}
public Collection<EnumOptionData> periodTypes() {
return this.periodTypes;
}
}
@@ -0,0 +1,176 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_CREATE_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_UPDATE_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.chartSlabs;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.endDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.nameParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.savingsProductIdParamName;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@Component
public class InterestRateChartDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartSlabDataValidator chartSlabDataValidator;
@Autowired
public InterestRateChartDataValidator(final FromJsonHelper fromApiJsonHelper,
final InterestRateChartSlabDataValidator chartSlabDataValidator) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.chartSlabDataValidator = chartSlabDataValidator;
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
validateForCreate(json, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForCreate(final String json, final DataValidatorBuilder baseDataValidator) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_CHART_CREATE_REQUEST_DATA_PARAMETERS);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(nameParamName, element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank();
}
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notNull();
}
final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed(fromDateParamName, element);
baseDataValidator.reset().parameter(fromDateParamName).value(fromDate).notNull();
LocalDate toDate = null;
if (this.fromApiJsonHelper.parameterExists(endDateParamName, element)) {
toDate = this.fromApiJsonHelper.extractLocalDateNamed(endDateParamName, element);
baseDataValidator.reset().parameter(endDateParamName).value(toDate).notNull();
}
if (fromDate != null && toDate != null) {
if (fromDate.isAfter(toDate)) {
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
}
}
// validate chart Slabs
validateChartSlabs(element, baseDataValidator);
}
public void validateUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
this.validateForUpdate(json, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUpdate(final String json, final DataValidatorBuilder baseDataValidator) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_CHART_UPDATE_REQUEST_DATA_PARAMETERS);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(savingsProductIdParamName, element)) {
final Long savingsProductId = this.fromApiJsonHelper.extractLongNamed(savingsProductIdParamName, element);
baseDataValidator.reset().parameter(savingsProductIdParamName).value(savingsProductId).notNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(nameParamName, element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank();
}
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notNull();
}
LocalDate fromDate = null;
if (this.fromApiJsonHelper.parameterExists(fromDateParamName, element)) {
fromDate = this.fromApiJsonHelper.extractLocalDateNamed(fromDateParamName, element);
baseDataValidator.reset().parameter(fromDateParamName).value(fromDate).notNull();
}
LocalDate toDate = null;
if (this.fromApiJsonHelper.parameterExists(endDateParamName, element)) {
toDate = this.fromApiJsonHelper.extractLocalDateNamed(endDateParamName, element);
baseDataValidator.reset().parameter(endDateParamName).value(toDate).notNull();
}
if (fromDate != null && toDate != null) {
if (fromDate.isAfter(toDate)) {
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
}
}
validateChartSlabs(element, baseDataValidator);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
private void validateChartSlabs(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
if (topLevelJsonElement.has(chartSlabs) && topLevelJsonElement.get(chartSlabs).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chartSlabs).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject interstRateChartElement = array.get(i).getAsJsonObject();
if (this.fromApiJsonHelper.parameterExists(idParamName, interstRateChartElement)) {
final Long id = this.fromApiJsonHelper.extractLongNamed(idParamName, interstRateChartElement);
baseDataValidator.reset().parameter(idParamName).value(id).notNull().integerGreaterThanZero();
this.chartSlabDataValidator.validateChartSlabsUpdate(interstRateChartElement, baseDataValidator, locale);
} else {
this.chartSlabDataValidator.validateChartSlabsCreate(interstRateChartElement, baseDataValidator, locale);
}
}
}
}
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface InterestRateChartRepository extends JpaRepository<InterestRateChart, Long>, JpaSpecificationExecutor<InterestRateChart> {
}
@@ -0,0 +1,53 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.exception.InterestRateChartNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* Wrapper for {@link InterestRateChartRepository} that is responsible for
* checking if {@link InterestRateChart} is returned when using
* <code>findOne</code> repository method and throwing an appropriate not found
* exception.
* </p>
*
* <p>
* This is to avoid need for checking and throwing in multiple areas of code
* base where {@link InterestRateChartRepository} is required.
* </p>
*/
@Service
public class InterestRateChartRepositoryWrapper {
private final InterestRateChartRepository repository;
@Autowired
public InterestRateChartRepositoryWrapper(final InterestRateChartRepository repository) {
this.repository = repository;
}
public InterestRateChart findOneWithNotFoundDetection(final Long intrestRateChartId) {
final InterestRateChart interestRateChart = this.repository.findOne(intrestRateChartId);
if (interestRateChart == null) { throw new InterestRateChartNotFoundException(intrestRateChartId); }
return interestRateChart;
}
public void save(final InterestRateChart interestRateChart) {
this.repository.save(interestRateChart);
}
public void delete(final InterestRateChart interestRateChart) {
this.repository.delete(interestRateChart);
}
public void saveAndFlush(final InterestRateChart interestRateChart) {
this.repository.saveAndFlush(interestRateChart);
}
}
@@ -0,0 +1,101 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import java.math.BigDecimal;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
/**
* Immutable data object representing a InterestRateChartSlab.
*/
public class InterestRateChartSlabData {
private final Long id;
private final String description;
private final EnumOptionData periodType;
private final Integer fromPeriod;
private final Integer toPeriod;
private final BigDecimal amountRangeFrom;
private final BigDecimal amountRangeTo;
private final BigDecimal annualInterestRate;
private final CurrencyData currency;
// template
private Collection<EnumOptionData> periodTypes;
public static InterestRateChartSlabData instance(Long id, String description, EnumOptionData periodType, Integer fromPeriod,
Integer toPeriod, BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, CurrencyData currency) {
Collection<EnumOptionData> periodTypes = null;
return new InterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency, periodTypes);
}
public static InterestRateChartSlabData withTemplate(InterestRateChartSlabData chartSlab, Collection<EnumOptionData> periodTypes) {
return new InterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod, chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo,
chartSlab.annualInterestRate, chartSlab.currency, periodTypes);
}
private InterestRateChartSlabData(Long id, String description, EnumOptionData periodType, Integer fromPeriod, Integer toPeriod,
BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, CurrencyData currency, Collection<EnumOptionData> periodTypes) {
this.id = id;
this.description = description;
this.periodType = periodType;
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currency = currency;
this.periodTypes = periodTypes;
}
public String description() {
return this.description;
}
public EnumOptionData periodType() {
return this.periodType;
}
public Integer fromPeriod() {
return this.fromPeriod;
}
public Integer toPeriod() {
return this.toPeriod;
}
public BigDecimal amountRangeFrom() {
return this.amountRangeFrom;
}
public BigDecimal amountRangeTo() {
return this.amountRangeTo;
}
public BigDecimal annualInterestRate() {
return this.annualInterestRate;
}
public CurrencyData currency() {
return this.currency;
}
public Collection<EnumOptionData> periodTypes() {
return this.periodTypes;
}
}
@@ -0,0 +1,207 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_CREATE_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_UPDATE_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeFromParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeToParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.annualInterestRateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
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.interestratechart.InterestRateChartPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@Component
public class InterestRateChartSlabDataValidator {
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public InterestRateChartSlabDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_CHART_SLAB_CREATE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final JsonObject objectElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(objectElement);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank().notExceedingLengthOf(3);
validateChartSlabsCreate(element, baseDataValidator, locale);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateChartSlabsCreate(final JsonElement element, final DataValidatorBuilder baseDataValidator, final Locale locale) {
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notNull();
}
final Integer periodType = this.fromApiJsonHelper.extractIntegerNamed(periodTypeParamName, element, locale);
baseDataValidator.reset().parameter(periodTypeParamName).value(periodType).notNull()
.isOneOfTheseValues(InterestRateChartPeriodType.integerValues());
Integer toPeriod = null;
final Integer fromPeriod = this.fromApiJsonHelper.extractIntegerNamed(fromPeriodParamName, element, locale);
baseDataValidator.reset().parameter(fromPeriodParamName).value(fromPeriod).notNull().integerZeroOrGreater();
if (this.fromApiJsonHelper.parameterExists(toPeriodParamName, element)) {
toPeriod = this.fromApiJsonHelper.extractIntegerNamed(toPeriodParamName, element, locale);
baseDataValidator.reset().parameter(toPeriodParamName).value(toPeriod).notNull().integerZeroOrGreater();
}
if (fromPeriod != null && toPeriod != null) {
if (fromPeriod > toPeriod) {
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("fromperiod.greater.than.to.period");
}
}
BigDecimal amountRangeFrom = null;
BigDecimal amountRangeTo = null;
if (this.fromApiJsonHelper.parameterExists(amountRangeFromParamName, element)) {
amountRangeFrom = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeFromParamName, element, locale);
baseDataValidator.reset().parameter(amountRangeFromParamName).value(amountRangeFrom).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(amountRangeToParamName, element)) {
amountRangeTo = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeToParamName, element, locale);
baseDataValidator.reset().parameter(amountRangeToParamName).value(amountRangeTo).notNull().positiveAmount();
}
if (amountRangeFrom != null && amountRangeTo != null) {
if (amountRangeFrom.compareTo(amountRangeTo) > 1) {
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("fromperiod.greater.than.toperiod");
}
}
final BigDecimal annualInterestRate = this.fromApiJsonHelper.extractBigDecimalNamed(annualInterestRateParamName, element, locale);
baseDataValidator.reset().parameter(annualInterestRateParamName).value(annualInterestRate).notNull().zeroOrPositiveAmount();
}
public void validateUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_CHART_SLAB_UPDATE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final JsonObject objectElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(objectElement);
validateChartSlabsUpdate(element, baseDataValidator, locale);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateChartSlabsUpdate(final JsonElement element, final DataValidatorBuilder baseDataValidator, final Locale locale) {
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notNull();
}
if (this.fromApiJsonHelper.parameterExists(periodTypeParamName, element)) {
final Integer periodType = this.fromApiJsonHelper.extractIntegerNamed(periodTypeParamName, element, locale);
baseDataValidator.reset().parameter(periodTypeParamName).value(periodType).notNull()
.isOneOfTheseValues(InterestRateChartPeriodType.integerValues());
}
Integer fromPeriod = null;
Integer toPeriod = null;
if (this.fromApiJsonHelper.parameterExists(fromPeriodParamName, element)) {
fromPeriod = this.fromApiJsonHelper.extractIntegerNamed(fromPeriodParamName, element, locale);
baseDataValidator.reset().parameter(fromPeriodParamName).value(fromPeriod).notNull().integerGreaterThanNumber(-1);
}
if (this.fromApiJsonHelper.parameterExists(toPeriodParamName, element)) {
toPeriod = this.fromApiJsonHelper.extractIntegerNamed(toPeriodParamName, element, locale);
baseDataValidator.reset().parameter(toPeriodParamName).value(toPeriod).notNull().integerGreaterThanNumber(-1);
}
if (fromPeriod != null && toPeriod != null) {
if (fromPeriod > toPeriod) {
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("fromperiod.greater.than.toperiod");
}
}
BigDecimal amountRangeFrom = null;
BigDecimal amountRangeTo = null;
if (this.fromApiJsonHelper.parameterExists(amountRangeFromParamName, element)) {
amountRangeFrom = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeFromParamName, element, locale);
baseDataValidator.reset().parameter(amountRangeFromParamName).value(amountRangeFrom).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(amountRangeToParamName, element)) {
amountRangeTo = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeToParamName, element, locale);
baseDataValidator.reset().parameter(amountRangeToParamName).value(amountRangeTo).notNull().positiveAmount();
}
if (amountRangeFrom != null && amountRangeTo != null) {
if (amountRangeFrom.compareTo(amountRangeTo) > 1) {
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("fromperiod.greater.than.toperiod");
}
}
if (this.fromApiJsonHelper.parameterExists(annualInterestRateParamName, element)) {
final BigDecimal annualInterestRate = this.fromApiJsonHelper.extractBigDecimalNamed(annualInterestRateParamName, element,
locale);
baseDataValidator.reset().parameter(annualInterestRateParamName).value(annualInterestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(currencyCodeParamName, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank().notExceedingLengthOf(3);
}
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface InterestRateChartSlabRepository extends JpaRepository<InterestRateChartSlab, Long>, JpaSpecificationExecutor<InterestRateChartSlab> {
}
@@ -0,0 +1,53 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.data;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.mifosplatform.portfolio.interestratechart.exception.InterestRateChartSlabNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* Wrapper for {@link InterestRateChartSlabRepository} that is responsible for checking
* if {@link InterestRateChartSlab} is returned when using <code>findOne</code>
* repository method and throwing an appropriate not found exception.
* </p>
*
* <p>
* This is to avoid need for checking and throwing in multiple areas of code
* base where {@link InterestRateChartSlabRepository} is required.
* </p>
*/
@Service
public class InterestRateChartSlabRepositoryWrapper {
private final InterestRateChartSlabRepository repository;
@Autowired
public InterestRateChartSlabRepositoryWrapper(final InterestRateChartSlabRepository repository) {
this.repository = repository;
}
public InterestRateChartSlab findOneWithNotFoundDetection(final Long chartSlabId) {
final InterestRateChartSlab chartSlab = this.repository.findOne(chartSlabId);
if (chartSlab == null) { throw new InterestRateChartSlabNotFoundException(chartSlabId); }
return chartSlab;
}
public void save(final InterestRateChartSlab chartSlab) {
this.repository.save(chartSlab);
}
public void delete(final InterestRateChartSlab chartSlab) {
this.repository.delete(chartSlab);
}
public void saveAndFlush(final InterestRateChartSlab chartSlab) {
this.repository.saveAndFlush(chartSlab);
}
}
@@ -0,0 +1,261 @@
/**
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* This Source Code Form is subject to the terms of the Mozilla Public
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.domain;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeFromParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeToParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.annualInterestRateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.deleteParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromPeriodParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.periodTypeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.toPeriodParamName;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.springframework.data.jpa.domain.AbstractPersistable;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@Entity
@Table(name = "m_interest_rate_chart")
public class InterestRateChart extends AbstractPersistable<Long> {
@Embedded
private InterestRateChartFields chartFields;
@OneToMany(mappedBy = "interestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<InterestRateChartSlab> chartSlabs = new HashSet<InterestRateChartSlab>();
protected InterestRateChart() {
//
}
public static InterestRateChart createNew(InterestRateChartFields chartFields,
Collection<InterestRateChartSlab> interestRateChartSlabs) {
return new InterestRateChart(chartFields, new HashSet<InterestRateChartSlab>(interestRateChartSlabs));
}
private InterestRateChart(InterestRateChartFields chartFields,
Set<InterestRateChartSlab> interestRateChartSlabs) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
// validate before setting the other fields
this.validateChartSlabs(baseDataValidator);
this.throwExceptionIfValidationWarningsExist(dataValidationErrors);
this.chartFields = chartFields;
this.addChartSlabs(interestRateChartSlabs);
}
public void validateChartSlabs(DataValidatorBuilder baseDataValidator) {
Collection<InterestRateChartSlab> chartSlabs = this.setOfChartSlabs();
Integer tmpPeriodType = null;
List<InterestRateChartSlab> chartSlabsList = new ArrayList<InterestRateChartSlab>(chartSlabs);
for (int i = 0; i < chartSlabsList.size(); i++) {
InterestRateChartSlab iSlabs = chartSlabsList.get(i);
if (tmpPeriodType == null) {
tmpPeriodType = iSlabs.slabFields().periodType();
} else if (!iSlabs.slabFields().periodType().equals(tmpPeriodType)) {
baseDataValidator.parameter(periodTypeParamName).value(iSlabs.slabFields().periodType())
.failWithCode("period.type.is.not.same", tmpPeriodType);
}
for (int j = i + 1; j < chartSlabsList.size(); j++) {
InterestRateChartSlab jSlabs = chartSlabsList.get(j);
if (iSlabs.slabFields().isPeriodOverlapping(jSlabs.slabFields())) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.period.overlapping", iSlabs.slabFields()
.fromPeriod(), iSlabs.slabFields().toPeriod(), jSlabs.slabFields().fromPeriod(), jSlabs
.slabFields().toPeriod());
}
}
}
}
public void addChartSlabs(Collection<InterestRateChartSlab> interestRateChartSlabsSet) {
Set<InterestRateChartSlab> existingChartSlabs = setOfChartSlabs();
for (InterestRateChartSlab newChartSlabs : interestRateChartSlabsSet) {
newChartSlabs.setInterestRateChart(this);
existingChartSlabs.add(newChartSlabs);
}
}
public void addChartSlab(InterestRateChartSlab newChartSlab) {
newChartSlab.setInterestRateChart(this);
setOfChartSlabs().add(newChartSlab);
}
public Set<InterestRateChartSlab> setOfChartSlabs() {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<InterestRateChartSlab>();
}
return this.chartSlabs;
}
public void update(JsonCommand command, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
this.update(command, actualChanges, baseDataValidator, null, null);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Set<InterestRateChart> existingCharts, String currencyCode) {
this.chartFields.update(command, actualChanges, baseDataValidator);
// interestRateChartSlabs
if (command.hasParameter(InterestRateChartApiConstants.chartSlabs)) {
updateChartSlabs(command, actualChanges, baseDataValidator, currencyCode);
}
this.validateCharts(baseDataValidator, existingCharts);
}
private void validateCharts(final DataValidatorBuilder baseDataValidator, final Set<InterestRateChart> existingCharts) {
for (InterestRateChart existingChart : existingCharts) {
if (!existingChart.equals(this)) {
if (this.chartFields.isOverlapping(existingChart.chartFields)) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.overlapping.from.and.end.dates",
existingChart.getFromDateAsLocalDate(), existingChart.getEndDateAsLocalDate(), this.getFromDateAsLocalDate(),
this.getEndDateAsLocalDate());
}
}
}
}
public void updateChartSlabs(JsonCommand command, final Map<String, Object> actualChanges,
final DataValidatorBuilder baseDataValidator, String currencyCode) {
final Map<String, Object> deleteChartSlabs = new HashMap<String, Object>();
final Map<String, Object> chartSlabsChanges = new HashMap<String, Object>();
if (command.hasParameter(InterestRateChartApiConstants.chartSlabs)) {
final JsonArray array = command.arrayOfParameterNamed(InterestRateChartApiConstants.chartSlabs);
if (array != null) {
for (int i = 0; i < array.size(); i++) {
final JsonObject chartSlabsElement = array.get(i).getAsJsonObject();
JsonCommand chartSlabsCommand = JsonCommand.fromExistingCommand(command, chartSlabsElement);
if (chartSlabsCommand.parameterExists(idParamName)) {
final Long chartSlabId = chartSlabsCommand.longValueOfParameterNamed(idParamName);
final InterestRateChartSlab chartSlab = this.findChartSlab(chartSlabId);
if (chartSlab == null) {
baseDataValidator.parameter(idParamName).value(chartSlabId)
.failWithCode("no.chart.slab.associated.with.id");
} else if (chartSlabsCommand.parameterExists(deleteParamName)) {
if (this.removeChartSlab(chartSlab)) {
deleteChartSlabs.put(idParamName, chartSlabId);
}
} else {
chartSlab.update(chartSlabsCommand, chartSlabsChanges, baseDataValidator);
}
} else {
/**
* TODO: AA: Move this code to
* InterestRateChartSlabAssembler
*/
final String description = chartSlabsCommand.stringValueOfParameterNamed(descriptionParamName);
final Integer periodTypeId = chartSlabsCommand.integerValueOfParameterNamed(periodTypeParamName);
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(periodTypeId);
final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName);
final Integer toPeriod = chartSlabsCommand.integerValueOfParameterNamed(toPeriodParamName);
final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName);
final BigDecimal amountRangeTo = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeToParamName);
final BigDecimal annualInterestRate = chartSlabsCommand
.bigDecimalValueOfParameterNamed(annualInterestRateParamName);
final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description, periodFrequencyType,
fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, annualInterestRate, currencyCode);
final InterestRateChartSlab chartSlab = InterestRateChartSlab.createNew(slabFields, this);
chartSlab.slabFields().validateChartSlabPlatformRules(chartSlabsCommand, baseDataValidator);
this.addChartSlab(chartSlab);
}
}
}
}
// add chart slab changes to actual changes list.
if (!chartSlabsChanges.isEmpty()) {
actualChanges.put(InterestRateChartApiConstants.chartSlabs, chartSlabsChanges);
}
// add deleted chart Slabs to actual changes
if (!deleteChartSlabs.isEmpty()) {
actualChanges.put("deletedChartSlabs", deleteChartSlabs);
}
this.validateChartSlabs(baseDataValidator);
}
public InterestRateChartSlab findChartSlab(Long chartSlabId) {
final Set<InterestRateChartSlab> chartSlabs = setOfChartSlabs();
for (InterestRateChartSlab interestRateChartSlab : chartSlabs) {
if (interestRateChartSlab.getId().equals(chartSlabId)) { return interestRateChartSlab; }
}
return null;
}
private boolean removeChartSlab(InterestRateChartSlab chartSlab) {
final Set<InterestRateChartSlab> chartSlabs = setOfChartSlabs();
return chartSlabs.remove(chartSlab);
}
public LocalDate getFromDateAsLocalDate() {
return this.chartFields.getFromDateAsLocalDate();
}
public LocalDate getEndDateAsLocalDate() {
return this.chartFields.getEndDateAsLocalDate();
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public InterestRateChartFields chartFields() {
return this.chartFields;
}
public boolean isApplicableChartFor(final LocalDate target){
return this.chartFields.isApplicableChartFor(target);
}
}
@@ -0,0 +1,150 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.domain;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.dateFormatParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.endDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.localeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.nameParamName;
import java.util.Date;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
import org.mifosplatform.infrastructure.core.service.DateUtils;
@Embeddable
public class InterestRateChartFields {
@Column(name = "name", length = 100, unique = false, nullable = false)
private String name;
@Column(name = "description", nullable = true)
private String description;
@Temporal(TemporalType.DATE)
@Column(name = "from_date", nullable = false)
private Date fromDate;
@Temporal(TemporalType.DATE)
@Column(name = "end_date", nullable = false)
private Date endDate;
protected InterestRateChartFields() {
//
}
public static InterestRateChartFields createNew(String name, String description, LocalDate fromDate, LocalDate toDate) {
return new InterestRateChartFields(name, description, fromDate, toDate);
}
private InterestRateChartFields(String name, String description, LocalDate fromDate, LocalDate toDate) {
this.name = name;
this.description = description;
this.fromDate = fromDate.toDate();
this.endDate = (toDate == null) ? null : toDate.toDate();
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator) {
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, newValue);
this.description = newValue;
}
final String localeAsInput = command.locale();
final String dateFormat = command.dateFormat();
if (command.isChangeInLocalDateParameterNamed(fromDateParamName, getFromDateAsLocalDate())) {
final LocalDate newValue = command.localDateValueOfParameterNamed(fromDateParamName);
final String newValueAsString = command.stringValueOfParameterNamed(fromDateParamName);
actualChanges.put(fromDateParamName, newValueAsString);
actualChanges.put(localeParamName, localeAsInput);
actualChanges.put(dateFormatParamName, dateFormat);
this.fromDate = newValue.toDate();
}
if (command.isChangeInLocalDateParameterNamed(endDateParamName, getFromDateAsLocalDate())) {
final LocalDate newValue = command.localDateValueOfParameterNamed(endDateParamName);
final String newValueAsString = command.stringValueOfParameterNamed(endDateParamName);
actualChanges.put(endDateParamName, newValueAsString);
actualChanges.put(localeParamName, localeAsInput);
actualChanges.put(dateFormatParamName, dateFormat);
this.endDate = newValue.toDate();
}
if (isFromDateAfterToDate()) {
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
}
}
public boolean isFromDateAfterToDate() {
return isFromDateAfter(getEndDateAsLocalDate());
}
public boolean isFromDateAfter(LocalDate compare) {
final LocalDate fromDate = getFromDateAsLocalDate();
if (fromDate != null && compare != null) { return fromDate.isAfter(compare); }
return false;
}
public LocalDate getFromDateAsLocalDate() {
LocalDate fromDate = null;
if (this.fromDate != null) {
fromDate = new LocalDate(this.fromDate);
}
return fromDate;
}
public LocalDate getEndDateAsLocalDate() {
LocalDate endDate = null;
if (this.endDate != null) {
endDate = new LocalDate(this.endDate);
}
return endDate;
}
public boolean isOverlapping(InterestRateChartFields that) {
final LocalDate thisFromDate = this.getFromDateAsLocalDate();
LocalDate thisEndDate = this.getEndDateAsLocalDate();
thisEndDate = thisEndDate == null ? DateUtils.getLocalDateOfTenant() : thisEndDate;
final LocalDate thatFromDate = that.getFromDateAsLocalDate();
LocalDate thatEndDate = that.getEndDateAsLocalDate();
thatEndDate = thatEndDate == null ? DateUtils.getLocalDateOfTenant() : thatEndDate;
final LocalDateInterval thisInterval = LocalDateInterval.create(thisFromDate, thisEndDate);
final LocalDateInterval thatInterval = LocalDateInterval.create(thatFromDate, thatEndDate);
if(thisInterval.containsPortionOf(thatInterval) || thisInterval.contains(thatInterval)){
return true;
}
return false;// no overlapping
}
public boolean isApplicableChartFor(final LocalDate target){
final LocalDate endDate = this.endDate == null ? DateUtils.getLocalDateOfTenant() : this.getEndDateAsLocalDate();
final LocalDateInterval interval = LocalDateInterval.create(getFromDateAsLocalDate(), endDate);
return interval.contains(target);
}
}
@@ -0,0 +1,79 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.domain;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_interest_rate_slab")
public class InterestRateChartSlab extends AbstractPersistable<Long> {
@Embedded
private InterestRateChartSlabFields slabFields;
@ManyToOne(optional = false)
@JoinColumn(name = "interest_rate_chart_id", referencedColumnName = "id", nullable = false)
private InterestRateChart interestRateChart;
protected InterestRateChartSlab() {
//
}
public static InterestRateChartSlab createNew(InterestRateChartSlabFields slabFields, InterestRateChart interestRateChart) {
return new InterestRateChartSlab(slabFields, interestRateChart);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
this.update(command, actualChanges, baseDataValidator);
this.interestRateChart.validateChartSlabs(baseDataValidator);
this.throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator) {
this.slabFields.update(command, actualChanges, baseDataValidator);
}
private InterestRateChartSlab(InterestRateChartSlabFields slabFields, InterestRateChart interestRateChart) {
this.slabFields = slabFields;
this.interestRateChart = interestRateChart;
if (this.interestRateChart != null) {
interestRateChart.addChartSlab(this);
}
}
public void setInterestRateChart(InterestRateChart interestRateChart) {
this.interestRateChart = interestRateChart;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public InterestRateChartSlabFields slabFields(){
return this.slabFields;
}
}
@@ -0,0 +1,213 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.domain;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeFromParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeToParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.annualInterestRateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromPeriodParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.periodTypeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.toPeriodParamName;
import java.math.BigDecimal;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.joda.time.Weeks;
import org.joda.time.Years;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
@Embeddable
public class InterestRateChartSlabFields {
@Column(name = "description", nullable = true)
private String description;
@Column(name = "period_type_enum", nullable = false)
private Integer periodType;
@Column(name = "from_period", nullable = false)
private Integer fromPeriod;
@Column(name = "to_period", nullable = true)
private Integer toPeriod;
@Column(name = "amount_range_from", scale = 6, precision = 19)
private BigDecimal amountRangeFrom;
@Column(name = "amount_range_to", scale = 6, precision = 19)
private BigDecimal amountRangeTo;
@Column(name = "annual_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal annualInterestRate;
@Column(name = "currency_code", nullable = false)
private String currencyCode;
protected InterestRateChartSlabFields() {
//
}
public static InterestRateChartSlabFields createNew(String description, final SavingsPeriodFrequencyType periodFrequencyType, Integer fromPeriod, Integer toPeriod,
BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, String currencyCode) {
return new InterestRateChartSlabFields(description, periodFrequencyType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currencyCode);
}
private InterestRateChartSlabFields(String description, final SavingsPeriodFrequencyType periodFrequencyType, Integer fromPeriod, Integer toPeriod,
BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, String currencyCode) {
this.description = description;
this.periodType = (periodFrequencyType == null) ? null : periodFrequencyType.getValue();
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currencyCode = currencyCode;
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator) {
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, newValue);
this.description = newValue;
}
if (command.isChangeInIntegerParameterNamed(periodTypeParamName, periodType)) {
final Integer newValue = command.integerValueOfParameterNamed(periodTypeParamName);
actualChanges.put(periodTypeParamName, newValue);
this.periodType = newValue;
}
if (command.isChangeInIntegerParameterNamed(fromPeriodParamName, fromPeriod)) {
final Integer newValue = command.integerValueOfParameterNamed(fromPeriodParamName);
actualChanges.put(fromPeriodParamName, newValue);
this.fromPeriod = newValue;
}
if (command.isChangeInIntegerParameterNamed(toPeriodParamName, toPeriod)) {
final Integer newValue = command.integerValueOfParameterNamed(toPeriodParamName);
actualChanges.put(toPeriodParamName, newValue);
this.toPeriod = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(amountRangeFromParamName, amountRangeFrom)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeFromParamName);
actualChanges.put(amountRangeFromParamName, newValue);
this.amountRangeFrom = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(amountRangeToParamName, amountRangeTo)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeToParamName);
actualChanges.put(amountRangeToParamName, newValue);
this.amountRangeTo = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(annualInterestRateParamName, annualInterestRate)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(annualInterestRateParamName);
actualChanges.put(annualInterestRateParamName, newValue);
this.annualInterestRate = newValue;
}
this.validateChartSlabPlatformRules(command, baseDataValidator);
}
public void validateChartSlabPlatformRules(JsonCommand chartSlabsCommand, DataValidatorBuilder baseDataValidator) {
if (this.isFromPeriodGreaterThanToPeriod()) {
final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName);
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("from.period.is.greater.than.to.period");
}
if (this.isAmountRangeFromGreaterThanTo()) {
final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName);
baseDataValidator.parameter(amountRangeFromParamName).value(amountRangeFrom)
.failWithCode("amount.range.from.is.greater.than.amount.range.to");
}
}
public boolean isFromPeriodGreaterThanToPeriod() {
boolean isGreater = false;
if (this.toPeriod != null && fromPeriod.compareTo(this.toPeriod) > 1) {
isGreater = true;
}
return isGreater;
}
public boolean isAmountRangeFromGreaterThanTo() {
boolean isGreater = false;
if (this.amountRangeFrom != null && this.amountRangeTo != null && this.amountRangeFrom.compareTo(this.amountRangeTo) > 1) {
isGreater = true;
}
return isGreater;
}
public Integer periodType() {
return this.periodType;
}
public Integer fromPeriod() {
return this.fromPeriod;
}
public Integer toPeriod() {
return this.toPeriod;
}
public boolean isPeriodOverlapping(InterestRateChartSlabFields that) {
if (that.toPeriod == null){
if (this.toPeriod == null){
return true;
}
return that.fromPeriod <= this.toPeriod;
}
return this.fromPeriod <= that.toPeriod && that.fromPeriod <= this.toPeriod;
}
public boolean isBetweenPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate){
final Integer compare = depositPeriod(periodStartDate, periodEndDate);
return (compare < this.fromPeriod || (this.toPeriod != null && compare > this.toPeriod)) ? false : true;
}
public boolean isAmountRangeProvided(){
return (this.amountRangeFrom == null) ? false : true;
}
public BigDecimal annualInterestRate() {
return this.annualInterestRate;
}
public Integer depositPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) {
Integer actualDepositPeriod = 0;
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.periodType());
switch (periodFrequencyType) {
case DAYS:
actualDepositPeriod = Days.daysBetween(periodStartDate, periodEndDate).getDays();
break;
case WEEKS:
actualDepositPeriod = Weeks.weeksBetween(periodStartDate, periodEndDate).getWeeks();
break;
case MONTHS:
actualDepositPeriod = Months.monthsBetween(periodStartDate, periodEndDate).getMonths();
break;
case YEARS:
actualDepositPeriod = Years.yearsBetween(periodStartDate, periodEndDate).getYears();
break;
case INVALID:
actualDepositPeriod = 0;// default value
break;
}
return actualDepositPeriod;
}
}
@@ -0,0 +1,15 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class InterestRateChartNotFoundException extends AbstractPlatformResourceNotFoundException {
public InterestRateChartNotFoundException(final Long id) {
super("error.msg.interest.rate.chart.id.invalid", "Interest rate chart with identifier " + id + " does not exist", id);
}
}
@@ -0,0 +1,19 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class InterestRateChartSlabNotFoundException extends AbstractPlatformResourceNotFoundException {
public InterestRateChartSlabNotFoundException(final Long id) {
super("error.msg.interest.rate.chart.slab.id.invalid", "Interest rate chart slab with identifier " + id + " does not exist", id);
}
public InterestRateChartSlabNotFoundException(final Long id, final Long chartId) {
super("error.msg.interest.rate.chart.slab.id.invalid", "Interest rate chart slab with identifier " + id + " does not exist in interest chart with identifier " + chartId , id, chartId);
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CreateInterestRateChartCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartWritePlatformService writePlatformService;
@Autowired
public CreateInterestRateChartCommandHandler(final InterestRateChartWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.create(command);
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartSlabWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CreateInterestRateChartSlabCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartSlabWritePlatformService writePlatformService;
@Autowired
public CreateInterestRateChartSlabCommandHandler(final InterestRateChartSlabWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.create(command);
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DeleteInterestRateChartCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartWritePlatformService writePlatformService;
@Autowired
public DeleteInterestRateChartCommandHandler(final InterestRateChartWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteChart(command.entityId());
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartSlabWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DeleteInterestRateChartSlabCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartSlabWritePlatformService writePlatformService;
@Autowired
public DeleteInterestRateChartSlabCommandHandler(final InterestRateChartSlabWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteChartSlab(command.entityId(), command.interestRateChartId());
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UpdateInterestRateChartCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartWritePlatformService writePlatformService;
@Autowired
public UpdateInterestRateChartCommandHandler(final InterestRateChartWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.update(command.entityId(), command);
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartSlabWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UpdateInterestRateChartSlabCommandHandler implements NewCommandSourceHandler {
private final InterestRateChartSlabWritePlatformService writePlatformService;
@Autowired
public UpdateInterestRateChartSlabCommandHandler(final InterestRateChartSlabWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.update(command.entityId(), command.interestRateChartId(), command);
}
}
@@ -0,0 +1,94 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.endDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromDateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.nameParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartRepositoryWrapper;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartFields;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class InterestRateChartAssembler {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper;
private final InterestRateChartSlabAssembler chartSlabAssembler;
@Autowired
public InterestRateChartAssembler(final FromJsonHelper fromApiJsonHelper,
final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper,
final InterestRateChartSlabAssembler chartSlabAssembler) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.interestRateChartRepositoryWrapper = interestRateChartRepositoryWrapper;
this.chartSlabAssembler = chartSlabAssembler;
}
/**
* Assembles a new {@link InterestRateChart} from JSON Slabs passed in
* request
*/
public InterestRateChart assembleFrom(final JsonCommand command) {
final JsonElement element = command.parsedJson();
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@SuppressWarnings("unused")
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
final InterestRateChart newChart = this.assembleFrom(element, currencyCode);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
return newChart;
}
public InterestRateChart assembleFrom(final JsonElement element, final String currencyCode) {
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed(fromDateParamName, element);
final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(endDateParamName, element);
// assemble chart Slabs
final Collection<InterestRateChartSlab> newChartSlabs = this.chartSlabAssembler.assembleChartSlabsFrom(element,
currencyCode);
final InterestRateChartFields fields = InterestRateChartFields.createNew(name, description, fromDate, toDate);
final InterestRateChart newChart = InterestRateChart.createNew(fields, newChartSlabs);
return newChart;
}
public InterestRateChart assembleFrom(final Long interestRateChartId) {
final InterestRateChart interestRateChart = this.interestRateChartRepositoryWrapper
.findOneWithNotFoundDetection(interestRateChartId);
return interestRateChart;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
@@ -0,0 +1,15 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
public interface InterestRateChartDropdownReadPlatformService {
Collection<EnumOptionData> retrievePeriodTypeOptions();
}
@@ -0,0 +1,22 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartPeriodType;
import org.springframework.stereotype.Service;
@Service
public class InterestRateChartDropdownReadPlatformServiceImpl implements InterestRateChartDropdownReadPlatformService {
@Override
public Collection<EnumOptionData> retrievePeriodTypeOptions() {
return InterestRateChartEnumerations.periodType(InterestRateChartPeriodType.values());
}
}
@@ -0,0 +1,57 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartPeriodType;
public class InterestRateChartEnumerations {
public static EnumOptionData periodType(final Integer type) {
return periodType(InterestRateChartPeriodType.fromInt(type));
}
public static EnumOptionData periodType(final InterestRateChartPeriodType type) {
EnumOptionData optionData = new EnumOptionData(InterestRateChartPeriodType.INVALID.getValue().longValue(),
InterestRateChartPeriodType.INVALID.getCode(), "Invalid");
switch (type) {
case INVALID:
break;
case DAYS:
optionData = new EnumOptionData(InterestRateChartPeriodType.DAYS.getValue().longValue(),
InterestRateChartPeriodType.DAYS.getCode(), "Days");
break;
case WEEKS:
optionData = new EnumOptionData(InterestRateChartPeriodType.WEEKS.getValue().longValue(),
InterestRateChartPeriodType.WEEKS.getCode(), "Weeks");
break;
case MONTHS:
optionData = new EnumOptionData(InterestRateChartPeriodType.MONTHS.getValue().longValue(),
InterestRateChartPeriodType.MONTHS.getCode(), "Months");
break;
case YEARS:
optionData = new EnumOptionData(InterestRateChartPeriodType.YEARS.getValue().longValue(),
InterestRateChartPeriodType.YEARS.getCode(), "Years");
break;
}
return optionData;
}
public static List<EnumOptionData> periodType(final InterestRateChartPeriodType[] periodTypes) {
final List<EnumOptionData> optionDatas = new ArrayList<EnumOptionData>();
for (final InterestRateChartPeriodType periodType : periodTypes) {
if (!periodType.isInvalid()) {
optionDatas.add(periodType(periodType));
}
}
return optionDatas;
}
}
@@ -0,0 +1,33 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.Collection;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
public interface InterestRateChartReadPlatformService {
//Collection<InterestRateChartData> retrieveAll(Long savingsProductId);
InterestRateChartData retrieveOne(Long interestChartId);
//Collection<InterestRateChartData> retrieveAllWithSlabs();
Collection<InterestRateChartData> retrieveAllWithSlabs(Long savingsProductId);
Collection<InterestRateChartData> retrieveAllWithSlabsWithTemplate(Long savingsProductId);
InterestRateChartData retrieveOneWithSlabs(Long interestChartId);
InterestRateChartData retrieveWithTemplate(InterestRateChartData interestRateChartData);
InterestRateChartData retrieveOneWithSlabsOnProductId(Long productId);
InterestRateChartData template();
InterestRateChartData retrieveActiveChartWithTemplate(Long productId);
}
@@ -0,0 +1,279 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
import org.mifosplatform.portfolio.interestratechart.exception.InterestRateChartNotFoundException;
import org.mifosplatform.portfolio.savings.data.DepositProductData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class InterestRateChartReadPlatformServiceImpl implements InterestRateChartReadPlatformService {
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
private final InterestRateChartMapper chartRowMapper = new InterestRateChartMapper();
private final InterestRateChartExtractor chartExtractor = new InterestRateChartExtractor();
private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService;
@Autowired
public InterestRateChartReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource,
InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.chartDropdownReadPlatformService = chartDropdownReadPlatformService;
}
/*
* @Override public Collection<InterestRateChartData> retrieveAll(Long
* productId) {
*
* // TODO return null; }
*/
@Override
public InterestRateChartData retrieveOne(Long chartId) {
try {
this.context.authenticatedUser();
final String sql = "select " + this.chartRowMapper.schema() + " where irc.id = ?";
return this.jdbcTemplate.queryForObject(sql, this.chartRowMapper, new Object[] { chartId });
} catch (final EmptyResultDataAccessException e) {
throw new InterestRateChartNotFoundException(chartId);
}
}
/*
* @Override public Collection<InterestRateChartData>
* retrieveAllWithSlabs() { this.context.authenticatedUser(); final String
* sql = "select " + this.chartExtractor.schema() +
* " order by irc.id, ircd.id "; return this.jdbcTemplate.query(sql,
* this.chartExtractor); }
*/
@Override
public Collection<InterestRateChartData> retrieveAllWithSlabs(Long productId) {
this.context.authenticatedUser();
String sql = "select " + this.chartExtractor.schema() + " where sp.id = ? order by irc.id, ircd.id";
return this.jdbcTemplate.query(sql, this.chartExtractor, new Object[] { productId });
}
@Override
public Collection<InterestRateChartData> retrieveAllWithSlabsWithTemplate(Long productId) {
Collection<InterestRateChartData> chartDatas = new ArrayList<InterestRateChartData>();
for (InterestRateChartData chartData : retrieveAllWithSlabs(productId)) {
chartDatas.add(retrieveWithTemplate(chartData));
}
return chartDatas;
}
@Override
public InterestRateChartData retrieveActiveChartWithTemplate(Long productId) {
Collection<InterestRateChartData> chartDatas = this.retrieveAllWithSlabsWithTemplate(productId);
return DepositProductData.activeChart(chartDatas);
}
@Override
public InterestRateChartData retrieveOneWithSlabs(Long chartId) {
this.context.authenticatedUser();
final String sql = "select " + this.chartExtractor.schema() + " where irc.id = ? order by ircd.id asc";
Collection<InterestRateChartData> chartDatas = this.jdbcTemplate.query(sql, this.chartExtractor, new Object[] { chartId });
if (chartDatas == null || chartDatas.isEmpty()) { throw new InterestRateChartNotFoundException(chartId); }
return chartDatas.iterator().next();
}
@Override
public InterestRateChartData retrieveWithTemplate(InterestRateChartData chartData) {
return InterestRateChartData.withTemplate(chartData, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions());
}
@Override
public InterestRateChartData retrieveOneWithSlabsOnProductId(@SuppressWarnings("unused") Long productId) {
// TODO Auto-generated method stub
return null;
}
@Override
public InterestRateChartData template() {
return InterestRateChartData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions());
}
private static final class InterestRateChartExtractor implements ResultSetExtractor<Collection<InterestRateChartData>> {
InterestRateChartMapper chartMapper = new InterestRateChartMapper();
InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper();
private final String schemaSql;
public String schema() {
return this.schemaSql;
}
private InterestRateChartExtractor() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("irc.id as ircId, irc.name as ircName, irc.description as ircDescription,")
.append("irc.from_date as ircFromDate, irc.end_date as ircEndDate, ")
.append("ircd.id as ircdId, ircd.description as ircdDescription, ircd.period_type_enum ircdPeriodTypeId, ")
.append("ircd.from_period as ircdFromPeriod, ircd.to_period as ircdToPeriod, ircd.amount_range_from as ircdAmountRangeFrom, ")
.append("ircd.amount_range_to as ircdAmountRangeTo, ircd.annual_interest_rate as ircdAnnualInterestRate, ")
.append("curr.code as currencyCode, curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ")
.append("curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf, ")
.append("sp.id as savingsProductId, sp.name as savingsProductName ")
.append("from ")
.append("m_interest_rate_chart irc left join m_interest_rate_slab ircd on irc.id=ircd.interest_rate_chart_id ")
.append("left join m_currency curr on ircd.currency_code= curr.code ")
.append("left join m_deposit_product_interest_rate_chart dpirc on irc.id=dpirc.interest_rate_chart_id ")
.append("left join m_savings_product sp on sp.id=dpirc.deposit_product_id ");
this.schemaSql = sqlBuilder.toString();
}
@Override
public Collection<InterestRateChartData> extractData(ResultSet rs) throws SQLException, DataAccessException {
List<InterestRateChartData> chartDataList = new ArrayList<InterestRateChartData>();
InterestRateChartData chartData = null;
Long interestRateChartId = null;
int ircIndex = 0;// Interest rate chart index
int ircdIndex = 0;// Interest rate chart Slabs index
while (rs.next()) {
Long tempIrcId = rs.getLong("ircId");
// first row or when interest rate chart id changes
if (chartData == null || (interestRateChartId != null && !interestRateChartId.equals(tempIrcId))) {
interestRateChartId = tempIrcId;
chartData = chartMapper.mapRow(rs, ircIndex++);
chartDataList.add(chartData);
ircdIndex = 0;// reset index
}
final InterestRateChartSlabData chartSlabsData = chartSlabsMapper.mapRow(rs, ircdIndex++);
if (chartSlabsData != null) {
chartData.addChartSlab(chartSlabsData);
}
}
return chartDataList;
}
}
public static final class InterestRateChartMapper implements RowMapper<InterestRateChartData> {
private final String schemaSql;
public String schema() {
return this.schemaSql;
}
private InterestRateChartMapper() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder.append("irc.id as ircId, irc.name as ircName, irc.description as ircDescription, ")
.append("irc.from_date as ircFromDate, irc.end_date as ircEndDate, irc.is_active_chart as isActiveChart, ")
.append("sp.id as savingsProductId, sp.name as savingsProductName ").append("from ")
.append("m_interest_rate_chart irc ")
.append("left join m_deposit_product_interest_rate_chart dpirc on irc.id=dpirc.interest_rate_chart_id ")
.append("left join m_savings_product sp on sp.id=dpirc.deposit_product_id ");
this.schemaSql = sqlBuilder.toString();
}
@Override
public InterestRateChartData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
final Long id = rs.getLong("ircId");
final String name = rs.getString("ircName");
final String description = rs.getString("ircDescription");
final LocalDate fromDate = JdbcSupport.getLocalDate(rs, "ircFromDate");
final LocalDate endDate = JdbcSupport.getLocalDate(rs, "ircEndDate");
final Long savingsProductId = rs.getLong("savingsProductId");
final String savingsProductName = rs.getString("savingsProductName");
return InterestRateChartData.instance(id, name, description, fromDate, endDate, savingsProductId, savingsProductName, null);
}
}
private static final class InterestRateChartSlabsMapper implements RowMapper<InterestRateChartSlabData> {
private final String schemaSql;
@SuppressWarnings("unused")
public String schema() {
return this.schemaSql;
}
private InterestRateChartSlabsMapper() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("ircd.id as ircdId, ircd.description as ircdDescription, ircd.period_type_enum ircdPeriodTypeId, ")
.append("ircd.from_period as ircdFromPeriod, ircd.to_period as ircdToPeriod, ircd.amount_range_from as ircdAmountRangeFrom, ")
.append("ircd.amount_range_to as ircdAmountRangeTo, ircd.annual_interest_rate as ircdAnnualInterestRate, ")
.append("curr.code as currencyCode, curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ")
.append("curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf ")
.append("from ").append("m_interest_rate_slab ircd ")
.append("left join m_currency curr on ircd.currency_code= curr.code ");
this.schemaSql = sqlBuilder.toString();
}
@Override
public InterestRateChartSlabData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
final Long id = JdbcSupport.getLongDefaultToNullIfZero(rs, "ircdId");
// If there are not chart Slabs are associated then in
// InterestRateChartExtractor the chart Slabs id will be null.
if (id == null) { return null; }
final String description = rs.getString("ircdDescription");
final Integer fromPeriod = JdbcSupport.getInteger(rs, "ircdFromPeriod");
final Integer toPeriod = JdbcSupport.getInteger(rs, "ircdToPeriod");
final Integer periodTypeId = JdbcSupport.getInteger(rs, "ircdPeriodTypeId");
final EnumOptionData periodType = InterestRateChartEnumerations.periodType(periodTypeId);
final BigDecimal amountRangeFrom = rs.getBigDecimal("ircdAmountRangeFrom");
final BigDecimal amountRangeTo = rs.getBigDecimal("ircdAmountRangeTo");
final BigDecimal annualInterestRate = rs.getBigDecimal("ircdAnnualInterestRate");
// currency Slabs
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
// currency
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf,
currencyDisplaySymbol, currencyNameCode);
return InterestRateChartSlabData.instance(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency);
}
}
}
@@ -0,0 +1,128 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeFromParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.amountRangeToParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.annualInterestRateParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.chartSlabs;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.fromPeriodParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.periodTypeParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.toPeriodParamName;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartRepositoryWrapper;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlabFields;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
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 InterestRateChartSlabAssembler {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper;
@Autowired
public InterestRateChartSlabAssembler(final FromJsonHelper fromApiJsonHelper,
final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.interestRateChartRepositoryWrapper = interestRateChartRepositoryWrapper;
}
/**
* Assembles a new {@link InterestRateChartSlab} from JSON Slabs passed in
* request
*/
public InterestRateChartSlab assembleFrom(final JsonCommand command) {
final JsonElement element = command.parsedJson();
final JsonObject elementObject = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(elementObject);
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
final Long chartId = command.interestRateChartId();
final InterestRateChart chart = this.interestRateChartRepositoryWrapper.findOneWithNotFoundDetection(chartId);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
final InterestRateChartSlab newChartSlab = assembleChartSlabs(chart, elementObject, currencyCode, locale);
// validate chart Slabs
newChartSlab.slabFields().validateChartSlabPlatformRules(command, baseDataValidator);
chart.validateChartSlabs(baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
return newChartSlab;
}
private InterestRateChartSlab assembleChartSlabs(final InterestRateChart interestRateChart, final JsonElement element,
final String currencyCode, final Locale locale) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
final Integer periodTypeId = this.fromApiJsonHelper.extractIntegerNamed(periodTypeParamName, element, locale);
final SavingsPeriodFrequencyType periodType = SavingsPeriodFrequencyType.fromInt(periodTypeId);
final Integer fromPeriod = this.fromApiJsonHelper.extractIntegerNamed(fromPeriodParamName, element, locale);
final Integer toPeriod = this.fromApiJsonHelper.extractIntegerNamed(toPeriodParamName, element, locale);
final BigDecimal amountRangeFrom = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeFromParamName, element, locale);
final BigDecimal amountRangeTo = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeToParamName, element, locale);
final BigDecimal annualInterestRate = this.fromApiJsonHelper.extractBigDecimalNamed(annualInterestRateParamName, element, locale);
final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description, periodType, fromPeriod, toPeriod,
amountRangeFrom, amountRangeTo, annualInterestRate, currencyCode);
return InterestRateChartSlab.createNew(slabFields, interestRateChart);
}
public InterestRateChartSlab assembleFrom(final Long chartSlabId, final Long chartId) {
final InterestRateChart chart = this.interestRateChartRepositoryWrapper.findOneWithNotFoundDetection(chartId);
final InterestRateChartSlab interestRateChartSlab = chart.findChartSlab(chartSlabId);
return interestRateChartSlab;
}
public Collection<InterestRateChartSlab> assembleChartSlabsFrom(final JsonElement element, String currencyCode) {
final Collection<InterestRateChartSlab> interestRateChartSlabsSet = new HashSet<InterestRateChartSlab>();
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
if (topLevelJsonElement.has(chartSlabs) && topLevelJsonElement.get(chartSlabs).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chartSlabs).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject interstRateChartElement = array.get(i).getAsJsonObject();
final InterestRateChartSlab chartSlab = this.assembleChartSlabs(null, interstRateChartElement, currencyCode, locale);
interestRateChartSlabsSet.add(chartSlab);
}
}
}
return interestRateChartSlabsSet;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
@@ -0,0 +1,19 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.Collection;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
public interface InterestRateChartSlabReadPlatformService {
Collection<InterestRateChartSlabData> retrieveAll(Long chartId);
InterestRateChartSlabData retrieveOne(Long chartId, Long chartSlabId);
InterestRateChartSlabData retrieveWithTemplate(InterestRateChartSlabData chartSlab);
}
@@ -0,0 +1,119 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
import org.mifosplatform.portfolio.interestratechart.exception.InterestRateChartSlabNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRateChartSlabReadPlatformService {
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
private final InterestRateChartSlabsMapper chartSlabRowMapper = new InterestRateChartSlabsMapper();
private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService;
@Autowired
public InterestRateChartSlabReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource,
InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.chartDropdownReadPlatformService = chartDropdownReadPlatformService;
}
@Override
public Collection<InterestRateChartSlabData> retrieveAll(Long chartId) {
this.context.authenticatedUser();
final String sql = "select " + this.chartSlabRowMapper.schema() + " where ircd.interest_rate_chart_id = ? order by ircd.id";
return this.jdbcTemplate.query(sql, this.chartSlabRowMapper, new Object[] { chartId });
}
@Override
public InterestRateChartSlabData retrieveOne(Long chartId, Long chartSlabId) {
try {
this.context.authenticatedUser();
final String sql = "select " + this.chartSlabRowMapper.schema() + " where ircd.interest_rate_chart_id = ? and ircd.id = ?";
return this.jdbcTemplate.queryForObject(sql, this.chartSlabRowMapper, new Object[] { chartId, chartSlabId });
} catch (final EmptyResultDataAccessException e) {
throw new InterestRateChartSlabNotFoundException(chartSlabId, chartId);
}
}
@Override
public InterestRateChartSlabData retrieveWithTemplate(InterestRateChartSlabData chartSlab) {
return InterestRateChartSlabData.withTemplate(chartSlab, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions());
}
private static final class InterestRateChartSlabsMapper implements RowMapper<InterestRateChartSlabData> {
private final String schemaSql;
public String schema() {
return this.schemaSql;
}
private InterestRateChartSlabsMapper() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("ircd.id as ircdId, ircd.description as ircdDescription, ircd.period_type_enum ircdPeriodTypeId, ")
.append("ircd.from_period as ircdFromPeriod, ircd.to_period as ircdToPeriod, ircd.amount_range_from as ircdAmountRangeFrom, ")
.append("ircd.amount_range_to as ircdAmountRangeTo, ircd.annual_interest_rate as ircdAnnualInterestRate, ")
.append("curr.code as currencyCode, curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ")
.append("curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf ")
.append("from ").append("m_interest_rate_slab ircd ")
.append("left join m_currency curr on ircd.currency_code= curr.code ");
this.schemaSql = sqlBuilder.toString();
}
@Override
public InterestRateChartSlabData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
final Long id = JdbcSupport.getLongDefaultToNullIfZero(rs, "ircdId");
// If there are not chart Slabs are associated then in
// InterestRateChartExtractor the chart Slabs id will be null.
if (id == null) { return null; }
final String description = rs.getString("ircdDescription");
final Integer fromPeriod = JdbcSupport.getInteger(rs, "ircdFromPeriod");
final Integer toPeriod = JdbcSupport.getInteger(rs, "ircdToPeriod");
final Integer periodTypeId = JdbcSupport.getInteger(rs, "ircdPeriodTypeId");
final EnumOptionData periodType = InterestRateChartEnumerations.periodType(periodTypeId);
final BigDecimal amountRangeFrom = rs.getBigDecimal("ircdAmountRangeFrom");
final BigDecimal amountRangeTo = rs.getBigDecimal("ircdAmountRangeTo");
final BigDecimal annualInterestRate = rs.getBigDecimal("ircdAnnualInterestRate");
// currency Slabs
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
// currency
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf,
currencyDisplaySymbol, currencyNameCode);
return InterestRateChartSlabData.instance(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency);
}
}
}
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface InterestRateChartSlabWritePlatformService {
CommandProcessingResult create(JsonCommand command);
CommandProcessingResult update(Long chartSlabId, Long interestChartId, JsonCommand command);
CommandProcessingResult deleteChartSlab(Long chartSlabId, Long interestRateChartId);
}
@@ -0,0 +1,105 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.LinkedHashMap;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartRepositoryWrapper;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabDataValidator;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabRepository;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.mifosplatform.portfolio.savings.domain.SavingsProductRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl implements InterestRateChartSlabWritePlatformService {
@SuppressWarnings("unused")
private final static Logger logger = LoggerFactory.getLogger(InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl.class);
@SuppressWarnings("unused")
private final PlatformSecurityContext context;
private final InterestRateChartSlabDataValidator interestRateChartSlabDataValidator;
@SuppressWarnings("unused")
private final InterestRateChartAssembler interestRateChartAssembler;
private final InterestRateChartSlabAssembler interestRateChartSlabAssembler;
@SuppressWarnings("unused")
private final InterestRateChartRepositoryWrapper interestRateChartRepository;
private final InterestRateChartSlabRepository chartSlabRepository;
@SuppressWarnings("unused")
private final SavingsProductRepository savingsProductRepository;
@Autowired
public InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context,
final InterestRateChartSlabDataValidator interestRateChartSlabDataValidator,
final InterestRateChartAssembler interestRateChartAssembler,
final InterestRateChartRepositoryWrapper interestRateChartRepository, final SavingsProductRepository savingsProductRepository,
final InterestRateChartSlabRepository chartSlabRepository,
final InterestRateChartSlabAssembler interestRateChartSlabAssembler) {
this.context = context;
this.interestRateChartSlabDataValidator = interestRateChartSlabDataValidator;
this.interestRateChartAssembler = interestRateChartAssembler;
this.interestRateChartRepository = interestRateChartRepository;
this.savingsProductRepository = savingsProductRepository;
this.chartSlabRepository = chartSlabRepository;
this.interestRateChartSlabAssembler = interestRateChartSlabAssembler;
}
@Override
@Transactional
public CommandProcessingResult create(JsonCommand command) {
this.interestRateChartSlabDataValidator.validateCreate(command.json());
final InterestRateChartSlab interestRateChartSlab = this.interestRateChartSlabAssembler.assembleFrom(command);
this.chartSlabRepository.saveAndFlush(interestRateChartSlab);
final Long interestRateChartId = interestRateChartSlab.getId();
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(interestRateChartId) //
.build();
}
@Override
@Transactional
public CommandProcessingResult update(Long chartSlabId, Long interestRateChartId, JsonCommand command) {
this.interestRateChartSlabDataValidator.validateUpdate(command.json());
final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
final InterestRateChartSlab updateChartSlabs = this.interestRateChartSlabAssembler.assembleFrom(chartSlabId,
interestRateChartId);
updateChartSlabs.update(command, changes);
this.chartSlabRepository.saveAndFlush(updateChartSlabs);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(interestRateChartId) //
.with(changes).build();
}
@Override
@Transactional
public CommandProcessingResult deleteChartSlab(Long chartSlabId, Long interestRateChartId) {
final InterestRateChartSlab deleteChartSlabs = this.interestRateChartSlabAssembler.assembleFrom(chartSlabId,
interestRateChartId);
this.chartSlabRepository.delete(deleteChartSlabs);
return new CommandProcessingResultBuilder() //
.withEntityId(chartSlabId) //
.build();
}
}
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface InterestRateChartWritePlatformService {
CommandProcessingResult create(JsonCommand command);
CommandProcessingResult update(Long interestChartId, JsonCommand command);
CommandProcessingResult deleteChart(Long interestChartId);
}
@@ -0,0 +1,92 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.interestratechart.service;
import java.util.LinkedHashMap;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartDataValidator;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartRepositoryWrapper;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class InterestRateChartWritePlatformServiceJpaRepositoryImpl implements InterestRateChartWritePlatformService {
@SuppressWarnings("unused")
private final static Logger logger = LoggerFactory.getLogger(InterestRateChartWritePlatformServiceJpaRepositoryImpl.class);
@SuppressWarnings("unused")
private final PlatformSecurityContext context;
private final InterestRateChartDataValidator interestRateChartDataValidator;
private final InterestRateChartAssembler interestRateChartAssembler;
private final InterestRateChartRepositoryWrapper interestRateChartRepository;
@Autowired
public InterestRateChartWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context,
final InterestRateChartDataValidator interestRateChartDataValidator,
final InterestRateChartAssembler interestRateChartAssembler,
final InterestRateChartRepositoryWrapper interestRateChartRepository) {
this.context = context;
this.interestRateChartDataValidator = interestRateChartDataValidator;
this.interestRateChartAssembler = interestRateChartAssembler;
this.interestRateChartRepository = interestRateChartRepository;
}
@Override
@Transactional
public CommandProcessingResult create(JsonCommand command) {
this.interestRateChartDataValidator.validateForCreate(command.json());
final InterestRateChart interestRateChart = this.interestRateChartAssembler.assembleFrom(command);
this.interestRateChartRepository.saveAndFlush(interestRateChart);
final Long interestRateChartId = interestRateChart.getId();
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(interestRateChartId) //
.build();
}
@Override
@Transactional
public CommandProcessingResult update(Long interestRateChartId, JsonCommand command) {
this.interestRateChartDataValidator.validateUpdate(command.json());
final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
final InterestRateChart interestRateChart = this.interestRateChartAssembler.assembleFrom(interestRateChartId);
interestRateChart.update(command, changes);
this.interestRateChartRepository.saveAndFlush(interestRateChart);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(interestRateChartId) //
.with(changes).build();
}
@Override
@Transactional
public CommandProcessingResult deleteChart(Long chartId) {
final InterestRateChart chart = this.interestRateChartRepository.findOneWithNotFoundDetection(chartId);
// validate if chart is associated with any accounts
this.interestRateChartRepository.delete(chart);
return new CommandProcessingResultBuilder() //
.withEntityId(chartId) //
.build();
}
}
@@ -1748,7 +1748,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(overdueInstallment.toString());
final JsonCommand command = JsonCommand.from(overdueInstallment.toString(), parsedCommand, this.fromApiJsonHelper,
null, null, null, null, null, overdueInstallment.getLoanId(), null, null, null, null);
null, null, null, null, null, overdueInstallment.getLoanId(), null, null, null, null, null, null);
applyChargeToOverdueLoanInstallment(overdueInstallment.getLoanId(), overdueInstallment.getChargeId(),
overdueInstallment.getPeriodNumber(), command);
@@ -0,0 +1,86 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.portfolio.savings.domain.FixedDepositAccount;
import org.mifosplatform.portfolio.savings.domain.RecurringDepositAccount;
/**
* An enumeration of different options available on account closure
* {@link FixedDepositAccount} & {@link RecurringDepositAccount}.
*/
public enum DepositAccountOnClosureType {
INVALID(0, "depositAccountClosureType.invalid"), //
WITHDRAW_DEPOSIT(100, "depositAccountClosureType.withdrawDeposit"), //
TRANSFER_TO_SAVINGS(200, "depositAccountClosureType.transferToSavings"), //
REINVEST(300, "depositAccountClosureType.reinvest"); //
private final Integer value;
private final String code;
private DepositAccountOnClosureType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public static DepositAccountOnClosureType fromInt(final Integer closureTypeValue) {
if (closureTypeValue == null) { return DepositAccountOnClosureType.INVALID; }
DepositAccountOnClosureType accountOnClosureType = DepositAccountOnClosureType.INVALID;
switch (closureTypeValue) {
case 100:
accountOnClosureType = DepositAccountOnClosureType.WITHDRAW_DEPOSIT;
break;
case 200:
accountOnClosureType = DepositAccountOnClosureType.TRANSFER_TO_SAVINGS;
break;
case 300:
accountOnClosureType = DepositAccountOnClosureType.REINVEST;
break;
}
return accountOnClosureType;
}
public boolean isWithdarwDeposit() {
return this.value.equals(DepositAccountOnClosureType.WITHDRAW_DEPOSIT.getValue());
}
public boolean isTransferToSavings() {
return this.value.equals(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getValue());
}
public boolean isReinvest() {
return this.value.equals(DepositAccountOnClosureType.REINVEST.getValue());
}
public boolean isInvalid() {
return this.value.equals(DepositAccountOnClosureType.INVALID.getValue());
}
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<Integer>();
for (final DepositAccountOnClosureType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
}
}
@@ -0,0 +1,108 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
/**
* An enumeration of different transactions that can occur on a
* {@link SavingsAccount}.
*/
public enum DepositAccountType {
INVALID(0, "depositAccountType.invalid"), //
SAVINGS_DEPOSIT(100, "depositAccountType.savingsDeposit"), //
FIXED_DEPOSIT(200, "depositAccountType.fixedDeposit"), //
RECURRING_DEPOSIT(300, "depositAccountType.recurringDeposit"), //
CURRENT_DEPOSIT(400, "depositAccountType.currentDeposit");
private final Integer value;
private final String code;
private static final String SPACE = " ";
private DepositAccountType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public static DepositAccountType fromInt(final Integer transactionType) {
if (transactionType == null) { return DepositAccountType.INVALID; }
DepositAccountType depositAccountType = DepositAccountType.INVALID;
switch (transactionType) {
case 100:
depositAccountType = DepositAccountType.SAVINGS_DEPOSIT;
break;
case 200:
depositAccountType = DepositAccountType.FIXED_DEPOSIT;
break;
case 300:
depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
break;
case 400:
depositAccountType = DepositAccountType.CURRENT_DEPOSIT;
break;
}
return depositAccountType;
}
public boolean isSavingsDeposit() {
return this.value.equals(DepositAccountType.SAVINGS_DEPOSIT.getValue());
}
public boolean isFixedDeposit() {
return this.value.equals(DepositAccountType.FIXED_DEPOSIT.getValue());
}
public boolean isRecurringDeposit() {
return this.value.equals(DepositAccountType.RECURRING_DEPOSIT.getValue());
}
public boolean isCurrentDeposit() {
return this.value.equals(DepositAccountType.CURRENT_DEPOSIT.getValue());
}
@Override
public String toString() {
return StringUtils.replace(code, "_", SPACE);
}
public String resourceName() {
String resourceName = "INVALID";
switch (this) {
case FIXED_DEPOSIT:
resourceName = DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME;
break;
case RECURRING_DEPOSIT:
resourceName = DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME;
break;
case SAVINGS_DEPOSIT:
resourceName = DepositsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
break;
default:
resourceName = "INVALID";
break;
}
return resourceName;
}
public boolean isInvalid() {
return this.value.equals(DepositAccountType.INVALID.value);
}
}
@@ -0,0 +1,357 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
public class DepositsApiConstants {
// Deposit products
public static final String FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME = "fixeddeposit";
public static final String RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME = "recurringdeposit";
// Deposti accounts
public static final String FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME = "fixeddepositaccount";
public static final String RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME = "recurringdepositaccount";
public static final String SAVINGS_ACCOUNT_RESOURCE_NAME = "savingsaccount";
public static final String SAVINGS_ACCOUNT_TRANSACTION_RESOURCE_NAME = "savingsaccount.transaction";
public static final String SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME = "savingsaccountcharge";
// deposit product actions
public static String summitalAction = ".summital";
public static String approvalAction = ".approval";
public static String undoApprovalAction = ".undoApproval";
public static String rejectAction = ".reject";
public static String withdrawnByApplicantAction = ".withdrawnByApplicant";
public static String activateAction = ".activate";
public static String modifyApplicationAction = ".modify";
public static String deleteApplicationAction = ".delete";
public static String undoTransactionAction = ".undotransaction";
public static String applyAnnualFeeTransactionAction = ".applyannualfee";
public static String adjustTransactionAction = ".adjusttransaction";
public static String closeAction = ".close";
public static String preMatureCloseAction = ".preMatureClose";
public static String payChargeTransactionAction = ".paycharge";
public static String waiveChargeTransactionAction = ".waivecharge";
// command
public static String COMMAND_UNDO_TRANSACTION = "undo";
public static String COMMAND_ADJUST_TRANSACTION = "modify";
public static String COMMAND_WAIVE_CHARGE = "waive";
public static String COMMAND_PAY_CHARGE = "paycharge";
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
public static final String monthDayFormatParamName = "monthDayFormat";
// deposit product and account parameters
public static final String idParamName = "id";
public static final String accountNoParamName = "accountNo";
public static final String externalIdParamName = "externalId";
public static final String statusParamName = "status";
public static final String clientIdParamName = "clientId";
public static final String groupIdParamName = "groupId";
public static final String productIdParamName = "productId";
public static final String fieldOfficerIdParamName = "fieldOfficerId";
public static final String submittedOnDateParamName = "submittedOnDate";
public static final String rejectedOnDateParamName = "rejectedOnDate";
public static final String withdrawnOnDateParamName = "withdrawnOnDate";
public static final String approvedOnDateParamName = "approvedOnDate";
public static final String activatedOnDateParamName = "activatedOnDate";
public static final String closedOnDateParamName = "closedOnDate";
public static final String activeParamName = "active";
public static final String nameParamName = "name";
public static final String shortNameParamName = "shortName";
public static final String descriptionParamName = "description";
public static final String currencyCodeParamName = "currencyCode";
public static final String digitsAfterDecimalParamName = "digitsAfterDecimal";
public static final String inMultiplesOfParamName = "inMultiplesOf";
public static final String nominalAnnualInterestRateParamName = "nominalAnnualInterestRate";
public static final String interestCompoundingPeriodTypeParamName = "interestCompoundingPeriodType";
public static final String interestPostingPeriodTypeParamName = "interestPostingPeriodType";
public static final String interestCalculationTypeParamName = "interestCalculationType";
public static final String interestCalculationDaysInYearTypeParamName = "interestCalculationDaysInYearType";
public static final String lockinPeriodFrequencyParamName = "lockinPeriodFrequency";
public static final String lockinPeriodFrequencyTypeParamName = "lockinPeriodFrequencyType";
public static final String feeAmountParamName = "feeAmount";// to be deleted
public static final String feeOnMonthDayParamName = "feeOnMonthDay";
public static final String feeIntervalParamName = "feeInterval";
public static final String accountingRuleParamName = "accountingRule";
public static final String paymentTypeIdParamName = "paymentTypeId";
public static final String transactionAccountNumberParamName = "accountNumber";
public static final String checkNumberParamName = "checkNumber";
public static final String routingCodeParamName = "routingCode";
public static final String receiptNumberParamName = "receiptNumber";
public static final String bankNumberParamName = "bankNumber";
// Preclosure parameters
public static final String interestFreePeriodApplicableParamName = "interestFreePeriodApplicable";
public static final String interestFreeFromPeriodParamName = "interestFreeFromPeriod";
public static final String interestFreeToPeriodParamName = "interestFreeToPeriod";
public static final String interestFreePeriodFrequencyTypeIdParamName = "interestFreePeriodFrequencyTypeId";
public static final String preClosurePenalApplicableParamName = "preClosurePenalApplicable";
public static final String preClosurePenalInterestParamName = "preClosurePenalInterest";
public static final String preClosurePenalInterestOnTypeIdParamName = "preClosurePenalInterestOnTypeId";
public static final String interestFreePeriodFrequencyType = "interestFreePeriodFrequencyType";
public static final String preClosurePenalInterestOnType = "preClosurePenalInterestOnType";
// term paramters
public static final String minDepositTermParamName = "minDepositTerm";
public static final String maxDepositTermParamName = "maxDepositTerm";
public static final String minDepositTermTypeIdParamName = "minDepositTermTypeId";
public static final String maxDepositTermTypeIdParamName = "maxDepositTermTypeId";
public static final String minDepositTermType = "minDepositTermType";
public static final String maxDepositTermType = "maxDepositTermType";
public static final String inMultiplesOfDepositTermParamName = "inMultiplesOfDepositTerm";
public static final String inMultiplesOfDepositTermTypeIdParamName = "inMultiplesOfDepositTermTypeId";
public static final String inMultiplesOfDepositTermType = "inMultiplesOfDepositTermType";
public static final String depositAmountParamName = "depositAmount";
public static final String depositPeriodParamName = "depositPeriod";
public static final String depositPeriodFrequencyIdParamName = "depositPeriodFrequencyId";
// recurring parameters
public static final String recurringDepositAmountParamName = "recurringDepositAmount";
public static final String recurringDepositType = "recurringDepositType";
public static final String recurringDepositFrequencyType = "recurringDepositFrequencyType";
public static final String recurringDepositFrequencyParamName = "recurringDepositFrequency";
public static final String recurringDepositTypeIdParamName = "recurringDepositTypeId";
public static final String recurringDepositFrequencyTypeIdParamName = "recurringDepositFrequencyTypeId";
// transaction parameters
public static final String transactionDateParamName = "transactionDate";
public static final String transactionAmountParamName = "transactionAmount";
public static final String paymentDetailDataParamName = "paymentDetailData";
public static final String runningBalanceParamName = "runningBalance";
public static final String reversedParamName = "reversed";
public static final String dateParamName = "date";
// charges parameters
public static final String chargeIdParamName = "chargeId";
public static final String chargesParamName = "charges";
public static final String savingsAccountChargeIdParamName = "savingsAccountChargeId";
public static final String chargeNameParamName = "name";
public static final String penaltyParamName = "penalty";
public static final String chargeTimeTypeParamName = "chargeTimeType";
public static final String dueAsOfDateParamName = "dueDate";
public static final String chargeCalculationTypeParamName = "chargeCalculationType";
public static final String percentageParamName = "percentage";
public static final String amountPercentageAppliedToParamName = "amountPercentageAppliedTo";
public static final String currencyParamName = "currency";
public static final String amountWaivedParamName = "amountWaived";
public static final String amountWrittenOffParamName = "amountWrittenOff";
public static final String amountOutstandingParamName = "amountOutstanding";
public static final String amountOrPercentageParamName = "amountOrPercentage";
public static final String amountParamName = "amount";
public static final String amountPaidParamName = "amountPaid";
public static final String chargeOptionsParamName = "chargeOptions";
public static final String chargePaymentModeParamName = "chargePaymentMode";
public static final String noteParamName = "note";
public static final String chartsParamName = "charts";
public static final String chartIdParamName = "chartId";
// deposit account associations
public static final String transactions = "transactions";
public static final String charges = "charges";
public static final String activeChart = "activeChart";
// account closure
public static final String onAccountClosureIdParamName = "onAccountClosureId";
public static final String transferDescriptionParamName = "transferDescription";
public static final String toSavingsAccountIdParamName = "toSavingsAccountId";
public static final String savingsAccounts = "savingsAccounts";
public static final String preMatureCloseOnDateParamName = "preMatureCloseOnDate";
// template
public static final String chartTemplate = "chartTemplate";
// allowed column names for sorting the query result
public final static Set<String> supportedOrderByValues = new HashSet<String>(Arrays.asList("id", "accountNumbr", "officeId",
"officeName"));
/**
* Deposit Product Parameters
*/
private static final Set<String> DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
monthDayFormatParamName, nameParamName, shortNameParamName, descriptionParamName, currencyCodeParamName,
digitsAfterDecimalParamName, inMultiplesOfParamName, nominalAnnualInterestRateParamName,
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
interestCalculationDaysInYearTypeParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
accountingRuleParamName, chargesParamName, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PENALTY_INCOME_ACCOUNT_MAPPING.getValue(), chartsParamName));
private static final Set<String> PRECLOSURE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
interestFreePeriodApplicableParamName, interestFreeFromPeriodParamName, interestFreeToPeriodParamName,
interestFreePeriodFrequencyTypeIdParamName, preClosurePenalApplicableParamName, preClosurePenalInterestParamName,
preClosurePenalInterestOnTypeIdParamName));
private static final Set<String> PRECLOSURE_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
interestFreePeriodApplicableParamName, interestFreeFromPeriodParamName, interestFreeToPeriodParamName,
interestFreePeriodFrequencyType, preClosurePenalApplicableParamName, preClosurePenalInterestParamName,
preClosurePenalInterestOnType));
private static final Set<String> DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
inMultiplesOfDepositTermTypeIdParamName));
private static final Set<String> DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
inMultiplesOfDepositTermType));
private static final Set<String> RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
recurringDepositFrequencyParamName));
private static final Set<String> RECURRING_DETAILS_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
recurringDepositAmountParamName, recurringDepositType, recurringDepositFrequencyParamName, recurringDepositFrequencyType));
public static final Set<String> DEPOSIT_PRECLOSURE_CALCULATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList(preMatureCloseOnDateParamName));
public static final Set<String> FIXED_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS = fixedDepositProductRequestData();
public static final Set<String> FIXED_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS = fixedDepositProductResponseData();
public static final Set<String> RECURRING_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS = recurringDepositProductRequestData();
public static final Set<String> RECURRING_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS = recurringDepositProductResponseData();
private static Set<String> fixedDepositProductRequestData() {
final Set<String> fixedDepositRequestData = new HashSet<String>();
fixedDepositRequestData.addAll(DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
return fixedDepositRequestData;
}
private static Set<String> fixedDepositProductResponseData() {
final Set<String> fixedDepositRequestData = new HashSet<String>();
fixedDepositRequestData.addAll(DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
fixedDepositRequestData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
return fixedDepositRequestData;
}
private static Set<String> recurringDepositProductRequestData() {
final Set<String> recurringDepositRequestData = new HashSet<String>();
recurringDepositRequestData.addAll(DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(RECURRING_DETAILS_REQUEST_DATA_PARAMETERS);
return recurringDepositRequestData;
}
private static Set<String> recurringDepositProductResponseData() {
final Set<String> recurringDepositRequestData = new HashSet<String>();
recurringDepositRequestData.addAll(DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
recurringDepositRequestData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
recurringDepositRequestData.addAll(RECURRING_DETAILS_RESPONSE_DATA_PARAMETERS);
return recurringDepositRequestData;
}
/**
* Depost Account parameters
*/
public static final Set<String> DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, monthDayFormatParamName, accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName,
productIdParamName, fieldOfficerIdParamName, submittedOnDateParamName, nominalAnnualInterestRateParamName,
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
interestCalculationDaysInYearTypeParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
chargesParamName, chartsParamName, depositAmountParamName, depositPeriodParamName, depositPeriodFrequencyIdParamName,
savingsAccounts));
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS = fixedDepositAccountRequestData();
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS = fixedDepositAccountResponseData();
public static final Set<String> RECURRING_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS = recurringDepositAccountRequestData();
public static final Set<String> RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS = recurringDepositAccountResponseData();
private static Set<String> fixedDepositAccountRequestData() {
final Set<String> fixedDepositRequestData = new HashSet<String>();
fixedDepositRequestData.addAll(DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
return fixedDepositRequestData;
}
private static Set<String> fixedDepositAccountResponseData() {
final Set<String> fixedDepositResponseData = new HashSet<String>();
fixedDepositResponseData.addAll(DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
fixedDepositResponseData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
fixedDepositResponseData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
return fixedDepositResponseData;
}
private static Set<String> recurringDepositAccountRequestData() {
final Set<String> recurringDepositRequestData = new HashSet<String>();
recurringDepositRequestData.addAll(DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(PRECLOSURE_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(DEPOSIT_TERM_REQUEST_DATA_PARAMETERS);
recurringDepositRequestData.addAll(RECURRING_DETAILS_REQUEST_DATA_PARAMETERS);
return recurringDepositRequestData;
}
private static Set<String> recurringDepositAccountResponseData() {
final Set<String> recurringDepositResponseData = new HashSet<String>();
recurringDepositResponseData.addAll(DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
recurringDepositResponseData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
recurringDepositResponseData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
recurringDepositResponseData.addAll(RECURRING_DETAILS_RESPONSE_DATA_PARAMETERS);
return recurringDepositResponseData;
}
public static final Set<String> DEPOSIT_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName, paymentTypeIdParamName,
transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
public static final Set<String> FIXED_DEPOSIT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
"accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName, runningBalanceParamName,
reversedParamName));
public static final Set<String> RECURRING_DEPOSIT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
"accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName, runningBalanceParamName,
reversedParamName));
public static final Set<String> SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, activatedOnDateParamName));
public static final Set<String> DEPOSIT_ACCOUNT_CLOSE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, closedOnDateParamName, noteParamName, onAccountClosureIdParamName, paymentTypeIdParamName,
transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName,
transferDescriptionParamName, toSavingsAccountIdParamName));
public static final Set<String> DEPOSIT_ACCOUNT_PRE_MATURE_CALCULATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
localeParamName, dateFormatParamName, closedOnDateParamName));
public static final Set<String> SAVINGS_ACCOUNT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(chargeIdParamName,
savingsAccountChargeIdParamName, chargeNameParamName, penaltyParamName, chargeTimeTypeParamName, dueAsOfDateParamName,
chargeCalculationTypeParamName, percentageParamName, amountPercentageAppliedToParamName, currencyParamName,
amountWaivedParamName, amountWrittenOffParamName, amountOutstandingParamName, amountOrPercentageParamName, amountParamName,
amountPaidParamName, chargeOptionsParamName));
public static final Set<String> SAVINGS_ACCOUNT_CHARGES_ADD_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
chargeIdParamName, amountParamName, dueAsOfDateParamName, dateFormatParamName, localeParamName, feeOnMonthDayParamName,
monthDayFormatParamName, feeIntervalParamName));
public static final Set<String> SAVINGS_ACCOUNT_CHARGES_PAY_CHARGE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
amountParamName, dueAsOfDateParamName, dateFormatParamName, localeParamName));
}
@@ -0,0 +1,74 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings;
import java.util.ArrayList;
import java.util.List;
/**
* An enumeration of supported calendar periods used in savings.
*/
public enum PreClosurePenalInterestOnType {
INVALID(0, "preClosurePenalInterestOnType.invalid"),
WHOLE_TERM(1, "preClosurePenalInterestOnType.wholeTerm"), //
TILL_PREMATURE_WITHDRAWAL(2, "preClosurePenalInterestOnType.tillPrematureWithdrawal"); //
private final Integer value;
private final String code;
private PreClosurePenalInterestOnType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public static PreClosurePenalInterestOnType fromInt(final Integer type) {
PreClosurePenalInterestOnType penalInterestType = PreClosurePenalInterestOnType.INVALID;
if (type != null) {
switch (type) {
case 1:
penalInterestType = PreClosurePenalInterestOnType.WHOLE_TERM;
break;
case 2:
penalInterestType = PreClosurePenalInterestOnType.TILL_PREMATURE_WITHDRAWAL;
break;
}
}
return penalInterestType;
}
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<Integer>();
for (final PreClosurePenalInterestOnType enumType : values()) {
if (enumType.getValue() > 0) {
values.add(enumType.getValue());
}
}
return values.toArray();
}
public boolean isInvalid(){
return this.value.equals(PreClosurePenalInterestOnType.INVALID.value);
}
public boolean isWholeTerm() {
return this.value.equals(PreClosurePenalInterestOnType.WHOLE_TERM.getValue());
}
public boolean isTillPrematureWithdrawal() {
return this.value.equals(PreClosurePenalInterestOnType.TILL_PREMATURE_WITHDRAWAL.getValue());
}
}
@@ -0,0 +1,66 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings;
import java.util.ArrayList;
import java.util.List;
/**
* An enumeration of supported calendar periods used in savings.
*/
public enum RecurringDepositType {
INVALID(0, "recurringDepositType.invalid"),
VOLUNTARY(1, "recurringDepositType.voluntary"), //
MANDATORY(2, "recurringDepositType.mandatory"); //
private final Integer value;
private final String code;
private RecurringDepositType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public static RecurringDepositType fromInt(final Integer type) {
RecurringDepositType rdType = RecurringDepositType.INVALID;
if (type != null) {
switch (type) {
case 1:
rdType = RecurringDepositType.VOLUNTARY;
break;
case 2:
rdType = RecurringDepositType.MANDATORY;
break;
}
}
return rdType;
}
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<Integer>();
for (final RecurringDepositType enumType : values()) {
if (enumType.getValue() > 0) {
values.add(enumType.getValue());
}
}
return values.toArray();
}
public boolean isInvalid(){
return this.value.equals(RecurringDepositType.INVALID.value);
}
}
@@ -35,6 +35,7 @@ public class SavingsApiConstants {
public static String closeAction = ".close";
public static String payChargeTransactionAction = ".paycharge";
public static String waiveChargeTransactionAction = ".waivecharge";
public static String updateMaturityDetailsAction = ".updateMaturityDetails";
// command
public static String COMMAND_UNDO_TRANSACTION = "undo";
@@ -5,6 +5,9 @@
*/
package org.mifosplatform.portfolio.savings;
import java.util.ArrayList;
import java.util.List;
/**
* An enumeration of supported calendar periods used in savings.
*/
@@ -51,4 +54,19 @@ public enum SavingsPeriodFrequencyType {
}
return repaymentFrequencyType;
}
public boolean isInvalid() {
return this.value.equals(SavingsPeriodFrequencyType.INVALID.value);
}
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<Integer>();
for (final SavingsPeriodFrequencyType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
}
}
@@ -0,0 +1,173 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
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.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/fixeddepositaccounts/{fixedDepositAccountId}/transactions")
@Component
@Scope("singleton")
public class FixedDepositAccountTransactionsApiResource {
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
@Autowired
public FixedDepositAccountTransactionsApiResource(final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@PathParam("fixedDepositAccountId") final Long fixedDepositAccountId,
// @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService.retrieveDepositTransactionTemplate(
fixedDepositAccountId, DepositAccountType.FIXED_DEPOSIT);
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
savingsAccount = SavingsAccountTransactionData.templateOnTop(savingsAccount, paymentTypeOptions);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("fixedDepositAccountId") final Long fixedDepositAccountId,
@PathParam("transactionId") final Long transactionId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
SavingsAccountTransactionData transactionData = this.savingsAccountReadPlatformService.retrieveSavingsTransaction(
fixedDepositAccountId, transactionId, DepositAccountType.FIXED_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
transactionData = SavingsAccountTransactionData.templateOnTop(transactionData, paymentTypeOptions);
}
return this.toApiJsonSerializer.serialize(settings, transactionData,
DepositsApiConstants.FIXED_DEPOSIT_TRANSACTION_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String transaction(@PathParam("fixedDepositAccountId") final Long fixedDepositAccountId,
@QueryParam("command") final String commandParam, final String apiRequestBodyAsJson) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
if (is(commandParam, "deposit")) {
final CommandWrapper commandRequest = builder.fixedDepositAccountDeposit(fixedDepositAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawal")) {
final CommandWrapper commandRequest = builder.fixedDepositAccountWithdrawal(fixedDepositAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
//
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "deposit", "withdrawal" });
}
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String adjustTransaction(@PathParam("fixedDepositAccountId") final Long fixedDepositAccountId,
@PathParam("transactionId") final Long transactionId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson) {
String jsonApiRequest = apiRequestBodyAsJson;
if (StringUtils.isBlank(jsonApiRequest)) {
jsonApiRequest = "{}";
}
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
CommandProcessingResult result = null;
if (is(commandParam, DepositsApiConstants.COMMAND_UNDO_TRANSACTION)) {
final CommandWrapper commandRequest = builder.undoSavingsAccountTransaction(fixedDepositAccountId, transactionId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, DepositsApiConstants.COMMAND_ADJUST_TRANSACTION)) {
final CommandWrapper commandRequest = builder.adjustSavingsAccountTransaction(fixedDepositAccountId, transactionId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
//
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "undo", "modify" });
}
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,318 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.api.JsonQuery;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.DepositAccountData;
import org.mifosplatform.portfolio.savings.data.FixedDepositAccountData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
import org.mifosplatform.portfolio.savings.service.DepositAccountPreMatureCalculationPlatformService;
import org.mifosplatform.portfolio.savings.service.DepositAccountReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsAccountChargeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.google.gson.JsonElement;
@Path("/fixeddepositaccounts")
@Component
@Scope("singleton")
public class FixedDepositAccountsApiResource {
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<DepositAccountData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final SavingsAccountChargeReadPlatformService savingsAccountChargeReadPlatformService;
private final FromJsonHelper fromJsonHelper;
private final DepositAccountPreMatureCalculationPlatformService accountPreMatureCalculationPlatformService;
@Autowired
public FixedDepositAccountsApiResource(final DepositAccountReadPlatformService depositAccountReadPlatformService,
final PlatformSecurityContext context, final DefaultToApiJsonSerializer<DepositAccountData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final SavingsAccountChargeReadPlatformService savingsAccountChargeReadPlatformService, final FromJsonHelper fromJsonHelper,
final DepositAccountPreMatureCalculationPlatformService accountPreMatureCalculationPlatformService) {
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.savingsAccountChargeReadPlatformService = savingsAccountChargeReadPlatformService;
this.fromJsonHelper = fromJsonHelper;
this.accountPreMatureCalculationPlatformService = accountPreMatureCalculationPlatformService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
@QueryParam("productId") final Long productId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final DepositAccountData account = this.depositAccountReadPlatformService.retrieveTemplate(DepositAccountType.FIXED_DEPOSIT,
clientId, groupId, productId, staffInSelectedOfficeOnly);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account, DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("paged") final Boolean paged,
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final PaginationParameters paginationParameters = PaginationParameters.instance(paged, offset, limit, orderBy, sortOrder);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (paginationParameters.isPaged()) {
final Page<DepositAccountData> account = this.depositAccountReadPlatformService.retrieveAllPaged(
DepositAccountType.FIXED_DEPOSIT, paginationParameters);
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
final Collection<DepositAccountData> account = this.depositAccountReadPlatformService.retrieveAll(DepositAccountType.FIXED_DEPOSIT,
paginationParameters);
return this.toApiJsonSerializer.serialize(settings, account, DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String submitApplication(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createFixedDepositAccount().withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("accountId") final Long accountId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final FixedDepositAccountData account = (FixedDepositAccountData) this.depositAccountReadPlatformService.retrieveOneWithChartSlabs(
DepositAccountType.FIXED_DEPOSIT, accountId);
final Set<String> mandatoryResponseParameters = new HashSet<String>();
final FixedDepositAccountData accountTemplate = populateTemplateAndAssociations(accountId, account, staffInSelectedOfficeOnly,
uriInfo, mandatoryResponseParameters);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
mandatoryResponseParameters);
return this.toApiJsonSerializer.serialize(settings, accountTemplate,
DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
private FixedDepositAccountData populateTemplateAndAssociations(final Long accountId, final FixedDepositAccountData savingsAccount,
final boolean staffInSelectedOfficeOnly, final UriInfo uriInfo, final Set<String> mandatoryResponseParameters) {
Collection<SavingsAccountTransactionData> transactions = null;
Collection<SavingsAccountChargeData> charges = null;
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
if (!associationParameters.isEmpty()) {
if (associationParameters.contains("all")) {
associationParameters.addAll(Arrays.asList(SavingsApiConstants.transactions, SavingsApiConstants.charges));
}
if (associationParameters.contains(SavingsApiConstants.transactions)) {
mandatoryResponseParameters.add(SavingsApiConstants.transactions);
final Collection<SavingsAccountTransactionData> currentTransactions = this.depositAccountReadPlatformService
.retrieveAllTransactions(DepositAccountType.FIXED_DEPOSIT, accountId);
if (!CollectionUtils.isEmpty(currentTransactions)) {
transactions = currentTransactions;
}
}
if (associationParameters.contains(SavingsApiConstants.charges)) {
mandatoryResponseParameters.add(SavingsApiConstants.charges);
final Collection<SavingsAccountChargeData> currentCharges = this.savingsAccountChargeReadPlatformService
.retrieveSavingsAccountCharges(accountId);
if (!CollectionUtils.isEmpty(currentCharges)) {
charges = currentCharges;
}
}
}
FixedDepositAccountData templateData = null;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
templateData = (FixedDepositAccountData) this.depositAccountReadPlatformService.retrieveTemplate(
DepositAccountType.FIXED_DEPOSIT, savingsAccount.clientId(), savingsAccount.groupId(), savingsAccount.productId(),
staffInSelectedOfficeOnly);
}
return FixedDepositAccountData.withTemplateOptions(savingsAccount, templateData, transactions, charges);
}
@PUT
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateFixedDepositAccount(accountId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleCommands(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo, final String apiRequestBodyAsJson) {
String jsonApiRequest = apiRequestBodyAsJson;
if (StringUtils.isBlank(jsonApiRequest)) {
jsonApiRequest = "{}";
}
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
CommandProcessingResult result = null;
if (is(commandParam, "reject")) {
final CommandWrapper commandRequest = builder.rejectFixedDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawnByApplicant")) {
final CommandWrapper commandRequest = builder.withdrawFixedDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "approve")) {
final CommandWrapper commandRequest = builder.approveFixedDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "undoapproval")) {
final CommandWrapper commandRequest = builder.undoFixedDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "activate")) {
final CommandWrapper commandRequest = builder.fixedDepositAccountActivation(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "calculateInterest")) {
final CommandWrapper commandRequest = builder.withNoJsonBody().fixedDepositAccountInterestCalculation(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "postInterest")) {
final CommandWrapper commandRequest = builder.fixedDepositAccountInterestPosting(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "close")) {
final CommandWrapper commandRequest = builder.closeFixedDepositAccount(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "prematureClose")) {
final CommandWrapper commandRequest = builder.prematureCloseFixedDepositAccount(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "calculatePrematureAmount")) {
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
final DepositAccountData account = this.accountPreMatureCalculationPlatformService.calculatePreMatureAmount(accountId, query,
DepositAccountType.FIXED_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "reject",
"withdrawnByApplicant", "approve", "undoapproval", "activate", "calculateInterest", "postInterest", "close",
"prematureClose", "calculatePrematureAmount" }); }
return this.toApiJsonSerializer.serialize(result);
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
@DELETE
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("accountId") final Long accountId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteFixedDepositAccount(accountId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{accountId}/template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String accountClosureTemplate(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
DepositAccountData account = null;
if (is(commandParam, "close")) {
account = this.depositAccountReadPlatformService.retrieveOneWithClosureTemplate(DepositAccountType.FIXED_DEPOSIT, accountId);
}
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account, DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
}
@@ -0,0 +1,316 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService;
import org.mifosplatform.accounting.common.AccountingEnumerations;
import org.mifosplatform.accounting.common.AccountingRuleType;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
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.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartReadPlatformService;
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.data.FixedDepositProductData;
import org.mifosplatform.portfolio.savings.service.DepositProductReadPlatformService;
import org.mifosplatform.portfolio.savings.service.DepositsDropdownReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Path("/fixeddepositproducts")
@Component
@Scope("singleton")
public class FixedDepositProductsApiResource {
private final DepositProductReadPlatformService depositProductReadPlatformService;
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
private final CurrencyReadPlatformService currencyReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<FixedDepositProductData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
private final ChargeReadPlatformService chargeReadPlatformService;
private final InterestRateChartReadPlatformService chartReadPlatformService;
private final InterestRateChartReadPlatformService interestRateChartReadPlatformService;
private final DepositsDropdownReadPlatformService depositsDropdownReadPlatformService;
@Autowired
public FixedDepositProductsApiResource(final DepositProductReadPlatformService depositProductReadPlatformService,
final SavingsDropdownReadPlatformService dropdownReadPlatformService,
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<FixedDepositProductData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper, final CodeValueReadPlatformService codeValueReadPlatformService,
final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService,
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService,
final ChargeReadPlatformService chargeReadPlatformService, final InterestRateChartReadPlatformService chartReadPlatformService,
final InterestRateChartReadPlatformService interestRateChartReadPlatformService,
final DepositsDropdownReadPlatformService depositsDropdownReadPlatformService) {
this.depositProductReadPlatformService = depositProductReadPlatformService;
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.currencyReadPlatformService = currencyReadPlatformService;
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.chartReadPlatformService = chartReadPlatformService;
this.interestRateChartReadPlatformService = interestRateChartReadPlatformService;
this.depositsDropdownReadPlatformService = depositsDropdownReadPlatformService;
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String create(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createFixedDepositProduct().withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateFixedDepositProduct(productId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<FixedDepositProductData> products = (Collection) this.depositProductReadPlatformService
.retrieveAll(DepositAccountType.FIXED_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, products, DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
FixedDepositProductData fixedDepositProductData = (FixedDepositProductData) this.depositProductReadPlatformService.retrieveOne(
DepositAccountType.FIXED_DEPOSIT, productId);
final Collection<ChargeData> charges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
fixedDepositProductData = FixedDepositProductData.withCharges(fixedDepositProductData, charges);
final Collection<InterestRateChartData> charts = this.chartReadPlatformService.retrieveAllWithSlabsWithTemplate(productId);
fixedDepositProductData = FixedDepositProductData.withInterestChart(fixedDepositProductData, charts);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (fixedDepositProductData.hasAccountingEnabled()) {
final Map<String, Object> accountingMappings = this.accountMappingReadPlatformService
.fetchAccountMappingDetailsForSavingsProduct(productId, fixedDepositProductData.accountingRuleTypeId());
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = this.accountMappingReadPlatformService
.fetchPaymentTypeToFundSourceMappingsForSavingsProduct(productId);
Collection<ChargeToGLAccountMapper> feeToGLAccountMappings = this.accountMappingReadPlatformService
.fetchFeeToIncomeAccountMappingsForSavingsProduct(productId);
Collection<ChargeToGLAccountMapper> penaltyToGLAccountMappings = this.accountMappingReadPlatformService
.fetchPenaltyToIncomeAccountMappingsForSavingsProduct(productId);
fixedDepositProductData = FixedDepositProductData.withAccountingDetails(fixedDepositProductData, accountingMappings,
paymentChannelToFundSourceMappings, feeToGLAccountMappings, penaltyToGLAccountMappings);
}
if (settings.isTemplate()) {
fixedDepositProductData = handleTemplateRelatedData(fixedDepositProductData);
}
return this.toApiJsonSerializer.serialize(settings, fixedDepositProductData,
DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
final FixedDepositProductData fixedDepositProduct = handleTemplateRelatedData(null);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, fixedDepositProduct,
DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
private FixedDepositProductData handleTemplateRelatedData(final FixedDepositProductData savingsProduct) {
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
final EnumOptionData interestPostingPeriodType = SavingsEnumerations
.interestPostingPeriodType(SavingsPostingInterestPeriodType.MONTHLY);
final EnumOptionData interestCalculationType = SavingsEnumerations
.interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE);
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.DAYS_365);
final EnumOptionData accountingRule = AccountingEnumerations.accountingRuleType(AccountingRuleType.NONE);
CurrencyData currency = CurrencyData.blank();
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
if (currencyOptions.size() == 1) {
currency = new ArrayList<CurrencyData>(currencyOptions).get(0);
}
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveCompoundingInterestPeriodTypeOptions();
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveInterestPostingPeriodTypeOptions();
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationTypeOptions();
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationDaysInYearTypeOptions();
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
.retrieveLockinPeriodFrequencyTypeOptions();
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
final Collection<EnumOptionData> accountingRuleOptions = this.accountingDropdownReadPlatformService
.retrieveAccountingRuleTypeOptions();
final Map<String, List<GLAccountData>> accountingMappingOptions = this.accountingDropdownReadPlatformService
.retrieveAccountMappingOptionsForSavingsProducts();
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = this.depositsDropdownReadPlatformService
.retrievePreClosurePenalInterestOnTypeOptions();
final Collection<EnumOptionData> interestFreePeriodTypeOptions = this.depositsDropdownReadPlatformService
.retrieveInterestFreePeriodFrequencyTypeOptions();
final Collection<EnumOptionData> depositTermTypeOptions = this.depositsDropdownReadPlatformService.retrieveDepositTermTypeOptions();
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = this.depositsDropdownReadPlatformService
.retrieveInMultiplesOfDepositTermTypeOptions();
// charges
final boolean feeChargesOnly = true;
Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveSavingsAccountApplicableCharges(feeChargesOnly);
chargeOptions = CollectionUtils.isEmpty(chargeOptions) ? null : chargeOptions;
Collection<ChargeData> penaltyOptions = this.chargeReadPlatformService.retrieveSavingsAccountApplicablePenalties();
penaltyOptions = CollectionUtils.isEmpty(penaltyOptions) ? null : penaltyOptions;
// interest rate chart template
final InterestRateChartData chartTemplate = this.interestRateChartReadPlatformService.template();
FixedDepositProductData fixedDepositProductToReturn = null;
if (savingsProduct != null) {
fixedDepositProductToReturn = FixedDepositProductData.withTemplate(savingsProduct, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, chargeOptions, penaltyOptions, chartTemplate,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions);
} else {
fixedDepositProductToReturn = FixedDepositProductData.template(currency, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, accountingRule, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, chargeOptions, penaltyOptions, chartTemplate,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions);
}
return fixedDepositProductToReturn;
}
@DELETE
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("productId") final Long productId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteFixedDepositProduct(productId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,185 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
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.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
import org.mifosplatform.portfolio.savings.service.DepositAccountReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/recurringdepositaccounts/{recurringDepositAccountId}/transactions")
@Component
@Scope("singleton")
public class RecurringDepositAccountTransactionsApiResource {
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
@Autowired
public RecurringDepositAccountTransactionsApiResource(final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
final DepositAccountReadPlatformService depositAccountReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@PathParam("recurringDepositAccountId") final Long recurringDepositAccountId,
@QueryParam("command") final String commandParam, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
SavingsAccountTransactionData savingsAccount = null;
if (is(commandParam, "deposit")) {
savingsAccount = this.depositAccountReadPlatformService
.retrieveRecurringAccountDepositTransactionTemplate(recurringDepositAccountId);
} else if (is(commandParam, "withdrawal")) {
} else {
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "deposit", "withdrawal" });
}
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
savingsAccount = SavingsAccountTransactionData.templateOnTop(savingsAccount, paymentTypeOptions);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("recurringDepositAccountId") final Long recurringDepositAccountId,
@PathParam("transactionId") final Long transactionId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
SavingsAccountTransactionData transactionData = this.savingsAccountReadPlatformService.retrieveSavingsTransaction(
recurringDepositAccountId, transactionId, DepositAccountType.RECURRING_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
transactionData = SavingsAccountTransactionData.templateOnTop(transactionData, paymentTypeOptions);
}
return this.toApiJsonSerializer.serialize(settings, transactionData,
DepositsApiConstants.FIXED_DEPOSIT_TRANSACTION_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String transaction(@PathParam("recurringDepositAccountId") final Long recurringDepositAccountId,
@QueryParam("command") final String commandParam, final String apiRequestBodyAsJson) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
if (is(commandParam, "deposit")) {
final CommandWrapper commandRequest = builder.recurringAccountDeposit(recurringDepositAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawal")) {
final CommandWrapper commandRequest = builder.recurringAccountWithdrawal(recurringDepositAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
//
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "deposit", "withdrawal" });
}
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleTransactionCommands(@PathParam("recurringDepositAccountId") final Long recurringDepositAccountId,
@PathParam("transactionId") final Long transactionId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson) {
String jsonApiRequest = apiRequestBodyAsJson;
if (StringUtils.isBlank(jsonApiRequest)) {
jsonApiRequest = "{}";
}
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
CommandProcessingResult result = null;
if (is(commandParam, DepositsApiConstants.COMMAND_UNDO_TRANSACTION)) {
final CommandWrapper commandRequest = builder.undoSavingsAccountTransaction(recurringDepositAccountId, transactionId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, DepositsApiConstants.COMMAND_ADJUST_TRANSACTION)) {
final CommandWrapper commandRequest = builder.adjustRecurringAccountTransaction(recurringDepositAccountId, transactionId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
//
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "undo", "modify" });
}
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,324 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.api.JsonQuery;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.DepositAccountData;
import org.mifosplatform.portfolio.savings.data.RecurringDepositAccountData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
import org.mifosplatform.portfolio.savings.service.DepositAccountPreMatureCalculationPlatformService;
import org.mifosplatform.portfolio.savings.service.DepositAccountReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsAccountChargeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.google.gson.JsonElement;
@Path("/recurringdepositaccounts")
@Component
@Scope("singleton")
public class RecurringDepositAccountsApiResource {
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<DepositAccountData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final SavingsAccountChargeReadPlatformService savingsAccountChargeReadPlatformService;
private final FromJsonHelper fromJsonHelper;
private final DepositAccountPreMatureCalculationPlatformService accountPreMatureCalculationPlatformService;
@Autowired
public RecurringDepositAccountsApiResource(final DepositAccountReadPlatformService depositAccountReadPlatformService,
final PlatformSecurityContext context, final DefaultToApiJsonSerializer<DepositAccountData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final SavingsAccountChargeReadPlatformService savingsAccountChargeReadPlatformService, final FromJsonHelper fromJsonHelper,
final DepositAccountPreMatureCalculationPlatformService accountPreMatureCalculationPlatformService) {
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.savingsAccountChargeReadPlatformService = savingsAccountChargeReadPlatformService;
this.fromJsonHelper = fromJsonHelper;
this.accountPreMatureCalculationPlatformService = accountPreMatureCalculationPlatformService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
@QueryParam("productId") final Long productId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final DepositAccountData account = this.depositAccountReadPlatformService.retrieveTemplate(DepositAccountType.RECURRING_DEPOSIT,
clientId, groupId, productId, staffInSelectedOfficeOnly);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("paged") final Boolean paged,
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final PaginationParameters paginationParameters = PaginationParameters.instance(paged, offset, limit, orderBy, sortOrder);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (paginationParameters.isPaged()) {
final Page<DepositAccountData> account = this.depositAccountReadPlatformService.retrieveAllPaged(
DepositAccountType.RECURRING_DEPOSIT, paginationParameters);
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
final Collection<DepositAccountData> account = this.depositAccountReadPlatformService.retrieveAll(
DepositAccountType.RECURRING_DEPOSIT, paginationParameters);
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String submitApplication(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createRecurringDepositAccount().withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("accountId") final Long accountId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final RecurringDepositAccountData account = (RecurringDepositAccountData) this.depositAccountReadPlatformService
.retrieveOneWithChartSlabs(DepositAccountType.RECURRING_DEPOSIT, accountId);
final Set<String> mandatoryResponseParameters = new HashSet<String>();
final RecurringDepositAccountData accountTemplate = populateTemplateAndAssociations(accountId, account, staffInSelectedOfficeOnly,
uriInfo, mandatoryResponseParameters);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
mandatoryResponseParameters);
return this.toApiJsonSerializer.serialize(settings, accountTemplate,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
private RecurringDepositAccountData populateTemplateAndAssociations(final Long accountId,
final RecurringDepositAccountData savingsAccount, final boolean staffInSelectedOfficeOnly, final UriInfo uriInfo,
final Set<String> mandatoryResponseParameters) {
Collection<SavingsAccountTransactionData> transactions = null;
Collection<SavingsAccountChargeData> charges = null;
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
if (!associationParameters.isEmpty()) {
if (associationParameters.contains("all")) {
associationParameters.addAll(Arrays.asList(SavingsApiConstants.transactions, SavingsApiConstants.charges));
}
if (associationParameters.contains(SavingsApiConstants.transactions)) {
mandatoryResponseParameters.add(SavingsApiConstants.transactions);
final Collection<SavingsAccountTransactionData> currentTransactions = this.depositAccountReadPlatformService
.retrieveAllTransactions(DepositAccountType.RECURRING_DEPOSIT, accountId);
if (!CollectionUtils.isEmpty(currentTransactions)) {
transactions = currentTransactions;
}
}
if (associationParameters.contains(SavingsApiConstants.charges)) {
mandatoryResponseParameters.add(SavingsApiConstants.charges);
final Collection<SavingsAccountChargeData> currentCharges = this.savingsAccountChargeReadPlatformService
.retrieveSavingsAccountCharges(accountId);
if (!CollectionUtils.isEmpty(currentCharges)) {
charges = currentCharges;
}
}
}
RecurringDepositAccountData templateData = null;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
templateData = (RecurringDepositAccountData) this.depositAccountReadPlatformService.retrieveTemplate(
DepositAccountType.RECURRING_DEPOSIT, savingsAccount.clientId(), savingsAccount.groupId(), savingsAccount.productId(),
staffInSelectedOfficeOnly);
}
return RecurringDepositAccountData.withTemplateOptions(savingsAccount, templateData, transactions, charges);
}
@PUT
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRecurringDepositAccount(accountId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleCommands(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo, final String apiRequestBodyAsJson) {
String jsonApiRequest = apiRequestBodyAsJson;
if (StringUtils.isBlank(jsonApiRequest)) {
jsonApiRequest = "{}";
}
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
CommandProcessingResult result = null;
if (is(commandParam, "reject")) {
final CommandWrapper commandRequest = builder.rejectRecurringDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawnByApplicant")) {
final CommandWrapper commandRequest = builder.withdrawRecurringDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "approve")) {
final CommandWrapper commandRequest = builder.approveRecurringDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "undoapproval")) {
final CommandWrapper commandRequest = builder.undoRecurringDepositAccountApplication(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "activate")) {
final CommandWrapper commandRequest = builder.recurringDepositAccountActivation(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "calculateInterest")) {
final CommandWrapper commandRequest = builder.withNoJsonBody().recurringDepositAccountInterestCalculation(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "postInterest")) {
final CommandWrapper commandRequest = builder.recurringDepositAccountInterestPosting(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "close")) {
final CommandWrapper commandRequest = builder.closeRecurringDepositAccount(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "prematureClose")) {
final CommandWrapper commandRequest = builder.prematureCloseRecurringDepositAccount(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "calculatePrematureAmount")) {
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
final DepositAccountData account = this.accountPreMatureCalculationPlatformService.calculatePreMatureAmount(accountId, query,
DepositAccountType.RECURRING_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "reject",
"withdrawnByApplicant", "approve", "undoapproval", "activate", "calculateInterest", "postInterest", "close",
"prematureClose", "calculatePrematureAmount" }); }
return this.toApiJsonSerializer.serialize(result);
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
@DELETE
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("accountId") final Long accountId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteRecurringDepositAccount(accountId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{accountId}/template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String accountClosureTemplate(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
DepositAccountData account = null;
if (is(commandParam, "close")) {
account = this.depositAccountReadPlatformService
.retrieveOneWithClosureTemplate(DepositAccountType.RECURRING_DEPOSIT, accountId);
}
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, account,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS);
}
}
@@ -0,0 +1,318 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService;
import org.mifosplatform.accounting.common.AccountingEnumerations;
import org.mifosplatform.accounting.common.AccountingRuleType;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
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.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartReadPlatformService;
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.data.RecurringDepositProductData;
import org.mifosplatform.portfolio.savings.service.DepositProductReadPlatformService;
import org.mifosplatform.portfolio.savings.service.DepositsDropdownReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Path("/recurringdepositproducts")
@Component
@Scope("singleton")
public class RecurringDepositProductsApiResource {
private final DepositProductReadPlatformService depositProductReadPlatformService;
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
private final CurrencyReadPlatformService currencyReadPlatformService;
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<RecurringDepositProductData> toApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
private final ChargeReadPlatformService chargeReadPlatformService;
private final InterestRateChartReadPlatformService chartReadPlatformService;
private final InterestRateChartReadPlatformService interestRateChartReadPlatformService;
private final DepositsDropdownReadPlatformService depositsDropdownReadPlatformService;
@Autowired
public RecurringDepositProductsApiResource(final DepositProductReadPlatformService depositProductReadPlatformService,
final SavingsDropdownReadPlatformService dropdownReadPlatformService,
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<RecurringDepositProductData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper, final CodeValueReadPlatformService codeValueReadPlatformService,
final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService,
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService,
final ChargeReadPlatformService chargeReadPlatformService, final InterestRateChartReadPlatformService chartReadPlatformService,
final InterestRateChartReadPlatformService interestRateChartReadPlatformService,
final DepositsDropdownReadPlatformService depositsDropdownReadPlatformService) {
this.depositProductReadPlatformService = depositProductReadPlatformService;
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.currencyReadPlatformService = currencyReadPlatformService;
this.context = context;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.chartReadPlatformService = chartReadPlatformService;
this.interestRateChartReadPlatformService = interestRateChartReadPlatformService;
this.depositsDropdownReadPlatformService = depositsDropdownReadPlatformService;
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String create(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createRecurringDepositProduct().withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String update(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRecurringDepositProduct(productId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<RecurringDepositProductData> products = (Collection) this.depositProductReadPlatformService
.retrieveAll(DepositAccountType.RECURRING_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, products,
DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
RecurringDepositProductData recurringDepositProductData = (RecurringDepositProductData) this.depositProductReadPlatformService
.retrieveOne(DepositAccountType.RECURRING_DEPOSIT, productId);
final Collection<ChargeData> charges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
recurringDepositProductData = RecurringDepositProductData.withCharges(recurringDepositProductData, charges);
final Collection<InterestRateChartData> charts = this.chartReadPlatformService.retrieveAllWithSlabsWithTemplate(productId);
recurringDepositProductData = RecurringDepositProductData.withInterestChart(recurringDepositProductData, charts);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (recurringDepositProductData.hasAccountingEnabled()) {
final Map<String, Object> accountingMappings = this.accountMappingReadPlatformService
.fetchAccountMappingDetailsForSavingsProduct(productId, recurringDepositProductData.accountingRuleTypeId());
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = this.accountMappingReadPlatformService
.fetchPaymentTypeToFundSourceMappingsForSavingsProduct(productId);
Collection<ChargeToGLAccountMapper> feeToGLAccountMappings = this.accountMappingReadPlatformService
.fetchFeeToIncomeAccountMappingsForSavingsProduct(productId);
Collection<ChargeToGLAccountMapper> penaltyToGLAccountMappings = this.accountMappingReadPlatformService
.fetchPenaltyToIncomeAccountMappingsForSavingsProduct(productId);
recurringDepositProductData = RecurringDepositProductData.withAccountingDetails(recurringDepositProductData,
accountingMappings, paymentChannelToFundSourceMappings, feeToGLAccountMappings, penaltyToGLAccountMappings);
}
if (settings.isTemplate()) {
recurringDepositProductData = handleTemplateRelatedData(recurringDepositProductData);
}
return this.toApiJsonSerializer.serialize(settings, recurringDepositProductData,
DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
final RecurringDepositProductData recurringDepositProduct = handleTemplateRelatedData(null);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, recurringDepositProduct,
DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESPONSE_DATA_PARAMETERS);
}
private RecurringDepositProductData handleTemplateRelatedData(final RecurringDepositProductData savingsProduct) {
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
final EnumOptionData interestPostingPeriodType = SavingsEnumerations
.interestPostingPeriodType(SavingsPostingInterestPeriodType.MONTHLY);
final EnumOptionData interestCalculationType = SavingsEnumerations
.interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE);
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.DAYS_365);
final EnumOptionData accountingRule = AccountingEnumerations.accountingRuleType(AccountingRuleType.NONE);
CurrencyData currency = CurrencyData.blank();
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
if (currencyOptions.size() == 1) {
currency = new ArrayList<CurrencyData>(currencyOptions).get(0);
}
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveCompoundingInterestPeriodTypeOptions();
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveInterestPostingPeriodTypeOptions();
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationTypeOptions();
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationDaysInYearTypeOptions();
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
.retrieveLockinPeriodFrequencyTypeOptions();
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
final Collection<EnumOptionData> accountingRuleOptions = this.accountingDropdownReadPlatformService
.retrieveAccountingRuleTypeOptions();
final Map<String, List<GLAccountData>> accountingMappingOptions = this.accountingDropdownReadPlatformService
.retrieveAccountMappingOptionsForSavingsProducts();
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = this.depositsDropdownReadPlatformService
.retrievePreClosurePenalInterestOnTypeOptions();
final Collection<EnumOptionData> interestFreePeriodTypeOptions = this.depositsDropdownReadPlatformService
.retrieveInterestFreePeriodFrequencyTypeOptions();
// charges
final boolean feeChargesOnly = true;
Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveSavingsAccountApplicableCharges(feeChargesOnly);
chargeOptions = CollectionUtils.isEmpty(chargeOptions) ? null : chargeOptions;
Collection<ChargeData> penaltyOptions = this.chargeReadPlatformService.retrieveSavingsAccountApplicablePenalties();
penaltyOptions = CollectionUtils.isEmpty(penaltyOptions) ? null : penaltyOptions;
Collection<EnumOptionData> recurringDepositTypeOptions = this.depositsDropdownReadPlatformService
.retrieveRecurringDepositTypeOptions();
Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = this.depositsDropdownReadPlatformService
.retrieveRecurringDepositFrequencyTypeOptions();
final Collection<EnumOptionData> depositTermTypeOptions = this.depositsDropdownReadPlatformService.retrieveDepositTermTypeOptions();
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = this.depositsDropdownReadPlatformService
.retrieveInMultiplesOfDepositTermTypeOptions();
// interest rate chart template
final InterestRateChartData chartTemplate = this.interestRateChartReadPlatformService.template();
RecurringDepositProductData recurringDepositProductToReturn = null;
if (savingsProduct != null) {
recurringDepositProductToReturn = RecurringDepositProductData.withTemplate(savingsProduct, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, chargeOptions, penaltyOptions, chartTemplate,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
} else {
recurringDepositProductToReturn = RecurringDepositProductData.template(currency, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, accountingRule, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, chargeOptions, penaltyOptions, chartTemplate,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
return recurringDepositProductToReturn;
}
@DELETE
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String delete(@PathParam("productId") final Long productId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteRecurringDepositProduct(productId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -31,6 +31,7 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
@@ -81,7 +82,7 @@ public class SavingsAccountTransactionsApiResource {
// FIXME - KW - for now just send back generic default information for
// both deposit/withdrawal templates
SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService.retrieveDepositTransactionTemplate(savingsId);
SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService.retrieveDepositTransactionTemplate(savingsId, DepositAccountType.SAVINGS_DEPOSIT);
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
savingsAccount = SavingsAccountTransactionData.templateOnTop(savingsAccount, paymentTypeOptions);
@@ -100,7 +101,7 @@ public class SavingsAccountTransactionsApiResource {
this.context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
SavingsAccountTransactionData transactionData = this.savingsAccountReadPlatformService.retrieveSavingsTransaction(savingsId,
transactionId);
transactionId, DepositAccountType.SAVINGS_DEPOSIT);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
if (settings.isTemplate()) {
final Collection<CodeValueData> paymentTypeOptions = this.codeValueReadPlatformService
@@ -37,6 +37,7 @@ import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSeria
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
@@ -161,7 +162,7 @@ public class SavingsAccountsApiResource {
if (associationParameters.contains(SavingsApiConstants.transactions)) {
mandatoryResponseParameters.add(SavingsApiConstants.transactions);
final Collection<SavingsAccountTransactionData> currentTransactions = this.savingsAccountReadPlatformService
.retrieveAllTransactions(accountId);
.retrieveAllTransactions(accountId, DepositAccountType.SAVINGS_DEPOSIT);
if (!CollectionUtils.isEmpty(currentTransactions)) {
transactions = currentTransactions;
}
@@ -0,0 +1,280 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
/**
* Immutable data object representing abstract for Fixed and Recurring Deposit Accounts
* Accounts.
*/
public class DepositAccountData {
protected final Long id;
protected final String accountNo;
protected final String externalId;
protected final Long groupId;
protected final String groupName;
protected final Long clientId;
protected final String clientName;
protected final Long savingsProductId;
protected final String savingsProductName;
protected final Long fieldOfficerId;
protected final String fieldOfficerName;
protected final SavingsAccountStatusEnumData status;
protected final SavingsAccountApplicationTimelineData timeline;
protected final CurrencyData currency;
protected final BigDecimal nominalAnnualInterestRate;
protected final EnumOptionData interestCompoundingPeriodType;
protected final EnumOptionData interestPostingPeriodType;
protected final EnumOptionData interestCalculationType;
protected final EnumOptionData interestCalculationDaysInYearType;
protected final BigDecimal minRequiredOpeningBalance;
protected final Integer lockinPeriodFrequency;
protected final EnumOptionData lockinPeriodFrequencyType;
protected final boolean withdrawalFeeForTransfers;
protected final EnumOptionData depositType;
// associations
protected final SavingsAccountSummaryData summary;
protected final Collection<SavingsAccountTransactionData> transactions;
protected final Collection<SavingsAccountChargeData> charges;
protected final DepositAccountInterestRateChartData accountChart;
// template
protected final Collection<DepositProductData> productOptions;
protected final Collection<StaffData> fieldOfficerOptions;
protected final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestCalculationTypeOptions;
protected final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
protected final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
protected final Collection<EnumOptionData> withdrawalFeeTypeOptions;
protected final Collection<ChargeData> chargeOptions;
protected final SavingsAccountChargeData withdrawalFee;
protected final SavingsAccountChargeData annualFee;
protected final DepositAccountInterestRateChartData chartTemplate;
public static DepositAccountData instance(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldOfficerId, final String fieldOfficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal interestRate,
final EnumOptionData interestCompoundingPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
final SavingsAccountSummaryData summary, final EnumOptionData depositType) {
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
return new DepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, depositType);
}
public static DepositAccountData lookup(final Long id, final String accountNo, final EnumOptionData depositType) {
final String externalId = null;
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal interestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
return new DepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, depositType);
}
protected DepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldofficerId, final String fieldofficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final EnumOptionData depositType) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.groupId = groupId;
this.groupName = groupName;
this.clientId = clientId;
this.clientName = clientName;
this.savingsProductId = productId;
this.savingsProductName = productName;
this.fieldOfficerId = fieldofficerId;
this.fieldOfficerName = fieldofficerName;
this.status = status;
this.timeline = timeline;
this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
this.lockinPeriodFrequency = lockinPeriodFrequency;
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.withdrawalFeeForTransfers = withdrawalFeeForTransfers;
this.summary = summary;
this.transactions = transactions;
this.productOptions = productOptions;
this.fieldOfficerOptions = fieldOfficerOptions;
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
this.charges = charges;// charges associated with Savings account
// charges available for adding to Savings account
this.chargeOptions = chargeOptions;
this.withdrawalFee = getWithdrawalFee();
this.annualFee = getAnnualFee();
this.accountChart = accountChart;
this.chartTemplate = chartTemplate;
this.depositType = depositType;
}
private SavingsAccountChargeData getWithdrawalFee() {
for (SavingsAccountChargeData charge : this.charges()) {
if (charge.isWithdrawalFee()) return charge;
}
return null;
}
private SavingsAccountChargeData getAnnualFee() {
for (SavingsAccountChargeData charge : this.charges()) {
if (charge.isAnnualFee()) return charge;
}
return null;
}
public Long id() {
return this.id;
}
public Long clientId() {
return this.clientId;
}
public Long groupId() {
return this.groupId;
}
public Long productId() {
return this.savingsProductId;
}
public CurrencyData currency() {
return this.currency;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) { return false; }
final DepositAccountData rhs = (DepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
public Collection<SavingsAccountChargeData> charges() {
return (this.charges == null) ? new HashSet<SavingsAccountChargeData>() : this.charges;
}
public EnumOptionData depositType() {
return depositType;
}
public String accountNo() {
return accountNo;
}
}
@@ -0,0 +1,613 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeFromPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeToPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestOnTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargesParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.feeIntervalParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.fieldOfficerIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.groupIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.productIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.MonthDay;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
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.interestratechart.InterestRateChartPeriodType;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType;
import org.mifosplatform.portfolio.savings.RecurringDepositType;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@Component
public class DepositAccountDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private final DepositProductDataValidator productDataValidator;
@Autowired
public DepositAccountDataValidator(final FromJsonHelper fromApiJsonHelper, final DepositProductDataValidator productDataValidator) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.productDataValidator = productDataValidator;
}
private void validateFixedDepositForSubmit(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailsForSubmit(element, baseDataValidator);
validatePreClosureDetailForSubmit(element, baseDataValidator);
validateDepositTermDeatilForSubmit(element, baseDataValidator, DepositAccountType.FIXED_DEPOSIT);
validateSavingsCharges(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateFixedDepositForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailsForUpdate(element, baseDataValidator);
validatePreClosureDetailForUpdate(element, baseDataValidator);
validateDepositTermDeatilForUpdate(element, baseDataValidator);
// validateSavingsCharges(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateRecurringDepositForSubmit(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailsForSubmit(element, baseDataValidator);
validatePreClosureDetailForSubmit(element, baseDataValidator);
validateDepositTermDeatilForSubmit(element, baseDataValidator, DepositAccountType.RECURRING_DEPOSIT);
validateRecurringDetailForSubmit(element, baseDataValidator);
validateSavingsCharges(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateRecurringDepositForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailsForUpdate(element, baseDataValidator);
validatePreClosureDetailForUpdate(element, baseDataValidator);
validateDepositTermDeatilForUpdate(element, baseDataValidator);
validateRecurringDetailForUpdate(element, baseDataValidator);
// validateSavingsCharges(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateDepositDetailsForSubmit(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
if (clientId != null) {
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).longGreaterThanZero();
}
final Long groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
if (groupId != null) {
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).longGreaterThanZero();
}
if (clientId == null && groupId == null) {
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
final Long productId = this.fromApiJsonHelper.extractLongNamed(productIdParamName, element);
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
if (this.fromApiJsonHelper.parameterExists(fieldOfficerIdParamName, element)) {
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
baseDataValidator.reset().parameter(fieldOfficerIdParamName).value(fieldOfficerId).ignoreIfNull().integerGreaterThanZero();
}
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
baseDataValidator.reset().parameter(submittedOnDateParamName).value(submittedOnDate).notNull();
if (this.fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
final String accountNo = this.fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
if (this.fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName,
element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
final Integer interestPostingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestPostingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
minRequiredOpeningBalanceParamName, element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).integerZeroOrGreater();
if (lockinPeriodFrequency != null) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
.inMinMaxRange(0, 3);
}
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
if (lockinPeriodFrequencyType != null) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull()
.integerZeroOrGreater();
}
}
}
private void validateDepositDetailsForUpdate(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
Long clientId = null;
if (this.fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
Long groupId = null;
if (this.fromApiJsonHelper.parameterExists(productIdParamName, element)) {
groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
}
if (clientId == null && groupId == null) {
// either clientId or groupId must exists if param passed for
// update.
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
}
Long groupId = null;
if (this.fromApiJsonHelper.parameterExists(groupIdParamName, element)) {
groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
if (this.fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
}
if (clientId == null && groupId == null) {
// either clientId or groupId must exists if param passed for
// update.
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
}
if (this.fromApiJsonHelper.parameterExists(productIdParamName, element)) {
final Long productId = this.fromApiJsonHelper.extractLongNamed(productIdParamName, element);
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(fieldOfficerIdParamName, element)) {
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
baseDataValidator.reset().parameter(fieldOfficerIdParamName).value(fieldOfficerId).ignoreIfNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(submittedOnDateParamName, element)) {
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
baseDataValidator.reset().parameter(submittedOnDateParamName).value(submittedOnDate).notNull();
}
if (this.fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
final String accountNo = this.fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
if (this.fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName,
element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
final Integer interestPostingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestPostingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
minRequiredOpeningBalanceParamName, element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
.integerZeroOrGreater();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
}
}
private void validatePreClosureDetailForSubmit(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(interestFreePeriodApplicableParamName, element)) {
final boolean interestFreePeriodApplicable = fromApiJsonHelper.extractBooleanNamed(interestFreePeriodApplicableParamName,
element);
if (interestFreePeriodApplicable) {
final Integer interestFreeFromPeriod = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestFreeFromPeriodParamName,
element);
baseDataValidator.reset().parameter(interestFreeFromPeriodParamName).value(interestFreeFromPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.integerZeroOrGreater();
final Integer interestFreeToPeriod = fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestFreeToPeriodParamName, element);
baseDataValidator.reset().parameter(interestFreeToPeriodParamName).value(interestFreeToPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.integerZeroOrGreater().integerGreaterThanNumber(interestFreeFromPeriod);
final Integer periodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestFreePeriodFrequencyTypeIdParamName, element);
baseDataValidator.reset().parameter(interestFreePeriodFrequencyTypeIdParamName).value(periodFrequencyType)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.isOneOfTheseValues(InterestRateChartPeriodType.integerValues());
}
}
if (fromApiJsonHelper.parameterExists(preClosurePenalApplicableParamName, element)) {
final boolean preClosurePenalApplicable = fromApiJsonHelper.extractBooleanNamed(preClosurePenalApplicableParamName, element);
if (preClosurePenalApplicable) {
final BigDecimal penalInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(preClosurePenalInterestParamName,
element);
baseDataValidator.reset().parameter(preClosurePenalInterestParamName).value(penalInterestRate)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, preClosurePenalApplicable)
.zeroOrPositiveAmount();
final Integer preClosurePenalInterestType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
preClosurePenalInterestOnTypeIdParamName, element);
baseDataValidator.reset().parameter(preClosurePenalInterestOnTypeIdParamName).value(preClosurePenalInterestType)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, preClosurePenalApplicable)
.isOneOfTheseValues(PreClosurePenalInterestOnType.integerValues());
}
}
}
private void validatePreClosureDetailForUpdate(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
this.productDataValidator.validatePreClosureDetailForUpdate(element, baseDataValidator);
}
private void validateDepositTermDeatilForSubmit(final JsonElement element, final DataValidatorBuilder baseDataValidator,
final DepositAccountType depositType) {
Integer minTerm = null;
if (fromApiJsonHelper.parameterExists(minDepositTermParamName, element)) {
minTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermParamName, element);
baseDataValidator.reset().parameter(minDepositTermParamName).value(minTerm).integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(maxDepositTermParamName, element)) {
final Integer maxTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermParamName, element);
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm).integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(minDepositTermTypeIdParamName, element)) {
final Integer minDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(minDepositTermTypeIdParamName).value(minDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
if (fromApiJsonHelper.parameterExists(maxDepositTermTypeIdParamName, element)) {
final Integer maxDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(maxDepositTermTypeIdParamName).value(maxDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
if (fromApiJsonHelper.parameterExists(inMultiplesOfDepositTermParamName, element)) {
final Integer inMultiplesOfDepositTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(inMultiplesOfDepositTermParamName,
element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermParamName).value(inMultiplesOfDepositTerm).integerGreaterThanZero();
final Integer inMultiplesOfDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
inMultiplesOfDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermTypeIdParamName).value(inMultiplesOfDepositTermType)
.cantBeBlankWhenParameterProvidedIs(inMultiplesOfDepositTermParamName, inMultiplesOfDepositTerm)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
// for recurring deposit the total deposit amount is derived from
// recurring deposit amount * number of deposits.
if (depositType.isFixedDeposit()) {
final BigDecimal depositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositAmountParamName, element);
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notNull().positiveAmount();
}
final Integer depositPeriod = fromApiJsonHelper.extractIntegerSansLocaleNamed(depositPeriodParamName, element);
baseDataValidator.reset().parameter(depositPeriodParamName).value(depositPeriod).notNull().integerGreaterThanZero();
final Integer depositPeriodFrequencyId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(depositPeriodFrequencyIdParamName,
element);
baseDataValidator.reset().parameter(depositPeriodFrequencyIdParamName).value(depositPeriodFrequencyId)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
private void validateDepositTermDeatilForUpdate(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
this.productDataValidator.validateDepositTermDetailForUpdate(element, baseDataValidator);
if (fromApiJsonHelper.parameterExists(depositAmountParamName, element)) {
final BigDecimal depositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositAmountParamName, element);
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notNull().positiveAmount();
}
if (fromApiJsonHelper.parameterExists(depositPeriodParamName, element)) {
final Integer depositPeriod = fromApiJsonHelper.extractIntegerSansLocaleNamed(depositPeriodParamName, element);
baseDataValidator.reset().parameter(depositPeriodParamName).value(depositPeriod).notNull().integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(depositPeriodFrequencyIdParamName, element)) {
final Integer depositPeriodFrequencyId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
depositPeriodFrequencyIdParamName, element);
baseDataValidator.reset().parameter(depositPeriodFrequencyIdParamName).value(depositPeriodFrequencyId)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
}
private void validateRecurringDetailForSubmit(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(recurringDepositTypeIdParamName, element)) {
final Integer rdTypeId = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositTypeIdParamName, element);
baseDataValidator.reset().parameter(recurringDepositTypeIdParamName).value(rdTypeId).notNull()
.isOneOfTheseValues(RecurringDepositType.integerValues());
}
if (fromApiJsonHelper.parameterExists(recurringDepositFrequencyParamName, element)) {
final Integer rdFrequency = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositFrequencyParamName, element);
baseDataValidator.reset().parameter(recurringDepositFrequencyParamName).value(rdFrequency).notNull().integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(recurringDepositFrequencyTypeIdParamName, element)) {
final Integer rdFrequencyTypeId = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositFrequencyTypeIdParamName,
element);
baseDataValidator.reset().parameter(recurringDepositFrequencyTypeIdParamName).value(rdFrequencyTypeId).notNull()
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
}
private void validateRecurringDetailForUpdate(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
this.productDataValidator.validateRecurringDepositUpdate(element, baseDataValidator);
}
public void validateForSubmit(final String json, final DepositAccountType depositAccountType) {
if (depositAccountType.isFixedDeposit()) {
this.validateFixedDepositForSubmit(json);
} else if (depositAccountType.isRecurringDeposit()) {
this.validateRecurringDepositForSubmit(json);
} else {
// FIXME: AA handle unsupported deposit account type
// throw unsupported account type exception
}
}
private void validateSavingsCharges(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
final String monthDayFormat = this.fromApiJsonHelper.extractMonthDayFormatParameter(topLevelJsonElement);
if (topLevelJsonElement.has(chargesParamName) && topLevelJsonElement.get(chargesParamName).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chargesParamName).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject savingsChargeElement = array.get(i).getAsJsonObject();
// final Long id =
// this.fromApiJsonHelper.extractLongNamed(idParamName,
// savingsChargeElement);
final Long chargeId = this.fromApiJsonHelper.extractLongNamed(chargeIdParamName, savingsChargeElement);
baseDataValidator.reset().parameter(chargeIdParamName).value(chargeId).longGreaterThanZero();
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, savingsChargeElement, locale);
baseDataValidator.reset().parameter(amountParamName).value(amount).notNull().positiveAmount();
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, savingsChargeElement)) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, savingsChargeElement,
monthDayFormat, locale);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDay).notNull();
}
if (this.fromApiJsonHelper.parameterExists(feeIntervalParamName, savingsChargeElement)) {
final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed(feeIntervalParamName, savingsChargeElement,
Locale.getDefault());
baseDataValidator.reset().parameter(feeIntervalParamName).value(feeInterval).notNull().inMinMaxRange(1, 12);
}
}
}
}
}
public void validateForUpdate(final String json, final DepositAccountType depositAccountType) {
if (depositAccountType.isFixedDeposit()) {
this.validateFixedDepositForUpdate(json);
} else if (depositAccountType.isRecurringDeposit()) {
this.validateRecurringDepositForUpdate(json);
} else {
// FIXME: AA handle unsupported deposit account type
// throw unsupported account type exception
}
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
@@ -0,0 +1,120 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
/**
* Immutable data object representing a deposit account interest rate chart.
*/
public class DepositAccountInterestRateChartData {
private final Long id;
private final String name;
private final String description;
private final LocalDate fromDate;
private final LocalDate endDate;
private final Long accountId;
private final String accountNumber;
// associations
private Set<DepositAccountInterestRateChartSlabData> chartSlabs;
// template
private Collection<EnumOptionData> periodTypes;
public static DepositAccountInterestRateChartData instance(Long id, String name, String description, LocalDate fromDate,
LocalDate endDate, Long accountId, String accountNumber, Set<DepositAccountInterestRateChartSlabData> chartSlabs,
Collection<EnumOptionData> periodTypes) {
return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, accountId, accountNumber, chartSlabs,
periodTypes);
}
public static DepositAccountInterestRateChartData from(InterestRateChartData productChartData) {
final Long id = null;
final Long accountId = null;
final String accountNumber = null;
Set<DepositAccountInterestRateChartSlabData> fromProdChartSlabs = new HashSet<DepositAccountInterestRateChartSlabData>();
Set<InterestRateChartSlabData> productChartSlabDatas = productChartData.chartSlabs();
if (productChartSlabDatas != null) {
for (InterestRateChartSlabData productChartSlabData : productChartSlabDatas) {
fromProdChartSlabs.add(DepositAccountInterestRateChartSlabData.from(productChartSlabData));
}
}
return new DepositAccountInterestRateChartData(id, productChartData.name(), productChartData.description(),
productChartData.fromDate(), productChartData.endDate(), accountId, accountNumber, fromProdChartSlabs,
productChartData.periodTypes());
}
public static DepositAccountInterestRateChartData withSlabs(DepositAccountInterestRateChartData interestRateChartData,
Set<DepositAccountInterestRateChartSlabData> chartSlabs) {
return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name,
interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate,
interestRateChartData.accountId, interestRateChartData.accountNumber, chartSlabs, interestRateChartData.periodTypes);
}
public static DepositAccountInterestRateChartData withTemplate(DepositAccountInterestRateChartData interestRateChartData,
Collection<EnumOptionData> periodTypes) {
return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name,
interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate,
interestRateChartData.accountId, interestRateChartData.accountNumber, interestRateChartData.chartSlabs, periodTypes);
}
public static DepositAccountInterestRateChartData template(Collection<EnumOptionData> periodTypes) {
final Long id = null;
final String name = null;
final String description = null;
final LocalDate fromDate = null;
final LocalDate endDate = null;
final Long accountId = null;
final String accountNumber = null;
final Set<DepositAccountInterestRateChartSlabData> chartSlabs = null;
return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, accountId, accountNumber, chartSlabs,
periodTypes);
}
private DepositAccountInterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate,
Long accountId, String accountNumber, Set<DepositAccountInterestRateChartSlabData> chartSlabs,
Collection<EnumOptionData> periodTypes) {
this.id = id;
this.name = name;
this.description = description;
this.fromDate = fromDate;
this.endDate = endDate;
this.chartSlabs = chartSlabs;
this.accountId = accountId;
this.accountNumber = accountNumber;
this.periodTypes = periodTypes;
}
public void addChartSlab(final DepositAccountInterestRateChartSlabData chartSlab) {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<DepositAccountInterestRateChartSlabData>();
}
this.chartSlabs.add(chartSlab);
}
public boolean isFromDateAfter(final LocalDate compareDate) {
return (compareDate == null) ? false : this.fromDate.isAfter(compareDate);
}
public LocalDate endDate() {
return this.endDate;
}
public LocalDate fromDate() {
return this.fromDate;
}
}
@@ -0,0 +1,68 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData;
/**
* Immutable data object representing deposit accounts Interest rate Slabs.
*/
public class DepositAccountInterestRateChartSlabData {
private final Long id;
private final String description;
private final EnumOptionData periodType;
private final Integer fromPeriod;
private final Integer toPeriod;
private final BigDecimal amountRangeFrom;
private final BigDecimal amountRangeTo;
private final BigDecimal annualInterestRate;
private final CurrencyData currency;
// associations
// template
@SuppressWarnings("unused")
private Collection<EnumOptionData> periodTypes;
public static DepositAccountInterestRateChartSlabData instance(Long id, String description, EnumOptionData periodType, Integer fromPeriod,
Integer toPeriod, BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, CurrencyData currency) {
Collection<EnumOptionData> periodTypes = null;
return new DepositAccountInterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency, periodTypes);
}
public static DepositAccountInterestRateChartSlabData from(InterestRateChartSlabData chartSlabData) {
final Long id = null;
return new DepositAccountInterestRateChartSlabData(id, chartSlabData.description(), chartSlabData.periodType(), chartSlabData.fromPeriod(), chartSlabData.toPeriod(), chartSlabData.amountRangeFrom(), chartSlabData.amountRangeTo(),
chartSlabData.annualInterestRate(), chartSlabData.currency(), chartSlabData.periodTypes());
}
public static DepositAccountInterestRateChartSlabData withTemplate(DepositAccountInterestRateChartSlabData chartSlab, Collection<EnumOptionData> periodTypes) {
return new DepositAccountInterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod, chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo,
chartSlab.annualInterestRate, chartSlab.currency, periodTypes);
}
private DepositAccountInterestRateChartSlabData(Long id, String description, EnumOptionData periodType, Integer fromPeriod, Integer toPeriod,
BigDecimal amountRangeFrom, BigDecimal amountRangeTo, BigDecimal annualInterestRate, CurrencyData currency, Collection<EnumOptionData> periodTypes) {
this.id = id;
this.description = description;
this.periodType = periodType;
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currency = currency;
this.periodTypes = periodTypes;
}
}
@@ -0,0 +1,190 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.activatedOnDateParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.bankNumberParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.checkNumberParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.closedOnDateParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccountClosureIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.paymentTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.receiptNumberParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.routingCodeParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.toSavingsAccountIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transactionAccountNumberParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transactionAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transactionDateParamName;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
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.savings.DepositAccountOnClosureType;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
@Component
public class DepositAccountTransactionDataValidator {
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public DepositAccountTransactionDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validate(final JsonCommand command, DepositAccountType depositAccountType) {
final String json = command.json();
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.DEPOSIT_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(depositAccountType.resourceName());
final JsonElement element = command.parsedJson();
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(transactionDateParamName, element);
baseDataValidator.reset().parameter(transactionDateParamName).value(transactionDate).notNull();
final BigDecimal transactionAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(transactionAmountParamName, element);
baseDataValidator.reset().parameter(transactionAmountParamName).value(transactionAmount).notNull().positiveAmount();
// Validate all string payment detail fields for max length
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(paymentTypeIdParamName, element);
baseDataValidator.reset().parameter(paymentTypeIdParamName).value(paymentTypeId).ignoreIfNull().integerGreaterThanZero();
final Set<String> paymentDetailParameters = new HashSet<String>(Arrays.asList(transactionAccountNumberParamName,
checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
for (final String paymentDetailParameterName : paymentDetailParameters) {
final String paymentDetailParameterValue = this.fromApiJsonHelper.extractStringNamed(paymentDetailParameterName, element);
baseDataValidator.reset().parameter(paymentDetailParameterName).value(paymentDetailParameterValue).ignoreIfNull()
.notExceedingLengthOf(50);
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateActivation(final JsonCommand command) {
final String json = command.json();
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsApiConstants.SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
final JsonElement element = command.parsedJson();
final LocalDate activationDate = this.fromApiJsonHelper.extractLocalDateNamed(activatedOnDateParamName, element);
baseDataValidator.reset().parameter(activatedOnDateParamName).value(activationDate).notNull();
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validatePreMatureAmountCalculation(final String json, final DepositAccountType depositAccountType) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.DEPOSIT_ACCOUNT_PRE_MATURE_CALCULATION_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(depositAccountType
.resourceName());
final JsonElement element = this.fromApiJsonHelper.parse(json);
final LocalDate closeDate = this.fromApiJsonHelper.extractLocalDateNamed(closedOnDateParamName, element);
baseDataValidator.reset().parameter(closedOnDateParamName).value(closeDate).notNull();
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateClosing(final JsonCommand command, DepositAccountType depositAccountType, final boolean isPreMatureClose) {
final String json = command.json();
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
DepositsApiConstants.DEPOSIT_ACCOUNT_CLOSE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(depositAccountType
.resourceName());
final JsonElement element = command.parsedJson();
final LocalDate activationDate = this.fromApiJsonHelper.extractLocalDateNamed(closedOnDateParamName, element);
baseDataValidator.reset().parameter(closedOnDateParamName).value(activationDate).notNull();
final Integer onAccountClosureId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(onAccountClosureIdParamName, element);
baseDataValidator.reset().parameter(onAccountClosureIdParamName).value(onAccountClosureId).notBlank()
.isOneOfTheseValues(DepositAccountOnClosureType.integerValues());
if (onAccountClosureId != null) {
final DepositAccountOnClosureType accountOnClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
if (accountOnClosureType.isTransferToSavings()) {
final Long toSavingsAccountId = this.fromApiJsonHelper.extractLongNamed(toSavingsAccountIdParamName, element);
baseDataValidator.reset().parameter(toSavingsAccountIdParamName).value(toSavingsAccountId)
.cantBeBlankWhenParameterProvidedIs(onAccountClosureIdParamName, onAccountClosureId);
} else if (accountOnClosureType.isReinvest() && isPreMatureClose) {
baseDataValidator.reset().parameter(onAccountClosureIdParamName).value(onAccountClosureId)
.failWithCode("reinvest.not.allowed", "Re-Invest is not supported for account pre mature close");
}
}
// Validate all string payment detail fields for max length
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(paymentTypeIdParamName, element);
baseDataValidator.reset().parameter(paymentTypeIdParamName).value(paymentTypeId).ignoreIfNull().integerGreaterThanZero();
final Set<String> paymentDetailParameters = new HashSet<String>(Arrays.asList(transactionAccountNumberParamName,
checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
for (final String paymentDetailParameterName : paymentDetailParameters) {
final String paymentDetailParameterValue = this.fromApiJsonHelper.extractStringNamed(paymentDetailParameterName, element);
baseDataValidator.reset().parameter(paymentDetailParameterName).value(paymentDetailParameterValue).ignoreIfNull()
.notExceedingLengthOf(50);
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
//
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
@@ -0,0 +1,364 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.mifosplatform.accounting.common.AccountingRuleType;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
/**
* Immutable data object represents a partial data of Deposit Proucts.
*/
public class DepositProductData {
protected final Long id;
protected final String name;
protected final String shortName;
protected final String description;
protected final CurrencyData currency;
protected final BigDecimal nominalAnnualInterestRate;
protected final EnumOptionData interestCompoundingPeriodType;
protected final EnumOptionData interestPostingPeriodType;
protected final EnumOptionData interestCalculationType;
protected final EnumOptionData interestCalculationDaysInYearType;
// protected final BigDecimal minRequiredOpeningBalance;
protected final Integer lockinPeriodFrequency;
protected final EnumOptionData lockinPeriodFrequencyType;
// protected final boolean withdrawalFeeForTransfers;
// accounting
protected final EnumOptionData accountingRule;
protected final Map<String, Object> accountingMappings;
protected final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
protected final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
protected final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
// charges
protected final Collection<ChargeData> charges;
// interest rate charts
protected final Collection<InterestRateChartData> interestRateCharts;
protected final InterestRateChartData activeChart;
// template
protected final Collection<CurrencyData> currencyOptions;
protected final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestCalculationTypeOptions;
protected final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
protected final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
protected final Collection<EnumOptionData> withdrawalFeeTypeOptions;
protected final Collection<CodeValueData> paymentTypeOptions;
protected final Collection<EnumOptionData> accountingRuleOptions;
protected final Map<String, List<GLAccountData>> accountingMappingOptions;
protected final Collection<ChargeData> chargeOptions;
protected final Collection<ChargeData> penaltyOptions;
protected final InterestRateChartData chartTemplate;
public static DepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingRule, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate);
}
public static DepositProductData withCharges(final DepositProductData existingProduct, final Collection<ChargeData> charges) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate);
}
/**
* Returns a {@link DepositProductData} that contains and exist
* {@link DepositProductData} data with further template data for dropdowns.
*/
public static DepositProductData withTemplate(final DepositProductData existingProduct, final Collection<CurrencyData> currencyOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate);
}
public static DepositProductData withAccountingDetails(final DepositProductData existingProduct,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate);
}
public static DepositProductData instance(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate);
}
public static DepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate);
}
public static DepositProductData withInterestChart(final DepositProductData existingProduct,
final Collection<InterestRateChartData> interestRateCharts) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
existingProduct.charges, existingProduct.chargeOptions, existingProduct.penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings, interestRateCharts,
existingProduct.chartTemplate);
}
protected DepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate) {
this.id = id;
this.name = name;
this.shortName = shortName;
this.description = description;
this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestCompoundingPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.accountingRule = accountingType;
this.lockinPeriodFrequency = lockinPeriodFrequency;
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.currencyOptions = currencyOptions;
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
this.paymentTypeOptions = paymentTypeOptions;
this.accountingMappingOptions = accountingMappingOptions;
this.accountingRuleOptions = accountingRuleOptions;
if (accountingMappings == null || accountingMappings.isEmpty()) {
this.accountingMappings = null;
} else {
this.accountingMappings = accountingMappings;
}
this.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
this.charges = charges;// charges associated with Savings product
this.chargeOptions = chargeOptions;// charges available for adding to
// Savings product
this.penaltyOptions = penaltyOptions;// penalties available for adding
// to Savings product
this.feeToIncomeAccountMappings = feeToIncomeAccountMappings;
this.penaltyToIncomeAccountMappings = penaltyToIncomeAccountMappings;
this.interestRateCharts = interestRateCharts;
this.activeChart = activeChart(this.interestRateCharts);
this.chartTemplate = chartTemplate;
}
public static InterestRateChartData activeChart(Collection<InterestRateChartData> interestRateCharts) {
InterestRateChartData activeChart = null;
if (interestRateCharts != null) {
for (InterestRateChartData chartData : interestRateCharts) {
if (activeChart == null) {
activeChart = chartData;
} else {
if (!activeChart.isFromDateAfter(chartData.endDate())) {
activeChart = chartData;
}
}
}
}
return activeChart;
}
public boolean hasAccountingEnabled() {
return this.accountingRule.getId() > AccountingRuleType.NONE.getValue();
}
public int accountingRuleTypeId() {
return this.accountingRule.getId().intValue();
}
}
@@ -0,0 +1,736 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.chartsParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeFromPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeToPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestOnTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.feeAmountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nameParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.shortNameParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.joda.time.MonthDay;
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
import org.mifosplatform.accounting.common.AccountingRuleType;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
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.interestratechart.InterestRateChartPeriodType;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartDataValidator;
import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType;
import org.mifosplatform.portfolio.savings.RecurringDepositType;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@Component
public class DepositProductDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartDataValidator chartDataValidator;
@Autowired
public DepositProductDataValidator(FromJsonHelper fromApiJsonHelper, InterestRateChartDataValidator chartDataValidator) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.chartDataValidator = chartDataValidator;
}
public void validateForFixedDepositCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, FIXED_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator);
validatePreClosureDetailForCreate(element, baseDataValidator);
validateDepositTermDeatilForCreate(element, baseDataValidator);
validateChartsData(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForFixedDepositUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, FIXED_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForUpdate(element, fromApiJsonHelper, baseDataValidator);
validatePreClosureDetailForUpdate(element, baseDataValidator);
validateDepositTermDetailForUpdate(element, baseDataValidator);
validateChartsData(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForRecurringDepositCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, RECURRING_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator);
validatePreClosureDetailForCreate(element, baseDataValidator);
validateDepositTermDeatilForCreate(element, baseDataValidator);
validateRecurringDetailForCreate(element, baseDataValidator);
validateChartsData(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForRecurringDepositUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, RECURRING_DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForUpdate(element, fromApiJsonHelper, baseDataValidator);
validatePreClosureDetailForUpdate(element, baseDataValidator);
validateDepositTermDetailForUpdate(element, baseDataValidator);
validateRecurringDepositUpdate(element, baseDataValidator);
validateChartsData(element, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateDepositDetailForCreate(final JsonElement element, final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator) {
final String name = fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
final String shortName = fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
final String description = fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
final String currencyCode = fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
if (fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
final Integer inMultiplesOf = fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
}
if (fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal nominalAnnualInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
nominalAnnualInterestRateParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(nominalAnnualInterestRate).notNull()
.zeroOrPositiveAmount();
}
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
final Integer interestPostingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName,
element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
/*
* if
* (fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName
* , element)) { final BigDecimal minOpeningBalance =
* fromApiJsonHelper.extractBigDecimalWithLocaleNamed
* (minRequiredOpeningBalanceParamName, element);
* baseDataValidator.reset
* ().parameter(minRequiredOpeningBalanceParamName
* ).value(minOpeningBalance).zeroOrPositiveAmount(); }
*/
if (fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).integerZeroOrGreater();
if (lockinPeriodFrequency != null) {
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
.inMinMaxRange(0, 3);
}
}
if (fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
if (lockinPeriodFrequencyType != null) {
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull()
.integerZeroOrGreater();
}
}
// accounting related data validation
final Integer accountingRuleType = fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
if (isCashBasedAccounting(accountingRuleType)) {
final Long savingsControlAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue())
.value(savingsControlAccountId).notNull().integerGreaterThanZero();
final Long savingsReferenceAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId)
.notNull().integerGreaterThanZero();
final Long incomeFromPenaltyId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue())
.value(incomeFromPenaltyId).notNull().integerGreaterThanZero();
validatePaymentChannelFundSourceMappings(fromApiJsonHelper, baseDataValidator, element);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element);
}
}
public void validatePreClosureDetailForCreate(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(interestFreePeriodApplicableParamName, element)) {
final boolean interestFreePeriodApplicable = fromApiJsonHelper.extractBooleanNamed(interestFreePeriodApplicableParamName,
element);
if (interestFreePeriodApplicable) {
final Integer interestFreeFromPeriod = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestFreeFromPeriodParamName,
element);
baseDataValidator.reset().parameter(interestFreeFromPeriodParamName).value(interestFreeFromPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.integerZeroOrGreater();
final Integer interestFreeToPeriod = fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestFreeToPeriodParamName, element);
baseDataValidator.reset().parameter(interestFreeToPeriodParamName).value(interestFreeToPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.integerZeroOrGreater().integerGreaterThanNumber(interestFreeFromPeriod);
final Integer periodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestFreePeriodFrequencyTypeIdParamName, element);
baseDataValidator.reset().parameter(interestFreePeriodFrequencyTypeIdParamName).value(periodFrequencyType)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, interestFreePeriodApplicable)
.isOneOfTheseValues(InterestRateChartPeriodType.integerValues());
}
}
if (fromApiJsonHelper.parameterExists(preClosurePenalApplicableParamName, element)) {
final boolean preClosurePenalApplicable = fromApiJsonHelper.extractBooleanNamed(preClosurePenalApplicableParamName, element);
if (preClosurePenalApplicable) {
final BigDecimal penalInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(preClosurePenalInterestParamName,
element);
baseDataValidator.reset().parameter(preClosurePenalInterestParamName).value(penalInterestRate)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, preClosurePenalApplicable)
.zeroOrPositiveAmount();
final Integer preClosurePenalInterestType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
preClosurePenalInterestOnTypeIdParamName, element);
baseDataValidator.reset().parameter(preClosurePenalInterestOnTypeIdParamName).value(preClosurePenalInterestType)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, preClosurePenalApplicable)
.isOneOfTheseValues(PreClosurePenalInterestOnType.integerValues());
}
}
}
public void validateDepositTermDeatilForCreate(JsonElement element, DataValidatorBuilder baseDataValidator) {
final Integer minTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermParamName, element);
baseDataValidator.reset().parameter(minDepositTermParamName).value(minTerm).integerGreaterThanZero();
if (fromApiJsonHelper.parameterExists(maxDepositTermParamName, element)) {
final Integer maxTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermParamName, element);
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm).integerGreaterThanZero();
}
final Integer minDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(minDepositTermTypeIdParamName).value(minDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
if (fromApiJsonHelper.parameterExists(maxDepositTermTypeIdParamName, element)) {
final Integer maxDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(maxDepositTermTypeIdParamName).value(maxDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
if (fromApiJsonHelper.parameterExists(inMultiplesOfDepositTermParamName, element)) {
final Integer inMultiplesOfDepositTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(inMultiplesOfDepositTermParamName,
element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermParamName).value(inMultiplesOfDepositTerm).integerGreaterThanZero();
final Integer inMultiplesOfDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
inMultiplesOfDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermTypeIdParamName).value(inMultiplesOfDepositTermType)
.cantBeBlankWhenParameterProvidedIs(inMultiplesOfDepositTermParamName, inMultiplesOfDepositTerm)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
}
private void validateChartsData(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
if (topLevelJsonElement.has(chartsParamName) && topLevelJsonElement.get(chartsParamName).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chartsParamName).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject interestRateChartElement = array.get(i).getAsJsonObject();
final String json = this.fromApiJsonHelper.toJson(interestRateChartElement);
// chart for create
if (!this.fromApiJsonHelper.parameterExists(idParamName, interestRateChartElement)) {
this.chartDataValidator.validateForCreate(json, baseDataValidator);
} else { // chart for update
this.chartDataValidator.validateForUpdate(json, baseDataValidator);
}
}
}
}
}
public void validateDepositDetailForUpdate(final JsonElement element, final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(nameParamName, element)) {
final String name = fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
}
if (fromApiJsonHelper.parameterExists(shortNameParamName, element)) {
final String shortName = fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
}
if (fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
}
if (fromApiJsonHelper.parameterExists(currencyCodeParamName, element)) {
final String currencyCode = fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
}
if (fromApiJsonHelper.parameterExists(digitsAfterDecimalParamName, element)) {
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
}
if (fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
final Integer inMultiplesOf = fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
}
if (fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.inMinMaxRange(1, 2);
}
if (fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(360, 365);
}
if (fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
.integerZeroOrGreater();
}
if (fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
}
if (fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
final Boolean isWithdrawalFeeApplicableForTransfers = fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName,
element);
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
.ignoreIfNull().validateForBooleanValue();
}
if (fromApiJsonHelper.parameterExists(feeAmountParamName, element)) {
final BigDecimal annualFeeAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(feeAmountParamName, element);
baseDataValidator.reset().parameter(feeAmountParamName).value(annualFeeAmount).ignoreIfNull().zeroOrPositiveAmount();
}
if (fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, element)) {
final MonthDay monthDayOfAnnualFee = fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDayOfAnnualFee).ignoreIfNull();
}
final Long savingsControlAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long savingsReferenceAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
.value(savingsReferenceAccountId).ignoreIfNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
.value(transfersInSuspenseAccountId).ignoreIfNull().integerGreaterThanZero();
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
.value(interestOnSavingsAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromPenaltyId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.ignoreIfNull().integerGreaterThanZero();
validatePaymentChannelFundSourceMappings(fromApiJsonHelper, baseDataValidator, element);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element);
}
public void validatePreClosureDetailForUpdate(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(interestFreePeriodApplicableParamName, element)) {
final Boolean interestFreePeriodApplicable = fromApiJsonHelper.extractBooleanNamed(interestFreePeriodApplicableParamName,
element);
baseDataValidator.reset().parameter(interestFreePeriodApplicableParamName).value(interestFreePeriodApplicable).notNull();
}
if (fromApiJsonHelper.parameterExists(interestFreeFromPeriodParamName, element)) {
final Integer interestFreeFromPeriod = fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestFreeFromPeriodParamName, element);
baseDataValidator.reset().parameter(interestFreeFromPeriodParamName).value(interestFreeFromPeriod).notNull()
.integerZeroOrGreater();
}
if (fromApiJsonHelper.parameterExists(interestFreeToPeriodParamName, element)) {
final Integer interestFreeToPeriod = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestFreeToPeriodParamName, element);
baseDataValidator.reset().parameter(interestFreeToPeriodParamName).value(interestFreeToPeriod).notNull().integerZeroOrGreater();
}
if (fromApiJsonHelper.parameterExists(interestFreePeriodFrequencyTypeIdParamName, element)) {
final Integer periodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestFreePeriodFrequencyTypeIdParamName, element);
baseDataValidator.reset().parameter(interestFreePeriodFrequencyTypeIdParamName).value(periodFrequencyType).notNull()
.isOneOfTheseValues(InterestRateChartPeriodType.integerValues());
}
if (fromApiJsonHelper.parameterExists(preClosurePenalApplicableParamName, element)) {
final Boolean preClosurePenalApplicable = fromApiJsonHelper.extractBooleanNamed(preClosurePenalApplicableParamName, element);
baseDataValidator.reset().parameter(preClosurePenalApplicableParamName).value(preClosurePenalApplicable).notNull();
}
if (fromApiJsonHelper.parameterExists(preClosurePenalInterestParamName, element)) {
final BigDecimal penalInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(preClosurePenalInterestParamName,
element);
baseDataValidator.reset().parameter(preClosurePenalInterestParamName).value(penalInterestRate).notNull().zeroOrPositiveAmount();
}
if (fromApiJsonHelper.parameterExists(preClosurePenalInterestOnTypeIdParamName, element)) {
final Integer preClosurePenalInterestType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
preClosurePenalInterestOnTypeIdParamName, element);
baseDataValidator.reset().parameter(preClosurePenalInterestOnTypeIdParamName).value(preClosurePenalInterestType).notNull()
.isOneOfTheseValues(PreClosurePenalInterestOnType.integerValues());
}
}
public void validateDepositTermDetailForUpdate(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(minDepositTermParamName, element)) {
final Integer minTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermParamName, element);
baseDataValidator.reset().parameter(minDepositTermParamName).value(minTerm).integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(maxDepositTermParamName, element)) {
final Integer maxTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermParamName, element);
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm).integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(minDepositTermTypeIdParamName, element)) {
final Integer minDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(minDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(minDepositTermTypeIdParamName).value(minDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
if (fromApiJsonHelper.parameterExists(maxDepositTermTypeIdParamName, element)) {
final Integer maxDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(maxDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(maxDepositTermTypeIdParamName).value(maxDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
if (fromApiJsonHelper.parameterExists(inMultiplesOfDepositTermParamName, element)) {
final Integer inMultiplesOfDepositTerm = fromApiJsonHelper.extractIntegerSansLocaleNamed(inMultiplesOfDepositTermParamName,
element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermParamName).value(inMultiplesOfDepositTerm).integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(inMultiplesOfDepositTermTypeIdParamName, element)) {
final Integer inMultiplesOfDepositTermType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(
inMultiplesOfDepositTermTypeIdParamName, element);
baseDataValidator.reset().parameter(inMultiplesOfDepositTermTypeIdParamName).value(inMultiplesOfDepositTermType)
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
}
/**
* Validation for advanced accounting options
*/
private void validatePaymentChannelFundSourceMappings(final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (fromApiJsonHelper.parameterExists(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element)) {
final JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
if (paymentChannelMappingArray != null && paymentChannelMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
final Long paymentTypeId = jsonObject.get(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
final Long paymentSpecificFundAccountId = jsonObject.get(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue())
.getAsLong();
baseDataValidator
.reset()
.parameter(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.toString()).value(paymentTypeId).notNull()
.integerGreaterThanZero();
baseDataValidator
.reset()
.parameter(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).value(paymentSpecificFundAccountId)
.notNull().integerGreaterThanZero();
i++;
} while (i < paymentChannelMappingArray.size());
}
}
}
private void validateChargeToIncomeAccountMappings(final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator, final JsonElement element) {
// validate for both fee and penalty charges
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element, true);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element, true);
}
private void validateChargeToIncomeAccountMappings(final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator, final JsonElement element, final boolean isPenalty) {
String parameterName;
if (isPenalty) {
parameterName = SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PENALTY_INCOME_ACCOUNT_MAPPING.getValue();
} else {
parameterName = SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FEE_INCOME_ACCOUNT_MAPPING.getValue();
}
if (fromApiJsonHelper.parameterExists(parameterName, element)) {
final JsonArray chargeToIncomeAccountMappingArray = fromApiJsonHelper.extractJsonArrayNamed(parameterName, element);
if (chargeToIncomeAccountMappingArray != null && chargeToIncomeAccountMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject();
final Long chargeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.getValue(),
jsonObject);
final Long incomeAccountId = fromApiJsonHelper.extractLongNamed(
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_ACCOUNT_ID.getValue(), jsonObject);
baseDataValidator.reset()
.parameter(parameterName + "[" + i + "]." + SAVINGS_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.getValue())
.value(chargeId).notNull().integerGreaterThanZero();
baseDataValidator.reset()
.parameter(parameterName + "[" + i + "]." + SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_ACCOUNT_ID.getValue())
.value(incomeAccountId).notNull().integerGreaterThanZero();
i++;
} while (i < chargeToIncomeAccountMappingArray.size());
}
}
}
public void validateRecurringDetailForCreate(JsonElement element, DataValidatorBuilder baseDataValidator) {
final Integer rdTypeId = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositTypeIdParamName, element);
baseDataValidator.reset().parameter(recurringDepositTypeIdParamName).value(rdTypeId).notNull()
.isOneOfTheseValues(RecurringDepositType.integerValues());
final Integer rdFrequency = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositFrequencyParamName, element);
baseDataValidator.reset().parameter(recurringDepositFrequencyParamName).value(rdFrequency).notNull().integerGreaterThanZero();
final Integer rdFrequencyTypeId = fromApiJsonHelper
.extractIntegerSansLocaleNamed(recurringDepositFrequencyTypeIdParamName, element);
baseDataValidator.reset().parameter(recurringDepositFrequencyTypeIdParamName).value(rdFrequencyTypeId).notNull()
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
public void validateRecurringDepositUpdate(JsonElement element, DataValidatorBuilder baseDataValidator) {
if (fromApiJsonHelper.parameterExists(recurringDepositTypeIdParamName, element)) {
final Integer rdTypeId = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositTypeIdParamName, element);
baseDataValidator.reset().parameter(recurringDepositTypeIdParamName).value(rdTypeId).notNull()
.isOneOfTheseValues(RecurringDepositType.integerValues());
}
if (fromApiJsonHelper.parameterExists(recurringDepositFrequencyParamName, element)) {
final Integer rdFrequency = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositFrequencyParamName, element);
baseDataValidator.reset().parameter(recurringDepositFrequencyParamName).value(rdFrequency).notNull().integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists(recurringDepositFrequencyTypeIdParamName, element)) {
final Integer rdFrequencyTypeId = fromApiJsonHelper.extractIntegerSansLocaleNamed(recurringDepositFrequencyTypeIdParamName,
element);
baseDataValidator.reset().parameter(recurringDepositFrequencyTypeIdParamName).value(rdFrequencyTypeId).notNull()
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
}
}
}
@@ -0,0 +1,486 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
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;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
/**
* Immutable data object representing a Fixed Deposit account.
*/
public class FixedDepositAccountData extends DepositAccountData {
// additional fields
private boolean interestFreePeriodApplicable;
private Integer interestFreeFromPeriod;
private Integer interestFreeToPeriod;
private EnumOptionData interestFreePeriodFrequencyType;
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private BigDecimal depositAmount;
private BigDecimal maturityAmount;
private LocalDate maturityDate;
private Integer depositPeriod;
private EnumOptionData depositPeriodFrequency;
// used for account close
private EnumOptionData onAccountClosure;
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> depositTermTypeOptions;
private Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions;
private Collection<EnumOptionData> depositPeriodFrequencyOptions;
private Collection<SavingsAccountData> savingsAccounts;
// for account close
private Collection<EnumOptionData> onAccountClosureOptions;
private Collection<CodeValueData> paymentTypeOptions;
public static FixedDepositAccountData instance(final DepositAccountData depositAccountData, final boolean interestFreePeriodApplicable,
final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod, final EnumOptionData interestFreePeriodFrequencyType,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm, final Integer maxDepositTerm,
final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal maturityAmount,
final LocalDate maturityDate, final Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
final EnumOptionData onAccountClosure) {
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
return new FixedDepositAccountData(depositAccountData.id, depositAccountData.accountNo, depositAccountData.externalId,
depositAccountData.groupId, depositAccountData.groupName, depositAccountData.clientId, depositAccountData.clientName,
depositAccountData.savingsProductId, depositAccountData.savingsProductName, depositAccountData.fieldOfficerId,
depositAccountData.fieldOfficerName, depositAccountData.status, depositAccountData.timeline, depositAccountData.currency,
depositAccountData.nominalAnnualInterestRate, depositAccountData.interestCompoundingPeriodType,
depositAccountData.interestPostingPeriodType, depositAccountData.interestCalculationType,
depositAccountData.interestCalculationDaysInYearType, depositAccountData.minRequiredOpeningBalance,
depositAccountData.lockinPeriodFrequency, depositAccountData.lockinPeriodFrequencyType,
depositAccountData.withdrawalFeeForTransfers, depositAccountData.summary, depositAccountData.transactions,
depositAccountData.productOptions, depositAccountData.fieldOfficerOptions,
depositAccountData.interestCompoundingPeriodTypeOptions, depositAccountData.interestPostingPeriodTypeOptions,
depositAccountData.interestCalculationTypeOptions, depositAccountData.interestCalculationDaysInYearTypeOptions,
depositAccountData.lockinPeriodFrequencyTypeOptions, depositAccountData.withdrawalFeeTypeOptions,
depositAccountData.charges, depositAccountData.chargeOptions, depositAccountData.accountChart,
depositAccountData.chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod, interestFreeToPeriod,
interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
depositPeriodFrequencyOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions,
savingsAccountDatas);
}
public static FixedDepositAccountData withInterestChart(final FixedDepositAccountData account,
final DepositAccountInterestRateChartData accountChart) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, account.transactions,
account.productOptions, account.fieldOfficerOptions, account.interestCompoundingPeriodTypeOptions,
account.interestPostingPeriodTypeOptions, account.interestCalculationTypeOptions,
account.interestCalculationDaysInYearTypeOptions, account.lockinPeriodFrequencyTypeOptions,
account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions, accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.interestFreePeriodTypeOptions, account.preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
account.inMultiplesOfDepositTermTypeOptions, account.depositTermTypeOptions, account.depositType, account.onAccountClosure,
account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
}
public static FixedDepositAccountData withTemplateOptions(final FixedDepositAccountData account,
final FixedDepositAccountData template, final Collection<SavingsAccountTransactionData> transactions,
final Collection<SavingsAccountChargeData> charges) {
if (template == null) {
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
return withTemplateOptions(account, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions, charges, chargeOptions,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions);
}
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, transactions,
template.productOptions, template.fieldOfficerOptions, template.interestCompoundingPeriodTypeOptions,
template.interestPostingPeriodTypeOptions, template.interestCalculationTypeOptions,
template.interestCalculationDaysInYearTypeOptions, template.lockinPeriodFrequencyTypeOptions,
template.withdrawalFeeTypeOptions, charges, template.chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, template.interestFreePeriodTypeOptions,
template.preClosurePenalInterestOnTypeOptions, account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType,
account.maxDepositTermType, account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate, account.depositPeriod, account.depositPeriodFrequency,
template.depositTermTypeOptions, template.inMultiplesOfDepositTermTypeOptions, template.depositPeriodFrequencyOptions,
account.depositType, account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions,
account.savingsAccounts);
}
public static FixedDepositAccountData withTemplateOptions(final FixedDepositAccountData account,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions,
final Collection<EnumOptionData> depositPeriodFrequencyOptions) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
}
public static FixedDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
final String groupName) {
final Long id = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final BigDecimal maturityAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
return new FixedDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, interestFreePeriodApplicable,
interestFreeFromPeriod, interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, interestFreePeriodTypeOptions,
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
public static FixedDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<CodeValueData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
return new FixedDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, interestFreePeriodApplicable,
interestFreeFromPeriod, interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, interestFreePeriodTypeOptions,
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, depositPeriodFrequencyOptions,
depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
public static FixedDepositAccountData withClosureTemplateDetails(final FixedDepositAccountData account,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<CodeValueData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, account.transactions,
account.productOptions, account.fieldOfficerOptions, account.interestCompoundingPeriodTypeOptions,
account.interestPostingPeriodTypeOptions, account.interestCalculationTypeOptions,
account.interestCalculationDaysInYearTypeOptions, account.lockinPeriodFrequencyTypeOptions,
account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.interestFreePeriodTypeOptions, account.preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.depositTermTypeOptions,
account.inMultiplesOfDepositTermTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
private FixedDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldofficerId, final String fieldofficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType,
final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
final EnumOptionData depositPeriodFrequency, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions,
final Collection<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas) {
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions, fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType);
// fixed deposit additional fields
this.interestFreePeriodApplicable = interestFreePeriodApplicable;
this.interestFreeFromPeriod = interestFreeFromPeriod;
this.interestFreeToPeriod = interestFreeToPeriod;
this.interestFreePeriodFrequencyType = interestFreePeriodFrequencyType;
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = maturityDate;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = depositPeriodFrequency;
this.onAccountClosure = onAccountClosure;
// template
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.depositTermTypeOptions = depositTermTypeOptions;
this.inMultiplesOfDepositTermTypeOptions = inMultiplesOfDepositTermTypeOptions;
this.depositPeriodFrequencyOptions = depositPeriodFrequencyOptions;
// account close template options
this.onAccountClosureOptions = onAccountClosureOptions;
this.paymentTypeOptions = paymentTypeOptions;
this.savingsAccounts = savingsAccountDatas;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) { return false; }
final FixedDepositAccountData rhs = (FixedDepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
}
@@ -0,0 +1,392 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
/**
* Immutable data object representing a Fixed Deposit product.
*/
public class FixedDepositProductData extends DepositProductData {
// additional fields
private boolean interestFreePeriodApplicable;
private Integer interestFreeFromPeriod;
private Integer interestFreeToPeriod;
protected EnumOptionData interestFreePeriodFrequencyType;
private boolean preClosurePenalApplicable;
protected BigDecimal preClosurePenalInterest;
protected EnumOptionData preClosurePenalInterestOnType;
protected Integer minDepositTerm;
protected Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
protected Integer inMultiplesOfDepositTerm;
protected EnumOptionData inMultiplesOfDepositTermType;
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> depositTermTypeOptions;
private Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions;
public static FixedDepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> interestFreePeriodTypes,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
return new FixedDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, accountingRule, accountingMappings, paymentChannelToFundSourceMappings,
currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions);
}
public static FixedDepositProductData withCharges(final FixedDepositProductData existingProduct, final Collection<ChargeData> charges) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.interestFreePeriodApplicable, existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
existingProduct.interestFreePeriodTypeOptions, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.depositTermTypeOptions, existingProduct.inMultiplesOfDepositTermTypeOptions);
}
/**
* Returns a {@link FixedDepositProductData} that contains and exist
* {@link FixedDepositProductData} data with further template data for
* dropdowns.
*/
public static FixedDepositProductData withTemplate(final FixedDepositProductData existingProduct,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> interestFreePeriodTypes,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate, existingProduct.interestFreePeriodApplicable,
existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType, interestFreePeriodTypes,
preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static FixedDepositProductData withAccountingDetails(final FixedDepositProductData existingProduct,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
accountingMappings, paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.interestFreePeriodApplicable, existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
existingProduct.interestFreePeriodTypeOptions, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.depositTermTypeOptions, existingProduct.inMultiplesOfDepositTermTypeOptions);
}
public static FixedDepositProductData instance(final DepositProductData depositProductData, final boolean interestFreePeriodApplicable,
final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod, final EnumOptionData interestFreePeriodFrequencyType,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm, final Integer maxDepositTerm,
final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final Collection<EnumOptionData> interestFreePeriodTypes = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
return new FixedDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
depositProductData.description, depositProductData.currency, depositProductData.nominalAnnualInterestRate,
depositProductData.interestCompoundingPeriodType, depositProductData.interestPostingPeriodType,
depositProductData.interestCalculationType, depositProductData.interestCalculationDaysInYearType,
depositProductData.lockinPeriodFrequency, depositProductData.lockinPeriodFrequencyType, depositProductData.accountingRule,
accountingMappings, paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static FixedDepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Collection<EnumOptionData> interestFreePeriodTypes = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
return new FixedDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings,
currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static FixedDepositProductData withInterestChart(final FixedDepositProductData existingProduct,
final Collection<InterestRateChartData> interestRateCharts) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
existingProduct.charges, existingProduct.chargeOptions, existingProduct.penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings, interestRateCharts,
existingProduct.chartTemplate, existingProduct.interestFreePeriodApplicable, existingProduct.interestFreeFromPeriod,
existingProduct.interestFreeToPeriod, existingProduct.interestFreePeriodFrequencyType,
existingProduct.preClosurePenalApplicable, existingProduct.preClosurePenalInterest,
existingProduct.preClosurePenalInterestOnType, existingProduct.interestFreePeriodTypeOptions,
existingProduct.preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, existingProduct.depositTermTypeOptions,
existingProduct.inMultiplesOfDepositTermTypeOptions);
}
private FixedDepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType,
final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType,
final Collection<EnumOptionData> depositTermTypeOptions, Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate);
// fixed deposit additional fields
this.interestFreePeriodApplicable = interestFreePeriodApplicable;
this.interestFreeFromPeriod = interestFreeFromPeriod;
this.interestFreeToPeriod = interestFreeToPeriod;
this.interestFreePeriodFrequencyType = interestFreePeriodFrequencyType;
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
// template
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.depositTermTypeOptions = depositTermTypeOptions;
this.inMultiplesOfDepositTermTypeOptions = inMultiplesOfDepositTermTypeOptions;
}
}
@@ -0,0 +1,536 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
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;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
/**
* Immutable data object representing a Recurring Deposit account.
*/
public class RecurringDepositAccountData extends DepositAccountData {
// additional fields
private boolean interestFreePeriodApplicable;
private Integer interestFreeFromPeriod;
private Integer interestFreeToPeriod;
private EnumOptionData interestFreePeriodFrequencyType;
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private BigDecimal depositAmount;
private BigDecimal maturityAmount;
private LocalDate maturityDate;
private Integer depositPeriod;
private EnumOptionData depositPeriodFrequency;
private BigDecimal recurringDepositAmount;
private EnumOptionData recurringDepositType;
private Integer recurringDepositFrequency;
private EnumOptionData recurringDepositFrequencyType;
// used for account close
private EnumOptionData onAccountClosure;
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> recurringDepositTypeOptions;
private Collection<EnumOptionData> recurringDepositFrequencyTypeOptions;
private Collection<EnumOptionData> depositTermTypeOptions;
private Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions;
private Collection<EnumOptionData> depositPeriodFrequencyOptions;
private Collection<SavingsAccountData> savingsAccounts;
// for account close
private Collection<EnumOptionData> onAccountClosureOptions;
private Collection<CodeValueData> paymentTypeOptions;
public static RecurringDepositAccountData instance(final DepositAccountData depositAccountData,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
final EnumOptionData depositPeriodFrequency, final BigDecimal recurringDepositAmount,
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
final EnumOptionData recurringDepositFrequencyType, final EnumOptionData onAccountClosure) {
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
return new RecurringDepositAccountData(depositAccountData.id, depositAccountData.accountNo, depositAccountData.externalId,
depositAccountData.groupId, depositAccountData.groupName, depositAccountData.clientId, depositAccountData.clientName,
depositAccountData.savingsProductId, depositAccountData.savingsProductName, depositAccountData.fieldOfficerId,
depositAccountData.fieldOfficerName, depositAccountData.status, depositAccountData.timeline, depositAccountData.currency,
depositAccountData.nominalAnnualInterestRate, depositAccountData.interestCompoundingPeriodType,
depositAccountData.interestPostingPeriodType, depositAccountData.interestCalculationType,
depositAccountData.interestCalculationDaysInYearType, depositAccountData.minRequiredOpeningBalance,
depositAccountData.lockinPeriodFrequency, depositAccountData.lockinPeriodFrequencyType,
depositAccountData.withdrawalFeeForTransfers, depositAccountData.summary, depositAccountData.transactions,
depositAccountData.productOptions, depositAccountData.fieldOfficerOptions,
depositAccountData.interestCompoundingPeriodTypeOptions, depositAccountData.interestPostingPeriodTypeOptions,
depositAccountData.interestCalculationTypeOptions, depositAccountData.interestCalculationDaysInYearTypeOptions,
depositAccountData.lockinPeriodFrequencyTypeOptions, depositAccountData.withdrawalFeeTypeOptions,
depositAccountData.charges, depositAccountData.chargeOptions, depositAccountData.accountChart,
depositAccountData.chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod, interestFreeToPeriod,
interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
public static RecurringDepositAccountData withInterestChart(final RecurringDepositAccountData account,
final DepositAccountInterestRateChartData accountChart) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, account.transactions,
account.productOptions, account.fieldOfficerOptions, account.interestCompoundingPeriodTypeOptions,
account.interestPostingPeriodTypeOptions, account.interestCalculationTypeOptions,
account.interestCalculationDaysInYearTypeOptions, account.lockinPeriodFrequencyTypeOptions,
account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions, accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.interestFreePeriodTypeOptions, account.preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.recurringDepositAmount,
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
}
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
final RecurringDepositAccountData template, final Collection<SavingsAccountTransactionData> transactions,
final Collection<SavingsAccountChargeData> charges) {
if (template == null) {
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
return withTemplateOptions(account, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions, charges, chargeOptions,
interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions, depositTermTypeOptions,
inMultiplesOfDepositTermTypeOptions, recurringDepositTypeOptions, recurringDepositFrequencyTypeOptions,
depositPeriodFrequencyOptions);
}
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, transactions,
template.productOptions, template.fieldOfficerOptions, template.interestCompoundingPeriodTypeOptions,
template.interestPostingPeriodTypeOptions, template.interestCalculationTypeOptions,
template.interestCalculationDaysInYearTypeOptions, template.lockinPeriodFrequencyTypeOptions,
template.withdrawalFeeTypeOptions, charges, template.chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, template.interestFreePeriodTypeOptions,
template.preClosurePenalInterestOnTypeOptions, account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType,
account.maxDepositTermType, account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount,
account.maturityAmount, account.maturityDate, account.depositPeriod, account.depositPeriodFrequency,
account.recurringDepositAmount, template.depositTermTypeOptions, template.inMultiplesOfDepositTermTypeOptions,
account.recurringDepositType, account.recurringDepositFrequency, account.recurringDepositFrequencyType,
template.recurringDepositTypeOptions, template.recurringDepositFrequencyTypeOptions,
template.depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, account.savingsAccounts);
}
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions,
final Collection<EnumOptionData> recurringDepositTypeOptions,
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions,
final Collection<EnumOptionData> depositPeriodFrequencyOptions) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, interestFreePeriodTypeOptions, preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.recurringDepositAmount,
depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
account.recurringDepositFrequency, account.recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
}
public static RecurringDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
final String groupName) {
final Long id = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final BigDecimal maturityAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final BigDecimal recurringDepositAmount = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final EnumOptionData recurringDepositType = null;
final Integer recurringDepositFrequency = null;
final EnumOptionData recurringDepositFrequencyType = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.RECURRING_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
return new RecurringDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, interestFreePeriodApplicable,
interestFreeFromPeriod, interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, interestFreePeriodTypeOptions,
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
public static RecurringDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas) {
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final BigDecimal recurringDepositAmount = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
final EnumOptionData recurringDepositType = null;
final Integer recurringDepositFrequency = null;
final EnumOptionData recurringDepositFrequencyType = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Collection<EnumOptionData> depositPeriodFrequencyOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.RECURRING_DEPOSIT.getValue());
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
return new RecurringDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, interestFreePeriodApplicable,
interestFreeFromPeriod, interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, interestFreePeriodTypeOptions,
preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
public static RecurringDepositAccountData withClosureTemplateDetails(final RecurringDepositAccountData account,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.summary, account.transactions,
account.productOptions, account.fieldOfficerOptions, account.interestCompoundingPeriodTypeOptions,
account.interestPostingPeriodTypeOptions, account.interestCalculationTypeOptions,
account.interestCalculationDaysInYearTypeOptions, account.lockinPeriodFrequencyTypeOptions,
account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions, account.accountChart, account.chartTemplate,
account.interestFreePeriodApplicable, account.interestFreeFromPeriod, account.interestFreeToPeriod,
account.interestFreePeriodFrequencyType, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.interestFreePeriodTypeOptions, account.preClosurePenalInterestOnTypeOptions,
account.minDepositTerm, account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType,
account.inMultiplesOfDepositTerm, account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount,
account.maturityDate, account.depositPeriod, account.depositPeriodFrequency, account.recurringDepositAmount,
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
}
private RecurringDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldofficerId, final String fieldofficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType,
final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
final EnumOptionData depositPeriodFrequency, final BigDecimal recurringDepositAmount,
final Collection<EnumOptionData> depositTermTypeOptions, Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions,
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
final EnumOptionData recurringDepositFrequencyType, final Collection<EnumOptionData> recurringDepositTypeOptions,
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions,
final Collection<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas) {
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions, fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType);
this.interestFreePeriodApplicable = interestFreePeriodApplicable;
this.interestFreeFromPeriod = interestFreeFromPeriod;
this.interestFreeToPeriod = interestFreeToPeriod;
this.interestFreePeriodFrequencyType = interestFreePeriodFrequencyType;
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = maturityDate;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = depositPeriodFrequency;
this.recurringDepositAmount = recurringDepositAmount;
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
this.recurringDepositFrequency = recurringDepositFrequency;
this.recurringDepositType = recurringDepositType;
// template data
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.recurringDepositTypeOptions = recurringDepositTypeOptions;
this.recurringDepositFrequencyTypeOptions = recurringDepositFrequencyTypeOptions;
this.depositTermTypeOptions = depositTermTypeOptions;
this.inMultiplesOfDepositTermTypeOptions = inMultiplesOfDepositTermTypeOptions;
this.depositPeriodFrequencyOptions = depositPeriodFrequencyOptions;
this.onAccountClosure = onAccountClosure;
this.savingsAccounts = savingsAccountDatas;
// account close template options
this.onAccountClosureOptions = onAccountClosureOptions;
this.paymentTypeOptions = paymentTypeOptions;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) { return false; }
final RecurringDepositAccountData rhs = (RecurringDepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
}
@@ -0,0 +1,433 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData;
/**
* Immutable data object represent a Recurring Deposit product.
*/
public class RecurringDepositProductData extends DepositProductData {
private boolean interestFreePeriodApplicable;
private Integer interestFreeFromPeriod;
private Integer interestFreeToPeriod;
protected EnumOptionData interestFreePeriodFrequencyType;
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private EnumOptionData recurringDepositType;
private Integer recurringDepositFrequency;
private EnumOptionData recurringDepositFrequencyType;
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> recurringDepositTypeOptions;
private Collection<EnumOptionData> recurringDepositFrequencyTypeOptions;
private Collection<EnumOptionData> depositTermTypeOptions;
private Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions;
public static RecurringDepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> interestFreePeriodTypes,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> recurringDepositTypeOptions,
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final EnumOptionData recurringDepositType = null;
final Integer recurringDepositFrequency = null;
final EnumOptionData recurringDepositFrequencyType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, accountingRule, accountingMappings, paymentChannelToFundSourceMappings,
currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static RecurringDepositProductData withCharges(final RecurringDepositProductData existingProduct,
final Collection<ChargeData> charges) {
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.interestFreePeriodApplicable, existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
existingProduct.interestFreePeriodTypeOptions, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
existingProduct.inMultiplesOfDepositTermTypeOptions);
}
/**
* Returns a {@link RecurringDepositProductData} that contains and exist
* {@link RecurringDepositProductData} data with further template data for
* dropdowns.
*/
public static RecurringDepositProductData withTemplate(final RecurringDepositProductData existingProduct,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> interestFreePeriodTypes,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> recurringDepositTypeOptions,
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate, existingProduct.interestFreePeriodApplicable,
existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType, interestFreePeriodTypes,
preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, existingProduct.recurringDepositType,
existingProduct.recurringDepositFrequency, existingProduct.recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static RecurringDepositProductData withAccountingDetails(final RecurringDepositProductData existingProduct,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule,
accountingMappings, paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.interestFreePeriodApplicable, existingProduct.interestFreeFromPeriod, existingProduct.interestFreeToPeriod,
existingProduct.interestFreePeriodFrequencyType, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
existingProduct.interestFreePeriodTypeOptions, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
existingProduct.inMultiplesOfDepositTermTypeOptions);
}
public static RecurringDepositProductData instance(final DepositProductData depositProductData,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType,
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
final EnumOptionData recurringDepositFrequencyType) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final Collection<EnumOptionData> interestFreePeriodTypes = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
return new RecurringDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
depositProductData.description, depositProductData.currency, depositProductData.nominalAnnualInterestRate,
depositProductData.interestCompoundingPeriodType, depositProductData.interestPostingPeriodType,
depositProductData.interestCalculationType, depositProductData.interestCalculationDaysInYearType,
depositProductData.lockinPeriodFrequency, depositProductData.lockinPeriodFrequencyType, depositProductData.accountingRule,
accountingMappings, paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static RecurringDepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<CodeValueData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final boolean interestFreePeriodApplicable = false;
final Integer interestFreeFromPeriod = null;
final Integer interestFreeToPeriod = null;
final EnumOptionData interestFreePeriodFrequencyType = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Collection<EnumOptionData> interestFreePeriodTypes = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final EnumOptionData recurringDepositType = null;
final Integer recurringDepositFrequency = null;
final EnumOptionData recurringDepositFrequencyType = null;
final Collection<EnumOptionData> recurringDepositTypeOptions = null;
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final Collection<EnumOptionData> depositTermTypeOptions = null;
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings,
currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
}
public static RecurringDepositProductData withInterestChart(final RecurringDepositProductData product,
final Collection<InterestRateChartData> interestRateCharts) {
return new RecurringDepositProductData(product.id, product.name, product.shortName, product.description, product.currency,
product.nominalAnnualInterestRate, product.interestCompoundingPeriodType, product.interestPostingPeriodType,
product.interestCalculationType, product.interestCalculationDaysInYearType, product.lockinPeriodFrequency,
product.lockinPeriodFrequencyType, product.accountingRule, product.accountingMappings,
product.paymentChannelToFundSourceMappings, product.currencyOptions, product.interestCompoundingPeriodTypeOptions,
product.interestPostingPeriodTypeOptions, product.interestCalculationTypeOptions,
product.interestCalculationDaysInYearTypeOptions, product.lockinPeriodFrequencyTypeOptions,
product.withdrawalFeeTypeOptions, product.paymentTypeOptions, product.accountingRuleOptions,
product.accountingMappingOptions, product.charges, product.chargeOptions, product.penaltyOptions,
product.feeToIncomeAccountMappings, product.penaltyToIncomeAccountMappings, interestRateCharts, product.chartTemplate,
product.interestFreePeriodApplicable, product.interestFreeFromPeriod, product.interestFreeToPeriod,
product.interestFreePeriodFrequencyType, product.preClosurePenalApplicable, product.preClosurePenalInterest,
product.preClosurePenalInterestOnType, product.interestFreePeriodTypeOptions, product.preClosurePenalInterestOnTypeOptions,
product.minDepositTerm, product.maxDepositTerm, product.minDepositTermType, product.maxDepositTermType,
product.inMultiplesOfDepositTerm, product.inMultiplesOfDepositTermType, product.recurringDepositType,
product.recurringDepositFrequency, product.recurringDepositFrequencyType, product.recurringDepositTypeOptions,
product.recurringDepositFrequencyTypeOptions, product.depositTermTypeOptions, product.inMultiplesOfDepositTermTypeOptions);
}
private RecurringDepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType,
final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate,
final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod, final Integer interestFreeToPeriod,
final EnumOptionData interestFreePeriodFrequencyType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType,
final Collection<EnumOptionData> interestFreePeriodTypeOptions,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType,
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
final EnumOptionData recurringDepositFrequencyType, final Collection<EnumOptionData> recurringDepositTypeOptions,
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate);
this.interestFreePeriodApplicable = interestFreePeriodApplicable;
this.interestFreeFromPeriod = interestFreeFromPeriod;
this.interestFreeToPeriod = interestFreeToPeriod;
this.interestFreePeriodFrequencyType = interestFreePeriodFrequencyType;
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
this.recurringDepositFrequency = recurringDepositFrequency;
this.recurringDepositType = recurringDepositType;
// template data
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.recurringDepositTypeOptions = recurringDepositTypeOptions;
this.recurringDepositFrequencyTypeOptions = recurringDepositFrequencyTypeOptions;
this.depositTermTypeOptions = depositTermTypeOptions;
this.inMultiplesOfDepositTermTypeOptions = inMultiplesOfDepositTermTypeOptions;
}
}
@@ -28,13 +28,15 @@ public class SavingsAccountStatusEnumData {
@SuppressWarnings("unused")
private final boolean closed;
@SuppressWarnings("unused")
private final boolean prematureClosed;
@SuppressWarnings("unused")
private final boolean transferInProgress;
@SuppressWarnings("unused")
private final boolean transferOnHold;
public SavingsAccountStatusEnumData(final Long id, final String code, final String value, final boolean submittedAndPendingApproval,
final boolean approved, final boolean rejected, final boolean withdrawnByApplicant, final boolean active, final boolean closed,
final boolean transferInProgress, final boolean transferOnHold) {
final boolean prematureClosed, final boolean transferInProgress, final boolean transferOnHold) {
this.id = id;
this.code = code;
this.value = value;
@@ -44,6 +46,7 @@ public class SavingsAccountStatusEnumData {
this.withdrawnByApplicant = withdrawnByApplicant;
this.active = active;
this.closed = closed;
this.prematureClosed = prematureClosed;
this.transferInProgress = transferInProgress;
this.transferOnHold = transferOnHold;
}
@@ -0,0 +1,368 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.chartIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.fieldOfficerIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.groupIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.productIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import java.math.BigDecimal;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper;
import org.mifosplatform.portfolio.group.exception.CenterNotActiveException;
import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.RecurringDepositType;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.exception.FixedDepositProductNotFoundException;
import org.mifosplatform.portfolio.savings.exception.RecurringDepositProductNotFoundException;
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class DepositAccountAssembler {
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
private final SavingsHelper savingsHelper = new SavingsHelper();
private final ClientRepositoryWrapper clientRepository;
private final GroupRepositoryWrapper groupRepository;
private final StaffRepositoryWrapper staffRepository;
private final FixedDepositProductRepository fixedDepositProductRepository;
private final RecurringDepositProductRepository recurringDepositProductRepository;
private final SavingsAccountRepositoryWrapper savingsAccountRepository;
private final SavingsAccountChargeAssembler savingsAccountChargeAssembler;
private final FromJsonHelper fromApiJsonHelper;
private final DepositProductAssembler depositProductAssembler;
@Autowired
public DepositAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
final ClientRepositoryWrapper clientRepository, final GroupRepositoryWrapper groupRepository,
final StaffRepositoryWrapper staffRepository, final FixedDepositProductRepository fixedDepositProductRepository,
final SavingsAccountRepositoryWrapper savingsAccountRepository,
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
final DepositProductAssembler depositProductAssembler, final RecurringDepositProductRepository recurringDepositProductRepository) {
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
this.clientRepository = clientRepository;
this.groupRepository = groupRepository;
this.staffRepository = staffRepository;
this.fixedDepositProductRepository = fixedDepositProductRepository;
this.savingsAccountRepository = savingsAccountRepository;
this.savingsAccountChargeAssembler = savingsAccountChargeAssembler;
this.fromApiJsonHelper = fromApiJsonHelper;
this.depositProductAssembler = depositProductAssembler;
this.recurringDepositProductRepository = recurringDepositProductRepository;
}
/**
* Assembles a new {@link SavingsAccount} from JSON details passed in
* request inheriting details where relevant from chosen
* {@link SavingsProduct}.
*/
public SavingsAccount assembleFrom(final JsonCommand command, final AppUser submittedBy, final DepositAccountType depositAccountType) {
final JsonElement element = command.parsedJson();
final String accountNo = this.fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
final Long productId = this.fromApiJsonHelper.extractLongNamed(productIdParamName, element);
SavingsProduct product = null;
if (depositAccountType.isFixedDeposit()) {
product = this.fixedDepositProductRepository.findOne(productId);
if (product == null) { throw new FixedDepositProductNotFoundException(productId); }
} else if (depositAccountType.isRecurringDeposit()) {
product = this.recurringDepositProductRepository.findOne(productId);
if (product == null) { throw new RecurringDepositProductNotFoundException(productId); }
}
if (product == null) { throw new SavingsProductNotFoundException(productId); }
Client client = null;
Group group = null;
Staff fieldOfficer = null;
AccountType accountType = AccountType.INVALID;
final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId);
accountType = AccountType.INDIVIDUAL;
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
}
final Long groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
if (groupId != null) {
group = this.groupRepository.findOneWithNotFoundDetection(groupId);
accountType = AccountType.GROUP;
}
if (group != null && client != null) {
if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); }
accountType = AccountType.JLG;
if (group.isNotActive()) {
if (group.isCenter()) { throw new CenterNotActiveException(groupId); }
throw new GroupNotActiveException(groupId);
}
}
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
if (fieldOfficerId != null) {
fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId);
}
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
BigDecimal interestRate = null;
if (command.parameterExists(nominalAnnualInterestRateParamName)) {
interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
} else {
interestRate = product.nominalAnnualInterestRate();
}
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
if (interestPeriodTypeValue != null) {
interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
} else {
interestCompoundingPeriodType = product.interestCompoundingPeriodType();
}
SavingsPostingInterestPeriodType interestPostingPeriodType = null;
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
if (interestPostingPeriodTypeValue != null) {
interestPostingPeriodType = SavingsPostingInterestPeriodType.fromInt(interestPostingPeriodTypeValue);
} else {
interestPostingPeriodType = product.interestPostingPeriodType();
}
SavingsInterestCalculationType interestCalculationType = null;
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
if (interestCalculationTypeValue != null) {
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
} else {
interestCalculationType = product.interestCalculationType();
}
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null;
final Integer interestCalculationDaysInYearTypeValue = command
.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
if (interestCalculationDaysInYearTypeValue != null) {
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
} else {
interestCalculationDaysInYearType = product.interestCalculationDaysInYearType();
}
BigDecimal minRequiredOpeningBalance = null;
if (command.parameterExists(minRequiredOpeningBalanceParamName)) {
minRequiredOpeningBalance = command.bigDecimalValueOfParameterNamed(minRequiredOpeningBalanceParamName);
} else {
minRequiredOpeningBalance = product.minRequiredOpeningBalance();
}
@SuppressWarnings("unused")
Integer lockinPeriodFrequency = null;
if (command.parameterExists(lockinPeriodFrequencyParamName)) {
lockinPeriodFrequency = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
} else {
lockinPeriodFrequency = product.lockinPeriodFrequency();
}
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
Integer lockinPeriodFrequencyTypeValue = null;
if (command.parameterExists(lockinPeriodFrequencyTypeParamName)) {
lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
if (lockinPeriodFrequencyTypeValue != null) {
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
}
} else {
lockinPeriodFrequencyType = product.lockinPeriodFrequencyType();
}
boolean iswithdrawalFeeApplicableForTransfer = false;
if (command.parameterExists(withdrawalFeeForTransfersParamName)) {
iswithdrawalFeeApplicableForTransfer = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
}
final Set<SavingsAccountCharge> charges = this.savingsAccountChargeAssembler.fromParsedJson(element, product.currency().getCode());
DepositAccountInterestRateChart accountChart = null;
InterestRateChart productChart = null;
if (command.parameterExists(chartIdParamName)) {
Long chartId = command.longValueOfParameterNamed(chartIdParamName);
productChart = product.findChart(chartId);
} else {
productChart = product.applicableChart(submittedOnDate);
}
accountChart = DepositAccountInterestRateChart.from(productChart);
SavingsAccount account = null;
if (depositAccountType.isFixedDeposit()) {
final DepositProductTermAndPreClosure prodTermAndPreClosure = ((FixedDepositProduct) product).depositProductTermAndPreClosure();
final DepositAccountTermAndPreClosure accountTermAndPreClosure = this.assembleAccountTermAndPreClosure(command,
prodTermAndPreClosure);
FixedDepositAccount fdAccount = FixedDepositAccount.createNewApplicationForSubmittal(client, group, product, fieldOfficer,
accountNo, externalId, accountType, submittedOnDate, submittedBy, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequencyTypeValue, lockinPeriodFrequencyType, iswithdrawalFeeApplicableForTransfer, charges,
accountTermAndPreClosure, accountChart);
accountTermAndPreClosure.updateAccountReference(fdAccount);
fdAccount.validateDomainRules();
account = fdAccount;
} else if (depositAccountType.isRecurringDeposit()) {
final DepositProductTermAndPreClosure prodTermAndPreClosure = ((RecurringDepositProduct) product)
.depositProductTermAndPreClosure();
final DepositAccountTermAndPreClosure accountTermAndPreClosure = this.assembleAccountTermAndPreClosure(command,
prodTermAndPreClosure);
final DepositProductRecurringDetail prodRecurringDetail = ((RecurringDepositProduct) product).depositRecurringDetail();
final DepositAccountRecurringDetail accountRecurringDetail = this.assembleAccountRecurringDetail(command,
prodRecurringDetail.recurringDetail());
RecurringDepositAccount rdAccount = RecurringDepositAccount.createNewApplicationForSubmittal(client, group, product,
fieldOfficer, accountNo, externalId, accountType, submittedOnDate, submittedBy, interestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
minRequiredOpeningBalance, lockinPeriodFrequencyTypeValue, lockinPeriodFrequencyType,
iswithdrawalFeeApplicableForTransfer, charges, accountTermAndPreClosure, accountRecurringDetail, accountChart);
accountTermAndPreClosure.updateAccountReference(rdAccount);
accountRecurringDetail.updateAccountReference(rdAccount);
rdAccount.validateDomainRules();
account = rdAccount;
}
if (account != null) {
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant(), depositAccountType.resourceName());
}
return account;
}
public SavingsAccount assembleFrom(final Long savingsId, DepositAccountType depositAccountType) {
final SavingsAccount account = this.savingsAccountRepository.findOneWithNotFoundDetection(savingsId, depositAccountType);
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
return account;
}
public void assignSavingAccountHelpers(final SavingsAccount savingsAccount) {
savingsAccount.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
}
public DepositAccountTermAndPreClosure assembleAccountTermAndPreClosure(final JsonCommand command,
final DepositProductTermAndPreClosure productTermAndPreclosure) {
final DepositPreClosureDetail productPreClosure = (productTermAndPreclosure == null) ? null : productTermAndPreclosure
.depositPreClosureDetail();
final DepositTermDetail productTerm = (productTermAndPreclosure == null) ? null : productTermAndPreclosure.depositTermDetail();
final DepositPreClosureDetail updatedProductPreClosure = this.depositProductAssembler.assemblePreClosureDetail(command,
productPreClosure);
final DepositTermDetail updatedProductTerm = this.depositProductAssembler.assembleDepositTermDetail(command, productTerm);
final BigDecimal depositAmount = command.bigDecimalValueOfParameterNamed(depositAmountParamName);
final Integer depositPeriod = command.integerValueOfParameterNamed(depositPeriodParamName);
final Integer depositPeriodFrequencyId = command.integerValueOfParameterNamed(depositPeriodFrequencyIdParamName);
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
final SavingsAccount account = null;
// calculate maturity amount
final BigDecimal maturityAmount = null;// calculated and updated in
// account
final LocalDate maturityDate = null;// calculated and updated in account
final DepositAccountOnClosureType accountOnClosureType = null;
return DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure, updatedProductTerm, account, depositAmount,
maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
}
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final JsonCommand command,
final DepositRecurringDetail prodRecurringDetail) {
RecurringDepositType recurringDepositType = null;
Integer recurringDepositTypeValue = null;
final BigDecimal recurringDepositAmount = command.bigDecimalValueOfParameterNamed(recurringDepositAmountParamName);
if (command.parameterExists(recurringDepositTypeIdParamName)) {
recurringDepositTypeValue = command.integerValueOfParameterNamed(recurringDepositTypeIdParamName);
} else {
recurringDepositTypeValue = prodRecurringDetail.recurringDepositType();
}
if (recurringDepositTypeValue != null) {
recurringDepositType = RecurringDepositType.fromInt(recurringDepositTypeValue);
}
SavingsPeriodFrequencyType recurringDepositFrequencyType = null;
Integer recurringDepositFrequencyTypeValue = null;
if (command.parameterExists(recurringDepositFrequencyTypeIdParamName)) {
recurringDepositFrequencyTypeValue = command.integerValueOfParameterNamed(recurringDepositFrequencyTypeIdParamName);
} else {
recurringDepositFrequencyTypeValue = prodRecurringDetail.recurringDepositFrequencyTypeId();
}
if (recurringDepositFrequencyTypeValue != null) {
recurringDepositFrequencyType = SavingsPeriodFrequencyType.fromInt(recurringDepositFrequencyTypeValue);
}
Integer recurringDepositFrequency = null;
if (command.parameterExists(recurringDepositFrequencyTypeIdParamName)) {
recurringDepositFrequency = command.integerValueOfParameterNamed(recurringDepositFrequencyParamName);
} else {
recurringDepositFrequency = prodRecurringDetail.recurringDepositFrequency();
}
final DepositRecurringDetail depositRecurringDetail = DepositRecurringDetail.createFrom(recurringDepositType,
recurringDepositFrequency, recurringDepositFrequencyType);
final DepositAccountRecurringDetail depositAccountRecurringDetail = DepositAccountRecurringDetail.createNew(recurringDepositAmount,
depositRecurringDetail, null);
return depositAccountRecurringDetail;
}
}
@@ -0,0 +1,30 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import java.math.BigDecimal;
import java.util.Map;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.useradministration.domain.AppUser;
public interface DepositAccountDomainService {
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee);
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail);
SavingsAccountTransaction handleAccountClosure(SavingsAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
LocalDate tenantsTodayDate, Map<String, Object> changes);
SavingsAccountTransaction handleAccountPreMatureClosure(SavingsAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
LocalDate tenantsTodayDate, Map<String, Object> changes);
}
@@ -0,0 +1,320 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.toSavingsAccountIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferDescriptionParamName;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.account.domain.AccountTransferDetailRepository;
import org.mifosplatform.portfolio.account.domain.AccountTransferDetails;
import org.mifosplatform.portfolio.account.domain.AccountTransferTransaction;
import org.mifosplatform.portfolio.account.domain.AccountTransferType;
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DepositAccountDomainServiceJpa implements DepositAccountDomainService {
private final SavingsAccountRepositoryWrapper savingsAccountRepository;
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
private final AccountTransferDetailRepository accountTransferDetailRepository;
private final DepositAccountAssembler depositAccountAssembler;
private final SavingsAccountDomainService savingsAccountDomainService;
@Autowired
public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository,
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
final JournalEntryWritePlatformService journalEntryWritePlatformService,
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final AccountTransferDetailRepository accountTransferDetailRepository, final DepositAccountAssembler depositAccountAssembler,
final SavingsAccountDomainService savingsAccountDomainService) {
this.savingsAccountRepository = savingsAccountRepository;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
this.accountTransferDetailRepository = accountTransferDetailRepository;
this.depositAccountAssembler = depositAccountAssembler;
this.savingsAccountDomainService = savingsAccountDomainService;
}
@Transactional
@Override
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
final boolean applyWithdrawFee) {
final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date());
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, applyWithdrawFee);
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
saveTransactionToGenerateTransactionId(withdrawal);
this.savingsAccountRepository.save(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return withdrawal;
}
@Transactional
@Override
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date());
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today);
}
saveTransactionToGenerateTransactionId(deposit);
this.savingsAccountRepository.save(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return deposit;
}
@Transactional
@Override
public SavingsAccountTransaction handleAccountClosure(final SavingsAccount account, final PaymentDetail paymentDetail,
final AppUser user, final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final DepositAccountType depositAccountType = account.depositAccountType();
SavingsAccountTransaction withdrawal = null;
final MathContext mc = MathContext.DECIMAL64;
if (depositAccountType.isFixedDeposit()) {
final FixedDepositAccount fdAccount = (FixedDepositAccount) account;
withdrawal = fdAccount.close(user, command, tenantsTodayDate, paymentDetail, changes);
final Money transactionAmount = withdrawal.getAmount(fdAccount.getCurrency());
final LocalDate transactionDate = withdrawal.transactionLocalDate();
if (fdAccount.isReinvestOnClosure()) {
FixedDepositAccount reinvestedDeposit = fdAccount.reInvest(transactionAmount);
fdAccount.updateMaturityDateAndAmountBeforeAccountActivation(mc);
this.savingsAccountRepository.save(reinvestedDeposit);
autoGenerateAccountNumber(reinvestedDeposit);
} else if (fdAccount.isTransferToSavingsOnClosure()) {
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
DepositAccountType.SAVINGS_DEPOSIT);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
withdrawal.transactionLocalDate(), transactionAmount.getAmount(), null);
final AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToSavingsTransfer(fdAccount.office(),
fdAccount.getClient(), fdAccount, toSavingsAccount.office(), toSavingsAccount.getClient(), toSavingsAccount,
AccountTransferType.ACCOUNT_TRANSFER.getValue());
AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(
accountTransferDetails, withdrawal, deposit, transactionDate, transactionAmount, transferDescription);
accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction);
this.accountTransferDetailRepository.save(accountTransferDetails);
}
} else if (depositAccountType.isRecurringDeposit()) {
final RecurringDepositAccount rdAccount = (RecurringDepositAccount) account;
withdrawal = rdAccount.close(user, command, tenantsTodayDate, paymentDetail, changes);
final Money transactionAmount = withdrawal.getAmount(rdAccount.getCurrency());
final LocalDate transactionDate = withdrawal.transactionLocalDate();
if (rdAccount.isReinvestOnClosure()) {
RecurringDepositAccount reinvestedDeposit = rdAccount.reInvest(transactionAmount);
final LocalDate transactionStartDate = rdAccount.depositStartDate();
rdAccount.updateMaturityDateAndAmount(mc, transactionStartDate);
this.savingsAccountRepository.save(reinvestedDeposit);
autoGenerateAccountNumber(reinvestedDeposit);
} else if (rdAccount.isTransferToSavingsOnClosure()) {
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
DepositAccountType.SAVINGS_DEPOSIT);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
withdrawal.transactionLocalDate(), transactionAmount.getAmount(), null);
final AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToSavingsTransfer(rdAccount.office(),
rdAccount.getClient(), rdAccount, toSavingsAccount.office(), toSavingsAccount.getClient(), toSavingsAccount,
AccountTransferType.ACCOUNT_TRANSFER.getValue());
AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(
accountTransferDetails, withdrawal, deposit, transactionDate, transactionAmount, transferDescription);
accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction);
this.accountTransferDetailRepository.save(accountTransferDetails);
}
}
this.savingsAccountRepository.save(account);
if (withdrawal != null) {
saveTransactionToGenerateTransactionId(withdrawal);
}
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return withdrawal;
}
private void autoGenerateAccountNumber(final SavingsAccount account) {
if (account.isAccountNumberRequiresAutoGeneration()) {
final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory
.determineSavingsAccountNoGenerator(account.getId());
account.updateAccountNo(accountNoGenerator.generate());
this.savingsAccountRepository.save(account);
}
}
@Transactional
@Override
public SavingsAccountTransaction handleAccountPreMatureClosure(final SavingsAccount account, final PaymentDetail paymentDetail,
final AppUser user, final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final DepositAccountType depositAccountType = account.depositAccountType();
SavingsAccountTransaction withdrawal = null;
if (depositAccountType.isFixedDeposit()) {
final FixedDepositAccount fdAccount = (FixedDepositAccount) account;
withdrawal = fdAccount.prematureClosure(user, command, tenantsTodayDate, paymentDetail, changes);
final Money transactionAmount = withdrawal.getAmount(fdAccount.getCurrency());
final LocalDate transactionDate = withdrawal.transactionLocalDate();
if (fdAccount.isTransferToSavingsOnClosure()) {
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
DepositAccountType.SAVINGS_DEPOSIT);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
withdrawal.transactionLocalDate(), transactionAmount.getAmount(), null);
final AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToSavingsTransfer(fdAccount.office(),
fdAccount.getClient(), fdAccount, toSavingsAccount.office(), toSavingsAccount.getClient(), toSavingsAccount,
AccountTransferType.ACCOUNT_TRANSFER.getValue());
AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(
accountTransferDetails, withdrawal, deposit, transactionDate, transactionAmount, transferDescription);
accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction);
this.accountTransferDetailRepository.save(accountTransferDetails);
}
} else if (depositAccountType.isRecurringDeposit()) {
final RecurringDepositAccount rdAccount = (RecurringDepositAccount) account;
withdrawal = rdAccount.prematureClosure(user, command, tenantsTodayDate, paymentDetail, changes);
final Money transactionAmount = withdrawal.getAmount(rdAccount.getCurrency());
final LocalDate transactionDate = withdrawal.transactionLocalDate();
if (rdAccount.isTransferToSavingsOnClosure()) {
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
DepositAccountType.SAVINGS_DEPOSIT);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
transactionDate, transactionAmount.getAmount(), null);
final AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToSavingsTransfer(rdAccount.office(),
rdAccount.getClient(), rdAccount, toSavingsAccount.office(), toSavingsAccount.getClient(), toSavingsAccount,
AccountTransferType.ACCOUNT_TRANSFER.getValue());
AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(
accountTransferDetails, withdrawal, deposit, transactionDate, transactionAmount, transferDescription);
accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction);
this.accountTransferDetailRepository.save(accountTransferDetails);
}
}
if (withdrawal != null) {
saveTransactionToGenerateTransactionId(withdrawal);
}
this.savingsAccountRepository.save(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return withdrawal;
}
private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) {
this.savingsAccountTransactionRepository.save(transaction);
return transaction.getId();
}
private void updateExistingTransactionsDetails(SavingsAccount account, Set<Long> existingTransactionIds,
Set<Long> existingReversedTransactionIds) {
existingTransactionIds.addAll(account.findExistingTransactionIds());
existingReversedTransactionIds.addAll(account.findExistingReversedTransactionIds());
}
private void postJournalEntries(final SavingsAccount savingsAccount, final Set<Long> existingTransactionIds,
final Set<Long> existingReversedTransactionIds) {
final MonetaryCurrency currency = savingsAccount.getCurrency();
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepositoryWrapper.findOneWithNotFoundDetection(currency);
final Map<String, Object> accountingBridgeData = savingsAccount.deriveAccountingBridgeData(applicationCurrency.toData(),
existingTransactionIds, existingReversedTransactionIds);
this.journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData);
}
}
@@ -0,0 +1,130 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.joda.time.LocalDate;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartFields;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_savings_account_interest_rate_chart")
public class DepositAccountInterestRateChart extends AbstractPersistable<Long> {
@Embedded
private InterestRateChartFields chartFields;
@OneToOne
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account;
@OneToMany(mappedBy = "depositAccountInterestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<DepositAccountInterestRateChartSlabs> chartSlabs = new HashSet<DepositAccountInterestRateChartSlabs>();
protected DepositAccountInterestRateChart() {
//
}
public static DepositAccountInterestRateChart from(InterestRateChart productChart) {
final Set<InterestRateChartSlab> chartSlabs = productChart.setOfChartSlabs();
final Set<DepositAccountInterestRateChartSlabs> depostiChartSlabs = new HashSet<DepositAccountInterestRateChartSlabs>();
for (InterestRateChartSlab interestRateChartSlab : chartSlabs) {
depostiChartSlabs.add(DepositAccountInterestRateChartSlabs.from(interestRateChartSlab.slabFields(), null));
}
final DepositAccountInterestRateChart depositChart = new DepositAccountInterestRateChart(productChart.chartFields(), null, depostiChartSlabs);
//update deposit account interest rate chart ference to chart Slabs
depositChart.updateChartSlabsReference();
return depositChart;
}
private DepositAccountInterestRateChart(InterestRateChartFields chartFields, SavingsAccount account,
Set<DepositAccountInterestRateChartSlabs> chartSlabs) {
this.chartFields = chartFields;
this.account = account;
this.chartSlabs = chartSlabs;
}
private void updateChartSlabsReference(){
final Set<DepositAccountInterestRateChartSlabs> chartSlabs = setOfChartSlabs();
for (DepositAccountInterestRateChartSlabs chartSlab : chartSlabs) {
chartSlab.updateChartReference(this);
}
}
public Set<DepositAccountInterestRateChartSlabs> setOfChartSlabs() {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<DepositAccountInterestRateChartSlabs>();
}
return this.chartSlabs;
}
public DepositAccountInterestRateChartSlabs findChartSlab(Long chartSlabId) {
final Set<DepositAccountInterestRateChartSlabs> chartSlabs = setOfChartSlabs();
for (DepositAccountInterestRateChartSlabs interestRateChartSlab : chartSlabs) {
if (interestRateChartSlab.getId().equals(chartSlabId)) { return interestRateChartSlab; }
}
return null;
}
/*private boolean removeChartSlab(DepositAccountInterestRateChartSlabs chartSlab) {
final Set<DepositAccountInterestRateChartSlabs> chartSlabs = setOfChartSlabs();
return chartSlabs.remove(chartSlab);
}*/
public LocalDate getFromDateAsLocalDate() {
return this.chartFields.getFromDateAsLocalDate();
}
public LocalDate getEndDateAsLocalDate() {
return this.chartFields.getEndDateAsLocalDate();
}
public Long savingsAccountId() {
return this.account == null ? null : this.account.getId();
}
public SavingsAccount savingsAccount() {
return this.account;
}
/*private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}*/
public InterestRateChartFields chartFields() {
return this.chartFields;
}
public void updateDepositAccountReference(final SavingsAccount account){
this.account = account;
}
public BigDecimal getApplicableInterestRate(@SuppressWarnings("unused") final BigDecimal depositAmount, final LocalDate periodStartDate, final LocalDate periodEndDate){
BigDecimal effectiveInterestRate = BigDecimal.ZERO;
for (DepositAccountInterestRateChartSlabs slab : setOfChartSlabs()) {
if(slab.slabFields().isBetweenPeriod(periodStartDate, periodEndDate)){
effectiveInterestRate = slab.slabFields().annualInterestRate();
}
}
return effectiveInterestRate;
}
}
@@ -0,0 +1,59 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlabFields;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_savings_account_interest_rate_slab")
public class DepositAccountInterestRateChartSlabs extends AbstractPersistable<Long> {
@Embedded
private InterestRateChartSlabFields slabFields;
@ManyToOne(optional = false)
@JoinColumn(name = "savings_account_interest_rate_chart_id", referencedColumnName = "id", nullable = false)
private DepositAccountInterestRateChart depositAccountInterestRateChart;
protected DepositAccountInterestRateChartSlabs() {
//
}
private DepositAccountInterestRateChartSlabs(InterestRateChartSlabFields slabFields,
DepositAccountInterestRateChart depositAccountInterestRateChart) {
this.slabFields = slabFields;
this.depositAccountInterestRateChart = depositAccountInterestRateChart;
}
public void setDepositAccountInterestRateChart(DepositAccountInterestRateChart depositAccountInterestRateChart) {
this.depositAccountInterestRateChart = depositAccountInterestRateChart;
}
public Long savingsProductId() {
return this.depositAccountInterestRateChart.savingsAccountId();
}
public InterestRateChartSlabFields slabFields() {
return this.slabFields;
}
public static DepositAccountInterestRateChartSlabs from(InterestRateChartSlabFields slabFields,
DepositAccountInterestRateChart depositAccountInterestRateChart){
return new DepositAccountInterestRateChartSlabs(slabFields, depositAccountInterestRateChart);
}
public void updateChartReference(final DepositAccountInterestRateChart chart){
this.depositAccountInterestRateChart = chart;
}
}
@@ -0,0 +1,101 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositAmountParamName;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_deposit_account_recurring_detail")
public class DepositAccountRecurringDetail extends AbstractPersistable<Long> {
@Column(name = "recurring_deposit_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal recurringDepositAmount;
@Embedded
private DepositRecurringDetail recurringDetail;
@OneToOne
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account;
protected DepositAccountRecurringDetail() {
super();
}
public static DepositAccountRecurringDetail createNew(final BigDecimal recurringDepositAmount, DepositRecurringDetail recurringDetail, SavingsAccount account) {
return new DepositAccountRecurringDetail(recurringDepositAmount, recurringDetail, account);
}
private DepositAccountRecurringDetail(final BigDecimal recurringDepositAmount, DepositRecurringDetail recurringDetail, SavingsAccount account) {
this.recurringDepositAmount = recurringDepositAmount;
this.recurringDetail = recurringDetail;
this.account = account;
}
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (command.isChangeInBigDecimalParameterNamed(recurringDepositAmountParamName, this.recurringDepositAmount)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(recurringDepositAmountParamName);
actualChanges.put(recurringDepositAmountParamName, newValue);
this.recurringDepositAmount = newValue;
}
if (this.recurringDetail != null) {
actualChanges.putAll(this.recurringDetail.update(command, baseDataValidator));
}
return actualChanges;
}
public DepositRecurringDetail recurringDetail() {
return this.recurringDetail;
}
public void updateAccountReference(final SavingsAccount account) {
this.account = account;
}
public Integer recurringDepositType() {
return this.recurringDetail().recurringDepositType();
}
public Integer recurringDepositFrequency() {
return this.recurringDetail().recurringDepositFrequency();
}
public Integer recurringDepositFrequencyTypeId() {
return this.recurringDetail().recurringDepositFrequencyTypeId();
}
public SavingsPeriodFrequencyType recurringDepositFrequencyType() {
return SavingsPeriodFrequencyType.fromInt(this.recurringDepositFrequencyTypeId());
}
public BigDecimal recurringDepositAmount(){
return this.recurringDepositAmount;
}
public DepositAccountRecurringDetail copy(){
final BigDecimal recurringDepositAmount = this.recurringDepositAmount;
final DepositRecurringDetail recurringDetail = this.recurringDetail.copy();
return DepositAccountRecurringDetail.createNew(recurringDepositAmount, recurringDetail, account);
}
}
@@ -0,0 +1,238 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodFrequencyIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.joda.time.Weeks;
import org.joda.time.Years;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_deposit_account_term_and_preclosure")
public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
@Column(name = "deposit_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal depositAmount;
@Column(name = "maturity_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal maturityAmount;
@Temporal(TemporalType.DATE)
@Column(name = "maturity_date", nullable = true)
private Date maturityDate;
@Column(name = "deposit_period", nullable = true)
private Integer depositPeriod;
@Column(name = "deposit_period_frequency_enum", nullable = true)
private Integer depositPeriodFrequency;
@Column(name = "on_account_closure_enum", nullable = false)
private Integer onAccountClosureType;
@Embedded
private DepositPreClosureDetail preClosureDetail;
@Embedded
protected DepositTermDetail depositTermDetail;
@OneToOne
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account;
protected DepositAccountTermAndPreClosure() {
super();
}
public static DepositAccountTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency,
final DepositAccountOnClosureType accountOnClosureType) {
return new DepositAccountTermAndPreClosure(preClosureDetail, depositTermDetail, account, depositAmount, maturityAmount,
maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
}
private DepositAccountTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency,
final DepositAccountOnClosureType accountOnClosureType) {
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = (maturityDate == null) ? null : maturityDate.toDate();
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = (depositPeriodFrequency == null) ? null : depositPeriodFrequency.getValue();
this.preClosureDetail = preClosureDetail;
this.depositTermDetail = depositTermDetail;
this.account = account;
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
}
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (command.isChangeInBigDecimalParameterNamed(depositAmountParamName, this.depositAmount)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(depositAmountParamName);
actualChanges.put(depositAmountParamName, newValue);
this.depositAmount = newValue;
}
if (command.isChangeInIntegerParameterNamed(depositPeriodParamName, this.depositPeriod)) {
final Integer newValue = command.integerValueOfParameterNamed(depositPeriodParamName);
actualChanges.put(depositPeriodParamName, newValue);
this.depositPeriod = newValue;
}
if (command.isChangeInIntegerParameterNamed(depositPeriodFrequencyIdParamName, this.depositPeriodFrequency)) {
final Integer newValue = command.integerValueOfParameterNamed(depositPeriodFrequencyIdParamName);
actualChanges.put(depositPeriodFrequencyIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
this.depositPeriodFrequency = newValue;
}
if (this.preClosureDetail != null) {
actualChanges.putAll(this.preClosureDetail.update(command, baseDataValidator));
}
if (this.depositTermDetail != null) {
actualChanges.putAll(this.depositTermDetail.update(command, baseDataValidator));
}
return actualChanges;
}
public DepositPreClosureDetail depositPreClosureDetail() {
return this.preClosureDetail;
}
public DepositTermDetail depositTermDetail() {
return this.depositTermDetail;
}
public BigDecimal depositAmount() {
return this.depositAmount;
}
public Integer depositPeriod() {
return this.depositPeriod;
}
public Integer depositPeriodFrequency() {
return this.depositPeriodFrequency;
}
public SavingsPeriodFrequencyType depositPeriodFrequencyType() {
return SavingsPeriodFrequencyType.fromInt(depositPeriodFrequency);
}
public void updateAccountReference(final SavingsAccount account) {
this.account = account;
}
public void updateMaturityDetails(final BigDecimal maturityAmount, final LocalDate maturityDate) {
this.maturityAmount = maturityAmount;
this.maturityDate = maturityDate.toDate();
}
public void updateMaturityDetails(final BigDecimal depositAmount, final BigDecimal interestPayable, final LocalDate maturityDate) {
this.depositAmount = depositAmount;
this.maturityAmount = this.depositAmount.add(interestPayable);
this.maturityDate = maturityDate.toDate();
}
public LocalDate getMaturityLocalDate() {
LocalDate maturityLocalDate = null;
if (this.maturityDate != null) {
maturityLocalDate = new LocalDate(this.maturityDate);
}
return maturityLocalDate;
}
public boolean isPreClosurePenalApplicable() {
if (this.preClosureDetail != null) { return this.preClosureDetail.preClosurePenalApplicable(); }
return false;
}
public Integer getActualDepositPeriod(final LocalDate interestPostingUpToDate, final SavingsPeriodFrequencyType periodFrequencyType) {
final LocalDate depositFromDate = this.account.accountSubmittedOrActivationDate();
Integer actualDepositPeriod = this.depositPeriod;
if (depositFromDate == null || getMaturityLocalDate() == null || interestPostingUpToDate.isEqual(getMaturityLocalDate())) { return actualDepositPeriod; }
final SavingsPeriodFrequencyType depositPeriodFrequencyType = periodFrequencyType;
switch (depositPeriodFrequencyType) {
case DAYS:
actualDepositPeriod = Days.daysBetween(depositFromDate, interestPostingUpToDate).getDays();
break;
case WEEKS:
actualDepositPeriod = Weeks.weeksBetween(depositFromDate, interestPostingUpToDate).getWeeks();
break;
case MONTHS:
actualDepositPeriod = Months.monthsBetween(depositFromDate, interestPostingUpToDate).getMonths();
break;
case YEARS:
actualDepositPeriod = Years.yearsBetween(depositFromDate, interestPostingUpToDate).getYears();
break;
case INVALID:
actualDepositPeriod = this.depositPeriod;// default value
break;
}
return actualDepositPeriod;
}
public BigDecimal maturityAmount() {
return this.maturityAmount;
}
public void updateOnAccountClosureStatus(final DepositAccountOnClosureType onClosureType) {
this.onAccountClosureType = onClosureType.getValue();
}
public boolean isReinvestOnClosure() {
return DepositAccountOnClosureType.fromInt(this.onAccountClosureType).isReinvest();
}
public boolean isTransferToSavingsOnClosure() {
return DepositAccountOnClosureType.fromInt(this.onAccountClosureType).isTransferToSavings();
}
public DepositAccountTermAndPreClosure deepCopy(Money depositAmount) {
final SavingsAccount account = null;
final BigDecimal maturityAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = this.depositPeriod;
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(this.depositPeriodFrequency);
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
final DepositAccountOnClosureType accountOnClosureType = null;
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, depositAmount.getAmount(), maturityAmount,
maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
}
}
@@ -0,0 +1,231 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeFromPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeToPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestOnTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localeParamName;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartPeriodType;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartEnumerations;
import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
/**
* DepositPreClosureDetail encapsulates all the details of a
* {@link FixedDepositProduct} that are also used and persisted by a
* {@link FixedDepositAccount}.
*/
@Embeddable
public class DepositPreClosureDetail {
@Column(name = "interest_free_period_applicable")
private boolean interestFreePeriodApplicable;
@Column(name = "pre_closure_penal_applicable")
private boolean preClosurePenalApplicable;
@Column(name = "interest_free_from_period", nullable = true)
private Integer interestFreeFromPeriod;
@Column(name = "interest_free_to_period", nullable = true)
private Integer interestFreeToPeriod;
@Column(name = "interest_free_period_frequency_enum", nullable = true)
private Integer interestFreePeriodFrequencyType;
@Column(name = "pre_closure_penal_interest", scale = 6, precision = 19, nullable = true)
private BigDecimal preClosurePenalInterest;
@Column(name = "pre_closure_penal_interest_on_enum", nullable = true)
private Integer preClosurePenalInterestOnType;
public static DepositPreClosureDetail createFrom(final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod,
final Integer interestFreeToPeriod, final InterestRateChartPeriodType periodType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final PreClosurePenalInterestOnType preClosurePenalInterestType) {
return new DepositPreClosureDetail(interestFreePeriodApplicable, interestFreeFromPeriod, interestFreeToPeriod, periodType,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestType);
}
protected DepositPreClosureDetail() {
//
}
private DepositPreClosureDetail(final boolean interestFreePeriodApplicable, final Integer interestFreeFromPeriod,
final Integer interestFreeToPeriod, final InterestRateChartPeriodType periodType, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final PreClosurePenalInterestOnType preClosurePenalInterestType) {
this.interestFreePeriodApplicable = interestFreePeriodApplicable;
this.interestFreeFromPeriod = interestFreeFromPeriod;
this.interestFreeToPeriod = interestFreeToPeriod;
this.interestFreePeriodFrequencyType = (periodType == null) ? null : periodType.getValue();
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = (preClosurePenalInterestType == null) ? null : preClosurePenalInterestType.getValue();
}
protected Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
final String localeAsInput = command.locale();
if (command.isChangeInBooleanParameterNamed(interestFreePeriodApplicableParamName, this.interestFreePeriodApplicable)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(interestFreePeriodApplicableParamName);
actualChanges.put(interestFreePeriodApplicableParamName, newValue);
this.interestFreePeriodApplicable = newValue;
}
if (this.interestFreePeriodApplicable) {
if (command.isChangeInIntegerParameterNamed(interestFreeFromPeriodParamName, this.interestFreeFromPeriod)) {
final Integer newValue = command.integerValueOfParameterNamed(interestFreeFromPeriodParamName);
actualChanges.put(interestFreeFromPeriodParamName, newValue);
this.interestFreeFromPeriod = newValue;
}
if (command.isChangeInIntegerParameterNamed(interestFreeToPeriodParamName, this.interestFreeToPeriod)) {
final Integer newValue = command.integerValueOfParameterNamed(interestFreeToPeriodParamName);
actualChanges.put(interestFreeToPeriodParamName, newValue);
this.interestFreeToPeriod = newValue;
}
if (command.isChangeInIntegerParameterNamed(interestFreePeriodFrequencyTypeIdParamName, this.interestFreePeriodFrequencyType)) {
final Integer newValue = command.integerValueOfParameterNamed(interestFreePeriodFrequencyTypeIdParamName);
actualChanges.put(interestFreePeriodFrequencyTypeIdParamName, InterestRateChartEnumerations.periodType(newValue));
this.interestFreePeriodFrequencyType = newValue;
}
if (this.interestFreeFromPeriod == null) {
baseDataValidator.parameter(interestFreeFromPeriodParamName).value(this.interestFreeFromPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, this.interestFreePeriodApplicable);
}
if (this.interestFreeToPeriod == null) {
baseDataValidator.parameter(interestFreeToPeriodParamName).value(this.interestFreeToPeriod)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, this.interestFreePeriodApplicable);
}
if (this.interestFreePeriodFrequencyType == null) {
baseDataValidator.parameter(interestFreePeriodFrequencyTypeIdParamName).value(this.interestFreePeriodFrequencyType)
.cantBeBlankWhenParameterProvidedIs(interestFreePeriodApplicableParamName, this.interestFreePeriodApplicable);
}
} else { // reset if interest free period is not applicable
this.interestFreeFromPeriod = null;
this.interestFreeToPeriod = null;
this.interestFreePeriodFrequencyType = null;
}
if (command.isChangeInBooleanParameterNamed(preClosurePenalApplicableParamName, this.preClosurePenalApplicable)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(preClosurePenalApplicableParamName);
actualChanges.put(preClosurePenalApplicableParamName, newValue);
this.preClosurePenalApplicable = newValue;
}
if (this.preClosurePenalApplicable) {
if (command.isChangeInBigDecimalParameterNamed(preClosurePenalInterestParamName, this.preClosurePenalInterest)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(preClosurePenalInterestParamName);
actualChanges.put(preClosurePenalInterestParamName, newValue);
actualChanges.put(localeParamName, localeAsInput);
this.preClosurePenalInterest = newValue;
}
if (command.isChangeInIntegerParameterNamed(preClosurePenalInterestOnTypeIdParamName, this.preClosurePenalInterestOnType)) {
final Integer newValue = command.integerValueOfParameterNamed(preClosurePenalInterestOnTypeIdParamName);
actualChanges.put(preClosurePenalInterestOnTypeIdParamName, SavingsEnumerations.preClosurePenaltyInterestOnType(newValue));
actualChanges.put(localeParamName, localeAsInput);
this.preClosurePenalInterestOnType = newValue;
}
if (this.preClosurePenalInterest == null) {
baseDataValidator.parameter(preClosurePenalInterestParamName).value(this.preClosurePenalInterest)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, this.preClosurePenalApplicable);
}
if (this.preClosurePenalInterestOnType == null) {
baseDataValidator.parameter(preClosurePenalInterestOnTypeIdParamName).value(this.preClosurePenalInterestOnType)
.cantBeBlankWhenParameterProvidedIs(preClosurePenalApplicableParamName, this.preClosurePenalApplicable);
}
} else { // reset if pre-closure penal interest is not applicable
this.preClosurePenalInterest = null;
this.preClosurePenalInterestOnType = null;
}
if (isFromPeriodAfterToPeriod()) {
baseDataValidator
.parameter(interestFreeFromPeriodParamName)
.value(this.interestFreeFromPeriod)
.failWithCode("interest.free.from.period.is.greater.than.to.period", this.interestFreeFromPeriod,
this.interestFreeToPeriod);
}
return actualChanges;
}
private boolean isFromPeriodAfterToPeriod() {
if (this.interestFreePeriodApplicable && this.interestFreeFromPeriod != null && this.interestFreeToPeriod != null) {
if (this.interestFreeFromPeriod.compareTo(interestFreeToPeriod) > 0) { return true; }
}
return false;
}
public boolean interestFreePeriodApplicable() {
return this.interestFreePeriodApplicable;
}
public boolean preClosurePenalApplicable() {
return this.preClosurePenalApplicable;
}
public Integer interestFreeFromPeriod() {
return this.interestFreeFromPeriod;
}
public Integer interestFreeToPeriod() {
return this.interestFreeToPeriod;
}
public Integer interestFreePeriodFrequencyType() {
return this.interestFreePeriodFrequencyType;
}
public BigDecimal preClosurePenalInterest() {
return this.preClosurePenalInterest;
}
public Integer preClosurePenalInterestOnTypeId() {
return this.preClosurePenalInterestOnType;
}
public PreClosurePenalInterestOnType preClosurePenalInterestOnType(){
return PreClosurePenalInterestOnType.fromInt(preClosurePenalInterestOnType);
}
public DepositPreClosureDetail copy(){
final boolean interestFreePeriodApplicable = this.interestFreePeriodApplicable;
final Integer interestFreeFromPeriod = this.interestFreeFromPeriod;
final Integer interestFreeToPeriod = this.interestFreeToPeriod;
final boolean preClosurePenalApplicable = this.preClosurePenalApplicable;
final BigDecimal preClosurePenalInterest = this.preClosurePenalInterest;
final InterestRateChartPeriodType periodType = InterestRateChartPeriodType.fromInt(this.interestFreePeriodFrequencyType);
final PreClosurePenalInterestOnType preClosurePenalInterestType = PreClosurePenalInterestOnType.fromInt(this.preClosurePenalInterestOnType);
return DepositPreClosureDetail.createFrom(interestFreePeriodApplicable, interestFreeFromPeriod, interestFreeToPeriod, periodType, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestType);
}
}
@@ -0,0 +1,538 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.chartsParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeFromPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreePeriodFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.interestFreeToPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalApplicableParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestOnTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosurePenalInterestParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargesParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.idParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nameParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.shortNameParamName;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.mifosplatform.accounting.common.AccountingRuleType;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.charge.exception.ChargeCannotBeAppliedToException;
import org.mifosplatform.portfolio.interestratechart.InterestRateChartPeriodType;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartAssembler;
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType;
import org.mifosplatform.portfolio.savings.RecurringDepositType;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@Component
public class DepositProductAssembler {
private final ChargeRepositoryWrapper chargeRepository;
private final InterestRateChartAssembler chartAssembler;
@Autowired
public DepositProductAssembler(final ChargeRepositoryWrapper chargeRepository, final InterestRateChartAssembler chartAssembler) {
this.chargeRepository = chargeRepository;
this.chartAssembler = chartAssembler;
}
public FixedDepositProduct assembleFixedDepositProduct(final JsonCommand command) {
final String name = command.stringValueOfParameterNamed(nameParamName);
final String shortName = command.stringValueOfParameterNamed(shortNameParamName);
final String description = command.stringValueOfParameterNamed(descriptionParamName);
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
final Integer inMultiplesOf = command.integerValueOfParameterNamed(inMultiplesOfParamName);
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
if (interestPeriodTypeValue != null) {
interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
}
SavingsPostingInterestPeriodType interestPostingPeriodType = null;
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
if (interestPostingPeriodTypeValue != null) {
interestPostingPeriodType = SavingsPostingInterestPeriodType.fromInt(interestPostingPeriodTypeValue);
}
SavingsInterestCalculationType interestCalculationType = null;
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
if (interestCalculationTypeValue != null) {
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
}
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null;
final Integer interestCalculationDaysInYearTypeValue = command
.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
if (interestCalculationDaysInYearTypeValue != null) {
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
}
final Integer lockinPeriodFrequency = command.integerValueOfParameterNamedDefaultToNullIfZero(lockinPeriodFrequencyParamName);
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
final Integer lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
if (lockinPeriodFrequencyTypeValue != null) {
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
}
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
depositTermDetail, null);
// Savings product charges
final Set<Charge> charges = assembleListOfSavingsProductCharges(command, currencyCode);
// Interest rate charts
final Set<InterestRateChart> charts = assembleListOfCharts(command, currency.getCode());
if (interestRate == null) {
interestRate = BigDecimal.ZERO;
}
FixedDepositProduct fixedDepositProduct = FixedDepositProduct.createNew(name, shortName, description, currency, interestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, accountingRuleType, charges, productTermAndPreClosure, charts);
// update product reference
productTermAndPreClosure.updateProductReference(fixedDepositProduct);
validateFixedDepositProductDomainRules(fixedDepositProduct);
return fixedDepositProduct;
}
private void validateFixedDepositProductDomainRules(FixedDepositProduct fixedDepositProduct) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_PRODUCT_RESOURCE_NAME);
final DepositTermDetail termDetails = fixedDepositProduct.depositProductTermAndPreClosure().depositTermDetail();
final boolean isMinTermGreaterThanMax = termDetails.isMinDepositTermGreaterThanMaxDepositTerm();
if (isMinTermGreaterThanMax) {
final Integer maxTerm = termDetails.maxDepositTerm();
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm)
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
}
fixedDepositProduct.validateCharts(baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public RecurringDepositProduct assembleRecurringDepositProduct(final JsonCommand command) {
final String name = command.stringValueOfParameterNamed(nameParamName);
final String shortName = command.stringValueOfParameterNamed(shortNameParamName);
final String description = command.stringValueOfParameterNamed(descriptionParamName);
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
final Integer inMultiplesOf = command.integerValueOfParameterNamed(inMultiplesOfParamName);
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
if (interestPeriodTypeValue != null) {
interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
}
SavingsPostingInterestPeriodType interestPostingPeriodType = null;
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
if (interestPostingPeriodTypeValue != null) {
interestPostingPeriodType = SavingsPostingInterestPeriodType.fromInt(interestPostingPeriodTypeValue);
}
SavingsInterestCalculationType interestCalculationType = null;
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
if (interestCalculationTypeValue != null) {
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
}
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null;
final Integer interestCalculationDaysInYearTypeValue = command
.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
if (interestCalculationDaysInYearTypeValue != null) {
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
}
final Integer lockinPeriodFrequency = command.integerValueOfParameterNamedDefaultToNullIfZero(lockinPeriodFrequencyParamName);
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
final Integer lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
if (lockinPeriodFrequencyTypeValue != null) {
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
}
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
depositTermDetail, null);
final DepositRecurringDetail recurringDetail = this.assembleRecurringDetail(command);
final DepositProductRecurringDetail productRecurringDetail = DepositProductRecurringDetail.createNew(recurringDetail, null);
// Savings product charges
final Set<Charge> charges = assembleListOfSavingsProductCharges(command, currencyCode);
// Interest rate charts
final Set<InterestRateChart> charts = assembleListOfCharts(command, currency.getCode());
if (interestRate == null) {
interestRate = BigDecimal.ZERO;
}
RecurringDepositProduct recurringDepositProduct = RecurringDepositProduct.createNew(name, shortName, description, currency,
interestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, lockinPeriodFrequency, lockinPeriodFrequencyType, accountingRuleType, charges,
productTermAndPreClosure, productRecurringDetail, charts);
// update product reference
productTermAndPreClosure.updateProductReference(recurringDepositProduct);
productRecurringDetail.updateProductReference(recurringDepositProduct);
validateRecurringDepositProductDomainRules(recurringDepositProduct);
return recurringDepositProduct;
}
private void validateRecurringDepositProductDomainRules(RecurringDepositProduct recurringDepositProduct) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME);
final DepositTermDetail termDetails = recurringDepositProduct.depositProductTermAndPreClosure().depositTermDetail();
final boolean isMinTermGreaterThanMax = termDetails.isMinDepositTermGreaterThanMaxDepositTerm();
if (isMinTermGreaterThanMax) {
final Integer maxTerm = termDetails.maxDepositTerm();
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm)
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
}
recurringDepositProduct.validateCharts(baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public DepositPreClosureDetail assemblePreClosureDetail(final JsonCommand command) {
boolean interestFreePeriodApplicable = false;
Integer interestFreeFromPeriod = null;
Integer interestFreeToPeriod = null;
InterestRateChartPeriodType interestFreePeriodFrequencyType = null;
if (command.parameterExists(interestFreePeriodApplicableParamName)) {
interestFreePeriodApplicable = command.booleanObjectValueOfParameterNamed(interestFreePeriodApplicableParamName);
if (interestFreePeriodApplicable) {
interestFreeFromPeriod = command.integerValueOfParameterNamed(interestFreeFromPeriodParamName);
interestFreeToPeriod = command.integerValueOfParameterNamed(interestFreeToPeriodParamName);
final Integer interestFreePreriodTypeId = command.integerValueOfParameterNamed(interestFreePeriodFrequencyTypeIdParamName);
interestFreePeriodFrequencyType = (interestFreePreriodTypeId == null) ? null : InterestRateChartPeriodType
.fromInt(interestFreePreriodTypeId);
}
}
boolean preClosurePenalApplicable = false;
BigDecimal preClosurePenalInterest = null;
PreClosurePenalInterestOnType preClosurePenalInterestType = null;
if (command.parameterExists(preClosurePenalApplicableParamName)) {
preClosurePenalApplicable = command.booleanObjectValueOfParameterNamed(preClosurePenalApplicableParamName);
if (preClosurePenalApplicable) {
preClosurePenalInterest = command.bigDecimalValueOfParameterNamed(preClosurePenalInterestParamName);
final Integer preClosurePenalInterestOnTypeId = command
.integerValueOfParameterNamed(preClosurePenalInterestOnTypeIdParamName);
preClosurePenalInterestType = preClosurePenalInterestOnTypeId == null ? null : PreClosurePenalInterestOnType
.fromInt(preClosurePenalInterestOnTypeId);
}
}
DepositPreClosureDetail preClosureDetail = DepositPreClosureDetail.createFrom(interestFreePeriodApplicable, interestFreeFromPeriod,
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestType);
return preClosureDetail;
}
public DepositPreClosureDetail assemblePreClosureDetail(final JsonCommand command, DepositPreClosureDetail produPreClosureDetail) {
boolean interestFreePeriodApplicable = false;
Integer interestFreeFromPeriod = null;
Integer interestFreeToPeriod = null;
InterestRateChartPeriodType interestFreePeriodFrequencyType = null;
Integer interestFreePreriodTypeId = null;
if (command.parameterExists(interestFreePeriodApplicableParamName)) {
interestFreePeriodApplicable = command.booleanObjectValueOfParameterNamed(interestFreePeriodApplicableParamName);
if (interestFreePeriodApplicable) {
if (command.parameterExists(interestFreeFromPeriodParamName)) {
interestFreeFromPeriod = command.integerValueOfParameterNamed(interestFreeFromPeriodParamName);
} else {
interestFreeFromPeriod = produPreClosureDetail.interestFreeFromPeriod();
}
if (command.parameterExists(interestFreeToPeriodParamName)) {
interestFreeToPeriod = command.integerValueOfParameterNamed(interestFreeToPeriodParamName);
} else {
interestFreeToPeriod = produPreClosureDetail.interestFreeToPeriod();
}
if (command.parameterExists(interestFreePeriodFrequencyTypeIdParamName)) {
interestFreePreriodTypeId = command.integerValueOfParameterNamed(interestFreePeriodFrequencyTypeIdParamName);
} else {
interestFreePreriodTypeId = produPreClosureDetail.interestFreePeriodFrequencyType();
}
interestFreePeriodFrequencyType = (interestFreePreriodTypeId == null) ? null : InterestRateChartPeriodType
.fromInt(interestFreePreriodTypeId);
}
} else {
interestFreePeriodApplicable = produPreClosureDetail.interestFreePeriodApplicable();
interestFreeFromPeriod = produPreClosureDetail.interestFreeFromPeriod();
interestFreeToPeriod = produPreClosureDetail.interestFreeToPeriod();
interestFreePreriodTypeId = produPreClosureDetail.interestFreePeriodFrequencyType();
interestFreePeriodFrequencyType = (interestFreePreriodTypeId == null) ? null : InterestRateChartPeriodType
.fromInt(interestFreePreriodTypeId);
}
boolean preClosurePenalApplicable = false;
BigDecimal preClosurePenalInterest = null;
PreClosurePenalInterestOnType preClosurePenalInterestType = null;
Integer preClosurePenalInterestOnTypeId = null;
if (command.parameterExists(preClosurePenalApplicableParamName)) {
preClosurePenalApplicable = command.booleanObjectValueOfParameterNamed(preClosurePenalApplicableParamName);
if (preClosurePenalApplicable) {
if (command.parameterExists(preClosurePenalInterestParamName)) {
preClosurePenalInterest = command.bigDecimalValueOfParameterNamed(preClosurePenalInterestParamName);
} else {
preClosurePenalInterest = produPreClosureDetail.preClosurePenalInterest();
}
if (command.parameterExists(preClosurePenalInterestParamName)) {
preClosurePenalInterestOnTypeId = command.integerValueOfParameterNamed(preClosurePenalInterestOnTypeIdParamName);
} else {
preClosurePenalInterestOnTypeId = produPreClosureDetail.preClosurePenalInterestOnTypeId();
}
}
} else {
preClosurePenalApplicable = produPreClosureDetail.preClosurePenalApplicable();
preClosurePenalInterest = produPreClosureDetail.preClosurePenalInterest();
preClosurePenalInterestOnTypeId = produPreClosureDetail.preClosurePenalInterestOnTypeId();
}
preClosurePenalInterestType = preClosurePenalInterestOnTypeId == null ? null : PreClosurePenalInterestOnType
.fromInt(preClosurePenalInterestOnTypeId);
DepositPreClosureDetail preClosureDetail1 = DepositPreClosureDetail.createFrom(interestFreePeriodApplicable,
interestFreeFromPeriod, interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestType);
return preClosureDetail1;
}
public DepositTermDetail assembleDepositTermDetail(final JsonCommand command) {
final Integer minDepositTerm = command.integerValueOfParameterNamed(minDepositTermParamName);
final Integer maxDepositTerm = command.integerValueOfParameterNamed(maxDepositTermParamName);
final Integer minDepositTermTypeId = command.integerValueOfParameterNamed(minDepositTermTypeIdParamName);
final SavingsPeriodFrequencyType minDepositTermType = (minDepositTermTypeId == null) ? null : SavingsPeriodFrequencyType
.fromInt(minDepositTermTypeId);
final Integer maxDepositTermTypeId = command.integerValueOfParameterNamed(maxDepositTermTypeIdParamName);
final SavingsPeriodFrequencyType maxDepositTermType = (maxDepositTermTypeId == null) ? null : SavingsPeriodFrequencyType
.fromInt(maxDepositTermTypeId);
final Integer inMultiplesOfDepositTerm = command.integerValueOfParameterNamed(inMultiplesOfDepositTermParamName);
final Integer inMultiplesOfDepositTermTypeId = command.integerValueOfParameterNamed(inMultiplesOfDepositTermTypeIdParamName);
final SavingsPeriodFrequencyType inMultiplesOfDepositTermType = (inMultiplesOfDepositTermTypeId == null) ? null
: SavingsPeriodFrequencyType.fromInt(inMultiplesOfDepositTermTypeId);
final DepositTermDetail depositTermDetail = DepositTermDetail.createFrom(minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType);
return depositTermDetail;
}
public DepositTermDetail assembleDepositTermDetail(final JsonCommand command, final DepositTermDetail prodDepositTermDetail) {
Integer minDepositTerm = null;
Integer maxDepositTerm = null;
Integer minDepositTermTypeId = null;
Integer maxDepositTermTypeId = null;
Integer inMultiplesOfDepositTerm = null;
Integer inMultiplesOfDepositTermTypeId = null;
if (command.parameterExists(minDepositTermParamName)) {
minDepositTerm = command.integerValueOfParameterNamed(minDepositTermParamName);
} else {
minDepositTerm = prodDepositTermDetail.minDepositTerm();
}
if (command.parameterExists(maxDepositTermParamName)) {
maxDepositTerm = command.integerValueOfParameterNamed(maxDepositTermParamName);
} else {
maxDepositTerm = prodDepositTermDetail.maxDepositTerm();
}
if (command.parameterExists(minDepositTermTypeIdParamName)) {
minDepositTermTypeId = command.integerValueOfParameterNamed(minDepositTermTypeIdParamName);
} else {
minDepositTermTypeId = prodDepositTermDetail.minDepositTermType();
}
if (command.parameterExists(maxDepositTermTypeIdParamName)) {
maxDepositTermTypeId = command.integerValueOfParameterNamed(maxDepositTermTypeIdParamName);
} else {
maxDepositTermTypeId = prodDepositTermDetail.maxDepositTermType();
}
final SavingsPeriodFrequencyType minDepositTermType = (minDepositTermTypeId == null) ? null : SavingsPeriodFrequencyType
.fromInt(minDepositTermTypeId);
final SavingsPeriodFrequencyType maxDepositTermType = (maxDepositTermTypeId == null) ? null : SavingsPeriodFrequencyType
.fromInt(maxDepositTermTypeId);
if (command.parameterExists(inMultiplesOfDepositTermParamName)) {
inMultiplesOfDepositTerm = command.integerValueOfParameterNamed(inMultiplesOfDepositTermParamName);
} else {
inMultiplesOfDepositTerm = prodDepositTermDetail.inMultiplesOfDepositTerm();
}
if (command.parameterExists(preClosurePenalApplicableParamName)) {
inMultiplesOfDepositTermTypeId = command.integerValueOfParameterNamed(inMultiplesOfDepositTermTypeIdParamName);
} else {
inMultiplesOfDepositTermTypeId = prodDepositTermDetail.inMultiplesOfDepositTermType();
}
final SavingsPeriodFrequencyType inMultiplesOfDepositTermType = (inMultiplesOfDepositTermTypeId == null) ? null
: SavingsPeriodFrequencyType.fromInt(inMultiplesOfDepositTermTypeId);
final DepositTermDetail depositTermDetail = DepositTermDetail.createFrom(minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType);
return depositTermDetail;
}
public DepositRecurringDetail assembleRecurringDetail(final JsonCommand command) {
RecurringDepositType recurringDepositType = null;
final Integer recurringDepositTypeValue = command.integerValueOfParameterNamed(recurringDepositTypeIdParamName);
if (recurringDepositTypeValue != null) {
recurringDepositType = RecurringDepositType.fromInt(recurringDepositTypeValue);
}
SavingsPeriodFrequencyType recurringDepositFrequencyType = null;
final Integer recurringDepositFrequencyTypeValue = command.integerValueOfParameterNamed(recurringDepositFrequencyTypeIdParamName);
if (recurringDepositFrequencyTypeValue != null) {
recurringDepositFrequencyType = SavingsPeriodFrequencyType.fromInt(recurringDepositFrequencyTypeValue);
}
final Integer recurringDepositFrequency = command.integerValueOfParameterNamed(recurringDepositFrequencyParamName);
final DepositRecurringDetail depositRecurringDetail = DepositRecurringDetail.createFrom(recurringDepositType,
recurringDepositFrequency, recurringDepositFrequencyType);
return depositRecurringDetail;
}
public Set<Charge> assembleListOfSavingsProductCharges(final JsonCommand command, final String savingsProductCurrencyCode) {
final Set<Charge> charges = new HashSet<Charge>();
if (command.parameterExists(chargesParamName)) {
final JsonArray chargesArray = command.arrayOfParameterNamed(chargesParamName);
if (chargesArray != null) {
for (int i = 0; i < chargesArray.size(); i++) {
final JsonObject jsonObject = chargesArray.get(i).getAsJsonObject();
if (jsonObject.has(idParamName)) {
final Long id = jsonObject.get(idParamName).getAsLong();
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(id);
if (!charge.isSavingsCharge()) {
final String errorMessage = "Charge with identifier " + charge.getId()
+ " cannot be applied to Savings product.";
throw new ChargeCannotBeAppliedToException("savings.product", errorMessage, charge.getId());
}
if (!savingsProductCurrencyCode.equals(charge.getCurrencyCode())) {
final String errorMessage = "Charge and Savings Product must have the same currency.";
throw new InvalidCurrencyException("charge", "attach.to.savings.product", errorMessage);
}
charges.add(charge);
}
}
}
}
return charges;
}
private Set<InterestRateChart> assembleListOfCharts(JsonCommand command, String currencyCode) {
final Set<InterestRateChart> charts = new HashSet<InterestRateChart>();
if (command.parameterExists(chartsParamName)) {
final JsonArray chartsArray = command.arrayOfParameterNamed(chartsParamName);
if (chartsArray != null) {
for (int i = 0; i < chartsArray.size(); i++) {
final JsonObject interstRateChartElement = chartsArray.get(i).getAsJsonObject();
InterestRateChart chart = this.chartAssembler.assembleFrom(interstRateChartElement, currencyCode);
charts.add(chart);
}
}
}
return charts;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
@@ -0,0 +1,61 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_deposit_product_recurring_detail")
public class DepositProductRecurringDetail extends AbstractPersistable<Long> {
@Embedded
private DepositRecurringDetail recurringDetail;
@OneToOne
@JoinColumn(name = "savings_product_id", nullable = false)
private RecurringDepositProduct product;
protected DepositProductRecurringDetail() {
super();
}
public static DepositProductRecurringDetail createNew(DepositRecurringDetail recurringDetail, SavingsProduct product) {
return new DepositProductRecurringDetail(recurringDetail, product);
}
private DepositProductRecurringDetail(DepositRecurringDetail recurringDetail, SavingsProduct product) {
this.recurringDetail = recurringDetail;
this.product = (RecurringDepositProduct) product;
}
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (this.recurringDetail != null) {
actualChanges.putAll(this.recurringDetail.update(command, baseDataValidator));
}
return actualChanges;
}
public DepositRecurringDetail recurringDetail() {
return this.recurringDetail;
}
public void updateProductReference(final SavingsProduct product) {
this.product = (RecurringDepositProduct) product;
}
}
@@ -0,0 +1,75 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_deposit_product_term_and_preclosure")
public class DepositProductTermAndPreClosure extends AbstractPersistable<Long> {
@Embedded
private DepositPreClosureDetail preClosureDetail;
@Embedded
protected DepositTermDetail depositTermDetail;
@OneToOne
@JoinColumn(name = "savings_product_id", nullable = false)
private FixedDepositProduct product;
protected DepositProductTermAndPreClosure() {
super();
}
public static DepositProductTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
SavingsProduct product) {
return new DepositProductTermAndPreClosure(preClosureDetail, depositTermDetail, product);
}
private DepositProductTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
SavingsProduct product) {
this.preClosureDetail = preClosureDetail;
this.depositTermDetail = depositTermDetail;
this.product = (FixedDepositProduct)product;
}
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (this.preClosureDetail != null) {
actualChanges.putAll(this.preClosureDetail.update(command, baseDataValidator));
}
if (this.depositTermDetail != null) {
actualChanges.putAll(this.depositTermDetail.update(command, baseDataValidator));
}
return actualChanges;
}
public DepositPreClosureDetail depositPreClosureDetail() {
return this.preClosureDetail;
}
public DepositTermDetail depositTermDetail() {
return this.depositTermDetail;
}
public void updateProductReference(final SavingsProduct product){
this.product = (FixedDepositProduct)product;
}
}
@@ -0,0 +1,105 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.portfolio.savings.RecurringDepositType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
/**
* DepositRecurringDetail encapsulates all the details of a
* {@link RecurringDepositProduct} that are also used and persisted by a
* {@link RecurringDepositAccount}.
*/
@Embeddable
public class DepositRecurringDetail {
@Column(name = "recurring_deposit_type_enum", nullable = true)
private Integer recurringDepositType;
@Column(name = "recurring_deposit_frequency", nullable = true)
private Integer recurringDepositFrequency;
@Column(name = "recurring_deposit_frequency_type_enum", nullable = true)
private Integer recurringDepositFrequencyType;
public static DepositRecurringDetail createFrom(final RecurringDepositType recurringDepositType,
final Integer recurringDepositFrequency, final SavingsPeriodFrequencyType recurringDepositFrequencyType) {
return new DepositRecurringDetail(recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType);
}
protected DepositRecurringDetail() {
//
}
private DepositRecurringDetail(final RecurringDepositType recurringDepositType, final Integer recurringDepositFrequency,
final SavingsPeriodFrequencyType recurringDepositFrequencyType) {
this.recurringDepositFrequency = recurringDepositFrequency;
this.recurringDepositFrequencyType = recurringDepositFrequencyType.getValue();
this.recurringDepositType = recurringDepositType.getValue();
}
public Map<String, Object> update(final JsonCommand command, @SuppressWarnings("unused") final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (command.isChangeInIntegerParameterNamed(recurringDepositFrequencyParamName, this.recurringDepositFrequency)) {
final Integer newValue = command.integerValueOfParameterNamed(recurringDepositFrequencyParamName);
actualChanges.put(recurringDepositFrequencyParamName, newValue);
this.recurringDepositFrequency = newValue;
}
if (command.isChangeInIntegerParameterNamed(recurringDepositFrequencyTypeIdParamName, this.recurringDepositFrequencyType)) {
final Integer newValue = command.integerValueOfParameterNamed(recurringDepositFrequencyTypeIdParamName);
actualChanges.put(recurringDepositFrequencyTypeIdParamName, SavingsEnumerations.recurringDepositFrequencyType(newValue));
this.recurringDepositFrequencyType = newValue;
}
if (command.isChangeInIntegerParameterNamed(recurringDepositTypeIdParamName, this.recurringDepositType)) {
final Integer newValue = command.integerValueOfParameterNamed(recurringDepositTypeIdParamName);
actualChanges.put(recurringDepositTypeIdParamName, SavingsEnumerations.recurringDepositType(newValue));
this.recurringDepositType = newValue;
}
return actualChanges;
}
public Integer recurringDepositType() {
return this.recurringDepositType;
}
public Integer recurringDepositFrequency() {
return this.recurringDepositFrequency;
}
public Integer recurringDepositFrequencyTypeId() {
return this.recurringDepositFrequencyType;
}
public SavingsPeriodFrequencyType recurringDepositFrequencyType() {
return SavingsPeriodFrequencyType.fromInt(this.recurringDepositFrequencyType);
}
public DepositRecurringDetail copy() {
final RecurringDepositType recurringDepositType = RecurringDepositType.fromInt(this.recurringDepositType);
final Integer recurringDepositFrequency = this.recurringDepositFrequency;
final SavingsPeriodFrequencyType recurringDepositFrequencyType = SavingsPeriodFrequencyType
.fromInt(this.recurringDepositFrequencyType);
return DepositRecurringDetail.createFrom(recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType);
}
}
@@ -0,0 +1,246 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermTypeIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.inMultiplesOfDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.minDepositTermParamName;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import org.joda.time.DateTimeConstants;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.joda.time.Weeks;
import org.joda.time.Years;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
/**
* DepositTermDetail encapsulates all the details of a
* {@link FixedDepositProduct} that are also used and persisted by a
* {@link FixedDepositAccount}.
*/
@Embeddable
public class DepositTermDetail {
@Column(name = "min_deposit_term", nullable = true)
private Integer minDepositTerm;
@Column(name = "max_deposit_term", nullable = true)
private Integer maxDepositTerm;
@Column(name = "min_deposit_term_type_enum", nullable = true)
private Integer minDepositTermType;
@Column(name = "max_deposit_term_type_enum", nullable = true)
private Integer maxDepositTermType;
@Column(name = "in_multiples_of_deposit_term", nullable = true)
private Integer inMultiplesOfDepositTerm;
@Column(name = "in_multiples_of_deposit_term_type_enum", nullable = true)
private Integer inMultiplesOfDepositTermType;
public static DepositTermDetail createFrom(final Integer minDepositTerm, final Integer maxDepositTerm,
final SavingsPeriodFrequencyType minDepositTermType, final SavingsPeriodFrequencyType maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final SavingsPeriodFrequencyType inMultiplesOfDepositTermType) {
return new DepositTermDetail(minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType);
}
protected DepositTermDetail() {
//
}
private DepositTermDetail(final Integer minDepositTerm, final Integer maxDepositTerm,
final SavingsPeriodFrequencyType minDepositTermType, final SavingsPeriodFrequencyType maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final SavingsPeriodFrequencyType inMultiplesOfDepositTermType) {
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = (minDepositTermType == null) ? null : minDepositTermType.getValue();
this.maxDepositTermType = (maxDepositTermType == null) ? null : maxDepositTermType.getValue();
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = (inMultiplesOfDepositTermType == null) ? null : inMultiplesOfDepositTermType.getValue();
}
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
if (command.isChangeInIntegerParameterNamed(minDepositTermParamName, this.minDepositTerm)) {
final Integer newValue = command.integerValueOfParameterNamed(minDepositTermParamName);
actualChanges.put(minDepositTermParamName, newValue);
this.minDepositTerm = newValue;
}
if (command.isChangeInIntegerParameterNamed(maxDepositTermParamName, this.maxDepositTerm)) {
final Integer newValue = command.integerValueOfParameterNamed(maxDepositTermParamName);
actualChanges.put(maxDepositTermParamName, newValue);
this.maxDepositTerm = newValue;
}
if (command.isChangeInIntegerParameterNamed(minDepositTermTypeIdParamName, this.minDepositTermType)) {
final Integer newValue = command.integerValueOfParameterNamed(minDepositTermTypeIdParamName);
actualChanges.put(minDepositTermTypeIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
this.minDepositTermType = newValue;
}
if (command.isChangeInIntegerParameterNamed(maxDepositTermTypeIdParamName, this.maxDepositTermType)) {
final Integer newValue = command.integerValueOfParameterNamed(maxDepositTermTypeIdParamName);
actualChanges.put(maxDepositTermTypeIdParamName, SavingsEnumerations.depositTermFrequencyType(newValue));
this.maxDepositTermType = newValue;
}
if (command.isChangeInIntegerParameterNamed(inMultiplesOfDepositTermParamName, this.inMultiplesOfDepositTerm)) {
final Integer newValue = command.integerValueOfParameterNamed(inMultiplesOfDepositTermParamName);
actualChanges.put(inMultiplesOfDepositTermParamName, newValue);
this.inMultiplesOfDepositTerm = newValue;
}
if (command.isChangeInIntegerParameterNamed(inMultiplesOfDepositTermTypeIdParamName, this.inMultiplesOfDepositTermType)) {
final Integer newValue = command.integerValueOfParameterNamed(inMultiplesOfDepositTermTypeIdParamName);
actualChanges.put(inMultiplesOfDepositTermTypeIdParamName, SavingsEnumerations.inMultiplesOfDepositTermFrequencyType(newValue));
this.inMultiplesOfDepositTermType = newValue;
}
if (isMinDepositTermGreaterThanMaxDepositTerm()) {
baseDataValidator.parameter(minDepositTermParamName).value(this.minDepositTerm)
.failWithCode(".greater.than.maxDepositTerm", this.minDepositTerm, this.maxDepositTerm);
}
return actualChanges;
}
public boolean isMinDepositTermGreaterThanMaxDepositTerm() {
if (this.minDepositTerm != null && this.maxDepositTerm != null) {
final Integer minDepositInDays = this.convertToSafeDays(minDepositTerm, SavingsPeriodFrequencyType.fromInt(minDepositTermType));
final Integer maxDepositInDays = this.convertToSafeDays(maxDepositTerm, SavingsPeriodFrequencyType.fromInt(maxDepositTermType));
if (minDepositInDays.compareTo(maxDepositInDays) > 0) { return true; }
}
return false;
}
public Integer minDepositTerm() {
return this.minDepositTerm;
}
public Integer maxDepositTerm() {
return this.maxDepositTerm;
}
public Integer minDepositTermType() {
return this.minDepositTermType;
}
public Integer maxDepositTermType() {
return this.maxDepositTermType;
}
public Integer inMultiplesOfDepositTerm() {
return this.inMultiplesOfDepositTerm;
}
public Integer inMultiplesOfDepositTermType() {
return this.inMultiplesOfDepositTermType;
}
public boolean isDepositBetweenMinAndMax(LocalDate depositStartDate, LocalDate depositEndDate) {
return isEqualOrGreaterThanMin(depositStartDate, depositEndDate) && isEqualOrLessThanMax(depositStartDate, depositEndDate);
}
public boolean isValidInMultiplesOfPeriod(final Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequencyType) {
final Integer depositPeriodInDays = this.convertToSafeDays(depositPeriod, depositPeriodFrequencyType);
final Integer inMultiplesOfInDays = this.convertToSafeDays(this.inMultiplesOfDepositTerm(),
SavingsPeriodFrequencyType.fromInt(this.inMultiplesOfDepositTermType()));
final Integer minDepositInDays = this.convertToSafeDays(minDepositTerm, SavingsPeriodFrequencyType.fromInt(minDepositTermType));
return ((depositPeriodInDays - minDepositInDays) % inMultiplesOfInDays == 0);
}
private boolean isEqualOrGreaterThanMin(LocalDate depositStartDate, LocalDate depositEndDate) {
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.minDepositTermType());
final Integer depositPeriod = depositPeriod(depositStartDate, depositEndDate, periodFrequencyType);
return depositPeriod.compareTo(minDepositTerm()) >= 0;
}
private boolean isEqualOrLessThanMax(LocalDate depositStartDate, LocalDate depositEndDate) {
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.maxDepositTermType());
final Integer depositPeriod = depositPeriod(depositStartDate, depositEndDate, periodFrequencyType);
return depositPeriod.compareTo(maxDepositTerm()) <= 0;
}
public Integer depositPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate,
final SavingsPeriodFrequencyType periodFrequencyType) {
Integer actualDepositPeriod = 0;
switch (periodFrequencyType) {
case DAYS:
actualDepositPeriod = Days.daysBetween(periodStartDate, periodEndDate).getDays();
break;
case WEEKS:
actualDepositPeriod = Weeks.weeksBetween(periodStartDate, periodEndDate).getWeeks();
break;
case MONTHS:
actualDepositPeriod = Months.monthsBetween(periodStartDate, periodEndDate).getMonths();
break;
case YEARS:
actualDepositPeriod = Years.yearsBetween(periodStartDate, periodEndDate).getYears();
break;
case INVALID:
actualDepositPeriod = 0;// default value
break;
}
return actualDepositPeriod;
}
private Integer convertToSafeDays(final Integer period, final SavingsPeriodFrequencyType periodFrequencyType) {
Integer toDays = 0;
switch (periodFrequencyType) {
case DAYS:
toDays = period;
break;
case WEEKS:
toDays = period * DateTimeConstants.DAYS_PER_WEEK;
break;
case MONTHS:
toDays = period * 30;// converting to stard 30 days
break;
case YEARS:
toDays = period * 365;
break;
case INVALID:
toDays = 0;// default value
break;
}
return toDays;
}
public DepositTermDetail copy() {
final Integer minDepositTerm = this.minDepositTerm;
final Integer maxDepositTerm = this.maxDepositTerm;
final SavingsPeriodFrequencyType minDepositTermType = SavingsPeriodFrequencyType.fromInt(this.minDepositTermType);
final SavingsPeriodFrequencyType maxDepositTermType = SavingsPeriodFrequencyType.fromInt(this.maxDepositTermType);
final Integer inMultiplesOfDepositTerm = this.inMultiplesOfDepositTerm;
final SavingsPeriodFrequencyType inMultiplesOfDepositTermType = SavingsPeriodFrequencyType.fromInt(this
.inMultiplesOfDepositTermType());
return DepositTermDetail.createFrom(minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType);
}
}
@@ -0,0 +1,697 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositPeriodParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.maxDepositTermParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccountClosureIdParamName;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart;
import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartAssembler;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType;
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@DiscriminatorValue("200")
public class FixedDepositAccount extends SavingsAccount {
@OneToOne(mappedBy = "account", cascade = CascadeType.ALL)
private DepositAccountTermAndPreClosure accountTermAndPreClosure;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "account")
protected DepositAccountInterestRateChart chart;
@Transient
protected InterestRateChartAssembler chartAssembler;
protected FixedDepositAccount() {
//
}
public static FixedDepositAccount createNewApplicationForSubmittal(final Client client, final Group group,
final SavingsProduct product, final Staff fieldOfficer, final String accountNo, final String externalId,
final AccountType accountType, final LocalDate submittedOnDate, final AppUser submittedBy, final BigDecimal interestRate,
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
final boolean withdrawalFeeApplicableForTransfer, final Set<SavingsAccountCharge> savingsAccountCharges,
final DepositAccountTermAndPreClosure accountTermAndPreClosure, final DepositAccountInterestRateChart chart) {
final SavingsAccountStatusType status = SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL;
final boolean allowOverdraft = false;
final BigDecimal overdraftLimit = new BigDecimal(0);
FixedDepositAccount account = new FixedDepositAccount(client, group, product, fieldOfficer, accountNo, externalId, status,
accountType, submittedOnDate, submittedBy, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeApplicableForTransfer, savingsAccountCharges, accountTermAndPreClosure, chart,
allowOverdraft, overdraftLimit);
return account;
}
private FixedDepositAccount(final Client client, final Group group, final SavingsProduct product, final Staff fieldOfficer,
final String accountNo, final String externalId, final SavingsAccountStatusType status, final AccountType accountType,
final LocalDate submittedOnDate, final AppUser submittedBy, final BigDecimal nominalAnnualInterestRate,
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
final boolean withdrawalFeeApplicableForTransfer, final Set<SavingsAccountCharge> savingsAccountCharges,
final DepositAccountTermAndPreClosure accountTermAndPreClosure, DepositAccountInterestRateChart chart,
final boolean allowOverdraft, final BigDecimal overdraftLimit) {
super(client, group, product, fieldOfficer, accountNo, externalId, status, accountType, submittedOnDate, submittedBy,
nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
withdrawalFeeApplicableForTransfer, savingsAccountCharges, allowOverdraft, overdraftLimit);
this.accountTermAndPreClosure = accountTermAndPreClosure;
this.chart = chart;
if (this.chart != null) {
this.chart.updateDepositAccountReference(this);
}
}
@Override
public void modifyApplication(final JsonCommand command, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.modifyApplicationAction);
super.modifyApplication(command, actualChanges, baseDataValidator);
accountTermAndPreClosure.update(command, baseDataValidator);
validateDomainRules(baseDataValidator);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
@Override
protected BigDecimal getEffectiveInterestRateAsFraction(final MathContext mc, final LocalDate interestPostingUpToDate) {
final boolean isPreMatureClosure = SavingsAccountStatusType.fromInt(this.status).isPreMatureClosure();
boolean applyPreMaturePenalty = false;
BigDecimal penalInterest = BigDecimal.ZERO;
LocalDate depositCloseDate = calculateMaturityDate();
if (isPreMatureClosure) {
if (this.accountTermAndPreClosure.isPreClosurePenalApplicable()) {
applyPreMaturePenalty = true;
penalInterest = this.accountTermAndPreClosure.depositPreClosureDetail().preClosurePenalInterest();
final PreClosurePenalInterestOnType preClosurePenalInterestOnType = this.accountTermAndPreClosure.depositPreClosureDetail()
.preClosurePenalInterestOnType();
if (preClosurePenalInterestOnType.isWholeTerm()) {
depositCloseDate = interestCalculatedUpto();
} else if (preClosurePenalInterestOnType.isTillPrematureWithdrawal()) {
depositCloseDate = interestPostingUpToDate;
}
}
}
final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount();
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate);
if (applyPreMaturePenalty) {
applicableInterestRate = applicableInterestRate.subtract(penalInterest);
applicableInterestRate = applicableInterestRate.compareTo(BigDecimal.ZERO) == -1 ? BigDecimal.ZERO : applicableInterestRate;
}
this.nominalAnnualInterestRate = applicableInterestRate;
return applicableInterestRate.divide(BigDecimal.valueOf(100l), mc);
}
public void updateMaturityDateAndAmountBeforeAccountActivation(final MathContext mc) {
List<SavingsAccountTransaction> allTransactions = new ArrayList<SavingsAccountTransaction>();
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date());
transaction.updateRunningBalance(transactionAmountMoney);
transaction.updateCumulativeBalanceAndDates(this.getCurrency(), interestCalculatedUpto());
allTransactions.add(transaction);
updateMaturityDateAndAmount(mc, allTransactions);
}
public void updateMaturityDateAndAmount(final MathContext mc, final List<SavingsAccountTransaction> transactions) {
final LocalDate maturityDate = calculateMaturityDate();
final LocalDate interestCalculationUpto = maturityDate.minusDays(1);
final List<PostingPeriod> postingPeriods = calculateInterestPayable(mc, interestCalculationUpto, transactions);
Money totalInterestPayable = Money.zero(getCurrency());
for (PostingPeriod postingPeriod : postingPeriods) {
totalInterestPayable = totalInterestPayable.plus(postingPeriod.getInterestEarned());
}
final Money depositAmount = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
final Money maturityAmount = depositAmount.plus(totalInterestPayable);
this.accountTermAndPreClosure.updateMaturityDetails(maturityAmount.getAmount(), maturityDate);
}
public void updateMaturityStatus() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.updateMaturityDetailsAction);
final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
if (!SavingsAccountStatusType.ACTIVE.hasStateOf(currentStatus)) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.active.state");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
final LocalDate todayDate = DateUtils.getLocalDateOfTenant();
if (!this.maturityDate().isAfter(todayDate)) {
// update account status
this.status = SavingsAccountStatusType.MATURED.getValue();
postMaturityInterest(maturityDate());
}
}
public LocalDate calculateMaturityDate() {
final LocalDate startDate = accountSubmittedOrActivationDate();
LocalDate maturityDate = null;
final Integer depositPeriod = this.accountTermAndPreClosure.depositPeriod();
switch (this.accountTermAndPreClosure.depositPeriodFrequencyType()) {
case DAYS:
maturityDate = startDate.plusDays(depositPeriod);
break;
case WEEKS:
maturityDate = startDate.plusWeeks(depositPeriod);
break;
case MONTHS:
maturityDate = startDate.plusMonths(depositPeriod);
break;
case YEARS:
maturityDate = startDate.plusYears(depositPeriod);
break;
case INVALID:
break;
}
return maturityDate;
}
private List<PostingPeriod> calculateInterestPayable(final MathContext mc, final LocalDate maturityDate,
final List<SavingsAccountTransaction> transactions) {
// 1. default to calculate interest based on entire history OR
// 2. determine latest 'posting period' and find interest credited to
// that period
// A generate list of EndOfDayBalances (not including interest postings)
final SavingsPostingInterestPeriodType postingPeriodType = SavingsPostingInterestPeriodType.fromInt(this.interestPostingPeriodType);
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
.fromInt(this.interestCompoundingPeriodType);
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
.fromInt(this.interestCalculationDaysInYearType);
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
accountSubmittedOrActivationDate(), maturityDate, postingPeriodType);
final List<PostingPeriod> allPostingPeriods = new ArrayList<PostingPeriod>();
Money periodStartingBalance = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
final BigDecimal interestRateAsFraction = getEffectiveInterestRateAsFraction(mc, maturityDate);
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
maturityDate);
periodStartingBalance = postingPeriod.closingBalance();
allPostingPeriods.add(postingPeriod);
}
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods);
return allPostingPeriods;
}
public SavingsAccountTransaction prematureClosure(final AppUser currentUser, final JsonCommand command,
final LocalDate tenantsTodayDate, final PaymentDetail paymentDetail, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + DepositsApiConstants.preMatureCloseAction);
final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
if (!SavingsAccountStatusType.ACTIVE.hasStateOf(currentStatus)) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.active.state");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
if (closedDate.isBefore(getActivationLocalDate())) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.after.activation.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
if (closedDate.isAfter(maturityDate())) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.before.maturity.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
if (closedDate.isAfter(tenantsTodayDate)) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("cannot.be.a.future.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
final List<SavingsAccountTransaction> savingsAccountTransactions = retreiveListOfTransactions();
if (savingsAccountTransactions.size() > 0) {
final SavingsAccountTransaction accountTransaction = savingsAccountTransactions.get(savingsAccountTransactions.size() - 1);
if (accountTransaction.isAfter(closedDate)) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.after.last.transaction.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_CLOSE_ACCOUNT, closedDate);
this.status = SavingsAccountStatusType.PRE_MATURE_CLOSURE.getValue();
final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);
postPreMaturityInterest(closedDate);
// withdraw deposit amount before closing the account
final Money transactionAmountMoney = Money.of(this.currency, this.getAccountBalance());
final SavingsAccountTransaction withdraw = SavingsAccountTransaction.withdrawal(this, office(), paymentDetail, closedDate,
transactionAmountMoney, new Date());
this.transactions.add(withdraw);
actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat());
actualChanges.put(SavingsApiConstants.closedOnDateParamName, closedDate.toString(fmt));
this.rejectedOnDate = null;
this.rejectedBy = null;
this.withdrawnOnDate = null;
this.withdrawnBy = null;
this.closedOnDate = closedDate.toDate();
this.closedBy = currentUser;
return withdraw;
}
@Override
protected void processAccountUponActivation(final DateTimeFormatter fmt) {
final Money depositAmount = Money.of(this.currency, this.accountTermAndPreClosure.depositAmount());
if (depositAmount.isGreaterThanZero()) {
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, getActivationLocalDate(),
depositAmount.getAmount(), null, new Date());
deposit(transactionDTO);
final LocalDate interestPostingUpToDate = interestPostingUpToDate(DateUtils.getLocalDateOfTenant());
// update existing transactions so derived balance fields are
// correct.
recalculateDailyBalances(Money.zero(this.currency), interestPostingUpToDate);
}
}
public SavingsAccountTransaction close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
final PaymentDetail paymentDetail, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.closeAction);
final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
if (!SavingsAccountStatusType.MATURED.hasStateOf(currentStatus)) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.matured.state");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
if (closedDate.isBefore(getActivationLocalDate())) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.after.activation.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
if (closedDate.isBefore(maturityDate())) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.after.account.maturity.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
if (closedDate.isAfter(tenantsTodayDate)) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("cannot.be.a.future.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
final List<SavingsAccountTransaction> savingsAccountTransactions = retreiveListOfTransactions();
if (savingsAccountTransactions.size() > 0) {
final SavingsAccountTransaction accountTransaction = savingsAccountTransactions.get(savingsAccountTransactions.size() - 1);
if (accountTransaction.isAfter(closedDate)) {
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
.failWithCode("must.be.after.last.transaction.date");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_CLOSE_ACCOUNT, closedDate);
this.status = SavingsAccountStatusType.CLOSED.getValue();
final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);
postMaturityInterest(maturityDate());
// withdraw deposit amount before closing the account
final Money transactionAmountMoney = Money.of(this.currency, this.getAccountBalance());
final SavingsAccountTransaction withdraw = SavingsAccountTransaction.withdrawal(this, office(), paymentDetail, closedDate,
transactionAmountMoney, new Date());
this.transactions.add(withdraw);
actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat());
actualChanges.put(SavingsApiConstants.closedOnDateParamName, closedDate.toString(fmt));
this.rejectedOnDate = null;
this.rejectedBy = null;
this.withdrawnOnDate = null;
this.withdrawnBy = null;
this.closedOnDate = closedDate.toDate();
this.closedBy = currentUser;
return withdraw;
}
public void postMaturityInterest(final LocalDate interestPostingUpToDate) {
final MathContext mc = MathContext.DECIMAL64;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate);
Money interestPostedToDate = Money.zero(this.currency);
boolean recalucateDailyBalanceDetails = false;
for (final PostingPeriod interestPostingPeriod : postingPeriods) {
LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();
interestPostingTransactionDate = interestPostingTransactionDate.isAfter(interestPostingUpToDate) ? interestPostingUpToDate
: interestPostingTransactionDate;
final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();
interestPostedToDate = interestPostedToDate.plus(interestEarnedToBePostedForPeriod);
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
} else {
final boolean correctionRequired = postingTransaction.hasNotAmount(interestEarnedToBePostedForPeriod);
if (correctionRequired) {
postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
}
}
}
if (recalucateDailyBalanceDetails) {
// update existing transactions so derived balance fields are
// correct.
recalculateDailyBalances(Money.zero(this.currency), interestPostingUpToDate);
}
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
}
public void postPreMaturityInterest(final LocalDate accountCloseDate) {
Money interestPostedToDate = totalInterestPosted();
final Money interestOnMaturity = calculatePreMatureInterest(accountCloseDate, retreiveOrderedNonInterestPostingTransactions());
boolean recalucateDailyBalance = false;
// post remaining interest
final Money remainigInterestToBePosted = interestOnMaturity.minus(interestPostedToDate);
if (!remainigInterestToBePosted.isZero()) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
accountCloseDate, remainigInterestToBePosted);
this.transactions.add(newPostingTransaction);
recalucateDailyBalance = true;
}
if (recalucateDailyBalance) {
// update existing transactions so derived balance fields are
// correct.
recalculateDailyBalances(Money.zero(this.currency), accountCloseDate);
}
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
this.accountTermAndPreClosure.updateMaturityDetails(this.getAccountBalance(), accountCloseDate);
}
public BigDecimal calculatePreMatureAmount(final LocalDate preMatureDate) {
final Money interestPostedToDate = totalInterestPosted().copy();
final Money interestEarnedTillDate = calculatePreMatureInterest(preMatureDate, retreiveOrderedNonInterestPostingTransactions());
final Money accountBalance = Money.of(getCurrency(), getAccountBalance());
final Money maturityAmount = accountBalance.minus(interestPostedToDate).plus(interestEarnedTillDate);
return maturityAmount.getAmount();
}
private Money calculatePreMatureInterest(final LocalDate preMatureDate, final List<SavingsAccountTransaction> transactions) {
final MathContext mc = MathContext.DECIMAL64;
final List<PostingPeriod> postingPeriods = calculateInterestPayable(mc, preMatureDate, transactions);
Money interestOnMaturity = Money.zero(this.currency);
for (final PostingPeriod interestPostingPeriod : postingPeriods) {
final Money interestEarnedForPeriod = interestPostingPeriod.getInterestEarned();
interestOnMaturity = interestOnMaturity.plus(interestEarnedForPeriod);
}
return interestOnMaturity;
}
@Override
public void postInterest(final MathContext mc, final LocalDate postingDate) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
super.postInterest(mc, interestPostingUpToDate);
}
@Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate);
}
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
LocalDate interestPostingUpToDate = interestPostingDate;
final LocalDate uptoMaturityDate = interestCalculatedUpto();
if (uptoMaturityDate != null && uptoMaturityDate.isBefore(interestPostingDate)) {
interestPostingUpToDate = uptoMaturityDate;
}
return interestPostingUpToDate;
}
public LocalDate maturityDate() {
return this.accountTermAndPreClosure.getMaturityLocalDate();
}
public BigDecimal maturityAmount() {
return this.accountTermAndPreClosure.maturityAmount();
}
private Money totalInterestPosted() {
Money interestPostedToDate = Money.zero(this.currency);
for (final SavingsAccountTransaction transaction : this.transactions) {
if (transaction.isInterestPostingAndNotReversed()) {
interestPostedToDate = interestPostedToDate.plus(transaction.getAmount(currency));
}
}
return interestPostedToDate;
}
@Override
public Map<String, Object> activate(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate) {
final Map<String, Object> actualChanges = super.activate(currentUser, command, tenantsTodayDate);
final MathContext mc = MathContext.DECIMAL64;
List<SavingsAccountTransaction> allTransactions = new ArrayList<SavingsAccountTransaction>();
allTransactions.addAll(retreiveOrderedNonInterestPostingTransactions());
updateMaturityDateAndAmount(mc, allTransactions);
return actualChanges;
}
private LocalDate depositStartDate() {
// TODO: Support to add deposit start date which can be a date after
// account activation date.
final LocalDate depositStartDate = accountSubmittedOrActivationDate();
return depositStartDate;
}
private LocalDate interestCalculatedUpto() {
LocalDate uptoMaturityDate = calculateMaturityDate();
if (uptoMaturityDate != null) {
// interest should not be calculated for maturity day
uptoMaturityDate = uptoMaturityDate.minusDays(1);
}
return uptoMaturityDate;
}
public void validateDomainRules() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME);
validateDomainRules(baseDataValidator);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
private void validateDomainRules(final DataValidatorBuilder baseDataValidator) {
final boolean isMinTermGreaterThanMax = this.accountTermAndPreClosure.depositTermDetail()
.isMinDepositTermGreaterThanMaxDepositTerm();
final boolean isValidDepositPeriod = this.accountTermAndPreClosure.depositTermDetail().isDepositBetweenMinAndMax(
depositStartDate(), calculateMaturityDate());
// deposit period should be within min and max deposit term
if (isMinTermGreaterThanMax) {
final Integer maxTerm = this.accountTermAndPreClosure.depositTermDetail().maxDepositTerm();
baseDataValidator.reset().parameter(maxDepositTermParamName).value(maxTerm)
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
}
final Integer depositPeriod = this.accountTermAndPreClosure.depositPeriod();
final SavingsPeriodFrequencyType depositPeriodFrequencyType = this.accountTermAndPreClosure.depositPeriodFrequencyType();
if (!isValidDepositPeriod) {
baseDataValidator.reset().parameter(depositPeriodParamName).value(depositPeriod)
.failWithCodeNoParameterAddedToErrorCode("deposit.period.not.between.min.and.max.deposit.term");
} else {
final Integer inMultiplesOf = this.accountTermAndPreClosure.depositTermDetail().inMultiplesOfDepositTerm();
if (inMultiplesOf != null) {
final boolean isValid = this.accountTermAndPreClosure.depositTermDetail().isValidInMultiplesOfPeriod(depositPeriod,
depositPeriodFrequencyType);
if (!isValid) {
baseDataValidator.reset().parameter(depositPeriodParamName).value(depositPeriod)
.failWithCodeNoParameterAddedToErrorCode("deposit.period.not.multiple.of.term");
}
}
}
if(this.chart == null){
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("no.valid.interest.rate.slab.available");
}else{
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
chartEndDate = chartEndDate == null ? DateUtils.getLocalDateOfTenant() : chartEndDate;
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
if(!chartInterval.contains(accountSubmittedOrActivationDate())){
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("no.valid.interest.rate.slab.available");
}
}
}
public boolean isReinvestOnClosure() {
return this.accountTermAndPreClosure.isReinvestOnClosure();
}
public boolean isTransferToSavingsOnClosure() {
return this.accountTermAndPreClosure.isTransferToSavingsOnClosure();
}
public FixedDepositAccount reInvest(Money depositAmount) {
final DepositAccountTermAndPreClosure newAccountTermAndPreClosure = this.accountTermAndPreClosure.deepCopy(depositAmount);
final SavingsProduct product = this.product;
final InterestRateChart productChart = product.applicableChart(getClosedOnDate());
final DepositAccountInterestRateChart newChart = DepositAccountInterestRateChart.from(productChart);
final AccountType accountType = AccountType.fromInt(this.accountType);
final SavingsPostingInterestPeriodType postingPeriodType = SavingsPostingInterestPeriodType.fromInt(this.interestPostingPeriodType);
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
.fromInt(this.interestCompoundingPeriodType);
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
.fromInt(this.interestCalculationDaysInYearType);
final BigDecimal minRequiredOpeningBalance = null;
final BigDecimal interestRate = BigDecimal.ZERO;
final Set<SavingsAccountCharge> savingsAccountCharges = null;
final SavingsPeriodFrequencyType lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
final Integer lockinPeriodFrequency = this.lockinPeriodFrequency;
final boolean withdrawalFeeApplicableForTransfer = false;
final String accountNumber = null;
final FixedDepositAccount reInvestedAccount = FixedDepositAccount.createNewApplicationForSubmittal(client, group, product, fieldOfficer, accountNumber, externalId,
accountType, getClosedOnDate(), closedBy, interestRate, compoundingPeriodType, postingPeriodType, interestCalculationType,
daysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
withdrawalFeeApplicableForTransfer, savingsAccountCharges, newAccountTermAndPreClosure, newChart);
newAccountTermAndPreClosure.updateAccountReference(reInvestedAccount);
newChart.updateDepositAccountReference(reInvestedAccount);
return reInvestedAccount;
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface FixedDepositAccountRepository extends JpaRepository<FixedDepositAccount, Long>, JpaSpecificationExecutor<FixedDepositAccount> {
}

Some files were not shown because too many files have changed in this diff Show More