Compare commits

...
10 Commits
30 changed files with 407 additions and 1235 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ see https://www.ohloh.net/p/mifosx for activity overview and basic code analysis
see https://github.com/keithwoodlock/mifosx/wiki/Developer-deep-dive-into-Http-API for info around resource-oriented API work
Amazon Public AMI
Amazon Public AMI (currently out-of-date and will be updated - so don't use
=================
Launch instance <a target="_blank" href="https://console.aws.amazon.com/ec2/home?region=eu-west-1#launchAmi=ami-7b0e0a0f" title="mifos platform api beta 2">ami-7b0e0a0f</a>
@@ -213,16 +213,27 @@ CREATE TABLE `portfolio_group` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`external_id` varchar(100) DEFAULT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `external_id` (`external_id`),
KEY `FKJPWG000000000003` (`createdby_id`),
KEY `FKJPWG000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPWG000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `admin_appuser` (`id`),
KEY `external_id` (`external_id`),
CONSTRAINT `FKJPWG000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_group_client` (
`group_id` bigint(20) NOT NULL,
`client_id` bigint(20) NOT NULL,
PRIMARY KEY (`group_id`,`client_id`),
KEY `client_id` (`client_id`),
CONSTRAINT `portfolio_group_client_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `portfolio_group` (`id`),
CONSTRAINT `portfolio_group_client_ibfk_2` FOREIGN KEY (`client_id`) REFERENCES `portfolio_client` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_client` (
@@ -247,7 +258,6 @@ CREATE TABLE `portfolio_client` (
CONSTRAINT `FKCE00CAB3E0DD567A` FOREIGN KEY (`office_id`) REFERENCES `org_office` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_product_loan` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`currency_code` varchar(3) NOT NULL,
@@ -284,54 +294,6 @@ CREATE TABLE `portfolio_product_loan` (
CONSTRAINT `FKAUD0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_product_savings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` varchar(500) DEFAULT NULL,
`currency_code` varchar(3) DEFAULT NULL,
`currency_digits` smallint(5) DEFAULT NULL,
`interest_rate` decimal(19,6) DEFAULT NULL,
`minimum_balance` decimal(19,6) DEFAULT NULL,
`maximum_balance` decimal(19,6) DEFAULT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKJPW0000000000003` (`createdby_id`),
KEY `FKJPW0000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPW0000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `admin_appuser` (`id`),
CONSTRAINT `FKJPW0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_product_deposit` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` varchar(500) DEFAULT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`minimum_balance` decimal(19,6) DEFAULT NULL,
`maximum_balance` decimal(19,6) DEFAULT NULL,
`tenure_months` int(11) NOT NULL,
`maturity_default_interest_rate` decimal(19,6) NOT NULL,
`maturity_min_interest_rate` decimal(19,6) NOT NULL,
`maturity_max_interest_rate` decimal(19,6) NOT NULL,
`can_renew` tinyint(1) NOT NULL DEFAULT '0',
`can_pre_close` tinyint(1) NOT NULL DEFAULT '0',
`pre_closure_interest_rate` decimal(19,6) NOT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKJPW0000000000003` (`createdby_id`),
KEY `FKJPW0000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPX0000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `admin_appuser` (`id`),
CONSTRAINT `FKJPX0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_loan` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`external_id` varchar(100) DEFAULT NULL,
@@ -429,6 +391,82 @@ CREATE TABLE `portfolio_loan_transaction` (
CONSTRAINT `FKCFCEA426FC69F3F1` FOREIGN KEY (`contra_id`) REFERENCES `portfolio_loan_transaction` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_product_savings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` varchar(500) DEFAULT NULL,
`currency_code` varchar(3) DEFAULT NULL,
`currency_digits` smallint(5) DEFAULT NULL,
`interest_rate` decimal(19,6) DEFAULT NULL,
`minimum_balance` decimal(19,6) DEFAULT NULL,
`maximum_balance` decimal(19,6) DEFAULT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKJPW0000000000003` (`createdby_id`),
KEY `FKJPW0000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPW0000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `admin_appuser` (`id`),
CONSTRAINT `FKJPW0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_product_deposit` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` varchar(500) DEFAULT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`minimum_balance` decimal(19,6) DEFAULT NULL,
`maximum_balance` decimal(19,6) DEFAULT NULL,
`tenure_months` int(11) NOT NULL,
`maturity_default_interest_rate` decimal(19,6) NOT NULL,
`maturity_min_interest_rate` decimal(19,6) NOT NULL,
`maturity_max_interest_rate` decimal(19,6) NOT NULL,
`can_renew` tinyint(1) NOT NULL DEFAULT '0',
`can_pre_close` tinyint(1) NOT NULL DEFAULT '0',
`pre_closure_interest_rate` decimal(19,6) NOT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKJPW0000000000003` (`createdby_id`),
KEY `FKJPW0000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPX0000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `admin_appuser` (`id`),
CONSTRAINT `FKJPX0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `admin_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_deposit_account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`external_id` varchar(100) DEFAULT NULL,
`client_id` bigint(20) NOT NULL,
`product_id` bigint(20) NOT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`deposit_amount` decimal(19,6) DEFAULT NULL,
`maturity_interest_rate` decimal(19,6) NOT NULL,
`tenure_months` int(11) NOT NULL,
`can_renew` tinyint(1) NOT NULL DEFAULT '0',
`can_pre_close` tinyint(1) NOT NULL DEFAULT '0',
`pre_closure_interest_rate` decimal(19,6) NOT NULL,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `deposit_acc_external_id` (`external_id`),
KEY `FKKW0000000000001` (`client_id`),
KEY `FKKW0000000000002` (`product_id`),
CONSTRAINT `FKKW0000000000001` FOREIGN KEY (`client_id`) REFERENCES `portfolio_client` (`id`),
CONSTRAINT `FKKW0000000000002` FOREIGN KEY (`product_id`) REFERENCES `portfolio_product_deposit` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `portfolio_note` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`client_id` bigint(20) NOT NULL,
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
DROP INDEX external_id ON portfolio_group;
ALTER TABLE portfolio_group ADD UNIQUE (external_id);
@@ -1,3 +1,4 @@
DROP TABLE if exists `portfolio_deposit_account`;
CREATE TABLE `portfolio_deposit_account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`external_id` varchar(100) DEFAULT NULL,
@@ -5,12 +6,9 @@ CREATE TABLE `portfolio_deposit_account` (
`product_id` bigint(20) NOT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`minimum_balance` decimal(19,6) DEFAULT NULL,
`maximum_balance` decimal(19,6) DEFAULT NULL,
`deposit_amount` decimal(19,6) DEFAULT NULL,
`maturity_interest_rate` decimal(19,6) NOT NULL,
`tenure_months` int(11) NOT NULL,
`maturity_default_interest_rate` decimal(19,6) NOT NULL,
`maturity_min_interest_rate` decimal(19,6) NOT NULL,
`maturity_max_interest_rate` decimal(19,6) NOT NULL,
`can_renew` tinyint(1) NOT NULL DEFAULT '0',
`can_pre_close` tinyint(1) NOT NULL DEFAULT '0',
`pre_closure_interest_rate` decimal(19,6) NOT NULL,
@@ -25,4 +23,5 @@ CREATE TABLE `portfolio_deposit_account` (
KEY `FKKW0000000000002` (`product_id`),
CONSTRAINT `FKKW0000000000001` FOREIGN KEY (`client_id`) REFERENCES `portfolio_client` (`id`),
CONSTRAINT `FKKW0000000000002` FOREIGN KEY (`product_id`) REFERENCES `portfolio_product_deposit` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -82,7 +82,7 @@ public class DepositAccountsApiResource {
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("createdOn", "lastModifedOn",
"id", "clientId", "clientName", "productId", "productName",
"currency", "deposit", "interestRate")
"currency", "deposit", "maturityInterestRate")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
@@ -105,7 +105,7 @@ public class DepositAccountsApiResource {
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("createdOn", "lastModifedOn",
"id", "clientId", "clientName", "productId", "productName",
"currency", "deposit", "interestRate")
"currency", "deposit", "maturityInterestRate")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
@@ -135,7 +135,7 @@ public class DepositAccountsApiResource {
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("createdOn", "lastModifedOn",
"id", "clientId", "clientName", "productId", "productName",
"currency", "deposit", "interestRate", "currencyOptions")
"currency", "deposit", "maturityInterestRate", "currencyOptions")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
@@ -75,7 +75,7 @@ public class GroupsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "externalId"));
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "externalId", "clientMembers"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo
.getQueryParameters());
@@ -27,6 +27,8 @@ import org.mifosng.platform.api.data.OfficeLookup;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.service.AppUserReadPlatformService;
import org.mifosng.platform.user.service.AppUserWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -50,6 +52,9 @@ public class UsersApiResource {
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private PlatformSecurityContext context;
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
@@ -145,7 +150,13 @@ public class UsersApiResource {
UserCommand command = this.apiDataConversionService.convertJsonToUserCommand(userId, jsonRequestBody);
this.appUserWritePlatformService.updateUser(command);
AppUser loggedInUser = context.authenticatedUser();
if (loggedInUser.hasIdOf(userId)) {
this.appUserWritePlatformService.updateUsersOwnAccountDetails(command);
} else {
this.appUserWritePlatformService.updateUser(command);
}
return Response.ok().entity(new EntityIdentifier(userId)).build();
}
@@ -16,7 +16,7 @@ public class DepositAccountCommand {
private final String currencyCode;
private final Integer digitsAfterDecimal;
private final BigDecimal depositAmount;
private final BigDecimal interestRate;
private final BigDecimal maturityInterestRate;
private final Integer termInMonths;
private final Set<String> modifiedParameters;
@@ -39,7 +39,7 @@ public class DepositAccountCommand {
this.currencyCode = currencyCode;
this.digitsAfterDecimal = digitsAfterDecimal;
this.depositAmount = depositAmount;
this.interestRate = interestRate;
this.maturityInterestRate = interestRate;
this.termInMonths = termInMonths;
this.modifiedParameters = modifiedParameters;
@@ -72,9 +72,9 @@ public class DepositAccountCommand {
public BigDecimal getDepositAmount() {
return depositAmount;
}
public BigDecimal getInterestRate() {
return interestRate;
public BigDecimal getMaturityInterestRate() {
return maturityInterestRate;
}
public Integer getTermInMonths() {
@@ -21,7 +21,7 @@ public class DepositAccountData {
private final CurrencyData currency;
private final BigDecimal deposit;
private final BigDecimal interestRate;
private final BigDecimal maturityInterestRate;
private final DateTime createdOn;
private final DateTime lastModifedOn;
@@ -38,7 +38,7 @@ public class DepositAccountData {
this.productName = null;
this.currency = null;
this.deposit = null;
this.interestRate = null;
this.maturityInterestRate = null;
this.currencyOptions = new ArrayList<CurrencyData>();
}
@@ -52,7 +52,7 @@ public class DepositAccountData {
this.productName = account.getProductName();
this.currency = account.getCurrency();
this.deposit = account.getDeposit();
this.interestRate = account.getInterestRate();
this.maturityInterestRate = account.getMaturityInterestRate();
this.currencyOptions = currencies;
}
@@ -75,7 +75,7 @@ public class DepositAccountData {
this.productName = productName;
this.currency = currency;
this.deposit = deposit;
this.interestRate=interestRate;
this.maturityInterestRate=interestRate;
this.currencyOptions = new ArrayList<CurrencyData>();
}
@@ -107,8 +107,8 @@ public class DepositAccountData {
return deposit;
}
public BigDecimal getInterestRate() {
return interestRate;
public BigDecimal getMaturityInterestRate() {
return maturityInterestRate;
}
public DateTime getCreatedOn() {
@@ -14,13 +14,8 @@ public class DepositProductData implements Serializable {
private String description;
private String currencyCode;
private Integer digitsAfterDecimal;
private BigDecimal minimumBalance = BigDecimal.ZERO;
private BigDecimal maximumBalance = BigDecimal.ZERO;
private DateTime createdOn;
private DateTime lastModifedOn;
private Integer tenureMonths;
private BigDecimal maturityDefaultInterestRate = BigDecimal.ZERO;
private BigDecimal maturityMinInterestRate = BigDecimal.ZERO;
@@ -28,11 +23,13 @@ public class DepositProductData implements Serializable {
private Boolean canRenew;
private Boolean canPreClose;
private BigDecimal preClosureInterestRate = BigDecimal.ZERO;
private DateTime createdOn;
private DateTime lastModifedOn;
private List<CurrencyData> currencyOptions = new ArrayList<CurrencyData>();
public DepositProductData() {
// TODO Auto-generated constructor stub
//
}
public DepositProductData(DateTime createdOn, DateTime lastModifedOn, Long id,String name, String description, String currencyCode, Integer digitsAfterDecimal,BigDecimal minimumBalance,BigDecimal maximumBalance,
@@ -1493,7 +1493,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("clientId", "productId", "externalId", "currencyCode", "digitsAfterDecimal", "depositAmount", "interestRate", "termInMonths", "locale")
Arrays.asList("clientId", "productId", "externalId", "currencyCode", "digitsAfterDecimal", "depositAmount", "maturityInterestRate", "termInMonths", "locale")
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
@@ -1504,7 +1504,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
String currencyCode=extractStringParameter("currencyCode", requestMap,modifiedParameters);
Integer digitsAfterDecimalValue = extractIntegerParameter("digitsAfterDecimal", requestMap, modifiedParameters);
BigDecimal depositAmount=extractBigDecimalParameter("depositAmount", requestMap, modifiedParameters);
BigDecimal interestRate = extractBigDecimalParameter("interestRate", requestMap, modifiedParameters);
BigDecimal interestRate = extractBigDecimalParameter("maturityInterestRate", requestMap, modifiedParameters);
Integer termInMonths = extractIntegerParameter("termInMonths", requestMap, modifiedParameters);
// isRenewable, isPreClosureAllowed, expectedDepositDate, pojectMaturityDate, projectedInterestAccrued
@@ -1636,7 +1636,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Set<String> supportedParameters = new HashSet<String>(
Arrays.asList("createdOn", "lastModifedOn",
"id", "clientId", "clientName", "productId", "productName",
"currency", "deposit", "interestRate", "currencyOptions")
"currency", "deposit", "maturityInterestRate", "currencyOptions")
);
final Set<String> parameterNamesToSkip = new HashSet<String>();
@@ -27,7 +27,7 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
private boolean deleted = false;
@Embedded
DepositProductRelatedDetail depositProductRelatedDetail;
private DepositProductRelatedDetail depositProductRelatedDetail;
protected DepositProduct(){
this.name = null;
@@ -115,4 +115,8 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
this.depositProductRelatedDetail.update(command);
}
public void validateInterestRateInRange(final BigDecimal interestRate) {
this.depositProductRelatedDetail.validateInterestRateInRange(interestRate);
}
}
@@ -8,6 +8,7 @@ import javax.persistence.Embedded;
import org.mifosng.platform.api.commands.DepositProductCommand;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.exceptions.InterestRateOutsideRangeException;
@Embeddable
public class DepositProductRelatedDetail {
@@ -165,4 +166,18 @@ import org.mifosng.platform.currency.domain.MonetaryCurrency;
}
}
public void validateInterestRateInRange(final BigDecimal interestRate) {
boolean inRange = true;
if (interestRate.compareTo(this.maturityMinInterestRate) < 0) {
inRange = false;
}
if (this.maturityMaxInterestRate.compareTo(interestRate) < 0) {
inRange = false;
}
if (!inRange) {
throw new InterestRateOutsideRangeException(interestRate, this.maturityMinInterestRate, this.maturityMaxInterestRate);
}
}
}
@@ -20,27 +20,21 @@ public class DepositProductCommandValidator {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product");
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.product");
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(500);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).notNull();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("canRenew").value(command.getCanRenew()).notNull();
baseDataValidator.reset().parameter("canPreClose").value(command.getCanPreClose()).notNull();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).notNull();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance());
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(command.getMaturityMinInterestRate(), command.getMaturityMaxInterestRate());
@@ -48,8 +42,6 @@ public class DepositProductCommandValidator {
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(command.getMaturityMinInterestRate(), command.getMaturityDefaultInterestRate());
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(command.getPreClosureInterestRate(), command.getMaturityMinInterestRate());
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
@@ -59,29 +51,23 @@ public class DepositProductCommandValidator {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("savingsproduct");
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.product");
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).notNull();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).notNull();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("canRenew").value(command.getCanRenew()).notNull();
baseDataValidator.reset().parameter("canPreClose").value(command.getCanPreClose()).notNull();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).notNull();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("canRenew").value(command.getCanRenew()).ignoreIfNull();
baseDataValidator.reset().parameter("canPreClose").value(command.getCanPreClose()).ignoreIfNull();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance());
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(command.getMaturityMinInterestRate(), command.getMaturityMaxInterestRate());
@@ -95,5 +81,4 @@ public class DepositProductCommandValidator {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
}
@@ -0,0 +1,14 @@
package org.mifosng.platform.exceptions;
import java.math.BigDecimal;
/**
* Exception thrown when an attempt is made update the parent of a root office.
*/
public class InterestRateOutsideRangeException extends AbstractPlatformDomainRuleException {
public InterestRateOutsideRangeException(final BigDecimal interestRate, final BigDecimal rangeMin, final BigDecimal rangeMax) {
super("error.msg.deposit.account.maturityInterestRate.outside.of.allowed.range", "Interest rate of " + interestRate.toPlainString() + " is outside of allowed range of ["
+ rangeMin.toPlainString() + ", " + rangeMax.toPlainString() + "].", interestRate, rangeMin, rangeMax);
}
}
@@ -9,10 +9,14 @@ import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.GroupNotFoundException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.group.domain.Group;
import org.mifosng.platform.group.domain.GroupRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
@@ -20,6 +24,8 @@ import org.springframework.util.ObjectUtils;
@Service
public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(GroupWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final GroupRepository groupRepository;
@@ -37,42 +43,51 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
@Transactional
@Override
public EntityIdentifier createGroup(GroupCommand command) {
try {
this.context.authenticatedUser();
this.context.authenticatedUser();
GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForCreate();
GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForCreate();
final Set<Client> clientMembers = assembleSetOfClients(command);
final Set<Client> clientMembers = assembleSetOfClients(command);
Group newGroup = Group.newGroup(command.getName(), command.getExternalId(), clientMembers);
Group newGroup = Group.newGroup(command.getName(), command.getExternalId(), clientMembers);
this.groupRepository.saveAndFlush(newGroup);
this.groupRepository.save(newGroup);
return new EntityIdentifier(newGroup.getId());
return new EntityIdentifier(newGroup.getId());
} catch (DataIntegrityViolationException dve) {
handleGroupDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));
}
}
@Transactional
@Override
public EntityIdentifier updateGroup(GroupCommand command) {
context.authenticatedUser();
try {
context.authenticatedUser();
GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForUpdate();
GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForUpdate();
Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) {
throw new GroupNotFoundException(command.getId());
Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) {
throw new GroupNotFoundException(command.getId());
}
final Set<Client> clientMembers = assembleSetOfClients(command);
groupForUpdate.update(command, clientMembers);
groupRepository.saveAndFlush(groupForUpdate);
return new EntityIdentifier(groupForUpdate.getId());
} catch (DataIntegrityViolationException dve) {
handleGroupDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));
}
final Set<Client> clientMembers = assembleSetOfClients(command);
groupForUpdate.update(command, clientMembers);
groupRepository.save(groupForUpdate);
return new EntityIdentifier(groupForUpdate.getId());
}
@Transactional
@@ -100,7 +115,7 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
for (String clientId : clientMembersArray) {
Long id = Long.valueOf(clientId);
Client client = this.clientRepository.findOne(id);
if (client == null) {
if (client == null || client.isDeleted()) {
throw new ClientNotFoundException(id);
}
clientMembers.add(client);
@@ -110,4 +125,19 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
return clientMembers;
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue is.
*/
private void handleGroupDataIntegrityIssues(final GroupCommand command, DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("external_id")) {
throw new PlatformDataIntegrityException("error.msg.group.duplicate.externalId", "Group with externalId {0} already exists", "externalId", command.getExternalId());
} else if (realCause.getMessage().contains("name")) {
throw new PlatformDataIntegrityException("error.msg.group.duplicate.name", "Group with name {0} already exists", "name", command.getName());
}
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.group.unknown.data.integrity.issue", "Unknown data integrity issue with resource.");
}
}
@@ -14,6 +14,7 @@ import org.mifosng.platform.api.commands.DepositAccountCommand;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.deposit.domain.DepositProduct;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.user.domain.AppUser;
@@ -25,9 +26,9 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@JoinColumn(name = "client_id", nullable = false)
private Client client;
// @ManyToOne
// @JoinColumn(name = "product_id")
// private final DepositAccountProduct depositAccountProduct;
@ManyToOne
@JoinColumn(name = "product_id")
private final DepositProduct product;
@Column(name = "external_id")
private String externalId;
@@ -57,15 +58,19 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
private boolean deleted = false;
protected DepositAccount() {
//
this.product = null;
}
public DepositAccount(final Client client, final String externalId, final Money deposit, final BigDecimal interestRate, final Integer termInMonths) {
public DepositAccount(
final Client client, final DepositProduct product,
final String externalId, final Money deposit, final BigDecimal interestRate, final Integer termInMonths) {
this.client = client;
this.product = product;
this.externalId = externalId;
this.currency = deposit.getCurrency();
this.depositAmount = deposit.getAmount();
this.interestRate = interestRate;
product.validateInterestRateInRange(interestRate);
this.tenureInMonths = termInMonths;
this.preClosureInterestRate = BigDecimal.ZERO;
}
@@ -5,7 +5,10 @@ import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.deposit.domain.DepositProduct;
import org.mifosng.platform.deposit.domain.DepositProductRepository;
import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.DepositProductNotFoundException;
import org.mifosng.platform.saving.domain.DepositAccount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -17,10 +20,12 @@ import org.springframework.stereotype.Service;
public class DepositAccountAssembler {
private final ClientRepository clientRepository;
private final DepositProductRepository depositProductRepository;
@Autowired
public DepositAccountAssembler(final ClientRepository clientRepository) {
public DepositAccountAssembler(final ClientRepository clientRepository, final DepositProductRepository depositProductRepository) {
this.clientRepository = clientRepository;
this.depositProductRepository = depositProductRepository;
}
public DepositAccount assembleFrom(final DepositAccountCommand command) {
@@ -28,11 +33,16 @@ public class DepositAccountAssembler {
Client client = this.clientRepository.findOne(command.getClientId());
if (client == null || client.isDeleted()) {
throw new ClientNotFoundException(command.getClientId());
}
DepositProduct product = this.depositProductRepository.findOne(command.getProductId());
if (product == null || product.isDeleted()) {
throw new DepositProductNotFoundException(command.getProductId());
}
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
Money deposit = Money.of(currency, command.getDepositAmount());
return new DepositAccount(client, command.getExternalId(), deposit, command.getInterestRate(), command.getTermInMonths());
return new DepositAccount(client, product, command.getExternalId(), deposit, command.getMaturityInterestRate(), command.getTermInMonths());
}
}
@@ -30,13 +30,13 @@ public class DepositAccountCommandValidator {
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("depositAmount").value(command.getDepositAmount()).ignoreIfNull().notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).ignoreIfNull().notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("termInMonths").value(command.getTermInMonths()).ignoreIfNull().notNull().integerGreaterThanZero();
baseDataValidator.reset().anyOfNotNull(
command.getClientId(), command.getProductId(), command.getExternalId(),
command.getCurrencyCode(),command.getDigitsAfterDecimal(),
command.getDepositAmount(), command.getInterestRate(),command.getTermInMonths());
command.getCurrencyCode(), command.getDigitsAfterDecimal(),
command.getDepositAmount(), command.getMaturityInterestRate(), command.getTermInMonths());
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
@@ -56,7 +56,7 @@ public class DepositAccountCommandValidator {
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("depositAmount").value(command.getDepositAmount()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("termInMonths").value(command.getTermInMonths()).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) {
@@ -75,9 +75,12 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
+ " da.deposit_amount as depositAmount, "
+ " da.maturity_interest_rate as interestRate, "
+ " da.created_date as createdon, da.lastmodified_date as modifiedon, "
+ " c.firstname as firstname, c.lastname as lastname, "
+ " c.firstname as firstname, c.lastname as lastname, pd.name as productName,"
+ " curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol"
+ " from portfolio_deposit_account da join ref_currency curr on curr.code = da.currency_code join portfolio_client c on c.id = da.client_id";
+ " from portfolio_deposit_account da "
+ " join ref_currency curr on curr.code = da.currency_code "
+ " join portfolio_client c on c.id = da.client_id "
+ " join portfolio_product_deposit pd on pd.id = da.product_id";
}
@Override
@@ -88,7 +91,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
Long clientId = rs.getLong("clientId");
String clientName = rs.getString("firstname") + " " + rs.getString("lastname");
Long productId = rs.getLong("productId");
String productName = "";
String productName = rs.getString("productName");
String currencyCode = rs.getString("currencyCode");
String currencyName = rs.getString("currencyName");
@@ -272,4 +272,8 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
return match;
}
public boolean hasIdOf(final Long userId) {
return getId().equals(userId);
}
}
@@ -13,4 +13,7 @@ public interface AppUserWritePlatformService {
@PreAuthorize(value = "hasRole('USER_ADMINISTRATION_SUPER_USER_ROLE')")
void deleteUser(final Long userId);
// we dont put any permissions on this e.g. a user with no admin rights can change their own details (email, username, password etc).
void updateUsersOwnAccountDetails(UserCommand command);
}
@@ -145,6 +145,12 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
}
}
@Transactional
@Override
public void updateUsersOwnAccountDetails(final UserCommand command) {
updateUser(command);
}
private Set<Role> assembleSetOfRoles(final UserCommand command) {
final Set<Role> allRoles = new HashSet<Role>();