diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 684d181d5..b506c8c10 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -2854,7 +2854,7 @@ GET https://DomainName/api/v1/clients/template
Optional Fields
- groupId, externalId, accountNo, staffId, mobileNo, savingsProductId + groupId, externalId, accountNo, staffId, mobileNo, savingsProductId, genderId, clientTypeId, clientClassificationId @@ -29483,6 +29483,14 @@ GET https://DomainName/api/v1/interestratecharts/template provide a description about the slab. + + incentives + + + + Represents incentives on interest for a perticular period. + + @@ -29526,7 +29534,15 @@ Request Body: "toPeriod": "180", "annualInterestRate": "5", "description": "5% interest from 1 day till 180 days of deposit", - "locale":"en" + "locale":"en", + "incentives":[{ + "entityType":"2", + "attributeName":2, + "conditionType":2, + "attributeValue":11, + "incentiveType":3, + "amount":"-1" + }] } @@ -29572,7 +29588,15 @@ GET https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs "displaySymbol": "$", "nameCode": "currency.USD", "displayLabel": "US Dollar ($)" - } + }, + "incentives":[{ + "id":1, + "entityType":{"id":2,"code":"InterestIncentiveEntityType.customer","value":"Customer"}, + "attributeName":{"id":2,"code":"InterestIncentiveAttributeName.gender","value":"Gender"}, "conditionType":{"id":2,"code":"incentiveConditionType.equal","value":"equal"}, + "attributeValue":"11","attributeValueDesc":"FEMALE", + "incentiveType":{"id":3,"code":"InterestIncentiveType.incentive","value":"Incentive"}, + "amount":-1.000000 + }] } ] @@ -29612,7 +29636,15 @@ GET https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs/{slabId} "displaySymbol": "$", "nameCode": "currency.USD", "displayLabel": "US Dollar ($)" - } + }, + "incentives":[{ + "id":1, + "entityType":{"id":2,"code":"InterestIncentiveEntityType.customer","value":"Customer"}, + "attributeName":{"id":2,"code":"InterestIncentiveAttributeName.gender","value":"Gender"}, "conditionType":{"id":2,"code":"incentiveConditionType.equal","value":"equal"}, + "attributeValue":"11","attributeValueDesc":"FEMALE", + "incentiveType":{"id":3,"code":"InterestIncentiveType.incentive","value":"Incentive"}, + "amount":-1.000000 + }] } diff --git a/mifosng-db/migrations/core_db/V175__added_incentive_interest_rates.sql b/mifosng-db/migrations/core_db/V175__added_incentive_interest_rates.sql new file mode 100755 index 000000000..c785d1a1d --- /dev/null +++ b/mifosng-db/migrations/core_db/V175__added_incentive_interest_rates.sql @@ -0,0 +1,49 @@ +ALTER TABLE `m_client` + ADD COLUMN `client_type_cv_id` INT(11) NULL DEFAULT NULL AFTER `default_savings_account`, + ADD COLUMN `client_classification_cv_id` INT(11) NULL DEFAULT NULL AFTER `client_type_cv_id`, + ADD CONSTRAINT `FK_m_client_type_m_code_value` FOREIGN KEY (`client_type_cv_id`) REFERENCES `m_code_value` (`id`), + ADD CONSTRAINT `FK_m_client_classification_m_code_value` FOREIGN KEY (`client_classification_cv_id`) REFERENCES `m_code_value` (`id`), + ADD CONSTRAINT `FK1_m_client_gender_m_code_value` FOREIGN KEY (`gender_cv_id`) REFERENCES `m_code_value` (`id`); + +INSERT INTO `m_code` (`code_name`, `is_system_defined`) VALUES ('ClientType', 1); +INSERT INTO `m_code` (`code_name`, `is_system_defined`) VALUES ('ClientClassification', 1); + + +CREATE TABLE `m_interest_incentives` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `interest_rate_slab_id` BIGINT(20) NOT NULL, + `entiry_type` SMALLINT(2) NOT NULL, + `attribute_name` SMALLINT(2) NOT NULL, + `condition_type` SMALLINT(2) NOT NULL, + `attribute_value` VARCHAR(50) NOT NULL, + `incentive_type` SMALLINT(2) NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_m_interest_incentives_m_interest_rate_slab` (`interest_rate_slab_id`), + CONSTRAINT `FK_m_interest_incentives_m_interest_rate_slab` FOREIGN KEY (`interest_rate_slab_id`) REFERENCES `m_interest_rate_slab` (`id`) +); + + +CREATE TABLE `m_savings_interest_incentives` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `deposit_account_interest_rate_slab_id` BIGINT(20) NOT NULL, + `entiry_type` SMALLINT(2) NOT NULL, + `attribute_name` SMALLINT(2) NOT NULL, + `condition_type` SMALLINT(2) NOT NULL, + `attribute_value` VARCHAR(50) NOT NULL, + `incentive_type` SMALLINT(2) NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_m_savings_interest_incentives_m_savings_interest_rate_slab` (`deposit_account_interest_rate_slab_id`), + CONSTRAINT `FK_m_savings_interest_incentives_m_savings_interest_rate_slab` FOREIGN KEY (`deposit_account_interest_rate_slab_id`) REFERENCES `m_savings_account_interest_rate_slab` (`id`) +); + +ALTER TABLE `m_interest_rate_slab` + DROP COLUMN `interest_rate_for_female`, + DROP COLUMN `interest_rate_for_children`, + DROP COLUMN `interest_rate_for_senior_citizen`; + +ALTER TABLE `m_savings_account_interest_rate_slab` + DROP COLUMN `interest_rate_for_female`, + DROP COLUMN `interest_rate_for_children`, + DROP COLUMN `interest_rate_for_senior_citizen`; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java index 53cec0aa6..56801d5e4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java @@ -338,6 +338,15 @@ public final class JsonCommand { return isChanged; } + public boolean isChangeInBigDecimalParameterNamed(final String parameterName, final BigDecimal existingValue, final Locale locale) { + boolean isChanged = false; + if (parameterExists(parameterName)) { + final BigDecimal workingValue = bigDecimalValueOfParameterNamed(parameterName, locale); + isChanged = differenceExists(existingValue, workingValue); + } + return isChanged; + } + public boolean isChangeInBigDecimalParameterNamedWithNullCheck(final String parameterName, final BigDecimal existingValue) { boolean isChanged = false; if (parameterExists(parameterName)) { @@ -371,6 +380,10 @@ public final class JsonCommand { return this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(parameterName, this.parsedCommand); } + public BigDecimal bigDecimalValueOfParameterNamed(final String parameterName, final Locale locale) { + return this.fromApiJsonHelper.extractBigDecimalNamed(parameterName, this.parsedCommand, locale); + } + public BigDecimal bigDecimalValueOfParameterNamedDefaultToNullIfZero(final String parameterName) { return defaultToNullIfZero(bigDecimalValueOfParameterNamed(parameterName)); } @@ -393,6 +406,15 @@ public final class JsonCommand { return isChanged; } + public boolean isChangeInIntegerParameterNamed(final String parameterName, final Integer existingValue, final Locale locale) { + boolean isChanged = false; + if (parameterExists(parameterName)) { + final Integer workingValue = integerValueOfParameterNamed(parameterName, locale); + isChanged = differenceExists(existingValue, workingValue); + } + return isChanged; + } + public boolean isChangeInIntegerParameterNamedWithNullCheck(final String parameterName, final Integer existingValue) { boolean isChanged = false; if (parameterExists(parameterName)) { @@ -410,6 +432,10 @@ public final class JsonCommand { return this.fromApiJsonHelper.extractIntegerWithLocaleNamed(parameterName, this.parsedCommand); } + public Integer integerValueOfParameterNamed(final String parameterName, final Locale locale) { + return this.fromApiJsonHelper.extractIntegerNamed(parameterName, this.parsedCommand, locale); + } + public Integer integerValueOfParameterNamedDefaultToNullIfZero(final String parameterName) { return defaultToNullIfZero(integerValueOfParameterNamed(parameterName)); } @@ -493,5 +519,5 @@ public final class JsonCommand { public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set requestDataParameters) { this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, requestDataParameters); } - + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java index c4e519ccd..f2ec031d8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java @@ -16,6 +16,8 @@ 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"; + public static final String CLIENT_TYPE = "ClientType"; + public static final String CLIENT_CLASSIFICATION = "ClientClassification"; // general public static final String localeParamName = "locale"; public static final String dateFormatParamName = "dateFormat"; @@ -43,6 +45,10 @@ public class ClientApiConstants { public static final String dateOfBirthParamName = "dateOfBirth"; public static final String genderIdParamName = "genderId"; public static final String genderParamName = "gender"; + public static final String clientTypeIdParamName = "clientTypeId"; + public static final String clientTypeParamName = "clientType"; + public static final String clientClassificationIdParamName = "clientClassificationId"; + public static final String clientClassificationParamName = "clientClassification"; // response parameters public static final String statusParamName = "status"; public static final String hierarchyParamName = "hierarchy"; @@ -67,12 +73,13 @@ public class ClientApiConstants { public static final Set CLIENT_CREATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, dateFormatParamName, groupIdParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName, middlenameParamName, lastnameParamName, fullnameParamName, officeIdParamName, activeParamName, activationDateParamName, - staffIdParamName, submittedOnDateParamName, savingsProductIdParamName, dateOfBirthParamName, genderIdParamName)); + staffIdParamName, submittedOnDateParamName, savingsProductIdParamName, dateOfBirthParamName, genderIdParamName, + clientTypeIdParamName, clientClassificationIdParamName)); public static final Set CLIENT_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, dateFormatParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName, middlenameParamName, lastnameParamName, fullnameParamName, activeParamName, activationDateParamName, staffIdParamName, savingsProductIdParamName, - dateOfBirthParamName, genderIdParamName)); + dateOfBirthParamName, genderIdParamName, clientTypeIdParamName, clientClassificationIdParamName)); /** * These parameters will match the class level parameters of @@ -84,7 +91,7 @@ public class ClientApiConstants { lastnameParamName, fullnameParamName, displayNameParamName, mobileNoParamName, officeIdParamName, officeNameParamName, transferToOfficeIdParamName, transferToOfficeNameParamName, hierarchyParamName, imageIdParamName, imagePresentParamName, staffIdParamName, staffNameParamName, timelineParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName, - dateOfBirthParamName, genderParamName)); + dateOfBirthParamName, genderParamName,clientTypeParamName,clientClassificationParamName)); public static final Set ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, dateFormatParamName, activationDateParamName)); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java index 125f7124a..bd92d278a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java @@ -42,6 +42,8 @@ final public class ClientData implements Comparable { private final String mobileNo; private final LocalDate dateOfBirth; private final CodeValueData gender; + private final CodeValueData clientType; + private final CodeValueData clientClassification; private final Long officeId; private final String officeName; @@ -69,13 +71,18 @@ final public class ClientData implements Comparable { private final Collection savingProductOptions; private final Collection savingAccountOptions; private final Collection genderOptions; + private final Collection clientTypeOptions; + private final Collection clientClassificationOptions; public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection officeOptions, final Collection staffOptions, final Collection closureReasons, - final Collection genderOptions, final Collection savingProductOptions) { + final Collection genderOptions, final Collection savingProductOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { + final CodeValueData clientType = null; + final CodeValueData clientClassification = null; 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); + joinedDate, null, null, null, officeOptions, null, staffOptions, closureReasons, genderOptions, null, savingProductOptions, + null, null, null, null, clientType, clientClassification, clientTypeOptions, clientClassificationOptions); } @@ -85,9 +92,11 @@ final public class ClientData implements Comparable { clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.mobileNo, clientData.dateOfBirth, clientData.gender, clientData.activationDate, clientData.imageId, clientData.staffId, - clientData.staffName, templateData.officeOptions, clientData.groups, templateData.staffOptions, templateData.closureReasons, templateData.genderOptions, clientData.timeline, - templateData.savingProductOptions, clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId, - clientData.savingAccountOptions); + clientData.staffName, templateData.officeOptions, clientData.groups, templateData.staffOptions, + templateData.closureReasons, templateData.genderOptions, clientData.timeline, templateData.savingProductOptions, + clientData.savingsProductId, clientData.savingsProductName, clientData.savingsAccountId, clientData.savingAccountOptions, + clientData.clientType, clientData.clientClassification, templateData.clientTypeOptions, + templateData.clientClassificationOptions); } @@ -98,9 +107,10 @@ final public class ClientData implements Comparable { clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.mobileNo, 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); + clientData.staffName, clientData.officeOptions, clientData.groups, clientData.staffOptions, clientData.closureReasons, + clientData.genderOptions, clientData.timeline, clientData.savingProductOptions, clientData.savingsProductId, + clientData.savingsProductName, clientData.savingsAccountId, savingAccountOptions, clientData.clientType, + clientData.clientClassification, clientData.clientTypeOptions, clientData.clientClassificationOptions); } @@ -111,22 +121,32 @@ final public class ClientData implements Comparable { 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); + clientData.savingAccountOptions, clientData.clientType, clientData.clientClassification, clientData.clientTypeOptions, + clientData.clientClassificationOptions); } public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname, final String middlename, final String lastname, final String fullname, final String displayName, final Long officeId, final String officeName) { - + final CodeValueData clientType = null; + final CodeValueData clientClassification = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; 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, null, null, null); + displayName, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, clientType, clientClassification, clientTypeOptions, clientClassificationOptions); } public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) { + final CodeValueData clientType = null; + final CodeValueData clientClassification = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; 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, null, null, null, clientType, + clientClassification, clientTypeOptions, clientClassificationOptions); } @@ -135,10 +155,14 @@ final public class ClientData implements Comparable { final String middlename, final String lastname, final String fullname, final String displayName, final String externalId, 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) { + final String savingsProductName, final Long savingsAccountId, final CodeValueData clientType, + final CodeValueData clientClassification) { + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; return new ClientData(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname, middlename, lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId, staffId, staffName, - null, null, null, null, null, timeline, null, savingsProductId, savingsProductName, savingsAccountId, null); + null, null, null, null, null, timeline, null, savingsProductId, savingsProductName, savingsAccountId, null, clientType, + clientClassification, clientTypeOptions, clientClassificationOptions); } @@ -148,9 +172,11 @@ final public class ClientData implements Comparable { final String mobileNo, final LocalDate dateOfBirth, final CodeValueData gender, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName, final Collection allowedOffices, final Collection groups, final Collection staffOptions, - final Collection closureReasons, final Collection genderOptions, final ClientTimelineData timeline, - final Collection savingProductOptions, final Long savingsProductId, final String savingsProductName, - final Long savingsAccountId, final Collection savingAccountOptions) { + final Collection closureReasons, final Collection genderOptions, + final ClientTimelineData timeline, final Collection savingProductOptions, final Long savingsProductId, + final String savingsProductName, final Long savingsAccountId, final Collection savingAccountOptions, + final CodeValueData clientType, final CodeValueData clientClassification, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { this.accountNo = accountNo; this.status = status; if (status != null) { @@ -173,6 +199,8 @@ final public class ClientData implements Comparable { this.activationDate = activationDate; this.dateOfBirth = dateOfBirth; this.gender = gender; + this.clientClassification = clientClassification; + this.clientType = clientType; this.imageId = imageId; if (imageId != null) { this.imagePresent = Boolean.TRUE; @@ -190,6 +218,8 @@ final public class ClientData implements Comparable { this.staffOptions = staffOptions; this.closureReasons = closureReasons; this.genderOptions = genderOptions; + this.clientClassificationOptions = clientClassificationOptions; + this.clientTypeOptions = clientTypeOptions; this.timeline = timeline; this.savingProductOptions = savingProductOptions; @@ -197,6 +227,7 @@ final public class ClientData implements Comparable { this.savingsProductName = savingsProductName; this.savingsAccountId = savingsAccountId; this.savingAccountOptions = savingAccountOptions; + } public Long id() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java index 5ac2c2e0a..c154294c3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java @@ -153,9 +153,21 @@ public final class ClientDataValidator { if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) { final Integer genderId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.genderIdParamName, element); - baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).notNull(); + baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).integerGreaterThanZero(); } + if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.clientTypeIdParamName, element)) { + final Integer clientType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.clientTypeIdParamName, + element); + baseDataValidator.reset().parameter(ClientApiConstants.clientTypeIdParamName).value(clientType).integerGreaterThanZero(); + } + + if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.clientClassificationIdParamName, element)) { + final Integer clientClassification = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + ClientApiConstants.clientClassificationIdParamName, element); + baseDataValidator.reset().parameter(ClientApiConstants.clientClassificationIdParamName).value(clientClassification) + .integerGreaterThanZero(); + } throwExceptionIfValidationWarningsExist(dataValidationErrors); } @@ -338,7 +350,20 @@ public final class ClientDataValidator { if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) { final Integer genderId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.genderIdParamName, element); - baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).notNull(); + baseDataValidator.reset().parameter(ClientApiConstants.genderIdParamName).value(genderId).integerGreaterThanZero(); + } + + if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.clientTypeIdParamName, element)) { + final Integer clientType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(ClientApiConstants.clientTypeIdParamName, + element); + baseDataValidator.reset().parameter(ClientApiConstants.clientTypeIdParamName).value(clientType).integerGreaterThanZero(); + } + + if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.clientClassificationIdParamName, element)) { + final Integer clientClassification = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + ClientApiConstants.clientClassificationIdParamName, element); + baseDataValidator.reset().parameter(ClientApiConstants.clientClassificationIdParamName).value(clientClassification) + .integerGreaterThanZero(); } if (!atLeastOneParameterPassedForUpdate) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java index e089fe407..9ab4cf1c5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java @@ -46,7 +46,6 @@ import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.portfolio.client.api.ClientApiConstants; import org.mifosplatform.portfolio.group.domain.Group; -import org.mifosplatform.portfolio.interestratechart.data.ClientIncentiveAttributes; import org.mifosplatform.portfolio.savings.domain.SavingsAccount; import org.mifosplatform.portfolio.savings.domain.SavingsProduct; import org.mifosplatform.useradministration.domain.AppUser; @@ -159,11 +158,17 @@ public final class Client extends AbstractPersistable { @JoinColumn(name = "default_savings_account", nullable = true) private SavingsAccount savingsAccount; - @Transient - private ClientIncentiveAttributes incentiveAttributes; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "client_type_cv_id", nullable = true) + private CodeValue clientType; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "client_classification_cv_id", nullable = true) + private CodeValue clientClassification; public static Client createNew(final AppUser currentUser, final Office clientOffice, final Group clientParentGroup, final Staff staff, - final SavingsProduct savingsProduct, final CodeValue gender, final JsonCommand command) { + final SavingsProduct savingsProduct, final CodeValue gender, final CodeValue clientType, final CodeValue clientClassification, + final JsonCommand command) { final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName); final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName); @@ -200,7 +205,7 @@ public final class Client extends AbstractPersistable { final SavingsAccount account = null; return new Client(currentUser, status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate, officeJoiningDate, externalId, mobileNo, staff, submittedOnDate, savingsProduct, account, dataOfBirth, - gender); + gender, clientType, clientClassification); } protected Client() { @@ -211,7 +216,7 @@ public final class Client extends AbstractPersistable { 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 LocalDate dateOfBirth, final CodeValue gender) { + final LocalDate dateOfBirth, final CodeValue gender, final CodeValue clientType, final CodeValue clientClassification) { if (StringUtils.isBlank(accountNo)) { this.accountNumber = new RandomPasswordGenerator(19).generate(); @@ -283,6 +288,8 @@ public final class Client extends AbstractPersistable { if (dateOfBirth != null) { this.dateOfBirth = dateOfBirth.toDateTimeAtStartOfDay().toDate(); } + this.clientType = clientType; + this.clientClassification = clientClassification; deriveDisplayName(); validate(); @@ -429,7 +436,7 @@ public final class Client extends AbstractPersistable { final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.staffIdParamName); actualChanges.put(ClientApiConstants.staffIdParamName, newValue); } - + if (command.isChangeInLongParameterNamed(ClientApiConstants.genderIdParamName, genderId())) { final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName); actualChanges.put(ClientApiConstants.genderIdParamName, newValue); @@ -440,6 +447,21 @@ public final class Client extends AbstractPersistable { actualChanges.put(ClientApiConstants.savingsProductIdParamName, newValue); } + if (command.isChangeInLongParameterNamed(ClientApiConstants.genderIdParamName, genderId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName); + actualChanges.put(ClientApiConstants.genderIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(ClientApiConstants.clientTypeIdParamName, clientTypeId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientTypeIdParamName); + actualChanges.put(ClientApiConstants.clientTypeIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(ClientApiConstants.clientClassificationIdParamName, clientClassificationId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientClassificationIdParamName); + actualChanges.put(ClientApiConstants.clientClassificationIdParamName, newValue); + } + final String dateFormatAsInput = command.dateFormat(); final String localeAsInput = command.locale(); @@ -703,10 +725,6 @@ public final class Client extends AbstractPersistable { this.savingsAccount = savingsAccount; } - public ClientIncentiveAttributes incentiveAttributes() { - return this.incentiveAttributes; - } - public void updateIncentiveAttributes(final Long ageLimitForChildren, final Long ageLimitForSeniorCitizen, final LocalDate compareOnDate) { boolean isFemale = false; boolean isChild = false; @@ -722,7 +740,7 @@ public final class Client extends AbstractPersistable { if (this.dateOfBirth != null) { final LocalDate dobLacalDate = LocalDate.fromDateFields(this.dateOfBirth); final int age = Years.yearsBetween(dobLacalDate, compareOnDate).getYears(); - + if (age >= ageLimitForSeniorCitizen.intValue()) { isSeniorCitizen = true; } @@ -732,15 +750,9 @@ public final class Client extends AbstractPersistable { } } - this.incentiveAttributes = ClientIncentiveAttributes.instance(isFemale, isChild, isSeniorCitizen); - } - public CodeValue gender() { - return this.gender; - } - - private Long genderId() { + public Long genderId() { Long genderId = null; if (this.gender != null) { genderId = this.gender.getId(); @@ -748,7 +760,47 @@ public final class Client extends AbstractPersistable { return genderId; } - public void updateGender(final CodeValue gender) { + public Long clientTypeId() { + Long clientTypeId = null; + if (this.clientType != null) { + clientTypeId = this.clientType.getId(); + } + return clientTypeId; + } + + public Long clientClassificationId() { + Long clientClassificationId = null; + if (this.clientClassification != null) { + clientClassificationId = this.clientClassification.getId(); + } + return clientClassificationId; + } + + public CodeValue gender() { + return this.gender; + } + + public CodeValue clientType() { + return this.clientType; + } + + public void updateClientType(CodeValue clientType) { + this.clientType = clientType; + } + + public CodeValue clientClassification() { + return this.clientClassification; + } + + public void updateClientClassification(CodeValue clientClassification) { + this.clientClassification = clientClassification; + } + + public void updateGender(CodeValue gender) { this.gender = gender; } + + public Date dateOfBirth() { + return this.dateOfBirth; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index b22b672c0..9648bd8de 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -98,7 +98,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final List genderOptions = new ArrayList( this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); - return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions, null, genderOptions, savingsProductDatas); + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + + return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions, null, genderOptions, savingsProductDatas, + clientTypeOptions, clientClassificationOptions); } @Override @@ -276,6 +283,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService 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.client_type_cv_id as clienttypeId, "); + sqlBuilder.append("cvclienttype.code_value as clienttypeValue, "); + sqlBuilder.append("c.client_classification_cv_id as classificationId, "); + sqlBuilder.append("cvclassification.code_value as classificationValue, "); 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, "); @@ -306,6 +317,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService 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 "); + sqlBuilder.append("left join m_code_value cvclienttype on cvclienttype.id = c.client_type_cv_id "); + sqlBuilder.append("left join m_code_value cvclassification on cvclassification.id = c.client_classification_cv_id "); this.schema = sqlBuilder.toString(); } @@ -341,6 +354,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String genderValue = rs.getString("genderValue"); final CodeValueData gender = CodeValueData.instance(genderId, genderValue); + final Long clienttypeId = JdbcSupport.getLong(rs, "clienttypeId"); + final String clienttypeValue = rs.getString("clienttypeValue"); + final CodeValueData clienttype = CodeValueData.instance(clienttypeId, clienttypeValue); + + final Long classificationId = JdbcSupport.getLong(rs, "classificationId"); + final String classificationValue = rs.getString("classificationValue"); + final CodeValueData classification = CodeValueData.instance(classificationId, classificationValue); + final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate"); final Long imageId = JdbcSupport.getLong(rs, "imageId"); final Long staffId = JdbcSupport.getLong(rs, "staffId"); @@ -371,7 +392,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname, middlename, lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId, - staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId); + staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId, clienttype, classification); } } @@ -407,6 +428,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService 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.client_type_cv_id as clienttypeId, "); + builder.append("cvclienttype.code_value as clienttypeValue, "); + builder.append("c.client_classification_cv_id as classificationId, "); + builder.append("cvclassification.code_value as classificationValue, "); builder.append("c.submittedon_date as submittedOnDate, "); builder.append("sbu.username as submittedByUsername, "); @@ -436,6 +461,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService 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 "); + builder.append("left join m_code_value cvclienttype on cvclienttype.id = c.client_type_cv_id "); + builder.append("left join m_code_value cvclassification on cvclassification.id = c.client_classification_cv_id "); this.schema = builder.toString(); } @@ -470,6 +497,15 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final Long genderId = JdbcSupport.getLong(rs, "genderId"); final String genderValue = rs.getString("genderValue"); final CodeValueData gender = CodeValueData.instance(genderId, genderValue); + + final Long clienttypeId = JdbcSupport.getLong(rs, "clienttypeId"); + final String clienttypeValue = rs.getString("clienttypeValue"); + final CodeValueData clienttype = CodeValueData.instance(clienttypeId, clienttypeValue); + + final Long classificationId = JdbcSupport.getLong(rs, "classificationId"); + final String classificationValue = rs.getString("classificationValue"); + final CodeValueData classification = CodeValueData.instance(classificationId, classificationValue); + final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate"); final Long imageId = JdbcSupport.getLong(rs, "imageId"); final Long staffId = JdbcSupport.getLong(rs, "staffId"); @@ -499,7 +535,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname, middlename, lastname, fullname, displayName, externalId, mobileNo, dateOfBirth, gender, activationDate, imageId, - staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId); + staffId, staffName, timeline, savingsProductId, savingsProductName, savingsAccountId, clienttype, classification); } } @@ -611,8 +647,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService public ClientData retrieveAllClosureReasons(final String clientClosureReason) { final List closureReasons = new ArrayList( this.codeValueReadPlatformService.retrieveCodeValuesByCode(clientClosureReason)); - - return ClientData.template(null, null, null, null, closureReasons, null, null); + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; + return ClientData.template(null, null, null, null, closureReasons, null, null, clientTypeOptions, clientClassificationOptions); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 901a4c6a3..a6832e786 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -189,6 +189,20 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP gender = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.GENDER, genderId); } + CodeValue clientType = null; + final Long clientTypeId = command.longValueOfParameterNamed(ClientApiConstants.clientTypeIdParamName); + if (clientTypeId != null) { + clientType = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_TYPE, + clientTypeId); + } + + CodeValue clientClassification = null; + final Long clientClassificationId = command.longValueOfParameterNamed(ClientApiConstants.clientClassificationIdParamName); + if (clientClassificationId != null) { + clientClassification = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection( + ClientApiConstants.CLIENT_CLASSIFICATION, clientClassificationId); + } + SavingsProduct savingsProduct = null; final Long savingsProductId = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName); if (savingsProductId != null) { @@ -197,7 +211,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP } - final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProduct, gender, command); + final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProduct, gender, + clientType, clientClassification, command); boolean rollbackTransaction = false; if (newClient.isActive()) { final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build(); @@ -283,6 +298,35 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP clientForUpdate.updateSavingsProduct(savingsProduct); } + if (changes.containsKey(ClientApiConstants.genderIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.GENDER, newValue); + } + clientForUpdate.updateGender(newCodeVal); + } + + if (changes.containsKey(ClientApiConstants.clientTypeIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientTypeIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_TYPE, + newValue); + } + clientForUpdate.updateClientType(newCodeVal); + } + + if (changes.containsKey(ClientApiConstants.clientClassificationIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientClassificationIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection( + ClientApiConstants.CLIENT_CLASSIFICATION, newValue); + } + clientForUpdate.updateClientClassification(newCodeVal); + } + if (!changes.isEmpty()) { this.clientRepository.saveAndFlush(clientForUpdate); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/domain/ConditionType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/domain/ConditionType.java new file mode 100755 index 000000000..a138641c0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/domain/ConditionType.java @@ -0,0 +1,84 @@ +/** + * 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.common.domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum ConditionType { + + INVALID(0, "ConditionType.invalid"), // + LESSTHAN(1, "ConditionType.lessthan"), // + EQUAL(2, "ConditionType.equal"), // + GRETERTHAN(3, "ConditionType.greterthan"), // + NOT_EQUAL(4, "ConditionType.notequal");// + + private final Integer value; + private final String code; + + private static final Map intToEnumMap = new HashMap(); + static { + for (final ConditionType type : ConditionType.values()) { + intToEnumMap.put(type.value, type); + } + } + + public static ConditionType fromInt(final Integer ruleTypeValue) { + final ConditionType type = intToEnumMap.get(ruleTypeValue); + return type; + } + + private ConditionType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + @Override + public String toString() { + return name().toString().replaceAll("_", " "); + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public boolean isConditionTypeEqual() { + return ConditionType.EQUAL.getValue().equals(this.value); + } + + public boolean isConditionTypeGreterThan() { + return ConditionType.GRETERTHAN.getValue().equals(this.value); + } + + public boolean isConditionTypeNotEqual() { + return ConditionType.NOT_EQUAL.getValue().equals(this.value); + } + + public boolean isConditionTypeLessThan() { + return ConditionType.LESSTHAN.getValue().equals(this.value); + } + + public boolean isInvalid() { + return ConditionType.INVALID.getValue().equals(this.value); + } + + public static Object[] integerValues() { + final List values = new ArrayList(); + for (final ConditionType enumType : values()) { + if (!enumType.isInvalid()) { + values.add(enumType.getValue()); + } + } + + return values.toArray(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/CommonEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/CommonEnumerations.java index b10966fb1..f75d362ad 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/CommonEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/CommonEnumerations.java @@ -1,6 +1,10 @@ package org.mifosplatform.portfolio.common.service; +import java.util.ArrayList; +import java.util.List; + import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.common.domain.ConditionType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; public class CommonEnumerations { @@ -36,4 +40,44 @@ public class CommonEnumerations { return optionData; } + public static EnumOptionData conditionType(final int id, final String codePrefix) { + return conditionType(ConditionType.fromInt(id), codePrefix); + } + + public static EnumOptionData conditionType(final ConditionType type, final String codePrefix) { + EnumOptionData optionData = null; + switch (type) { + case EQUAL: + optionData = new EnumOptionData(ConditionType.EQUAL.getValue().longValue(), codePrefix + ConditionType.EQUAL.getCode(), + "equal"); + break; + case NOT_EQUAL: + optionData = new EnumOptionData(ConditionType.NOT_EQUAL.getValue().longValue(), codePrefix + + ConditionType.NOT_EQUAL.getCode(), "notEqual"); + break; + case GRETERTHAN: + optionData = new EnumOptionData(ConditionType.GRETERTHAN.getValue().longValue(), codePrefix + + ConditionType.GRETERTHAN.getCode(), "greterthan"); + break; + case LESSTHAN: + optionData = new EnumOptionData(ConditionType.LESSTHAN.getValue().longValue(), codePrefix + + ConditionType.LESSTHAN.getCode(), "lessthan"); + break; + default: + optionData = new EnumOptionData(ConditionType.INVALID.getValue().longValue(), ConditionType.INVALID.getCode(), "Invalid"); + break; + } + return optionData; + } + + public static List conditionType(final ConditionType[] conditionTypes, final String codePrefix) { + final List optionDatas = new ArrayList(); + for (final ConditionType conditionType : conditionTypes) { + if (!conditionType.isInvalid()) { + optionDatas.add(conditionType(conditionType, codePrefix)); + } + } + return optionDatas; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformService.java index 7e96ad23a..f5fafda2c 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformService.java @@ -8,4 +8,6 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData; public interface DropdownReadPlatformService { List retrievePeriodFrequencyTypeOptions(); + + List retrieveConditionTypeOptions(); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformServiceImpl.java index 43eca29c1..d85a5b3cf 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/common/service/DropdownReadPlatformServiceImpl.java @@ -1,11 +1,13 @@ package org.mifosplatform.portfolio.common.service; +import static org.mifosplatform.portfolio.common.service.CommonEnumerations.conditionType; import static org.mifosplatform.portfolio.common.service.CommonEnumerations.termFrequencyType; import java.util.Arrays; import java.util.List; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.common.domain.ConditionType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.springframework.stereotype.Service; @@ -20,4 +22,12 @@ public class DropdownReadPlatformServiceImpl implements DropdownReadPlatformServ return loanTermFrequencyOptions; } + @Override + public List retrieveConditionTypeOptions() { + final List loanTermFrequencyOptions = Arrays.asList(conditionType(ConditionType.EQUAL, "condition"), + conditionType(ConditionType.NOT_EQUAL, "condition"), conditionType(ConditionType.GRETERTHAN, "condition"), + conditionType(ConditionType.LESSTHAN, "condition")); + return loanTermFrequencyOptions; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestIncentiveApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestIncentiveApiConstants.java new file mode 100755 index 000000000..ce93deaae --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestIncentiveApiConstants.java @@ -0,0 +1,32 @@ +package org.mifosplatform.portfolio.interestratechart; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public interface InterestIncentiveApiConstants { + + public static final String idParamName = "id"; + public static final String entityTypeParamName = "entityType"; + public static final String attributeNameParamName = "attributeName"; + public static final String conditionTypeParamName = "conditionType"; + public static final String attributeValueParamName = "attributeValue"; + public static final String incentiveTypeparamName = "incentiveType"; + public static final String amountParamName = "amount"; + public static final String deleteParamName = "delete"; + + public static final String INCENTIVE_RESOURCE_NAME = "interest.rate.incentives"; + + public static final Set INTERESTRATE_INCENTIVE_CREATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, + entityTypeParamName, attributeNameParamName, conditionTypeParamName, attributeValueParamName, incentiveTypeparamName, + amountParamName)); + + public static final Set INTERESTRATE_INCENTIVE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, + entityTypeParamName, attributeNameParamName, conditionTypeParamName, attributeValueParamName, incentiveTypeparamName, + amountParamName)); + + public static final Set INTERESTRATE_INCENTIVE_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, + entityTypeParamName, attributeNameParamName, conditionTypeParamName, attributeValueParamName, incentiveTypeparamName, + amountParamName)); + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestRateChartSlabApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestRateChartSlabApiConstants.java index f3e16be6f..7c31826ab 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestRateChartSlabApiConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/InterestRateChartSlabApiConstants.java @@ -30,25 +30,20 @@ public class InterestRateChartSlabApiConstants { public static final String amountRangeFromParamName = "amountRangeFrom"; public static final String amountRangeToParamName = "amountRangeTo"; public static final String annualInterestRateParamName = "annualInterestRate"; - public static final String interestRateForFemaleParamName = "interestRateForFemale"; - public static final String interestRateForChildrenParamName = "interestRateForChildren"; - public static final String interestRateForSeniorCitizenParamName = "interestRateForSeniorCitizen"; public static final String currencyCodeParamName = "currencyCode"; + public static final String incentivesParamName = "incentives"; // associations public static final Set INTERESTRATE_CHART_SLAB_CREATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList( localeParamName, idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName, - amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, interestRateForFemaleParamName, - interestRateForChildrenParamName, interestRateForSeniorCitizenParamName, currencyCodeParamName)); + amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName, incentivesParamName)); public static final Set INTERESTRATE_CHART_SLAB_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList( localeParamName, idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName, - amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, interestRateForFemaleParamName, - interestRateForChildrenParamName, interestRateForSeniorCitizenParamName, currencyCodeParamName)); + amountRangeFromParamName, amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName, incentivesParamName)); public static final Set INTERESTRATE_CHART_SLAB_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, idParamName, descriptionParamName, periodTypeParamName, fromPeriodParamName, toPeriodParamName, amountRangeFromParamName, - amountRangeToParamName, annualInterestRateParamName, interestRateForFemaleParamName, interestRateForChildrenParamName, - interestRateForSeniorCitizenParamName, currencyCodeParamName)); + amountRangeToParamName, annualInterestRateParamName, currencyCodeParamName, incentivesParamName)); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/ClientIncentiveAttributes.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/ClientIncentiveAttributes.java deleted file mode 100644 index bc31d7cf8..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/ClientIncentiveAttributes.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 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; - - -/** - * Immutable data object representing a ClientIncentiveAttributes used - * for determining interest rate applicable from Interest rate chart. - */ -public class ClientIncentiveAttributes { - - private final boolean isFemale; - private final boolean isChild; - private final boolean isSeniorCitizen; - - - public static ClientIncentiveAttributes instance(final boolean isFemale, final boolean isChild, final boolean isSeniorCitizen) { - return new ClientIncentiveAttributes(isFemale, isChild, isSeniorCitizen); - } - - - - private ClientIncentiveAttributes(final boolean isFemale, final boolean isChild, final boolean isSeniorCitizen) { - this.isFemale = isFemale; - this.isChild = isChild; - this.isSeniorCitizen = isSeniorCitizen; - } - - public boolean isFemale(){ - return this.isFemale; - } - - public boolean isChild(){ - return this.isChild; - } - - public boolean isSeniorCitizen(){ - return this.isSeniorCitizen; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveData.java new file mode 100755 index 000000000..e41809413 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveData.java @@ -0,0 +1,70 @@ +package org.mifosplatform.portfolio.interestratechart.data; + +import java.math.BigDecimal; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +public class InterestIncentiveData { + + @SuppressWarnings("unused") + private final Long id; + private final EnumOptionData entityType; + private final EnumOptionData attributeName; + private final EnumOptionData conditionType; + private final String attributeValue; + private final String attributeValueDesc; + private final EnumOptionData incentiveType; + private final BigDecimal amount; + + public static InterestIncentiveData instance(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName, + final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc, + final EnumOptionData incentiveType, final BigDecimal amount) { + + return new InterestIncentiveData(id, entityType, attributeName, conditionType, attributeValue, attributeValueDesc, incentiveType, + amount); + } + + private InterestIncentiveData(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName, + final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc, + final EnumOptionData incentiveType, final BigDecimal amount) { + + this.id = id; + this.entityType = entityType; + this.attributeName = attributeName; + this.conditionType = conditionType; + this.attributeValue = attributeValue; + this.attributeValueDesc = attributeValueDesc; + this.incentiveType = incentiveType; + this.amount = amount; + + } + + public EnumOptionData entityType() { + return this.entityType; + } + + public EnumOptionData attributeName() { + return this.attributeName; + } + + public EnumOptionData conditionType() { + return this.conditionType; + } + + public String attributeValue() { + return this.attributeValue; + } + + public EnumOptionData incentiveType() { + return this.incentiveType; + } + + public BigDecimal amount() { + return this.amount; + } + + public String attributeValueDesc() { + return this.attributeValueDesc; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveDataValidator.java new file mode 100755 index 000000000..12128f5a1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestIncentiveDataValidator.java @@ -0,0 +1,160 @@ +/** + * 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.InterestIncentiveApiConstants.INCENTIVE_RESOURCE_NAME; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.INTERESTRATE_INCENTIVE_CREATE_REQUEST_DATA_PARAMETERS; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.INTERESTRATE_INCENTIVE_UPDATE_REQUEST_DATA_PARAMETERS; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName; + +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.common.domain.ConditionType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveEntityType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveType; +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 InterestIncentiveDataValidator { + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public InterestIncentiveDataValidator(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateCreate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_INCENTIVE_CREATE_REQUEST_DATA_PARAMETERS); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(INCENTIVE_RESOURCE_NAME); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + final JsonObject objectElement = element.getAsJsonObject(); + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(objectElement); + validateIncentiveCreate(element, baseDataValidator, locale); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateIncentiveCreate(final JsonElement element, final DataValidatorBuilder baseDataValidator, final Locale locale) { + + Integer entityType = this.fromApiJsonHelper.extractIntegerNamed(entityTypeParamName, element, locale); + baseDataValidator.reset().parameter(entityTypeParamName).value(entityType).notNull() + .isOneOfTheseValues(InterestIncentiveEntityType.integerValues()); + + Integer attributeName = this.fromApiJsonHelper.extractIntegerNamed(attributeNameParamName, element, locale); + baseDataValidator.reset().parameter(attributeNameParamName).value(attributeName).notNull() + .isOneOfTheseValues(InterestIncentiveAttributeName.integerValues()); + + Integer conditionType = this.fromApiJsonHelper.extractIntegerNamed(conditionTypeParamName, element, locale); + baseDataValidator.reset().parameter(conditionTypeParamName).value(conditionType).notNull() + .isOneOfTheseValues(ConditionType.integerValues()); + + final String attributeValue = this.fromApiJsonHelper.extractStringNamed(attributeValueParamName, element); + baseDataValidator.reset().parameter(attributeValueParamName).value(attributeValue).notNull(); + + Integer incentiveType = this.fromApiJsonHelper.extractIntegerNamed(incentiveTypeparamName, element, locale); + baseDataValidator.reset().parameter(incentiveTypeparamName).value(incentiveType).notNull() + .isOneOfTheseValues(InterestIncentiveType.integerValues()); + + final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, element, locale); + baseDataValidator.reset().parameter(amountParamName).value(amount).notNull(); + + } + + public void validateUpdate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, INTERESTRATE_INCENTIVE_UPDATE_REQUEST_DATA_PARAMETERS); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(INCENTIVE_RESOURCE_NAME); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + final JsonObject objectElement = element.getAsJsonObject(); + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(objectElement); + validateIncentiveUpdate(element, baseDataValidator, locale); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateIncentiveUpdate(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(entityTypeParamName, element)) { + Integer entityType = this.fromApiJsonHelper.extractIntegerNamed(entityTypeParamName, element, locale); + baseDataValidator.reset().parameter(entityTypeParamName).value(entityType).notNull() + .isOneOfTheseValues(InterestIncentiveEntityType.integerValues()); + } + + if (this.fromApiJsonHelper.parameterExists(attributeNameParamName, element)) { + Integer attributeName = this.fromApiJsonHelper.extractIntegerNamed(attributeNameParamName, element, locale); + baseDataValidator.reset().parameter(attributeNameParamName).value(attributeName).notNull() + .isOneOfTheseValues(InterestIncentiveAttributeName.integerValues()); + } + + if (this.fromApiJsonHelper.parameterExists(conditionTypeParamName, element)) { + Integer conditionType = this.fromApiJsonHelper.extractIntegerNamed(conditionTypeParamName, element, locale); + baseDataValidator.reset().parameter(conditionTypeParamName).value(conditionType).notNull() + .isOneOfTheseValues(ConditionType.integerValues()); + } + + if (this.fromApiJsonHelper.parameterExists(attributeValueParamName, element)) { + final String attributeValue = this.fromApiJsonHelper.extractStringNamed(attributeValueParamName, element); + baseDataValidator.reset().parameter(attributeValueParamName).value(attributeValue).notNull(); + } + + if (this.fromApiJsonHelper.parameterExists(incentiveTypeparamName, element)) { + Integer incentiveType = this.fromApiJsonHelper.extractIntegerNamed(incentiveTypeparamName, element, locale); + baseDataValidator.reset().parameter(incentiveTypeparamName).value(incentiveType).notNull() + .isOneOfTheseValues(InterestIncentiveType.integerValues()); + } + + if (this.fromApiJsonHelper.parameterExists(amountParamName, element)) { + final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, element, locale); + baseDataValidator.reset().parameter(amountParamName).value(amount).notNull(); + } + + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartData.java index dc29bef6c..02799f43e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartData.java @@ -10,6 +10,7 @@ import java.util.HashSet; import java.util.Set; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; /** @@ -30,29 +31,55 @@ public class InterestRateChartData { // template private Collection periodTypes; + private final Collection entityTypeOptions; + private final Collection attributeNameOptions; + private final Collection conditionTypeOptions; + private final Collection incentiveTypeOptions; + private final Collection genderOptions; + private final Collection clientTypeOptions; + private final Collection clientClassificationOptions; public static InterestRateChartData instance(Long id, String name, String description, LocalDate fromDate, LocalDate endDate, Long savingsProductId, String savingsProductName) { Collection periodTypes = null; Set chartSlabs = null; + final Collection entityTypeOptions = null; + final Collection attributeNameOptions = null; + final Collection conditionTypeOptions = null; + final Collection incentiveTypeOptions = null; + final Collection genderOptions = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; return new InterestRateChartData(id, name, description, fromDate, endDate, savingsProductId, savingsProductName, chartSlabs, - periodTypes); + periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, + clientTypeOptions, clientClassificationOptions); } - public static InterestRateChartData withSlabs(InterestRateChartData interestRateChartData, - Set chartSlabs) { + public static InterestRateChartData withSlabs(InterestRateChartData interestRateChartData, Set chartSlabs) { return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.productId, - interestRateChartData.productName, chartSlabs, interestRateChartData.periodTypes); + interestRateChartData.productName, chartSlabs, interestRateChartData.periodTypes, interestRateChartData.entityTypeOptions, + interestRateChartData.attributeNameOptions, interestRateChartData.conditionTypeOptions, + interestRateChartData.incentiveTypeOptions, interestRateChartData.genderOptions, interestRateChartData.clientTypeOptions, + interestRateChartData.clientClassificationOptions); } - public static InterestRateChartData withTemplate(InterestRateChartData interestRateChartData, Collection periodTypes) { + public static InterestRateChartData withTemplate(InterestRateChartData interestRateChartData, Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.productId, - interestRateChartData.productName, interestRateChartData.chartSlabs, periodTypes); + interestRateChartData.productName, interestRateChartData.chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, + conditionTypeOptions, incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions); } - public static InterestRateChartData template(Collection periodTypes) { + public static InterestRateChartData template(Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { final Long id = null; final String name = null; final String description = null; @@ -63,11 +90,16 @@ public class InterestRateChartData { final Set chartSlabs = null; return new InterestRateChartData(id, name, description, fromDate, endDate, savingsProductId, savingsProductName, chartSlabs, - periodTypes); + periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, + clientTypeOptions, clientClassificationOptions); } private InterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate, Long savingsProductId, - String savingsProductName, Set chartSlabs, Collection periodTypes) { + String savingsProductName, Set chartSlabs, Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { this.id = id; this.name = name; this.description = description; @@ -77,6 +109,13 @@ public class InterestRateChartData { this.productId = savingsProductId; this.productName = savingsProductName; this.periodTypes = periodTypes; + this.attributeNameOptions = attributeNameOptions; + this.entityTypeOptions = entityTypeOptions; + this.conditionTypeOptions = conditionTypeOptions; + this.incentiveTypeOptions = incentiveTypeOptions; + this.genderOptions = genderOptions; + this.clientTypeOptions = clientTypeOptions; + this.clientClassificationOptions = clientClassificationOptions; } public void addChartSlab(final InterestRateChartSlabData chartSlab) { @@ -114,4 +153,33 @@ public class InterestRateChartData { public Collection periodTypes() { return this.periodTypes; } + + public Collection entityTypeOptions() { + return this.entityTypeOptions; + } + + public Collection attributeNameOptions() { + return this.attributeNameOptions; + } + + public Collection conditionTypeOptions() { + return this.conditionTypeOptions; + } + + public Collection incentiveTypeOptions() { + return this.incentiveTypeOptions; + } + + public Collection genderOptions() { + return this.genderOptions; + } + + public Collection clientTypeOptions() { + return this.clientTypeOptions; + } + + public Collection clientClassificationOptions() { + return this.clientClassificationOptions; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabData.java index 179a496b0..8142f544c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabData.java @@ -7,7 +7,10 @@ package org.mifosplatform.portfolio.interestratechart.data; import java.math.BigDecimal; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.organisation.monetary.data.CurrencyData; @@ -24,32 +27,54 @@ public class InterestRateChartSlabData { private final BigDecimal amountRangeFrom; private final BigDecimal amountRangeTo; private final BigDecimal annualInterestRate; - private final BigDecimal interestRateForFemale; - private final BigDecimal interestRateForChildren; - private final BigDecimal interestRateForSeniorCitizen; private final CurrencyData currency; + // associations + private Set incentives; + // template private final Collection periodTypes; + private final Collection entityTypeOptions; + private final Collection attributeNameOptions; + private final Collection conditionTypeOptions; + private final Collection incentiveTypeOptions; + private final Collection genderOptions; + private final Collection clientTypeOptions; + private final Collection clientClassificationOptions; public static InterestRateChartSlabData instance(final Long id, final String description, final EnumOptionData periodType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, - final BigDecimal annualInterestRate, final BigDecimal interestRateForFemale, final BigDecimal interestRateForChildren, - final BigDecimal interestRateForSeniorCitizen, final CurrencyData currency) { + final BigDecimal annualInterestRate, final CurrencyData currency) { final Collection periodTypes = null; + final Set incentivesData = null; + final Collection entityTypeOptions = null; + final Collection attributeNameOptions = null; + final Collection conditionTypeOptions = null; + final Collection incentiveTypeOptions = null; + final Collection genderOptions = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; return new InterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, - annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currency, periodTypes); + annualInterestRate, currency, incentivesData, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, + incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions); } public static InterestRateChartSlabData withTemplate(final InterestRateChartSlabData chartSlab, - final Collection periodTypes) { + final Collection periodTypes, final Collection entityTypeOptions, + final Collection attributeNameOptions, final Collection conditionTypeOptions, + final Collection incentiveTypeOptions, final Collection genderOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { return new InterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod, - chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, - chartSlab.interestRateForFemale, chartSlab.interestRateForChildren, chartSlab.interestRateForSeniorCitizen, - chartSlab.currency, periodTypes); + chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, chartSlab.currency, + chartSlab.incentives, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, + genderOptions, clientTypeOptions, clientClassificationOptions); } - public static InterestRateChartSlabData template(final Collection periodTypes) { + public static InterestRateChartSlabData template(final Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { final Long id = null; final String description = null; final EnumOptionData periodType = null; @@ -58,18 +83,20 @@ public class InterestRateChartSlabData { final BigDecimal amountRangeFrom = null; final BigDecimal amountRangeTo = null; final BigDecimal annualInterestRate = null; - final BigDecimal interestRateForFemale = null; - final BigDecimal interestRateForChildren = null; - final BigDecimal interestRateForSeniorCitizen = null; final CurrencyData currency = null; + final Set incentivesData = null; return new InterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, - annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currency, periodTypes); + annualInterestRate, currency, incentivesData, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, + incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions); } private InterestRateChartSlabData(final Long id, final String description, final EnumOptionData periodType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, final BigDecimal annualInterestRate, - final BigDecimal interestRateForFemale, final BigDecimal interestRateForChildren, - final BigDecimal interestRateForSeniorCitizen, final CurrencyData currency, final Collection periodTypes) { + final CurrencyData currency, final Set incentivesData, final Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { this.id = id; this.description = description; this.periodType = periodType; @@ -78,11 +105,16 @@ public class InterestRateChartSlabData { this.amountRangeFrom = amountRangeFrom; this.amountRangeTo = amountRangeTo; this.annualInterestRate = annualInterestRate; - this.interestRateForFemale = interestRateForFemale; - this.interestRateForChildren = interestRateForChildren; - this.interestRateForSeniorCitizen = interestRateForSeniorCitizen; this.currency = currency; this.periodTypes = periodTypes; + this.incentives = incentivesData; + this.attributeNameOptions = attributeNameOptions; + this.entityTypeOptions = entityTypeOptions; + this.conditionTypeOptions = conditionTypeOptions; + this.incentiveTypeOptions = incentiveTypeOptions; + this.genderOptions = genderOptions; + this.clientTypeOptions = clientTypeOptions; + this.clientClassificationOptions = clientClassificationOptions; } public String description() { @@ -112,18 +144,6 @@ public class InterestRateChartSlabData { public BigDecimal annualInterestRate() { return this.annualInterestRate; } - - public BigDecimal interestRateForFemale() { - return this.interestRateForFemale; - } - - public BigDecimal interestRateForChildren() { - return this.interestRateForChildren; - } - - public BigDecimal interestRateForSeniorCitizen() { - return this.interestRateForSeniorCitizen; - } public CurrencyData currency() { return this.currency; @@ -133,4 +153,44 @@ public class InterestRateChartSlabData { return this.periodTypes; } + public void addIncentives(final InterestIncentiveData incentiveData) { + if (this.incentives == null) { + this.incentives = new HashSet(); + } + + this.incentives.add(incentiveData); + } + + public Set incentives() { + return this.incentives; + } + + public Collection entityTypeOptions() { + return this.entityTypeOptions; + } + + public Collection attributeNameOptions() { + return this.attributeNameOptions; + } + + public Collection conditionTypeOptions() { + return this.conditionTypeOptions; + } + + public Collection incentiveTypeOptions() { + return this.incentiveTypeOptions; + } + + public Collection genderOptions() { + return this.genderOptions; + } + + public Collection clientTypeOptions() { + return this.clientTypeOptions; + } + + public Collection clientClassificationOptions() { + return this.clientClassificationOptions; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabDataValidator.java index 0d161f776..9ee79b909 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/data/InterestRateChartSlabDataValidator.java @@ -14,9 +14,7 @@ import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSla 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.interestRateForChildrenParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForFemaleParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForSeniorCitizenParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.incentivesParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName; @@ -34,9 +32,11 @@ 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.common.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants; 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; @@ -45,10 +45,13 @@ import com.google.gson.reflect.TypeToken; public class InterestRateChartSlabDataValidator { private final FromJsonHelper fromApiJsonHelper; + private final InterestIncentiveDataValidator interestIncentiveDataValidator; @Autowired - public InterestRateChartSlabDataValidator(final FromJsonHelper fromApiJsonHelper) { + public InterestRateChartSlabDataValidator(final FromJsonHelper fromApiJsonHelper, + final InterestIncentiveDataValidator interestIncentiveDataValidator) { this.fromApiJsonHelper = fromApiJsonHelper; + this.interestIncentiveDataValidator = interestIncentiveDataValidator; } public void validateCreate(final String json) { @@ -120,24 +123,7 @@ public class InterestRateChartSlabDataValidator { final BigDecimal annualInterestRate = this.fromApiJsonHelper.extractBigDecimalNamed(annualInterestRateParamName, element, locale); baseDataValidator.reset().parameter(annualInterestRateParamName).value(annualInterestRate).notNull().zeroOrPositiveAmount(); - if (this.fromApiJsonHelper.parameterExists(interestRateForFemaleParamName, element)) { - final BigDecimal interestRateForFemale = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForFemaleParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForFemaleParamName).value(interestRateForFemale).notNull().zeroOrPositiveAmount(); - } - - if (this.fromApiJsonHelper.parameterExists(interestRateForChildrenParamName, element)) { - final BigDecimal interestRateForChildren = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForChildrenParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForChildrenParamName).value(interestRateForChildren).notNull().zeroOrPositiveAmount(); - } - - if (this.fromApiJsonHelper.parameterExists(interestRateForSeniorCitizenParamName, element)) { - final BigDecimal interestRateForSeniorCitizen = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForSeniorCitizenParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForSeniorCitizenParamName).value(interestRateForSeniorCitizen).notNull().zeroOrPositiveAmount(); - } - + validateIncentives(element, baseDataValidator, locale); } public void validateUpdate(final String json) { @@ -213,33 +199,37 @@ public class InterestRateChartSlabDataValidator { baseDataValidator.reset().parameter(annualInterestRateParamName).value(annualInterestRate).notNull().zeroOrPositiveAmount(); } - if (this.fromApiJsonHelper.parameterExists(interestRateForFemaleParamName, element)) { - final BigDecimal interestRateForFemale = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForFemaleParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForFemaleParamName).value(interestRateForFemale).notNull().zeroOrPositiveAmount(); - } - - if (this.fromApiJsonHelper.parameterExists(interestRateForChildrenParamName, element)) { - final BigDecimal interestRateForChildren = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForChildrenParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForChildrenParamName).value(interestRateForChildren).notNull().zeroOrPositiveAmount(); - } - - if (this.fromApiJsonHelper.parameterExists(interestRateForSeniorCitizenParamName, element)) { - final BigDecimal interestRateForSeniorCitizen = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForSeniorCitizenParamName, element, - locale); - baseDataValidator.reset().parameter(interestRateForSeniorCitizenParamName).value(interestRateForSeniorCitizen).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); } - + validateIncentives(element, baseDataValidator, locale); } private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } + private void validateIncentives(JsonElement element, DataValidatorBuilder baseDataValidator, final Locale locale) { + + if (element.isJsonObject()) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + if (topLevelJsonElement.has(incentivesParamName) && topLevelJsonElement.get(incentivesParamName).isJsonArray()) { + final JsonArray array = topLevelJsonElement.get(incentivesParamName).getAsJsonArray(); + for (int i = 0; i < array.size(); i++) { + final JsonObject incentiveElement = array.get(i).getAsJsonObject(); + if (this.fromApiJsonHelper.parameterExists(InterestIncentiveApiConstants.idParamName, incentiveElement)) { + final Long id = this.fromApiJsonHelper + .extractLongNamed(InterestIncentiveApiConstants.idParamName, incentiveElement); + baseDataValidator.reset().parameter(InterestIncentiveApiConstants.idParamName).value(id).notNull() + .integerGreaterThanZero(); + this.interestIncentiveDataValidator.validateIncentiveUpdate(incentiveElement, baseDataValidator, locale); + } else { + this.interestIncentiveDataValidator.validateIncentiveCreate(incentiveElement, baseDataValidator, locale); + } + } + } + } + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentives.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentives.java new file mode 100755 index 000000000..7b9cbafd1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentives.java @@ -0,0 +1,64 @@ +package org.mifosplatform.portfolio.interestratechart.domain; + +import java.util.Locale; +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.DataValidatorBuilder; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_interest_incentives") +public class InterestIncentives extends AbstractPersistable { + + @ManyToOne + @JoinColumn(name = "interest_rate_slab_id", nullable = false) + private InterestRateChartSlab interestRateChartSlab; + + @Embedded + private InterestIncentivesFields interestIncentivesFields; + + protected InterestIncentives() { + + } + + /* + * public InterestIncentives(final InterestRateChartSlab + * interestRateChartSlab, final InterestIncentivesFields + * interestIncentivesFields) { this.interestRateChartSlab = + * interestRateChartSlab; this.interestIncentivesFields = + * interestIncentivesFields; } + */ + + public InterestRateChartSlab interestRateChartSlab() { + return this.interestRateChartSlab; + } + + public void updateInterestRateChartSlab(InterestRateChartSlab interestRateChartSlab) { + this.interestRateChartSlab = interestRateChartSlab; + } + + public InterestIncentives(final InterestRateChartSlab interestRateChartSlab, final InterestIncentivesFields interestIncentivesFields) { + this.interestRateChartSlab = interestRateChartSlab; + this.interestIncentivesFields = interestIncentivesFields; + if (this.interestRateChartSlab != null) { + interestRateChartSlab.addInterestIncentive(this); + } + } + + public void update(final JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator, + final Locale locale) { + this.interestIncentivesFields.update(command, actualChanges, baseDataValidator, locale); + } + + public InterestIncentivesFields interestIncentivesFields() { + return this.interestIncentivesFields; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentivesFields.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentivesFields.java new file mode 100755 index 000000000..82624fdee --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestIncentivesFields.java @@ -0,0 +1,159 @@ +package org.mifosplatform.portfolio.interestratechart.domain; + +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName; + +import java.math.BigDecimal; +import java.util.Locale; +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.common.domain.ConditionType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveEntityType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveType; + +@Embeddable +public class InterestIncentivesFields { + + @Column(name = "entiry_type", nullable = false) + private Integer entityType; + + @Column(name = "attribute_name", nullable = false) + private Integer attributeName; + + @Column(name = "condition_type", nullable = false) + private Integer conditionType; + + @Column(name = "attribute_value", nullable = false) + private String attributeValue; + + @Column(name = "incentive_type", nullable = false) + private Integer incentiveType; + + @Column(name = "amount", scale = 6, precision = 19, nullable = false) + private BigDecimal amount; + + protected InterestIncentivesFields() { + + } + + public static InterestIncentivesFields createNew(final Integer entityType, final Integer attributeName, final Integer conditionType, + final String attributeValue, final Integer incentiveType, final BigDecimal amount, final DataValidatorBuilder baseDataValidator) { + return new InterestIncentivesFields(entityType, attributeName, conditionType, attributeValue, incentiveType, amount, + baseDataValidator); + } + + private InterestIncentivesFields(final Integer entityType, final Integer attributeName, final Integer conditionType, + final String attributeValue, final Integer incentiveType, final BigDecimal amount, final DataValidatorBuilder baseDataValidator) { + this.entityType = entityType; + this.attributeName = attributeName; + this.attributeValue = attributeValue; + this.conditionType = conditionType; + this.incentiveType = incentiveType; + this.amount = amount; + validateIncentiveData(baseDataValidator); + } + + public InterestIncentiveAttributeName attributeName() { + return InterestIncentiveAttributeName.fromInt(this.attributeName); + } + + public ConditionType conditionType() { + return ConditionType.fromInt(this.conditionType); + } + + public String attributeValue() { + return this.attributeValue; + } + + public InterestIncentiveType incentiveType() { + return InterestIncentiveType.fromInt(this.incentiveType); + } + + public BigDecimal amount() { + return this.amount; + } + + public InterestIncentiveEntityType entiryType() { + return InterestIncentiveEntityType.fromInt(this.entityType); + } + + public void update(final JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator, + final Locale locale) { + if (command.isChangeInIntegerParameterNamed(entityTypeParamName, this.entityType, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(entityTypeParamName, locale); + actualChanges.put(entityTypeParamName, newValue); + this.entityType = newValue; + } + + if (command.isChangeInIntegerParameterNamed(attributeNameParamName, this.attributeName, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(attributeNameParamName, locale); + actualChanges.put(attributeNameParamName, newValue); + this.attributeName = newValue; + } + + if (command.isChangeInIntegerParameterNamed(conditionTypeParamName, this.conditionType, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(conditionTypeParamName, locale); + actualChanges.put(conditionTypeParamName, newValue); + this.conditionType = newValue; + } + + if (command.isChangeInStringParameterNamed(attributeValueParamName, this.attributeValue)) { + final String newValue = command.stringValueOfParameterNamed(attributeValueParamName); + actualChanges.put(attributeValueParamName, newValue); + this.attributeValue = newValue; + } + + if (command.isChangeInIntegerParameterNamed(incentiveTypeparamName, this.incentiveType, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(incentiveTypeparamName, locale); + actualChanges.put(incentiveTypeparamName, newValue); + this.incentiveType = newValue; + } + + if (command.isChangeInBigDecimalParameterNamed(amountParamName, this.amount, locale)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountParamName, locale); + actualChanges.put(amountParamName, newValue); + this.amount = newValue; + } + + validateIncentiveData(baseDataValidator); + + } + + public void validateIncentiveData(final DataValidatorBuilder baseDataValidator) { + + switch (attributeName()) { + case GENDER: + baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero(); + baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType) + .isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue()); + break; + case AGE: + baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero(); + break; + case CLIENT_CLASSIFICATION: + baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero(); + baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType) + .isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue()); + break; + case CLIENT_TYPE: + baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero(); + baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType) + .isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue()); + break; + + default: + break; + } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChart.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChart.java index a5bdc5ca4..aa6c49c2f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChart.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChart.java @@ -6,16 +6,13 @@ package org.mifosplatform.portfolio.interestratechart.domain; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.deleteParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName; 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.InterestRateChartApiConstants.deleteParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForChildrenParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForFemaleParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForSeniorCitizenParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName; @@ -25,6 +22,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -56,19 +54,17 @@ public class InterestRateChart extends AbstractPersistable { @OneToMany(mappedBy = "interestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) private Set chartSlabs = new HashSet(); - + protected InterestRateChart() { // } - public static InterestRateChart createNew(InterestRateChartFields chartFields, - Collection interestRateChartSlabs) { + public static InterestRateChart createNew(InterestRateChartFields chartFields, Collection interestRateChartSlabs) { return new InterestRateChart(chartFields, new HashSet(interestRateChartSlabs)); } - private InterestRateChart(InterestRateChartFields chartFields, - Set interestRateChartSlabs) { + private InterestRateChart(InterestRateChartFields chartFields, Set interestRateChartSlabs) { final List dataValidationErrors = new ArrayList(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) @@ -100,9 +96,9 @@ public class InterestRateChart extends AbstractPersistable { 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()); + baseDataValidator + .failWithCodeNoParameterAddedToErrorCode("chart.slabs.period.overlapping", iSlabs.slabFields().fromPeriod(), + iSlabs.slabFields().toPeriod(), jSlabs.slabFields().fromPeriod(), jSlabs.slabFields().toPeriod()); } } } @@ -170,7 +166,7 @@ public class InterestRateChart extends AbstractPersistable { final Map deleteChartSlabs = new HashMap(); final Map chartSlabsChanges = new HashMap(); - + final Locale locale = command.extractLocale(); if (command.hasParameter(InterestRateChartApiConstants.chartSlabs)) { final JsonArray array = command.arrayOfParameterNamed(InterestRateChartApiConstants.chartSlabs); if (array != null) { @@ -181,14 +177,13 @@ public class InterestRateChart extends AbstractPersistable { 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"); + 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); + chartSlab.update(chartSlabsCommand, chartSlabsChanges, baseDataValidator, locale); } } else { @@ -197,22 +192,22 @@ public class InterestRateChart extends AbstractPersistable { * InterestRateChartSlabAssembler */ final String description = chartSlabsCommand.stringValueOfParameterNamed(descriptionParamName); - final Integer periodTypeId = chartSlabsCommand.integerValueOfParameterNamed(periodTypeParamName); + final Integer periodTypeId = chartSlabsCommand.integerValueOfParameterNamed(periodTypeParamName, locale); 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 BigDecimal interestRateForFemale = chartSlabsCommand.bigDecimalValueOfParameterNamed(interestRateForFemaleParamName); - final BigDecimal interestRateForChildren = chartSlabsCommand.bigDecimalValueOfParameterNamed(interestRateForChildrenParamName); - final BigDecimal interestRateForSeniorCitizen = chartSlabsCommand.bigDecimalValueOfParameterNamed(interestRateForSeniorCitizenParamName); - - final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description, periodFrequencyType, - fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currencyCode); + final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName, locale); + final Integer toPeriod = chartSlabsCommand.integerValueOfParameterNamed(toPeriodParamName, locale); + final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName, + locale); + final BigDecimal amountRangeTo = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeToParamName, locale); + final BigDecimal annualInterestRate = chartSlabsCommand.bigDecimalValueOfParameterNamed( + annualInterestRateParamName, locale); + + 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); + chartSlab.slabFields().validateChartSlabPlatformRules(chartSlabsCommand, baseDataValidator, locale); + chartSlab.updateIncentives(chartSlabsCommand, actualChanges, baseDataValidator, chartSlab, locale); this.addChartSlab(chartSlab); } } @@ -261,8 +256,8 @@ public class InterestRateChart extends AbstractPersistable { public InterestRateChartFields chartFields() { return this.chartFields; } - - public boolean isApplicableChartFor(final LocalDate target){ + + public boolean isApplicableChartFor(final LocalDate target) { return this.chartFields.isApplicableChartFor(target); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlab.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlab.java index 792754e16..f025d46d0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlab.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlab.java @@ -5,24 +5,45 @@ */ package org.mifosplatform.portfolio.interestratechart.domain; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.deleteParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.idParamName; import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME; +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Locale; 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.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; 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.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants; +import org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants; import org.springframework.data.jpa.domain.AbstractPersistable; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + @Entity @Table(name = "m_interest_rate_slab") public class InterestRateChartSlab extends AbstractPersistable { @@ -34,6 +55,9 @@ public class InterestRateChartSlab extends AbstractPersistable { @JoinColumn(name = "interest_rate_chart_id", referencedColumnName = "id", nullable = false) private InterestRateChart interestRateChart; + @OneToMany(mappedBy = "interestRateChartSlab", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set interestIncentives = new HashSet(); + protected InterestRateChartSlab() { // } @@ -42,24 +66,25 @@ public class InterestRateChartSlab extends AbstractPersistable { return new InterestRateChartSlab(slabFields, interestRateChart); } - public void update(JsonCommand command, final Map actualChanges) { + public void update(JsonCommand command, final Map actualChanges, final Locale locale) { final List dataValidationErrors = new ArrayList(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) .resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME); - this.update(command, actualChanges, baseDataValidator); + this.update(command, actualChanges, baseDataValidator, locale); this.interestRateChart.validateChartSlabs(baseDataValidator); this.throwExceptionIfValidationWarningsExist(dataValidationErrors); } - public void update(JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator) { - this.slabFields.update(command, actualChanges, baseDataValidator); + public void update(JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator, + final Locale locale) { + this.slabFields.update(command, actualChanges, baseDataValidator,locale); + updateIncentives(command, actualChanges, baseDataValidator, this, locale); } private InterestRateChartSlab(InterestRateChartSlabFields slabFields, InterestRateChart interestRateChart) { this.slabFields = slabFields; this.interestRateChart = interestRateChart; - if (this.interestRateChart != null) { interestRateChart.addChartSlab(this); } @@ -72,8 +97,86 @@ public class InterestRateChartSlab extends AbstractPersistable { private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } - - public InterestRateChartSlabFields slabFields(){ + + public InterestRateChartSlabFields slabFields() { return this.slabFields; } + + public Set setOfInterestIncentives() { + if (this.interestIncentives == null) { + this.interestIncentives = new HashSet(); + } + return this.interestIncentives; + } + + public void addInterestIncentive(InterestIncentives interestIncentives) { + interestIncentives.updateInterestRateChartSlab(this); + setOfInterestIncentives().add(interestIncentives); + } + + public InterestIncentives findInterestIncentive(Long interestIncentiveId) { + final Set interestIncentives = setOfInterestIncentives(); + + for (InterestIncentives interestIncentive : interestIncentives) { + if (interestIncentive.getId().equals(interestIncentiveId)) { return interestIncentive; } + } + return null; + } + + public boolean removeInterestIncentive(InterestIncentives incentive) { + final Set incentives = setOfInterestIncentives(); + return incentives.remove(incentive); + } + + public void updateIncentives(JsonCommand command, final Map actualChanges, + final DataValidatorBuilder baseDataValidator, final InterestRateChartSlab chartSlab, final Locale locale) { + final Map deleteIncentives = new HashMap(); + final Map IncentiveChanges = new HashMap(); + if (command.hasParameter(InterestRateChartSlabApiConstants.incentivesParamName)) { + final JsonArray array = command.arrayOfParameterNamed(InterestRateChartSlabApiConstants.incentivesParamName); + if (array != null) { + for (int i = 0; i < array.size(); i++) { + final JsonObject incentiveElement = array.get(i).getAsJsonObject(); + JsonCommand incentivesCommand = JsonCommand.fromExistingCommand(command, incentiveElement); + if (incentivesCommand.parameterExists(InterestIncentiveApiConstants.idParamName)) { + final Long interestIncentiveId = incentivesCommand + .longValueOfParameterNamed(InterestIncentiveApiConstants.idParamName); + final InterestIncentives interestIncentives = chartSlab.findInterestIncentive(interestIncentiveId); + if (interestIncentives == null) { + baseDataValidator.parameter(InterestIncentiveApiConstants.idParamName).value(interestIncentiveId) + .failWithCode("no.interest.incentive.associated.with.id"); + } else if (incentivesCommand.parameterExists(deleteParamName)) { + if (chartSlab.removeInterestIncentive(interestIncentives)) { + deleteIncentives.put(idParamName, interestIncentiveId); + } + } else { + interestIncentives.update(incentivesCommand, IncentiveChanges, baseDataValidator, locale); + } + } else { + Integer entityType = incentivesCommand.integerValueOfParameterNamed(entityTypeParamName, locale); + Integer conditionType = incentivesCommand.integerValueOfParameterNamed(conditionTypeParamName, locale); + Integer attributeName = incentivesCommand.integerValueOfParameterNamed(attributeNameParamName, locale); + String attributeValue = incentivesCommand.stringValueOfParameterNamed(attributeValueParamName); + Integer incentiveType = incentivesCommand.integerValueOfParameterNamed(incentiveTypeparamName, locale); + BigDecimal amount = incentivesCommand.bigDecimalValueOfParameterNamed(amountParamName, locale); + InterestIncentivesFields incentivesFields = InterestIncentivesFields.createNew(entityType, attributeName, + conditionType, attributeValue, incentiveType, amount, baseDataValidator); + InterestIncentives incentives = new InterestIncentives(chartSlab, incentivesFields); + chartSlab.addInterestIncentive(incentives); + } + } + } + // add chart slab changes to actual changes list. + if (!IncentiveChanges.isEmpty()) { + actualChanges.put(InterestRateChartSlabApiConstants.incentivesParamName, IncentiveChanges); + } + + // add deleted chart Slabs to actual changes + if (!deleteIncentives.isEmpty()) { + actualChanges.put("deletedIncentives", deleteIncentives); + } + + } + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlabFields.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlabFields.java index 6986d388a..3323d0678 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlabFields.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/domain/InterestRateChartSlabFields.java @@ -8,15 +8,13 @@ package org.mifosplatform.portfolio.interestratechart.domain; 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.interestRateForFemaleParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForChildrenParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForSeniorCitizenParamName; 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.math.BigDecimal; +import java.util.Locale; import java.util.Map; import javax.persistence.Column; @@ -55,15 +53,7 @@ public class InterestRateChartSlabFields { @Column(name = "annual_interest_rate", scale = 6, precision = 19, nullable = false) private BigDecimal annualInterestRate; - @Column(name = "interest_rate_for_female", scale = 6, precision = 19, nullable = true) - private BigDecimal interestRateForFemale; - - @Column(name = "interest_rate_for_children", scale = 6, precision = 19, nullable = true) - private BigDecimal interestRateForChildren; - - @Column(name = "interest_rate_for_senior_citizen", scale = 6, precision = 19, nullable = true) - private BigDecimal interestRateForSeniorCitizen; - + @SuppressWarnings("unused") @Column(name = "currency_code", nullable = false) private String currencyCode; @@ -73,16 +63,14 @@ public class InterestRateChartSlabFields { public static InterestRateChartSlabFields createNew(final String description, final SavingsPeriodFrequencyType periodFrequencyType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, - final BigDecimal annualInterestRate, final BigDecimal interestRateForFemale, final BigDecimal interestRateForChildren, - final BigDecimal interestRateForSeniorCitizen, final String currencyCode) { + final BigDecimal annualInterestRate, final String currencyCode) { return new InterestRateChartSlabFields(description, periodFrequencyType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, - annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currencyCode); + annualInterestRate, currencyCode); } private InterestRateChartSlabFields(final String description, final SavingsPeriodFrequencyType periodFrequencyType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, - final BigDecimal annualInterestRate, final BigDecimal interestRateForFemale, final BigDecimal interestRateForChildren, - final BigDecimal interestRateForSeniorCitizen, final String currencyCode) { + final BigDecimal annualInterestRate, final String currencyCode) { this.description = description; this.periodType = (periodFrequencyType == null) ? null : periodFrequencyType.getValue(); this.fromPeriod = fromPeriod; @@ -90,13 +78,11 @@ public class InterestRateChartSlabFields { this.amountRangeFrom = amountRangeFrom; this.amountRangeTo = amountRangeTo; this.annualInterestRate = annualInterestRate; - this.interestRateForFemale = interestRateForFemale; - this.interestRateForChildren = interestRateForChildren; - this.interestRateForSeniorCitizen = interestRateForSeniorCitizen; this.currencyCode = currencyCode; } - public void update(final JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator) { + public void update(final JsonCommand command, final Map actualChanges, final DataValidatorBuilder baseDataValidator, + final Locale locale) { if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { final String newValue = command.stringValueOfParameterNamed(descriptionParamName); @@ -104,71 +90,54 @@ public class InterestRateChartSlabFields { this.description = newValue; } - if (command.isChangeInIntegerParameterNamed(periodTypeParamName, this.periodType)) { - final Integer newValue = command.integerValueOfParameterNamed(periodTypeParamName); + if (command.isChangeInIntegerParameterNamed(periodTypeParamName, this.periodType, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(periodTypeParamName, locale); actualChanges.put(periodTypeParamName, newValue); this.periodType = newValue; } - if (command.isChangeInIntegerParameterNamed(fromPeriodParamName, this.fromPeriod)) { - final Integer newValue = command.integerValueOfParameterNamed(fromPeriodParamName); + if (command.isChangeInIntegerParameterNamed(fromPeriodParamName, this.fromPeriod, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(fromPeriodParamName, locale); actualChanges.put(fromPeriodParamName, newValue); this.fromPeriod = newValue; } - if (command.isChangeInIntegerParameterNamed(toPeriodParamName, this.toPeriod)) { - final Integer newValue = command.integerValueOfParameterNamed(toPeriodParamName); + if (command.isChangeInIntegerParameterNamed(toPeriodParamName, this.toPeriod, locale)) { + final Integer newValue = command.integerValueOfParameterNamed(toPeriodParamName, locale); actualChanges.put(toPeriodParamName, newValue); this.toPeriod = newValue; } - if (command.isChangeInBigDecimalParameterNamed(amountRangeFromParamName, this.amountRangeFrom)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeFromParamName); + if (command.isChangeInBigDecimalParameterNamed(amountRangeFromParamName, this.amountRangeFrom, locale)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale); actualChanges.put(amountRangeFromParamName, newValue); this.amountRangeFrom = newValue; } - if (command.isChangeInBigDecimalParameterNamed(amountRangeToParamName, this.amountRangeTo)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeToParamName); + if (command.isChangeInBigDecimalParameterNamed(amountRangeToParamName, this.amountRangeTo, locale)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeToParamName, locale); actualChanges.put(amountRangeToParamName, newValue); this.amountRangeTo = newValue; } - if (command.isChangeInBigDecimalParameterNamed(annualInterestRateParamName, this.annualInterestRate)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(annualInterestRateParamName); + if (command.isChangeInBigDecimalParameterNamed(annualInterestRateParamName, this.annualInterestRate, locale)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(annualInterestRateParamName, locale); actualChanges.put(annualInterestRateParamName, newValue); this.annualInterestRate = newValue; } - if (command.isChangeInBigDecimalParameterNamed(interestRateForFemaleParamName, this.interestRateForFemale)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateForFemaleParamName); - actualChanges.put(interestRateForFemaleParamName, newValue); - this.interestRateForFemale = newValue; - } - - if (command.isChangeInBigDecimalParameterNamed(interestRateForChildrenParamName, this.interestRateForChildren)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateForChildrenParamName); - actualChanges.put(interestRateForChildrenParamName, newValue); - this.interestRateForChildren = newValue; - } - - if (command.isChangeInBigDecimalParameterNamed(interestRateForSeniorCitizenParamName, this.interestRateForSeniorCitizen)) { - final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateForSeniorCitizenParamName); - actualChanges.put(interestRateForSeniorCitizenParamName, newValue); - this.interestRateForSeniorCitizen = newValue; - } - - validateChartSlabPlatformRules(command, baseDataValidator); + validateChartSlabPlatformRules(command, baseDataValidator, locale); } - public void validateChartSlabPlatformRules(final JsonCommand chartSlabsCommand, final DataValidatorBuilder baseDataValidator) { + public void validateChartSlabPlatformRules(final JsonCommand chartSlabsCommand, final DataValidatorBuilder baseDataValidator, + Locale locale) { if (isFromPeriodGreaterThanToPeriod()) { - final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName); + final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName, locale); baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("from.period.is.greater.than.to.period"); } if (isAmountRangeFromGreaterThanTo()) { - final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName); + final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale); baseDataValidator.parameter(amountRangeFromParamName).value(amountRangeFrom) .failWithCode("amount.range.from.is.greater.than.amount.range.to"); } @@ -223,18 +192,6 @@ public class InterestRateChartSlabFields { return this.annualInterestRate; } - public BigDecimal interestRateForFemale() { - return this.interestRateForFemale; - } - - public BigDecimal interestRateForChildren() { - return this.interestRateForChildren; - } - - public BigDecimal interestRateForSeniorCitizen() { - return this.interestRateForSeniorCitizen; - } - public Integer depositPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) { Integer actualDepositPeriod = 0; final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(periodType()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculation.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculation.java new file mode 100755 index 000000000..fd5ffb619 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculation.java @@ -0,0 +1,33 @@ +package org.mifosplatform.portfolio.interestratechart.incentive; + +import java.math.BigDecimal; + +import org.mifosplatform.portfolio.common.domain.ConditionType; + +public abstract class AttributeIncentiveCalculation { + + public abstract BigDecimal calculateIncentive(final IncentiveDTO incentiveDTO); + + public boolean applyIncentive(ConditionType conditionType, Long attributeValue, Long actualValue) { + boolean applyIncentive = false; + int compareVal = actualValue.compareTo(attributeValue); + switch (conditionType) { + case LESSTHAN: + applyIncentive = compareVal < 0; + break; + case EQUAL: + applyIncentive = compareVal == 0; + break; + case NOT_EQUAL: + applyIncentive = compareVal != 0; + break; + case GRETERTHAN: + applyIncentive = compareVal > 0; + break; + default: + applyIncentive = false; + break; + } + return applyIncentive; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculationFactory.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculationFactory.java new file mode 100755 index 000000000..b26c43413 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/AttributeIncentiveCalculationFactory.java @@ -0,0 +1,17 @@ +package org.mifosplatform.portfolio.interestratechart.incentive; + +public class AttributeIncentiveCalculationFactory { + + public static AttributeIncentiveCalculation findAttributeIncentiveCalculation(InterestIncentiveEntityType entityType) { + AttributeIncentiveCalculation attributeIncentiveCalculation = null; + switch (entityType) { + case CUSTOMER: + attributeIncentiveCalculation = new ClientAttributeIncentiveCalculation(); + break; + default: + break; + } + return attributeIncentiveCalculation; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/ClientAttributeIncentiveCalculation.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/ClientAttributeIncentiveCalculation.java new file mode 100755 index 000000000..0ec74eb97 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/ClientAttributeIncentiveCalculation.java @@ -0,0 +1,67 @@ +package org.mifosplatform.portfolio.interestratechart.incentive; + +import java.math.BigDecimal; + +import org.joda.time.LocalDate; +import org.joda.time.Years; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.interestratechart.domain.InterestIncentivesFields; + +public class ClientAttributeIncentiveCalculation extends AttributeIncentiveCalculation { + + @Override + public BigDecimal calculateIncentive(IncentiveDTO incentiveDTO) { + final Client client = incentiveDTO.client(); + BigDecimal interest = incentiveDTO.interest(); + final InterestIncentivesFields incentivesFields = incentiveDTO.incentives(); + boolean applyIncentive = false; + switch (incentivesFields.attributeName()) { + case GENDER: + if (client.genderId() != null) { + applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()), + client.genderId()); + } + break; + case AGE: + if (client.dateOfBirth() != null) { + final LocalDate dobLacalDate = LocalDate.fromDateFields(client.dateOfBirth()); + final int age = Years.yearsBetween(dobLacalDate, LocalDate.now()).getYears(); + applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()), + Long.valueOf(age)); + } + break; + case CLIENT_TYPE: + if (client.clientTypeId() != null) { + applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()), + client.clientTypeId()); + } + break; + case CLIENT_CLASSIFICATION: + if (client.clientClassificationId() != null) { + applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()), + client.clientClassificationId()); + } + break; + + default: + break; + + } + if (applyIncentive) { + switch (incentivesFields.incentiveType()) { + case FIXED: + interest = incentivesFields.amount(); + break; + case INCENTIVE: + interest = interest.add(incentivesFields.amount()); + break; + default: + break; + + } + } + + return interest; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/IncentiveDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/IncentiveDTO.java new file mode 100755 index 000000000..95e69331d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/IncentiveDTO.java @@ -0,0 +1,31 @@ +package org.mifosplatform.portfolio.interestratechart.incentive; + +import java.math.BigDecimal; + +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.interestratechart.domain.InterestIncentivesFields; + +public class IncentiveDTO { + + private final Client client; + private final BigDecimal interest; + private final InterestIncentivesFields incentives; + + public IncentiveDTO(final Client client, final BigDecimal interest, final InterestIncentivesFields incentives) { + this.client = client; + this.interest = interest; + this.incentives = incentives; + } + + public Client client() { + return this.client; + } + + public BigDecimal interest() { + return this.interest; + } + + public InterestIncentivesFields incentives() { + return this.incentives; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java new file mode 100755 index 000000000..2079413ce --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java @@ -0,0 +1,99 @@ +/** + * 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.incentive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum InterestIncentiveAttributeName { + + INVALID(1, "InterestIncentiveAttributeName.invalid"), // + GENDER(2, "InterestIncentiveAttributeName.gender"), // + AGE(3, "InterestIncentiveAttributeName.age"), // + CLIENT_TYPE(4, "InterestIncentiveAttributeName.clientType"), // + CLIENT_CLASSIFICATION(5, "InterestIncentiveAttributeName.clientClassification"); // + + private final Integer value; + private final String code; + + private static final Map intToEnumMap = new HashMap(); + static { + for (final InterestIncentiveAttributeName type : InterestIncentiveAttributeName.values()) { + intToEnumMap.put(type.value, type); + } + } + + public static InterestIncentiveAttributeName fromInt(final Integer ruleTypeValue) { + final InterestIncentiveAttributeName type = intToEnumMap.get(ruleTypeValue); + return type; + } + + private InterestIncentiveAttributeName(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + @Override + public String toString() { + return name().toString().replaceAll("_", " "); + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public boolean isGender() { + return InterestIncentiveAttributeName.GENDER.getValue().equals(this.value); + } + + public boolean isAge() { + return InterestIncentiveAttributeName.AGE.getValue().equals(this.value); + } + + public boolean isClientType() { + return InterestIncentiveAttributeName.CLIENT_TYPE.getValue().equals(this.value); + } + + public boolean isClientClassification() { + return InterestIncentiveAttributeName.CLIENT_CLASSIFICATION.getValue().equals(this.value); + } + + public boolean isInvalid() { + return InterestIncentiveAttributeName.INVALID.getValue().equals(this.value); + } + + public static boolean isCodeValueAttribute(InterestIncentiveAttributeName attributeName) { + boolean isCodeValue = false; + switch (attributeName) { + case GENDER: + case CLIENT_TYPE: + case CLIENT_CLASSIFICATION: + isCodeValue = true; + break; + default: + break; + } + return isCodeValue; + } + + public static Object[] integerValues() { + final List values = new ArrayList(); + for (final InterestIncentiveAttributeName enumType : values()) { + if (!enumType.isInvalid()) { + values.add(enumType.getValue()); + } + } + + return values.toArray(); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java new file mode 100755 index 000000000..4dcbe2761 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java @@ -0,0 +1,70 @@ +/** + * 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.incentive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum InterestIncentiveEntityType { + + INVALID(1, "InterestIncentiveEntityType.invalid"), // + CUSTOMER(2, "InterestIncentiveEntityType.customer"), // + ACCOUNT(3, "InterestIncentiveEntityType.account"); // + + private final Integer value; + private final String code; + + private static final Map intToEnumMap = new HashMap(); + static { + for (final InterestIncentiveEntityType type : InterestIncentiveEntityType.values()) { + intToEnumMap.put(type.value, type); + } + } + + public static InterestIncentiveEntityType fromInt(final Integer ruleTypeValue) { + final InterestIncentiveEntityType type = intToEnumMap.get(ruleTypeValue); + return type; + } + + private InterestIncentiveEntityType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + @Override + public String toString() { + return name().toString().replaceAll("_", " "); + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public boolean isCustomer() { + return InterestIncentiveEntityType.CUSTOMER.getValue().equals(this.value); + } + + public boolean isInvalid() { + return InterestIncentiveEntityType.INVALID.getValue().equals(this.value); + } + + public static Object[] integerValues() { + final List values = new ArrayList(); + for (final InterestIncentiveEntityType enumType : values()) { + if (!enumType.isInvalid()) { + values.add(enumType.getValue()); + } + } + + return values.toArray(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveType.java new file mode 100755 index 000000000..55e1422e5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/incentive/InterestIncentiveType.java @@ -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.interestratechart.incentive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum InterestIncentiveType { + + INVALID(1, "InterestIncentiveType.invalid"), // + FIXED(2, "InterestIncentiveType.fixed"), // + INCENTIVE(3, "InterestIncentiveType.incentive"); // + + private final Integer value; + private final String code; + + private static final Map intToEnumMap = new HashMap(); + static { + for (final InterestIncentiveType type : InterestIncentiveType.values()) { + intToEnumMap.put(type.value, type); + } + } + + public static InterestIncentiveType fromInt(final Integer ruleTypeValue) { + final InterestIncentiveType type = intToEnumMap.get(ruleTypeValue); + return type; + } + + private InterestIncentiveType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + @Override + public String toString() { + return name().toString().replaceAll("_", " "); + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public boolean isIncentive() { + return InterestIncentiveType.INCENTIVE.getValue().equals(this.value); + } + + public boolean isFixed() { + return InterestIncentiveType.FIXED.getValue().equals(this.value); + } + + public boolean isInvalid() { + return InterestIncentiveType.INVALID.getValue().equals(this.value); + } + + public static Object[] integerValues() { + final List values = new ArrayList(); + for (final InterestIncentiveType enumType : values()) { + if (!enumType.isInvalid()) { + values.add(enumType.getValue()); + } + } + + return values.toArray(); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveAssembler.java new file mode 100755 index 000000000..8b6318825 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveAssembler.java @@ -0,0 +1,86 @@ +package org.mifosplatform.portfolio.interestratechart.service; + +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.INCENTIVE_RESOURCE_NAME; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.incentivesParamName; + +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.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.domain.InterestIncentives; +import org.mifosplatform.portfolio.interestratechart.domain.InterestIncentivesFields; +import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab; +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 InterestIncentiveAssembler { + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public InterestIncentiveAssembler(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public Collection assembleIncentivesFrom(final JsonElement element, InterestRateChartSlab interestRateChartSlab, + final Locale locale) { + final Collection interestIncentivesSet = new HashSet(); + + if (element.isJsonObject()) { + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + if (topLevelJsonElement.has(incentivesParamName) && topLevelJsonElement.get(incentivesParamName).isJsonArray()) { + final JsonArray array = topLevelJsonElement.get(incentivesParamName).getAsJsonArray(); + for (int i = 0; i < array.size(); i++) { + final JsonObject incentiveElement = array.get(i).getAsJsonObject(); + final InterestIncentives incentives = this.assembleFrom(incentiveElement, interestRateChartSlab, locale); + interestIncentivesSet.add(incentives); + } + } + } + + return interestIncentivesSet; + } + + private InterestIncentives assembleFrom(final JsonElement element, final InterestRateChartSlab interestRateChartSlab, + final Locale locale) { + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(INCENTIVE_RESOURCE_NAME); + InterestIncentivesFields incentivesFields = createInterestIncentiveFields(element, baseDataValidator, locale); + throwExceptionIfValidationWarningsExist(dataValidationErrors); + return new InterestIncentives(interestRateChartSlab, incentivesFields); + } + + private InterestIncentivesFields createInterestIncentiveFields(final JsonElement element, final DataValidatorBuilder baseDataValidator, + final Locale locale) { + Integer entityType = this.fromApiJsonHelper.extractIntegerNamed(entityTypeParamName, element, locale); + Integer conditionType = this.fromApiJsonHelper.extractIntegerNamed(conditionTypeParamName, element, locale); + Integer attributeName = this.fromApiJsonHelper.extractIntegerNamed(attributeNameParamName, element, locale); + String attributeValue = this.fromApiJsonHelper.extractStringNamed(attributeValueParamName, element); + Integer incentiveType = this.fromApiJsonHelper.extractIntegerNamed(incentiveTypeparamName, element, locale); + BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, element, locale); + return InterestIncentivesFields.createNew(entityType, attributeName, conditionType, attributeValue, incentiveType, amount, + baseDataValidator); + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveDropdownReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveDropdownReadPlatformService.java new file mode 100755 index 000000000..243d630f7 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentiveDropdownReadPlatformService.java @@ -0,0 +1,21 @@ +/** + * 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 InterestIncentiveDropdownReadPlatformService { + + Collection retrieveEntityTypeOptions(); + + Collection retrieveAttributeNameOptions(); + + Collection retrieveConditionTypeOptions(); + + Collection retrieveIncentiveTypeOptions(); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesDropdownReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesDropdownReadPlatformServiceImpl.java new file mode 100755 index 000000000..be31ed82e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesDropdownReadPlatformServiceImpl.java @@ -0,0 +1,36 @@ +package org.mifosplatform.portfolio.interestratechart.service; + +import java.util.Collection; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.common.domain.ConditionType; +import org.mifosplatform.portfolio.common.service.CommonEnumerations; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveEntityType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveType; +import org.springframework.stereotype.Service; + +@Service +public class InterestIncentivesDropdownReadPlatformServiceImpl implements InterestIncentiveDropdownReadPlatformService { + + @Override + public Collection retrieveEntityTypeOptions() { + return InterestIncentivesEnumerations.entityType(InterestIncentiveEntityType.values()); + } + + @Override + public Collection retrieveAttributeNameOptions() { + return InterestIncentivesEnumerations.attributeName(InterestIncentiveAttributeName.values()); + } + + @Override + public Collection retrieveConditionTypeOptions() { + return CommonEnumerations.conditionType(ConditionType.values(), "incentive"); + } + + @Override + public Collection retrieveIncentiveTypeOptions() { + return InterestIncentivesEnumerations.incentiveType(InterestIncentiveType.values()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesEnumerations.java new file mode 100755 index 000000000..9bc905500 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestIncentivesEnumerations.java @@ -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 java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveEntityType; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveType; + +public class InterestIncentivesEnumerations { + + public static EnumOptionData attributeName(final Integer attributeName) { + return attributeName(InterestIncentiveAttributeName.fromInt(attributeName)); + } + + public static EnumOptionData attributeName(final InterestIncentiveAttributeName type) { + EnumOptionData nameOptionData = new EnumOptionData(InterestIncentiveAttributeName.INVALID.getValue().longValue(), + InterestIncentiveAttributeName.INVALID.getCode(), "Invalid"); + + switch (type) { + case INVALID: + break; + case AGE: + nameOptionData = new EnumOptionData(InterestIncentiveAttributeName.AGE.getValue().longValue(), + InterestIncentiveAttributeName.AGE.getCode(), "age"); + break; + case GENDER: + nameOptionData = new EnumOptionData(InterestIncentiveAttributeName.GENDER.getValue().longValue(), + InterestIncentiveAttributeName.GENDER.getCode(), "Gender"); + break; + case CLIENT_TYPE: + nameOptionData = new EnumOptionData(InterestIncentiveAttributeName.CLIENT_TYPE.getValue().longValue(), + InterestIncentiveAttributeName.CLIENT_TYPE.getCode(), "Client Type"); + break; + case CLIENT_CLASSIFICATION: + nameOptionData = new EnumOptionData(InterestIncentiveAttributeName.CLIENT_CLASSIFICATION.getValue().longValue(), + InterestIncentiveAttributeName.CLIENT_CLASSIFICATION.getCode(), "Client Classification"); + break; + } + + return nameOptionData; + } + + public static List attributeName(final InterestIncentiveAttributeName[] attributeNames) { + final List optionDatas = new ArrayList(); + for (final InterestIncentiveAttributeName attributeName : attributeNames) { + if (!attributeName.isInvalid()) { + optionDatas.add(attributeName(attributeName)); + } + } + return optionDatas; + } + + public static EnumOptionData entityType(final Integer entityType) { + return entityType(InterestIncentiveEntityType.fromInt(entityType)); + } + + public static EnumOptionData entityType(final InterestIncentiveEntityType type) { + EnumOptionData nameOptionData = new EnumOptionData(InterestIncentiveEntityType.INVALID.getValue().longValue(), + InterestIncentiveEntityType.INVALID.getCode(), "Invalid"); + + switch (type) { + case INVALID: + break; + case ACCOUNT: + nameOptionData = new EnumOptionData(InterestIncentiveEntityType.ACCOUNT.getValue().longValue(), + InterestIncentiveEntityType.ACCOUNT.getCode(), "account"); + break; + case CUSTOMER: + nameOptionData = new EnumOptionData(InterestIncentiveEntityType.CUSTOMER.getValue().longValue(), + InterestIncentiveEntityType.CUSTOMER.getCode(), "Customer"); + break; + } + + return nameOptionData; + } + + public static List entityType(final InterestIncentiveEntityType[] entityTypes) { + final List optionDatas = new ArrayList(); + for (final InterestIncentiveEntityType entityType : entityTypes) { + if (!entityType.isInvalid()) { + optionDatas.add(entityType(entityType)); + } + } + return optionDatas; + } + + public static EnumOptionData incentiveType(final Integer incentiveType) { + return incentiveType(InterestIncentiveType.fromInt(incentiveType)); + } + + public static EnumOptionData incentiveType(final InterestIncentiveType type) { + EnumOptionData nameOptionData = new EnumOptionData(InterestIncentiveType.INVALID.getValue().longValue(), + InterestIncentiveType.INVALID.getCode(), "Invalid"); + + switch (type) { + case INVALID: + break; + case FIXED: + nameOptionData = new EnumOptionData(InterestIncentiveType.FIXED.getValue().longValue(), + InterestIncentiveType.FIXED.getCode(), "Fixed"); + break; + case INCENTIVE: + nameOptionData = new EnumOptionData(InterestIncentiveType.INCENTIVE.getValue().longValue(), + InterestIncentiveType.INCENTIVE.getCode(), "Incentive"); + break; + } + + return nameOptionData; + } + + public static List incentiveType(final InterestIncentiveType[] incentiveTypes) { + final List optionDatas = new ArrayList(); + for (final InterestIncentiveType incentiveType : incentiveTypes) { + if (!incentiveType.isInvalid()) { + optionDatas.add(incentiveType(incentiveType)); + } + } + return optionDatas; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java index e75d3e2d9..d46456cfc 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java @@ -13,14 +13,20 @@ import java.util.Collection; import java.util.List; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; 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.client.api.ClientApiConstants; +import org.mifosplatform.portfolio.common.service.CommonEnumerations; +import org.mifosplatform.portfolio.interestratechart.data.InterestIncentiveData; 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.interestratechart.incentive.InterestIncentiveAttributeName; import org.mifosplatform.portfolio.savings.data.DepositProductData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; @@ -38,13 +44,19 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha private final InterestRateChartMapper chartRowMapper = new InterestRateChartMapper(); private final InterestRateChartExtractor chartExtractor = new InterestRateChartExtractor(); private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService; + private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService; + private final CodeValueReadPlatformService codeValueReadPlatformService; @Autowired public InterestRateChartReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource, - InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService) { + InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService, + final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService, + final CodeValueReadPlatformService codeValueReadPlatformService) { this.context = context; this.jdbcTemplate = new JdbcTemplate(dataSource); this.chartDropdownReadPlatformService = chartDropdownReadPlatformService; + this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService; + this.codeValueReadPlatformService = codeValueReadPlatformService; } @Override @@ -94,7 +106,21 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha @Override public InterestRateChartData retrieveWithTemplate(InterestRateChartData chartData) { - return InterestRateChartData.withTemplate(chartData, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + return InterestRateChartData.withTemplate(chartData, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } @Override @@ -105,13 +131,26 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha @Override public InterestRateChartData template() { - return InterestRateChartData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + return InterestRateChartData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } private static final class InterestRateChartExtractor implements ResultSetExtractor> { InterestRateChartMapper chartMapper = new InterestRateChartMapper(); - InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper(); + InterestRateChartSlabExtractor chartSlabsMapper = new InterestRateChartSlabExtractor(); private final String schemaSql; @@ -128,13 +167,16 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha .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("ircd.interest_rate_for_female as ircdInterestRateForFemale, ircd.interest_rate_for_children as ircdInterestRateForChildren, ") - .append("ircd.interest_rate_for_senior_citizen as ircdInterestRateForSeniorCitizen, ") .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("sp.id as savingsProductId, sp.name as savingsProductName, ").append("iri.id as iriId, ") + .append(" iri.entiry_type as entityType, iri.attribute_name as attributeName ,") + .append(" iri.condition_type as conditionType, iri.attribute_value as attributeValue, ") + .append(" iri.incentive_type as incentiveType, iri.amount as amount, ") + .append("code.code_value as attributeValueDesc ").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_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ") + .append(" left join m_code_value code on code.id = iri.attribute_value ") .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 "); @@ -150,7 +192,6 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha 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"); @@ -160,10 +201,9 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha interestRateChartId = tempIrcId; chartData = chartMapper.mapRow(rs, ircIndex++); chartDataList.add(chartData); - ircdIndex = 0;// reset index } - final InterestRateChartSlabData chartSlabsData = chartSlabsMapper.mapRow(rs, ircdIndex++); + final InterestRateChartSlabData chartSlabsData = chartSlabsMapper.extractData(rs); if (chartSlabsData != null) { chartData.addChartSlab(chartSlabsData); } @@ -212,7 +252,6 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha private final String schemaSql; - @SuppressWarnings("unused") public String schema() { return this.schemaSql; } @@ -224,11 +263,14 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha .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("ircd.interest_rate_for_female as ircdInterestRateForFemale, ircd.interest_rate_for_children as ircdInterestRateForChildren, ") - .append("ircd.interest_rate_for_senior_citizen as ircdInterestRateForSeniorCitizen, ") .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("curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf, ") + .append("iri.id as iriId, ").append(" iri.entiry_type as entityType, iri.attribute_name as attributeName ,") + .append(" iri.condition_type as conditionType, iri.attribute_value as attributeValue, ") + .append(" iri.incentive_type as incentiveType, iri.amount as amount, ") + .append("code.code_value as attributeValueDesc ").append("from ").append("m_interest_rate_slab ircd ") + .append(" left join m_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ") + .append(" left join m_code_value code on code.id = iri.attribute_value ") .append("left join m_currency curr on ircd.currency_code= curr.code "); this.schemaSql = sqlBuilder.toString(); } @@ -248,9 +290,6 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha final BigDecimal amountRangeFrom = rs.getBigDecimal("ircdAmountRangeFrom"); final BigDecimal amountRangeTo = rs.getBigDecimal("ircdAmountRangeTo"); final BigDecimal annualInterestRate = rs.getBigDecimal("ircdAnnualInterestRate"); - final BigDecimal interestRateForFemale = rs.getBigDecimal("ircdInterestRateForFemale"); - final BigDecimal interestRateForChildren = rs.getBigDecimal("ircdInterestRateForChildren"); - final BigDecimal interestRateForSeniorCitizen = rs.getBigDecimal("ircdInterestRateForSeniorCitizen"); // currency Slabs final String currencyCode = rs.getString("currencyCode"); @@ -264,8 +303,86 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha currencyDisplaySymbol, currencyNameCode); return InterestRateChartSlabData.instance(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, - annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currency); + annualInterestRate, currency); } } + + private static final class InterestRateChartSlabExtractor implements ResultSetExtractor { + + InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper(); + InterestIncentiveMapper incentiveMapper = new InterestIncentiveMapper(); + + private final String schemaSql; + + @SuppressWarnings("unused") + public String schema() { + return this.schemaSql; + } + + private InterestRateChartSlabExtractor() { + this.schemaSql = chartSlabsMapper.schema(); + } + + @Override + public InterestRateChartSlabData extractData(ResultSet rs) throws SQLException, DataAccessException { + + InterestRateChartSlabData chartSlabData = null; + Long interestRateChartSlabId = null; + int ircIndex = 0;// Interest rate chart index + int ircdIndex = 0;// Interest rate chart Slabs index + rs.previous(); + while (rs.next()) { + Long tempIrcdId = rs.getLong("ircdId"); + if (interestRateChartSlabId == null || interestRateChartSlabId.equals(tempIrcdId)) { + if (chartSlabData == null) { + interestRateChartSlabId = tempIrcdId; + chartSlabData = chartSlabsMapper.mapRow(rs, ircIndex++); + } + final InterestIncentiveData incentiveData = incentiveMapper.mapRow(rs, ircdIndex++); + if (incentiveData != null) { + chartSlabData.addIncentives(incentiveData); + } + } else { + rs.previous(); + break; + } + + } + return chartSlabData; + } + + private static final class InterestIncentiveMapper implements RowMapper { + + @Override + public InterestIncentiveData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = JdbcSupport.getLongDefaultToNullIfZero(rs, "iriId"); + // If there are not Incentive are associated then in + // InterestRateChartExtractor the incentive id will be null. + if (id == null) { return null; } + + final String attributeValue = rs.getString("attributeValue"); + String attributeValueDesc = null; + final Integer entityType = JdbcSupport.getInteger(rs, "entityType"); + + final EnumOptionData entityTypeData = InterestIncentivesEnumerations.entityType(entityType); + + final Integer attributeName = JdbcSupport.getInteger(rs, "attributeName"); + if (InterestIncentiveAttributeName.isCodeValueAttribute(InterestIncentiveAttributeName.fromInt(attributeName))) { + attributeValueDesc = rs.getString("attributeValueDesc"); + } + final EnumOptionData attributeNameData = InterestIncentivesEnumerations.attributeName(attributeName); + final Integer conditionType = JdbcSupport.getInteger(rs, "conditionType"); + final EnumOptionData conditionTypeData = CommonEnumerations.conditionType(conditionType, "incentive"); + final Integer incentiveType = JdbcSupport.getInteger(rs, "incentiveType"); + final EnumOptionData incentiveTypeData = InterestIncentivesEnumerations.incentiveType(incentiveType); + final BigDecimal amount = rs.getBigDecimal("amount"); + + return InterestIncentiveData.instance(id, entityTypeData, attributeNameData, conditionTypeData, attributeValue, + attributeValueDesc, incentiveTypeData, amount); + + } + } + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabAssembler.java index d5072dc32..c8fa9138c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabAssembler.java @@ -5,19 +5,16 @@ */ package org.mifosplatform.portfolio.interestratechart.service; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.chartSlabs; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME; 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.interestRateForFemaleParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForChildrenParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.interestRateForSeniorCitizenParamName; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.chartSlabs; -import static org.mifosplatform.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName; +import static org.mifosplatform.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName; 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 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; @@ -49,12 +46,14 @@ public class InterestRateChartSlabAssembler { private final FromJsonHelper fromApiJsonHelper; private final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper; + private final InterestIncentiveAssembler incentiveAssembler; @Autowired public InterestRateChartSlabAssembler(final FromJsonHelper fromApiJsonHelper, - final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper) { + final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper, final InterestIncentiveAssembler incentiveAssembler) { this.fromApiJsonHelper = fromApiJsonHelper; this.interestRateChartRepositoryWrapper = interestRateChartRepositoryWrapper; + this.incentiveAssembler = incentiveAssembler; } /** @@ -78,7 +77,7 @@ public class InterestRateChartSlabAssembler { final InterestRateChartSlab newChartSlab = assembleChartSlabs(chart, elementObject, currencyCode, locale); // validate chart Slabs - newChartSlab.slabFields().validateChartSlabPlatformRules(command, baseDataValidator); + newChartSlab.slabFields().validateChartSlabPlatformRules(command, baseDataValidator, locale); chart.validateChartSlabs(baseDataValidator); throwExceptionIfValidationWarningsExist(dataValidationErrors); @@ -95,13 +94,12 @@ public class InterestRateChartSlabAssembler { 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 BigDecimal interestRateForFemale = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForFemaleParamName, element, locale); - final BigDecimal interestRateForChildren = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForChildrenParamName, element, locale); - final BigDecimal interestRateForSeniorCitizen = this.fromApiJsonHelper.extractBigDecimalNamed(interestRateForSeniorCitizenParamName, element, locale); - + final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description, periodType, fromPeriod, toPeriod, - amountRangeFrom, amountRangeTo, annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currencyCode); - return InterestRateChartSlab.createNew(slabFields, interestRateChart); + amountRangeFrom, amountRangeTo, annualInterestRate, currencyCode); + InterestRateChartSlab interestRateChartSlab = InterestRateChartSlab.createNew(slabFields, interestRateChart); + this.incentiveAssembler.assembleIncentivesFrom(element, interestRateChartSlab, locale); + return interestRateChartSlab; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformService.java index 649def7d1..fc774d293 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformService.java @@ -14,8 +14,9 @@ public interface InterestRateChartSlabReadPlatformService { Collection retrieveAll(Long chartId); InterestRateChartSlabData retrieveOne(Long chartId, Long chartSlabId); - + InterestRateChartSlabData retrieveWithTemplate(InterestRateChartSlabData chartSlab); - + InterestRateChartSlabData retrieveTemplate(); + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java index 8f25e7ce7..45d600e12 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java @@ -8,18 +8,27 @@ 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.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; 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.client.api.ClientApiConstants; +import org.mifosplatform.portfolio.common.service.CommonEnumerations; +import org.mifosplatform.portfolio.interestratechart.data.InterestIncentiveData; import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData; import org.mifosplatform.portfolio.interestratechart.exception.InterestRateChartSlabNotFoundException; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; @@ -28,43 +37,76 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat private final PlatformSecurityContext context; private final JdbcTemplate jdbcTemplate; - private final InterestRateChartSlabsMapper chartSlabRowMapper = new InterestRateChartSlabsMapper(); + private final InterestRateChartSlabExtractor chartSlabExtractor = new InterestRateChartSlabExtractor(); private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService; + private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService; + private final CodeValueReadPlatformService codeValueReadPlatformService; @Autowired public InterestRateChartSlabReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource, - InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService) { + InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService, + final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService, + final CodeValueReadPlatformService codeValueReadPlatformService) { this.context = context; this.jdbcTemplate = new JdbcTemplate(dataSource); this.chartDropdownReadPlatformService = chartDropdownReadPlatformService; + this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService; + this.codeValueReadPlatformService = codeValueReadPlatformService; } @Override public Collection 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 }); + final String sql = "select " + this.chartSlabExtractor.schema() + " where ircd.interest_rate_chart_id = ? order by ircd.id"; + return this.jdbcTemplate.query(sql, this.chartSlabExtractor, 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); - } + this.context.authenticatedUser(); + final String sql = "select " + this.chartSlabExtractor.schema() + " where irc.id = ? order by ircd.id asc"; + Collection chartDatas = this.jdbcTemplate.query(sql, this.chartSlabExtractor, new Object[] { + chartSlabId, chartId }); + if (chartDatas == null || chartDatas.isEmpty()) { throw new InterestRateChartSlabNotFoundException(chartSlabId, chartId); } + + return chartDatas.iterator().next(); } - + @Override public InterestRateChartSlabData retrieveWithTemplate(InterestRateChartSlabData chartSlab) { - return InterestRateChartSlabData.withTemplate(chartSlab, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + + return InterestRateChartSlabData.withTemplate(chartSlab, this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } @Override public InterestRateChartSlabData retrieveTemplate() { - return InterestRateChartSlabData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + return InterestRateChartSlabData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } private static final class InterestRateChartSlabsMapper implements RowMapper { @@ -82,11 +124,14 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat .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("ircd.interest_rate_for_female as ircdInterestRateForFemale, ircd.interest_rate_for_children as ircdInterestRateForChildren, ") - .append("ircd.interest_rate_for_senior_citizen as ircdInterestRateForSeniorCitizen, ") .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("curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf, ") + .append("iri.id as iriId, ").append(" iri.entiry_type as entityType, iri.attribute_name as attributeName ,") + .append(" iri.condition_type as conditionType, iri.attribute_value as attributeValue, ") + .append(" iri.incentive_type as incentiveType, iri.amount as amount, ").append("code.code_value as attributeValueDesc ") .append("from ").append("m_interest_rate_slab ircd ") + .append(" left join m_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ") + .append(" left join m_code_value code on code.id = iri.attribute_value ") .append("left join m_currency curr on ircd.currency_code= curr.code "); this.schemaSql = sqlBuilder.toString(); } @@ -106,9 +151,6 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat final BigDecimal amountRangeFrom = rs.getBigDecimal("ircdAmountRangeFrom"); final BigDecimal amountRangeTo = rs.getBigDecimal("ircdAmountRangeTo"); final BigDecimal annualInterestRate = rs.getBigDecimal("ircdAnnualInterestRate"); - final BigDecimal interestRateForFemale = rs.getBigDecimal("ircdInterestRateForFemale"); - final BigDecimal interestRateForChildren = rs.getBigDecimal("ircdInterestRateForChildren"); - final BigDecimal interestRateForSeniorCitizen = rs.getBigDecimal("ircdInterestRateForSeniorCitizen"); // currency Slabs final String currencyCode = rs.getString("currencyCode"); @@ -122,8 +164,82 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat currencyDisplaySymbol, currencyNameCode); return InterestRateChartSlabData.instance(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, - annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currency); + annualInterestRate, currency); } } + + private static final class InterestRateChartSlabExtractor implements ResultSetExtractor> { + + InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper(); + InterestIncentiveMapper incentiveMapper = new InterestIncentiveMapper(); + + private final String schemaSql; + + public String schema() { + return this.schemaSql; + } + + private InterestRateChartSlabExtractor() { + this.schemaSql = chartSlabsMapper.schema(); + } + + @Override + public Collection extractData(ResultSet rs) throws SQLException, DataAccessException { + + List chartDataList = new ArrayList(); + + InterestRateChartSlabData chartSlabData = null; + Long interestRateChartSlabId = null; + int ircIndex = 0;// Interest rate chart index + int ircdIndex = 0;// Interest rate chart Slabs index + + while (rs.next()) { + Long tempIrcdId = rs.getLong("ircdId"); + if (chartSlabData == null || (interestRateChartSlabId != null && !interestRateChartSlabId.equals(tempIrcdId))) { + interestRateChartSlabId = tempIrcdId; + chartSlabData = chartSlabsMapper.mapRow(rs, ircIndex++); + chartDataList.add(chartSlabData); + } + final InterestIncentiveData incentiveData = incentiveMapper.mapRow(rs, ircdIndex++); + if (incentiveData != null) { + chartSlabData.addIncentives(incentiveData); + } + } + return chartDataList; + } + } + + private static final class InterestIncentiveMapper implements RowMapper { + + @Override + public InterestIncentiveData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = JdbcSupport.getLongDefaultToNullIfZero(rs, "iriId"); + // If there are not Incentive are associated then in + // InterestRateChartExtractor the incentive id will be null. + if (id == null) { return null; } + + final String attributeValue = rs.getString("attributeValue"); + String attributeValueDesc = null; + final Integer entityType = JdbcSupport.getInteger(rs, "entityType"); + final EnumOptionData entityTypeData = InterestIncentivesEnumerations.entityType(entityType); + + final Integer attributeName = JdbcSupport.getInteger(rs, "attributeName"); + if (InterestIncentiveAttributeName.isCodeValueAttribute(InterestIncentiveAttributeName.fromInt(attributeName))) { + attributeValueDesc = rs.getString("attributeValueDesc"); + } + final EnumOptionData attributeNameData = InterestIncentivesEnumerations.attributeName(attributeName); + final Integer conditionType = JdbcSupport.getInteger(rs, "conditionType"); + final EnumOptionData conditionTypeData = CommonEnumerations.conditionType(conditionType, "incentive"); + final Integer incentiveType = JdbcSupport.getInteger(rs, "incentiveType"); + final EnumOptionData incentiveTypeData = InterestIncentivesEnumerations.incentiveType(incentiveType); + final BigDecimal amount = rs.getBigDecimal("amount"); + + return InterestIncentiveData.instance(id, entityTypeData, attributeNameData, conditionTypeData, attributeValue, + attributeValueDesc, incentiveTypeData, amount); + + } + + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl.java index 42a1cc002..b7a2caa68 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/interestratechart/service/InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl.java @@ -6,6 +6,7 @@ package org.mifosplatform.portfolio.interestratechart.service; import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Map; import org.mifosplatform.infrastructure.core.api.JsonCommand; @@ -80,8 +81,8 @@ public class InterestRateChartSlabWritePlatformServiceJpaRepositoryImpl implemen final Map changes = new LinkedHashMap(20); final InterestRateChartSlab updateChartSlabs = this.interestRateChartSlabAssembler.assembleFrom(chartSlabId, interestRateChartId); - - updateChartSlabs.update(command, changes); + final Locale locale = command.extractLocale(); + updateChartSlabs.update(command, changes,locale); this.chartSlabRepository.saveAndFlush(updateChartSlabs); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestIncentiveData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestIncentiveData.java new file mode 100755 index 000000000..9f17d0dd9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestIncentiveData.java @@ -0,0 +1,57 @@ +package org.mifosplatform.portfolio.savings.data; + +import java.math.BigDecimal; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.interestratechart.data.InterestIncentiveData; + +public class DepositAccountInterestIncentiveData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final EnumOptionData entityType; + @SuppressWarnings("unused") + private final EnumOptionData attributeName; + @SuppressWarnings("unused") + private final EnumOptionData conditionType; + @SuppressWarnings("unused") + private final String attributeValue; + @SuppressWarnings("unused") + private final String attributeValueDesc; + @SuppressWarnings("unused") + private final EnumOptionData incentiveType; + @SuppressWarnings("unused") + private final BigDecimal amount; + + public static DepositAccountInterestIncentiveData instance(final Long id, final EnumOptionData entityType, + final EnumOptionData attributeName, final EnumOptionData conditionType, final String attributeValue, + final String attributeValueDesc, final EnumOptionData incentiveType, final BigDecimal amount) { + + return new DepositAccountInterestIncentiveData(id, entityType, attributeName, conditionType, attributeValue, attributeValueDesc, + incentiveType, amount); + } + + public static DepositAccountInterestIncentiveData from(final InterestIncentiveData incentiveData) { + final Long id = null; + return new DepositAccountInterestIncentiveData(id, incentiveData.entityType(), incentiveData.attributeName(), + incentiveData.conditionType(), incentiveData.attributeValue(), incentiveData.attributeValueDesc(), + incentiveData.incentiveType(), incentiveData.amount()); + } + + private DepositAccountInterestIncentiveData(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName, + final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc, + final EnumOptionData incentiveType, final BigDecimal amount) { + + this.id = id; + this.entityType = entityType; + this.attributeName = attributeName; + this.conditionType = conditionType; + this.attributeValue = attributeValue; + this.attributeValueDesc = attributeValueDesc; + this.incentiveType = incentiveType; + this.amount = amount; + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartData.java index dca214c72..ba156df5e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartData.java @@ -10,6 +10,7 @@ import java.util.HashSet; import java.util.Set; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartData; import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData; @@ -31,13 +32,28 @@ public class DepositAccountInterestRateChartData { // template private Collection periodTypes; + private final Collection entityTypeOptions; + private final Collection attributeNameOptions; + private final Collection conditionTypeOptions; + private final Collection incentiveTypeOptions; + private final Collection genderOptions; + private final Collection clientTypeOptions; + private final Collection clientClassificationOptions; public static DepositAccountInterestRateChartData instance(Long id, String name, String description, LocalDate fromDate, LocalDate endDate, Long accountId, String accountNumber, Set chartSlabs, Collection periodTypes) { + final Collection entityTypeOptions = null; + final Collection attributeNameOptions = null; + final Collection conditionTypeOptions = null; + final Collection incentiveTypeOptions = null; + final Collection genderOptions = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, accountId, accountNumber, chartSlabs, - periodTypes); + periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, + clientTypeOptions, clientClassificationOptions); } public static DepositAccountInterestRateChartData from(InterestRateChartData productChartData) { @@ -54,24 +70,39 @@ public class DepositAccountInterestRateChartData { return new DepositAccountInterestRateChartData(id, productChartData.name(), productChartData.description(), productChartData.fromDate(), productChartData.endDate(), accountId, accountNumber, fromProdChartSlabs, - productChartData.periodTypes()); + productChartData.periodTypes(), productChartData.entityTypeOptions(), productChartData.attributeNameOptions(), + productChartData.conditionTypeOptions(), productChartData.incentiveTypeOptions(), productChartData.genderOptions(), + productChartData.clientTypeOptions(), productChartData.clientClassificationOptions()); } public static DepositAccountInterestRateChartData withSlabs(DepositAccountInterestRateChartData interestRateChartData, Set chartSlabs) { return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate, - interestRateChartData.accountId, interestRateChartData.accountNumber, chartSlabs, interestRateChartData.periodTypes); + interestRateChartData.accountId, interestRateChartData.accountNumber, chartSlabs, interestRateChartData.periodTypes, + interestRateChartData.entityTypeOptions, interestRateChartData.attributeNameOptions, + interestRateChartData.conditionTypeOptions, interestRateChartData.incentiveTypeOptions, + interestRateChartData.genderOptions, interestRateChartData.clientTypeOptions, + interestRateChartData.clientClassificationOptions); } public static DepositAccountInterestRateChartData withTemplate(DepositAccountInterestRateChartData interestRateChartData, - Collection periodTypes) { + Collection periodTypes, final Collection entityTypeOptions, + final Collection attributeNameOptions, final Collection conditionTypeOptions, + final Collection incentiveTypeOptions, final Collection genderOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate, - interestRateChartData.accountId, interestRateChartData.accountNumber, interestRateChartData.chartSlabs, periodTypes); + interestRateChartData.accountId, interestRateChartData.accountNumber, interestRateChartData.chartSlabs, periodTypes, + entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, clientTypeOptions, + clientClassificationOptions); } - public static DepositAccountInterestRateChartData template(Collection periodTypes) { + public static DepositAccountInterestRateChartData template(Collection periodTypes, + final Collection entityTypeOptions, final Collection attributeNameOptions, + final Collection conditionTypeOptions, final Collection incentiveTypeOptions, + final Collection genderOptions, final Collection clientTypeOptions, + final Collection clientClassificationOptions) { final Long id = null; final String name = null; final String description = null; @@ -81,12 +112,16 @@ public class DepositAccountInterestRateChartData { final String accountNumber = null; final Set chartSlabs = null; return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, accountId, accountNumber, chartSlabs, - periodTypes); + periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, + clientTypeOptions, clientClassificationOptions); } private DepositAccountInterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate, Long accountId, String accountNumber, Set chartSlabs, - Collection periodTypes) { + Collection periodTypes, final Collection entityTypeOptions, + final Collection attributeNameOptions, final Collection conditionTypeOptions, + final Collection incentiveTypeOptions, final Collection genderOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { this.id = id; this.name = name; this.description = description; @@ -96,6 +131,13 @@ public class DepositAccountInterestRateChartData { this.accountId = accountId; this.accountNumber = accountNumber; this.periodTypes = periodTypes; + this.attributeNameOptions = attributeNameOptions; + this.entityTypeOptions = entityTypeOptions; + this.conditionTypeOptions = conditionTypeOptions; + this.incentiveTypeOptions = incentiveTypeOptions; + this.genderOptions = genderOptions; + this.clientTypeOptions = clientTypeOptions; + this.clientClassificationOptions = clientClassificationOptions; } public void addChartSlab(final DepositAccountInterestRateChartSlabData chartSlab) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartSlabData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartSlabData.java index 869311907..d920a2947 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartSlabData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountInterestRateChartSlabData.java @@ -7,9 +7,13 @@ package org.mifosplatform.portfolio.savings.data; import java.math.BigDecimal; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +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.interestratechart.data.InterestIncentiveData; import org.mifosplatform.portfolio.interestratechart.data.InterestRateChartSlabData; /** @@ -25,47 +29,81 @@ public class DepositAccountInterestRateChartSlabData { private final BigDecimal amountRangeFrom; private final BigDecimal amountRangeTo; private final BigDecimal annualInterestRate; - private final BigDecimal interestRateForFemale; - private final BigDecimal interestRateForChildren; - private final BigDecimal interestRateForSeniorCitizen; private final CurrencyData currency; // associations + private Collection incentives; // template @SuppressWarnings("unused") private final Collection periodTypes; + @SuppressWarnings("unused") + private final Collection entityTypeOptions; + @SuppressWarnings("unused") + private final Collection attributeNameOptions; + @SuppressWarnings("unused") + private final Collection conditionTypeOptions; + @SuppressWarnings("unused") + private final Collection incentiveTypeOptions; + @SuppressWarnings("unused") + private final Collection genderOptions; + @SuppressWarnings("unused") + private final Collection clientTypeOptions; + @SuppressWarnings("unused") + private final Collection clientClassificationOptions; public static DepositAccountInterestRateChartSlabData instance(final Long id, final String description, final EnumOptionData periodType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, - final BigDecimal amountRangeTo, final BigDecimal annualInterestRate, final BigDecimal interestRateForFemale, - final BigDecimal interestRateForChildren, final BigDecimal interestRateForSeniorCitizen, final CurrencyData currency) { + final BigDecimal amountRangeTo, final BigDecimal annualInterestRate, final CurrencyData currency) { final Collection periodTypes = null; + final Collection entityTypeOptions = null; + final Collection attributeNameOptions = null; + final Collection conditionTypeOptions = null; + final Collection incentiveTypeOptions = null; + final Collection genderOptions = null; + final Collection clientTypeOptions = null; + final Collection clientClassificationOptions = null; + final Collection incentives = null; return new DepositAccountInterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, - amountRangeTo, annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, currency, - periodTypes); + amountRangeTo, annualInterestRate, incentives, currency, periodTypes, entityTypeOptions, attributeNameOptions, + conditionTypeOptions, incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions); } public static DepositAccountInterestRateChartSlabData from(final InterestRateChartSlabData chartSlabData) { final Long id = null; + Set fromProdIncentives = new HashSet(); + Set productIncentiveData = chartSlabData.incentives(); + if (productIncentiveData != null) { + for (InterestIncentiveData incentive : productIncentiveData) { + fromProdIncentives.add(DepositAccountInterestIncentiveData.from(incentive)); + } + } return new DepositAccountInterestRateChartSlabData(id, chartSlabData.description(), chartSlabData.periodType(), chartSlabData.fromPeriod(), chartSlabData.toPeriod(), chartSlabData.amountRangeFrom(), chartSlabData.amountRangeTo(), - chartSlabData.annualInterestRate(), chartSlabData.interestRateForFemale(), chartSlabData.interestRateForChildren(), - chartSlabData.interestRateForSeniorCitizen(), chartSlabData.currency(), chartSlabData.periodTypes()); + chartSlabData.annualInterestRate(), fromProdIncentives, chartSlabData.currency(), chartSlabData.periodTypes(), + chartSlabData.entityTypeOptions(), chartSlabData.attributeNameOptions(), chartSlabData.conditionTypeOptions(), + chartSlabData.incentiveTypeOptions(), chartSlabData.genderOptions(), chartSlabData.clientTypeOptions(), + chartSlabData.clientClassificationOptions()); } public static DepositAccountInterestRateChartSlabData withTemplate(final DepositAccountInterestRateChartSlabData chartSlab, - final Collection periodTypes) { + final Collection periodTypes, final Collection entityTypeOptions, + final Collection attributeNameOptions, final Collection conditionTypeOptions, + final Collection incentiveTypeOptions, final Collection genderOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { return new DepositAccountInterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod, - chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, - chartSlab.interestRateForFemale, chartSlab.interestRateForChildren, chartSlab.interestRateForSeniorCitizen, - chartSlab.currency, periodTypes); + chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, chartSlab.incentives, + chartSlab.currency, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, + genderOptions, clientTypeOptions, clientClassificationOptions); } private DepositAccountInterestRateChartSlabData(final Long id, final String description, final EnumOptionData periodType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, - final BigDecimal annualInterestRate, final BigDecimal interestRateForFemale, final BigDecimal interestRateForChildren, - final BigDecimal interestRateForSeniorCitizen, final CurrencyData currency, final Collection periodTypes) { + final BigDecimal annualInterestRate, final Collection incentivesData, + final CurrencyData currency, final Collection periodTypes, final Collection entityTypeOptions, + final Collection attributeNameOptions, final Collection conditionTypeOptions, + final Collection incentiveTypeOptions, final Collection genderOptions, + final Collection clientTypeOptions, final Collection clientClassificationOptions) { this.id = id; this.description = description; this.periodType = periodType; @@ -74,11 +112,23 @@ public class DepositAccountInterestRateChartSlabData { this.amountRangeFrom = amountRangeFrom; this.amountRangeTo = amountRangeTo; this.annualInterestRate = annualInterestRate; - this.interestRateForFemale = interestRateForFemale; - this.interestRateForChildren = interestRateForChildren; - this.interestRateForSeniorCitizen = interestRateForSeniorCitizen; this.currency = currency; this.periodTypes = periodTypes; + this.incentives = incentivesData; + this.attributeNameOptions = attributeNameOptions; + this.entityTypeOptions = entityTypeOptions; + this.conditionTypeOptions = conditionTypeOptions; + this.incentiveTypeOptions = incentiveTypeOptions; + this.genderOptions = genderOptions; + this.clientTypeOptions = clientTypeOptions; + this.clientClassificationOptions = clientClassificationOptions; + } + + public void addIncentives(final DepositAccountInterestIncentiveData incentive) { + if (this.incentives == null) { + this.incentives = new HashSet(); + } + this.incentives.add(incentive); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentive.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentive.java new file mode 100755 index 000000000..c7d11e11c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentive.java @@ -0,0 +1,33 @@ +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.InterestIncentivesFields; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_deposit_account_interest_incentives") +public class DepositAccountInterestIncentive extends AbstractPersistable { + + @ManyToOne + @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) + private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs; + + @Embedded + private InterestIncentivesFields interestIncentivesFields; + + protected DepositAccountInterestIncentive() { + // TODO Auto-generated constructor stub + } + + public DepositAccountInterestIncentive(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs, + final InterestIncentivesFields interestIncentivesFields) { + this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs; + this.interestIncentivesFields = interestIncentivesFields; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentives.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentives.java new file mode 100755 index 000000000..274dc26b3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestIncentives.java @@ -0,0 +1,47 @@ +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.InterestIncentivesFields; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_savings_interest_incentives") +public class DepositAccountInterestIncentives extends AbstractPersistable { + + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) + private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs; + + @Embedded + private InterestIncentivesFields interestIncentivesFields; + + protected DepositAccountInterestIncentives() { + + } + + private DepositAccountInterestIncentives(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs, + final InterestIncentivesFields interestIncentivesFields) { + this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs; + this.interestIncentivesFields = interestIncentivesFields; + } + + public static DepositAccountInterestIncentives from(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs, + final InterestIncentivesFields interestIncentivesFields) { + return new DepositAccountInterestIncentives(depositAccountInterestRateChartSlabs, interestIncentivesFields); + } + + public void updateDepositAccountInterestRateChartSlabs(DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs) { + this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs; + } + + public InterestIncentivesFields interestIncentivesFields() { + return this.interestIncentivesFields; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChart.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChart.java index c6ad48b89..b28b7fda7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChart.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChart.java @@ -20,10 +20,13 @@ import javax.persistence.Table; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; -import org.mifosplatform.portfolio.interestratechart.data.ClientIncentiveAttributes; +import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartFields; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab; +import org.mifosplatform.portfolio.interestratechart.incentive.AttributeIncentiveCalculation; +import org.mifosplatform.portfolio.interestratechart.incentive.AttributeIncentiveCalculationFactory; +import org.mifosplatform.portfolio.interestratechart.incentive.IncentiveDTO; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -49,7 +52,7 @@ public class DepositAccountInterestRateChart extends AbstractPersistable { final Set chartSlabs = productChart.setOfChartSlabs(); final Set depostiChartSlabs = new HashSet(); for (InterestRateChartSlab interestRateChartSlab : chartSlabs) { - depostiChartSlabs.add(DepositAccountInterestRateChartSlabs.from(interestRateChartSlab.slabFields(), null)); + depostiChartSlabs.add(DepositAccountInterestRateChartSlabs.from(interestRateChartSlab, null)); } final DepositAccountInterestRateChart depositChart = new DepositAccountInterestRateChart(productChart.chartFields(), null, depostiChartSlabs); @@ -112,25 +115,19 @@ public class DepositAccountInterestRateChart extends AbstractPersistable { this.account = account; } - public BigDecimal getApplicableInterestRate(final BigDecimal depositAmount, - final LocalDate periodStartDate, final LocalDate periodEndDate, final ClientIncentiveAttributes incentiveAttributes) { + public BigDecimal getApplicableInterestRate(final BigDecimal depositAmount, final LocalDate periodStartDate, + final LocalDate periodEndDate, final Client client) { BigDecimal effectiveInterestRate = BigDecimal.ZERO; for (DepositAccountInterestRateChartSlabs slab : setOfChartSlabs()) { if (slab.slabFields().isBetweenPeriod(periodStartDate, periodEndDate) && slab.slabFields().isAmountBetween(depositAmount)) { - if (incentiveAttributes == null) { - effectiveInterestRate = slab.slabFields().annualInterestRate(); - } else { - if (incentiveAttributes.isSeniorCitizen()) { - effectiveInterestRate = slab.slabFields().interestRateForSeniorCitizen(); - } - if (incentiveAttributes.isFemale()) { - - effectiveInterestRate = slab.slabFields().interestRateForFemale(); - } - if (incentiveAttributes.isChild()) { - effectiveInterestRate = slab.slabFields().interestRateForChildren(); - } + effectiveInterestRate = slab.slabFields().annualInterestRate(); + Set depositInterestIncentives = slab.setOfIncentives(); + for (DepositAccountInterestIncentives incentives : depositInterestIncentives) { + AttributeIncentiveCalculation attributeIncentiveCalculation = AttributeIncentiveCalculationFactory + .findAttributeIncentiveCalculation(incentives.interestIncentivesFields().entiryType()); + IncentiveDTO incentiveDTO = new IncentiveDTO(client, effectiveInterestRate, incentives.interestIncentivesFields()); + effectiveInterestRate = attributeIncentiveCalculation.calculateIncentive(incentiveDTO); } // effectiveInterestRate is zero or null then reset to default diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java index bf553d707..4167a9c35 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java @@ -5,12 +5,21 @@ */ package org.mifosplatform.portfolio.savings.domain; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import javax.persistence.Table; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; +import org.mifosplatform.portfolio.interestratechart.domain.InterestIncentives; +import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlab; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChartSlabFields; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -25,15 +34,19 @@ public class DepositAccountInterestRateChartSlabs extends AbstractPersistable interestIncentives = new HashSet(); + protected DepositAccountInterestRateChartSlabs() { // } - private DepositAccountInterestRateChartSlabs(InterestRateChartSlabFields slabFields, - DepositAccountInterestRateChart depositAccountInterestRateChart) { + DepositAccountInterestRateChart depositAccountInterestRateChart, final Set interestIncentives) { this.slabFields = slabFields; this.depositAccountInterestRateChart = depositAccountInterestRateChart; + this.interestIncentives = interestIncentives; } public void setDepositAccountInterestRateChart(DepositAccountInterestRateChart depositAccountInterestRateChart) { @@ -47,13 +60,36 @@ public class DepositAccountInterestRateChartSlabs extends AbstractPersistable depositInterestIncentives = new HashSet(); + Set incentives = interestRateChartSlab.setOfInterestIncentives(); + for (InterestIncentives incentive : incentives) { + depositInterestIncentives.add(DepositAccountInterestIncentives.from(null, incentive.interestIncentivesFields())); + } + DepositAccountInterestRateChartSlabs chartSlabs = new DepositAccountInterestRateChartSlabs(slabFields, + depositAccountInterestRateChart, depositInterestIncentives); + chartSlabs.updateIncentiveReference(); + return chartSlabs; } - - public void updateChartReference(final DepositAccountInterestRateChart chart){ + + private void updateIncentiveReference() { + final Set incentives = setOfIncentives(); + for (DepositAccountInterestIncentives depositInterestIncentives : incentives) { + depositInterestIncentives.updateDepositAccountInterestRateChartSlabs(this); + } + } + + public Set setOfIncentives() { + if (this.interestIncentives == null) { + this.interestIncentives = new HashSet(); + } + return this.interestIncentives; + } + + public void updateChartReference(final DepositAccountInterestRateChart chart) { this.depositAccountInterestRateChart = chart; } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java index 2a376ab2c..3074ec707 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/FixedDepositAccount.java @@ -41,7 +41,6 @@ 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.data.ClientIncentiveAttributes; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart; import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartAssembler; import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType; @@ -158,9 +157,8 @@ public class FixedDepositAccount extends SavingsAccount { } final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount(); - final ClientIncentiveAttributes incentiveAttributes = (this.client == null) ? null : this.client.incentiveAttributes(); applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate, - incentiveAttributes); + this.client); if (applyPreMaturePenalty) { applicableInterestRate = applicableInterestRate.subtract(penalInterest); @@ -673,9 +671,8 @@ public class FixedDepositAccount extends SavingsAccount { } final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount(); - final ClientIncentiveAttributes incentiveAttributes = (this.client == null) ? null : this.client.incentiveAttributes(); BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), - calculateMaturityDate(), incentiveAttributes); + calculateMaturityDate(), this.client); if (applicableInterestRate.equals(BigDecimal.ZERO)) { baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode( diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java index 40b88e87b..a8d43f6ff 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/RecurringDepositAccount.java @@ -27,7 +27,6 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.persistence.OneToOne; -import javax.persistence.Transient; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; @@ -46,9 +45,7 @@ import org.mifosplatform.portfolio.accountdetails.domain.AccountType; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.group.domain.Group; -import org.mifosplatform.portfolio.interestratechart.data.ClientIncentiveAttributes; import org.mifosplatform.portfolio.interestratechart.domain.InterestRateChart; -import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartAssembler; import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType; import org.mifosplatform.portfolio.savings.DepositsApiConstants; import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType; @@ -80,9 +77,6 @@ public class RecurringDepositAccount extends SavingsAccount { @OneToMany(cascade = CascadeType.ALL, mappedBy = "account", orphanRemoval = true) private List depositScheduleInstallments = new ArrayList(); - @Transient - private InterestRateChartAssembler chartAssembler; - protected RecurringDepositAccount() { // } @@ -192,9 +186,8 @@ public class RecurringDepositAccount extends SavingsAccount { } final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount(); - final ClientIncentiveAttributes incentiveAttributes = (this.client == null) ? null : this.client.incentiveAttributes(); BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate, - incentiveAttributes); + this.client); if (applyPreMaturePenalty) { applicableInterestRate = applicableInterestRate.subtract(penalInterest); @@ -941,9 +934,8 @@ public class RecurringDepositAccount extends SavingsAccount { } final BigDecimal maturityAmount = this.accountTermAndPreClosure.maturityAmount(); - final ClientIncentiveAttributes incentiveAttributes = (this.client == null) ? null : this.client.incentiveAttributes(); BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(maturityAmount, depositStartDate(), - calculateMaturityDate(), incentiveAttributes); + calculateMaturityDate(), this.client); if (applicableInterestRate.equals(BigDecimal.ZERO)) { baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode( diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java index 19dffb713..9671f2e3f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java @@ -13,14 +13,22 @@ import java.util.Collection; import java.util.List; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; 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.client.api.ClientApiConstants; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.common.service.CommonEnumerations; +import org.mifosplatform.portfolio.interestratechart.incentive.InterestIncentiveAttributeName; +import org.mifosplatform.portfolio.interestratechart.service.InterestIncentiveDropdownReadPlatformService; +import org.mifosplatform.portfolio.interestratechart.service.InterestIncentivesEnumerations; import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartDropdownReadPlatformService; import org.mifosplatform.portfolio.interestratechart.service.InterestRateChartEnumerations; +import org.mifosplatform.portfolio.savings.data.DepositAccountInterestIncentiveData; import org.mifosplatform.portfolio.savings.data.DepositAccountInterestRateChartData; import org.mifosplatform.portfolio.savings.data.DepositAccountInterestRateChartSlabData; import org.mifosplatform.portfolio.savings.exception.DepositAccountInterestRateChartNotFoundException; @@ -40,13 +48,19 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D private final DepositAccountInterestRateChartMapper chartRowMapper = new DepositAccountInterestRateChartMapper(); private final DepositAccountInterestRateChartExtractor chartExtractor = new DepositAccountInterestRateChartExtractor(); private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService; + private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService; + private final CodeValueReadPlatformService codeValueReadPlatformService; @Autowired public DepositAccountInterestRateChartReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource, - InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService) { + InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService, + final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService, + final CodeValueReadPlatformService codeValueReadPlatformService) { this.context = context; this.jdbcTemplate = new JdbcTemplate(dataSource); this.chartDropdownReadPlatformService = chartDropdownReadPlatformService; + this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService; + this.codeValueReadPlatformService = codeValueReadPlatformService; } @Override @@ -73,8 +87,23 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D @Override public DepositAccountInterestRateChartData retrieveWithTemplate(DepositAccountInterestRateChartData chartData) { + + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + return DepositAccountInterestRateChartData.withTemplate(chartData, - this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } @Override @@ -90,14 +119,28 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D @Override public DepositAccountInterestRateChartData template() { - return DepositAccountInterestRateChartData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions()); + + final List genderOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER)); + + final List clientTypeOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE)); + + final List clientClassificationOptions = new ArrayList( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION)); + return DepositAccountInterestRateChartData.template(this.chartDropdownReadPlatformService.retrievePeriodTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveEntityTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveAttributeNameOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveConditionTypeOptions(), + this.interestIncentiveDropdownReadPlatformService.retrieveIncentiveTypeOptions(), genderOptions, clientTypeOptions, + clientClassificationOptions); } private static final class DepositAccountInterestRateChartExtractor implements ResultSetExtractor> { DepositAccountInterestRateChartMapper chartMapper = new DepositAccountInterestRateChartMapper(); - DepositAccountInterestRateChartSlabsMapper chartSlabsMapper = new DepositAccountInterestRateChartSlabsMapper(); + InterestRateChartSlabExtractor chartSlabsMapper = new InterestRateChartSlabExtractor(); private final String schemaSql; @@ -114,13 +157,18 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D .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("ircd.interest_rate_for_female as ircdInterestRateForFemale, ircd.interest_rate_for_children as ircdInterestRateForChildren, ") - .append("ircd.interest_rate_for_senior_citizen as ircdInterestRateForSeniorCitizen, ") .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("sa.id as accountId, sa.account_no as accountNumber ") + .append("sa.id as accountId, sa.account_no as accountNumber, ") + .append("iri.id as iriId, ") + .append(" iri.entiry_type as entityType, iri.attribute_name as attributeName ,") + .append(" iri.condition_type as conditionType, iri.attribute_value as attributeValue, ") + .append(" iri.incentive_type as incentiveType, iri.amount as amount, ") + .append("code.code_value as attributeValueDesc ") .append("from ") .append("m_savings_account_interest_rate_chart irc left join m_savings_account_interest_rate_slab ircd on irc.id=ircd.savings_account_interest_rate_chart_id ") + .append(" left join m_savings_interest_incentives iri on iri.deposit_account_interest_rate_slab_id =ircd.id ") + .append(" left join m_code_value code on code.id = iri.attribute_value ") .append("left join m_currency curr on ircd.currency_code= curr.code ") .append("left join m_savings_account sa on irc.savings_account_id=sa.id "); @@ -135,7 +183,6 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D DepositAccountInterestRateChartData 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"); @@ -145,10 +192,9 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D interestRateChartId = tempIrcId; chartData = chartMapper.mapRow(rs, ircIndex++); chartDataList.add(chartData); - ircdIndex = 0;// reset index } - final DepositAccountInterestRateChartSlabData chartSlabsData = chartSlabsMapper.mapRow(rs, ircdIndex++); + final DepositAccountInterestRateChartSlabData chartSlabsData = chartSlabsMapper.extractData(rs); if (chartSlabsData != null) { chartData.addChartSlab(chartSlabsData); } @@ -167,6 +213,7 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D } private DepositAccountInterestRateChartMapper() { + final StringBuilder sqlBuilder = new StringBuilder(400); sqlBuilder.append("irc.id as ircId, irc.name as ircName, irc.description as ircDescription, ") @@ -186,12 +233,47 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D final Long accountId = rs.getLong("accountId"); final String accountNumber = rs.getString("accountNumber"); final Collection periodTypes = InterestRateChartEnumerations.periodType(PeriodFrequencyType.values()); + return DepositAccountInterestRateChartData.instance(id, name, description, fromDate, endDate, accountId, accountNumber, null, periodTypes); } } + private static final class InterestRateChartSlabExtractor implements ResultSetExtractor { + + DepositAccountInterestRateChartSlabsMapper chartSlabsMapper = new DepositAccountInterestRateChartSlabsMapper(); + InterestIncentiveMapper incentiveMapper = new InterestIncentiveMapper(); + + @Override + public DepositAccountInterestRateChartSlabData extractData(ResultSet rs) throws SQLException, DataAccessException { + + DepositAccountInterestRateChartSlabData chartSlabData = null; + Long interestRateChartSlabId = null; + int ircIndex = 0;// Interest rate chart index + int ircdIndex = 0;// Interest rate chart Slabs index + rs.previous(); + while (rs.next()) { + Long tempIrcdId = rs.getLong("ircdId"); + if (interestRateChartSlabId == null || interestRateChartSlabId.equals(tempIrcdId)) { + if (chartSlabData == null) { + interestRateChartSlabId = tempIrcdId; + chartSlabData = chartSlabsMapper.mapRow(rs, ircIndex++); + } + final DepositAccountInterestIncentiveData incentiveData = incentiveMapper.mapRow(rs, ircdIndex++); + if (incentiveData != null) { + chartSlabData.addIncentives(incentiveData); + } + } else { + rs.previous(); + break; + } + + } + return chartSlabData; + } + } + private static final class DepositAccountInterestRateChartSlabsMapper implements RowMapper { /* @@ -233,9 +315,6 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D final BigDecimal amountRangeFrom = rs.getBigDecimal("ircdAmountRangeFrom"); final BigDecimal amountRangeTo = rs.getBigDecimal("ircdAmountRangeTo"); final BigDecimal annualInterestRate = rs.getBigDecimal("ircdAnnualInterestRate"); - final BigDecimal interestRateForFemale = rs.getBigDecimal("ircdInterestRateForFemale"); - final BigDecimal interestRateForChildren = rs.getBigDecimal("ircdInterestRateForChildren"); - final BigDecimal interestRateForSeniorCitizen = rs.getBigDecimal("ircdInterestRateForSeniorCitizen"); // currency Slabs final String currencyCode = rs.getString("currencyCode"); @@ -249,8 +328,39 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D currencyDisplaySymbol, currencyNameCode); return DepositAccountInterestRateChartSlabData.instance(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, - amountRangeTo, annualInterestRate, interestRateForFemale, interestRateForChildren, interestRateForSeniorCitizen, - currency); + amountRangeTo, annualInterestRate, currency); + } + + } + + private static final class InterestIncentiveMapper implements RowMapper { + + @Override + public DepositAccountInterestIncentiveData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = JdbcSupport.getLongDefaultToNullIfZero(rs, "iriId"); + // If there are not Incentive are associated then in + // InterestRateChartExtractor the incentive id will be null. + if (id == null) { return null; } + + final String attributeValue = rs.getString("attributeValue"); + String attributeValueDesc = null; + final Integer entityType = JdbcSupport.getInteger(rs, "entityType"); + final EnumOptionData entityTypeData = InterestIncentivesEnumerations.entityType(entityType); + + final Integer attributeName = JdbcSupport.getInteger(rs, "attributeName"); + if (InterestIncentiveAttributeName.isCodeValueAttribute(InterestIncentiveAttributeName.fromInt(attributeName))) { + attributeValueDesc = rs.getString("attributeValueDesc"); + } + final EnumOptionData attributeNameData = InterestIncentivesEnumerations.attributeName(attributeName); + final Integer conditionType = JdbcSupport.getInteger(rs, "conditionType"); + final EnumOptionData conditionTypeData = CommonEnumerations.conditionType(conditionType, "incentive"); + final Integer incentiveType = JdbcSupport.getInteger(rs, "incentiveType"); + final EnumOptionData incentiveTypeData = InterestIncentivesEnumerations.incentiveType(incentiveType); + final BigDecimal amount = rs.getBigDecimal("amount"); + + return DepositAccountInterestIncentiveData.instance(id, entityTypeData, attributeNameData, conditionTypeData, attributeValue, + attributeValueDesc, incentiveTypeData, amount); + } }