wip:changes for client fees
This commit is contained in:
+7
-2
@@ -9,6 +9,7 @@ import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
@@ -54,8 +55,12 @@ public class OrganisationCurrency extends AbstractPersistable<Long> {
|
||||
this.nameCode = nameCode;
|
||||
this.displaySymbol = displaySymbol;
|
||||
}
|
||||
|
||||
|
||||
public final String getCode() {
|
||||
return code;
|
||||
return code;
|
||||
}
|
||||
|
||||
public final MonetaryCurrency toMonetaryCurrency() {
|
||||
return new MonetaryCurrency(this.code, this.decimalPlaces, this.inMultiplesOf);
|
||||
}
|
||||
}
|
||||
-1
@@ -121,7 +121,6 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
|
||||
}
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
|
||||
this.chargeRepository.save(chargeForUpdate);
|
||||
}
|
||||
|
||||
|
||||
+28
-2
@@ -5,11 +5,16 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.api;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
|
||||
public class ClientApiConstants {
|
||||
|
||||
@@ -74,6 +79,14 @@ public class ClientApiConstants {
|
||||
public static final String clientTypeParamName = "clientType";
|
||||
public static final String clientClassificationIdParamName = "clientClassificationId";
|
||||
public static final String clientClassificationParamName = "clientClassification";
|
||||
// request parameters for payment details
|
||||
public static final String paymentTypeIdParamName = "paymentTypeId";
|
||||
public static final String transactionAccountNumberParamName = "accountNumber";
|
||||
public static final String checkNumberParamName = "checkNumber";
|
||||
public static final String routingCodeParamName = "routingCode";
|
||||
public static final String receiptNumberParamName = "receiptNumber";
|
||||
public static final String bankNumberParamName = "bankNumber";
|
||||
|
||||
// response parameters
|
||||
public static final String statusParamName = "status";
|
||||
public static final String hierarchyParamName = "hierarchy";
|
||||
@@ -107,6 +120,14 @@ public class ClientApiConstants {
|
||||
public static final String amountPaidParamName = "amountPaid";
|
||||
public static final String chargeOptionsParamName = "chargeOptions";
|
||||
|
||||
// client transactions response parameters
|
||||
public static final String transactionAmountParamName = "transactionAmount";
|
||||
public static final String paymentDetailDataParamName = "paymentDetailData";
|
||||
public static final String reversedParamName = "reversed";
|
||||
public static final String dateParamName = "date";
|
||||
private static final String transactionTypeParamName = "type";
|
||||
private static final String transactionCurrencyParamName = "currency";
|
||||
|
||||
// associations related part of response
|
||||
public static final String groupsParamName = "groups";
|
||||
|
||||
@@ -160,7 +181,12 @@ public class ClientApiConstants {
|
||||
public static final Set<String> CLIENT_CHARGES_ADD_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(chargeIdParamName, amountParamName, dueAsOfDateParamName, dateFormatParamName, localeParamName));
|
||||
|
||||
public static final Set<String> CLIENT_CHARGES_PAY_CHARGE_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(amountParamName, transactionDateParamName, dateFormatParamName, localeParamName));
|
||||
public static final Set<String> CLIENT_CHARGES_PAY_CHARGE_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(amountParamName,
|
||||
transactionDateParamName, dateFormatParamName, localeParamName, paymentTypeIdParamName, transactionAccountNumberParamName,
|
||||
checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
|
||||
|
||||
public static final Set<String> CLIENT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName,
|
||||
transactionAmountParamName, paymentDetailDataParamName, reversedParamName, dateParamName, officeIdParamName,
|
||||
officeNameParamName, transactionTypeParamName, transactionCurrencyParamName, externalIdParamName, submittedOnDateParamName));
|
||||
|
||||
}
|
||||
+2
@@ -28,6 +28,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.client.data.ClientChargeData;
|
||||
import org.mifosplatform.portfolio.client.service.ClientChargeReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/clients/{clientId}/charges")
|
||||
@@ -41,6 +42,7 @@ public class ClientChargesApiResource {
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ClientChargesApiResource(final PlatformSecurityContext context, final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final ClientChargeReadPlatformService clientChargeReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<ClientChargeData> toApiJsonSerializer,
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package org.mifosplatform.portfolio.client.api;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
public class ClientPaymentsApiResource {
|
||||
|
||||
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package org.mifosplatform.portfolio.client.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.mifosplatform.portfolio.client.service.ClientTransactionReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/clients/{clientId}/transactions")
|
||||
@Component
|
||||
public class ClientTransactionsApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ClientTransactionReadPlatformService clientTransactionReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<ClientTransactionData> toApiJsonSerializer;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ClientTransactionsApiResource(final PlatformSecurityContext context,
|
||||
final ClientTransactionReadPlatformService clientTransactionReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<ClientTransactionData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.clientTransactionReadPlatformService = clientTransactionReadPlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllClientTransactions(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
|
||||
final Collection<ClientTransactionData> clientTransactions = this.clientTransactionReadPlatformService
|
||||
.retrieveAllTransactions(clientId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clientTransactions,
|
||||
ClientApiConstants.CLIENT_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveClientTransaction(@PathParam("clientId") final Long clientId,
|
||||
@PathParam("transactionId") final Long transactionId, @Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
|
||||
final ClientTransactionData clientTransaction = this.clientTransactionReadPlatformService.retrieveTransaction(clientId,
|
||||
transactionId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clientTransaction,
|
||||
ClientApiConstants.CLIENT_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.mifosplatform.portfolio.client.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
import org.mifosplatform.portfolio.paymenttype.data.PaymentTypeData;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ClientTransactionData {
|
||||
|
||||
private final Long id;
|
||||
private final Long officeId;
|
||||
private final String officeName;
|
||||
private final EnumOptionData type;
|
||||
private final LocalDate date;
|
||||
private final CurrencyData currency;
|
||||
private final PaymentDetailData paymentDetailData;
|
||||
private final BigDecimal amount;
|
||||
private final String externalId;
|
||||
private final LocalDate submittedOnDate;
|
||||
private final boolean reversed;
|
||||
|
||||
// templates
|
||||
final Collection<PaymentTypeData> paymentTypeOptions;
|
||||
|
||||
public static ClientTransactionData create(Long id, Long officeId, String officeName, EnumOptionData type, LocalDate date,
|
||||
CurrencyData currency, PaymentDetailData paymentDetailData, BigDecimal amount, String externalId, LocalDate submittedOnDate,
|
||||
boolean reversed) {
|
||||
final Collection<PaymentTypeData> paymentTypeOptions = null;
|
||||
return new ClientTransactionData(id, officeId, officeName, type, date, currency, paymentDetailData, amount, externalId,
|
||||
submittedOnDate, reversed, paymentTypeOptions);
|
||||
}
|
||||
|
||||
private ClientTransactionData(Long id, Long officeId, String officeName, EnumOptionData type, LocalDate date, CurrencyData currency,
|
||||
PaymentDetailData paymentDetailData, BigDecimal amount, String externalId, LocalDate submittedOnDate, boolean reversed,
|
||||
Collection<PaymentTypeData> paymentTypeOptions) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.type = type;
|
||||
this.date = date;
|
||||
this.currency = currency;
|
||||
this.paymentDetailData = paymentDetailData;
|
||||
this.amount = amount;
|
||||
this.externalId = externalId;
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
this.reversed = reversed;
|
||||
this.paymentTypeOptions = paymentTypeOptions;
|
||||
}
|
||||
|
||||
}
|
||||
+74
-21
@@ -1,7 +1,12 @@
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
|
||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@@ -12,11 +17,21 @@ import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.office.domain.OrganisationCurrency;
|
||||
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||
import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType;
|
||||
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
|
||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountCharge;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@@ -72,6 +87,8 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
@Column(name = "inactivated_on_date")
|
||||
private Date inactivationDate;
|
||||
|
||||
private OrganisationCurrency currency;
|
||||
|
||||
public static ClientCharge createNew(final Client client, final Charge charge, final JsonCommand command) {
|
||||
BigDecimal amount = command.bigDecimalValueOfParameterNamed(ClientApiConstants.amountParamName);
|
||||
final LocalDate dueDate = command.localDateValueOfParameterNamed(ClientApiConstants.dueAsOfDateParamName);
|
||||
@@ -101,6 +118,17 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Money pay(final MonetaryCurrency currency, final Money amountPaid) {
|
||||
Money amountPaidToDate = Money.of(currency, this.amountPaid);
|
||||
Money amountOutstanding = Money.of(currency, this.amountOutstanding);
|
||||
amountPaidToDate = amountPaidToDate.plus(amountPaid);
|
||||
amountOutstanding = amountOutstanding.minus(amountPaid);
|
||||
this.amountPaid = amountPaidToDate.getAmount();
|
||||
this.amountOutstanding = amountOutstanding.getAmount();
|
||||
this.paid = determineIfFullyPaid();
|
||||
return Money.of(currency, this.amountOutstanding);
|
||||
}
|
||||
|
||||
private void populateDerivedFields(final BigDecimal amount) {
|
||||
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
|
||||
case INVALID:
|
||||
@@ -152,6 +180,14 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
return this.amount.subtract(totalAccountedFor);
|
||||
}
|
||||
|
||||
public LocalDate getDueLocalDate() {
|
||||
LocalDate dueDate = null;
|
||||
if (this.dueDate != null) {
|
||||
dueDate = new LocalDate(this.dueDate);
|
||||
}
|
||||
return dueDate;
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return this.client;
|
||||
}
|
||||
@@ -172,26 +208,6 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
return this.chargeCalculation;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public BigDecimal getAmountPaid() {
|
||||
return this.amountPaid;
|
||||
}
|
||||
|
||||
public BigDecimal getAmountWaived() {
|
||||
return this.amountWaived;
|
||||
}
|
||||
|
||||
public BigDecimal getAmountWrittenOff() {
|
||||
return this.amountWrittenOff;
|
||||
}
|
||||
|
||||
public BigDecimal getAmountOutstanding() {
|
||||
return this.amountOutstanding;
|
||||
}
|
||||
|
||||
public boolean isPenaltyCharge() {
|
||||
return this.penaltyCharge;
|
||||
}
|
||||
@@ -204,10 +220,14 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
return this.waived;
|
||||
}
|
||||
|
||||
public boolean isStatus() {
|
||||
public boolean isActive() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public boolean isNotActive() {
|
||||
return !this.status;
|
||||
}
|
||||
|
||||
public Date getInactivationDate() {
|
||||
return this.inactivationDate;
|
||||
}
|
||||
@@ -220,4 +240,37 @@ public class ClientCharge extends AbstractPersistable<Long> {
|
||||
return this.client.getOffice().getId();
|
||||
}
|
||||
|
||||
public void setCurrency(OrganisationCurrency currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.currency.toMonetaryCurrency();
|
||||
}
|
||||
|
||||
public boolean isPaidOrPartiallyPaid(final MonetaryCurrency currency) {
|
||||
final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency));
|
||||
return Money.of(currency, this.amountPaid).plus(amountWaivedOrWrittenOff).isGreaterThanZero();
|
||||
}
|
||||
|
||||
public Money getAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amount);
|
||||
}
|
||||
|
||||
public Money getAmountPaid(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountPaid);
|
||||
}
|
||||
|
||||
public Money getAmountWaived(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountWaived);
|
||||
}
|
||||
|
||||
public Money getAmountWrittenOff(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountWrittenOff);
|
||||
}
|
||||
|
||||
public Money getAmountOutstanding(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountOutstanding);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -29,6 +29,11 @@ public class ClientChargePaidBy extends AbstractPersistable<Long> {
|
||||
|
||||
}
|
||||
|
||||
public static ClientChargePaidBy instance(final ClientTransaction clientTransaction, final ClientCharge clientCharge,
|
||||
final BigDecimal amount) {
|
||||
return new ClientChargePaidBy(clientTransaction, clientCharge, amount);
|
||||
}
|
||||
|
||||
public ClientChargePaidBy(final ClientTransaction clientTransaction, final ClientCharge clientCharge, final BigDecimal amount) {
|
||||
this.clientTransaction = clientTransaction;
|
||||
this.clientCharge = clientCharge;
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.mifosplatform.organisation.office.domain.OrganisationCurrencyRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class ClientChargeRepositoryWrapper {
|
||||
|
||||
private final ClientChargeRepository repository;
|
||||
private final OrganisationCurrencyRepositoryWrapper organisationCurrencyRepository;
|
||||
|
||||
@Autowired
|
||||
public ClientChargeRepositoryWrapper(final ClientChargeRepository repository,
|
||||
final OrganisationCurrencyRepositoryWrapper organisationCurrencyRepositoryWrapper) {
|
||||
this.repository = repository;
|
||||
this.organisationCurrencyRepository = organisationCurrencyRepositoryWrapper;
|
||||
}
|
||||
|
||||
public ClientCharge findOneWithNotFoundDetection(final Long id) {
|
||||
final ClientCharge clientCharge = this.repository.findOne(id);
|
||||
if (clientCharge == null) { throw new ChargeNotFoundException(id); }
|
||||
// enrich Client charge with details of Organizational currency
|
||||
clientCharge.setCurrency(organisationCurrencyRepository.findOneWithNotFoundDetection(clientCharge.getCharge().getCurrencyCode()));
|
||||
return clientCharge;
|
||||
}
|
||||
|
||||
public void save(final ClientCharge clientCharge) {
|
||||
this.repository.save(clientCharge);
|
||||
}
|
||||
|
||||
public void saveAndFlush(final ClientCharge clientCharge) {
|
||||
this.repository.saveAndFlush(clientCharge);
|
||||
}
|
||||
|
||||
public void delete(final ClientCharge clientCharge) {
|
||||
this.repository.delete(clientCharge);
|
||||
}
|
||||
|
||||
}
|
||||
+25
-1
@@ -5,6 +5,10 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public class ClientEnumerations {
|
||||
@@ -33,7 +37,8 @@ public class ClientEnumerations {
|
||||
optionData = new EnumOptionData(ClientStatus.REJECTED.getValue().longValue(), ClientStatus.REJECTED.getCode(), "Rejected");
|
||||
break;
|
||||
case WITHDRAWN:
|
||||
optionData = new EnumOptionData(ClientStatus.WITHDRAWN.getValue().longValue(), ClientStatus.WITHDRAWN.getCode(), "Withdrawn");
|
||||
optionData = new EnumOptionData(ClientStatus.WITHDRAWN.getValue().longValue(), ClientStatus.WITHDRAWN.getCode(),
|
||||
"Withdrawn");
|
||||
break;
|
||||
case TRANSFER_IN_PROGRESS:
|
||||
optionData = new EnumOptionData(ClientStatus.TRANSFER_IN_PROGRESS.getValue().longValue(),
|
||||
@@ -49,4 +54,23 @@ public class ClientEnumerations {
|
||||
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static EnumOptionData clientTransactionType(final int id) {
|
||||
return clientTransactionType(ClientTransactionType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData clientTransactionType(final ClientTransactionType clientTransactionType) {
|
||||
final EnumOptionData optionData = new EnumOptionData(clientTransactionType.getValue().longValue(), clientTransactionType.getCode(),
|
||||
clientTransactionType.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static List<EnumOptionData> clientTransactionType(final ClientTransactionType[] clientTransactionTypes) {
|
||||
final List<EnumOptionData> optionDatas = new ArrayList<>();
|
||||
for (final ClientTransactionType clientTransaction : clientTransactionTypes) {
|
||||
optionDatas.add(clientTransactionType(clientTransaction));
|
||||
}
|
||||
return optionDatas;
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -42,4 +43,10 @@ public class ClientRepositoryWrapper {
|
||||
public void delete(final Client client) {
|
||||
this.repository.delete(client);
|
||||
}
|
||||
|
||||
public Client getActiveClient(Long clientId) {
|
||||
final Client client = this.findOneWithNotFoundDetection(clientId);
|
||||
if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); }
|
||||
return client;
|
||||
}
|
||||
}
|
||||
+50
-12
@@ -18,9 +18,10 @@ import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargePaidBy;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
@@ -41,16 +42,15 @@ public class ClientTransaction extends AbstractPersistable<Long> {
|
||||
@JoinColumn(name = "payment_detail_id", nullable = true)
|
||||
private PaymentDetail paymentDetail;
|
||||
|
||||
@Column(name = "currency_code", length = 3)
|
||||
private String currencyCode;
|
||||
|
||||
@Column(name = "transaction_type_enum", nullable = false)
|
||||
private final Integer typeOf;
|
||||
private Integer typeOf;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "transaction_date", nullable = false)
|
||||
private final Date dateOf;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "submitted_on_date", nullable = false)
|
||||
private final Date submittedOnDate;
|
||||
private Date dateOf;
|
||||
|
||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal amount;
|
||||
@@ -63,13 +63,51 @@ public class ClientTransaction extends AbstractPersistable<Long> {
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private final Date createdDate;
|
||||
private Date createdDate;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "appuser_id", nullable = true)
|
||||
private final AppUser appUser;
|
||||
private AppUser appUser;
|
||||
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true)
|
||||
private Set<LoanChargePaidBy> loanChargesPaid = new HashSet<>();
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction", orphanRemoval = true)
|
||||
private Set<ClientChargePaidBy> clientChargePaidByCollection = new HashSet<>();
|
||||
|
||||
public static ClientTransaction payCharge(final Client client, final Office office, PaymentDetail paymentDetail, final LocalDate date,
|
||||
final Money amount, final String currencyCode, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final String externalId = null;
|
||||
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.PAY_CHARGE.getValue(), date, amount, isReversed,
|
||||
externalId, DateUtils.getDateOfTenant(), currencyCode, appUser);
|
||||
}
|
||||
|
||||
public static ClientTransaction waiver(final Client client, final Office office, final LocalDate date, final Money amount,
|
||||
final String currencyCode, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final String externalId = null;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.PAY_CHARGE.getValue(), date, amount, isReversed,
|
||||
externalId, DateUtils.getDateOfTenant(), currencyCode, appUser);
|
||||
}
|
||||
|
||||
public ClientTransaction(Client client, Office office, PaymentDetail paymentDetail, Integer typeOf, LocalDate transactionLocalDate,
|
||||
Money amount, boolean reversed, String externalId, Date createdDate, String currencyCode, AppUser appUser) {
|
||||
super();
|
||||
this.client = client;
|
||||
this.office = office;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.typeOf = typeOf;
|
||||
this.dateOf = transactionLocalDate.toDate();
|
||||
this.amount = amount.getAmount();
|
||||
this.reversed = reversed;
|
||||
this.externalId = externalId;
|
||||
this.createdDate = createdDate;
|
||||
this.currencyCode = currencyCode;
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
public Set<ClientChargePaidBy> getClientChargePaidByCollection() {
|
||||
return this.clientChargePaidByCollection;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface ClientTransactionRepository extends JpaRepository<ClientTransaction, Long>, JpaSpecificationExecutor<ClientTransaction> {
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ClientTransactionType {
|
||||
|
||||
PAY_CHARGE(1, "clientTransactionType.payCharge"), //
|
||||
WAIVE_CHARGE(2, "clientTransactionType.waiveCharge");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private ClientTransactionType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
private static final Map<Integer, ClientTransactionType> intToEnumMap = new HashMap<>();
|
||||
private static int minValue;
|
||||
private static int maxValue;
|
||||
|
||||
static {
|
||||
int i = 0;
|
||||
for (final ClientTransactionType type : ClientTransactionType.values()) {
|
||||
if (i == 0) {
|
||||
minValue = type.value;
|
||||
}
|
||||
intToEnumMap.put(type.value, type);
|
||||
if (minValue >= type.value) {
|
||||
minValue = type.value;
|
||||
}
|
||||
if (maxValue < type.value) {
|
||||
maxValue = type.value;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static ClientTransactionType fromInt(final int i) {
|
||||
final ClientTransactionType type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
public static int getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
public static int getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -17,6 +17,7 @@ import org.mifosplatform.portfolio.charge.service.ChargeEnumerations;
|
||||
import org.mifosplatform.portfolio.client.data.ClientChargeData;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientChargeNotFoundException;
|
||||
import org.mifosplatform.portfolio.common.service.DropdownReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -30,6 +31,7 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
|
||||
private final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService;
|
||||
private final DropdownReadPlatformService dropdownReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public ClientChargeReadPlatformServiceImpl(final PlatformSecurityContext context,
|
||||
final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService, final RoutingDataSource dataSource,
|
||||
final DropdownReadPlatformService dropdownReadPlatformService) {
|
||||
|
||||
+172
-41
@@ -1,9 +1,13 @@
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
@@ -13,9 +17,10 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepository;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
@@ -23,13 +28,14 @@ import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
import org.mifosplatform.portfolio.client.data.ClientChargeDataValidator;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientCharge;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientChargeRepository;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientChargePaidBy;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientChargeRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountCharge;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientTransaction;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientTransactionRepository;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -43,14 +49,17 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final HolidayRepositoryWrapper holidayRepository;
|
||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
||||
private final ClientChargeRepository clientChargeRepository;
|
||||
private final ClientChargeRepositoryWrapper clientChargeRepository;
|
||||
private final ClientTransactionRepository clientTransactionRepository;
|
||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ClientChargeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final ChargeRepositoryWrapper chargeRepository, final ClientChargeDataValidator clientChargeDataValidator,
|
||||
final ClientRepositoryWrapper clientRepository, final HolidayRepositoryWrapper holidayRepositoryWrapper,
|
||||
final ConfigurationDomainService configurationDomainService, final ClientChargeRepository clientChargeRepository,
|
||||
final WorkingDaysRepositoryWrapper workingDaysRepository) {
|
||||
final ConfigurationDomainService configurationDomainService, final ClientChargeRepositoryWrapper clientChargeRepository,
|
||||
final WorkingDaysRepositoryWrapper workingDaysRepository, final ClientTransactionRepository clientTransactionRepository,
|
||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService) {
|
||||
this.context = context;
|
||||
this.chargeRepository = chargeRepository;
|
||||
this.clientChargeDataValidator = clientChargeDataValidator;
|
||||
@@ -59,6 +68,8 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.clientChargeRepository = clientChargeRepository;
|
||||
this.workingDaysRepository = workingDaysRepository;
|
||||
this.clientTransactionRepository = clientTransactionRepository;
|
||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,17 +77,14 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
|
||||
this.clientChargeDataValidator.validateAdd(command.json());
|
||||
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
checkClientActive(client);
|
||||
final Client client = clientRepository.getActiveClient(clientId);
|
||||
|
||||
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
|
||||
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
|
||||
|
||||
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
|
||||
|
||||
validateDueDateOnWorkingDay(clientCharge, fmt);
|
||||
|
||||
this.clientChargeRepository.save(clientCharge);
|
||||
@@ -88,37 +96,109 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult payCharge(Long clientId, Long clientChargeId, JsonCommand command) {
|
||||
this.clientChargeDataValidator.validateAdd(command.json());
|
||||
|
||||
final Client client = this.clientRepository.getActiveClient(clientId);
|
||||
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed(ClientApiConstants.transactionDateParamName);
|
||||
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(ClientApiConstants.amountParamName);
|
||||
|
||||
final Money chargePaid = validatePaymentDateAndAmount(client, clientCharge, fmt, transactionDate, amountPaid);
|
||||
|
||||
// pay the charge
|
||||
clientCharge.pay(clientCharge.getCurrency(), chargePaid);
|
||||
|
||||
// create Payment Transaction
|
||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
|
||||
chargePaid, clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
||||
this.clientTransactionRepository.save(clientTransaction);
|
||||
|
||||
// update charge paid by associations
|
||||
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, amountPaid);
|
||||
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the charge due date is not on a holiday or a non working day
|
||||
* Validates transaction to ensure that <br>
|
||||
* charge is active <br>
|
||||
* transaction date is valid (between client activation and todays date)
|
||||
* <br>
|
||||
* charge is not already paid or waived <br>
|
||||
* amount is not more than total due
|
||||
*
|
||||
* @param savingsAccountCharge
|
||||
* @param client
|
||||
* @param clientCharge
|
||||
* @param fmt
|
||||
* @param transactionDate
|
||||
* @param amountPaid
|
||||
* @return
|
||||
*/
|
||||
private void validateDueDateOnWorkingDay(final SavingsAccountCharge savingsAccountCharge, final DateTimeFormatter fmt) {
|
||||
private Money validatePaymentDateAndAmount(final Client client, final ClientCharge clientCharge, final DateTimeFormatter fmt,
|
||||
final LocalDate transactionDate, final BigDecimal amountPaid) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
validateTransactionDateOnWorkingDay(transactionDate, clientCharge, fmt);
|
||||
|
||||
if (clientCharge.isNotActive()) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("charge.is.not.active");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (client.getActivationLocalDate() != null && transactionDate.isBefore(client.getActivationLocalDate())) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.transactionDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.before.activationDate");
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
if (DateUtils.isDateInTheFuture(transactionDate)) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.transactionDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.is.futureDate");
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
// validate charge is not already paid or waived
|
||||
if (clientCharge.isWaived()) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("transaction.invalid.account.charge.is.already.waived");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
} else if (clientCharge.isPaid()) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("transaction.invalid.account.charge.is.paid");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
final Money chargePaid = Money.of(clientCharge.getCurrency(), amountPaid);
|
||||
if (!clientCharge.getAmountOutstanding(clientCharge.getCurrency()).isGreaterThanOrEqualTo(chargePaid)) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("transaction.invalid.charge.amount.paid.in.access");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
return chargePaid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CommandProcessingResult updateCharge(Long clientId, JsonCommand command) {
|
||||
// TODO Auto-generated method stub
|
||||
this.clientChargeDataValidator.validateAdd(command.json());
|
||||
final Client client = clientRepository.getActiveClient(clientId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -134,22 +214,73 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult payCharge(Long clientId, Long clientChargeId, JsonCommand command) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult inactivateCharge(Long clientId, Long clientChargeId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkClientActive(Client client) {
|
||||
if (client != null) {
|
||||
if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); }
|
||||
/**
|
||||
* Ensures that the charge due date is not on a holiday or a non working day
|
||||
*
|
||||
* @param clientCharge
|
||||
* @param fmt
|
||||
*/
|
||||
private void validateDueDateOnWorkingDay(final ClientCharge clientCharge, final DateTimeFormatter fmt) {
|
||||
validateActivityDateFallOnAWorkingDay(clientCharge.getDueLocalDate(), clientCharge.getOfficeId(),
|
||||
ClientApiConstants.dueAsOfDateParamName, "charge.due.date.is.on.holiday", "charge.due.date.is.a.non.workingday", fmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the charge transaction date (for payments) is not on a
|
||||
* holiday or a non working day
|
||||
*
|
||||
* @param savingsAccountCharge
|
||||
* @param fmt
|
||||
*/
|
||||
private void validateTransactionDateOnWorkingDay(final LocalDate transactionDate, final ClientCharge clientCharge,
|
||||
final DateTimeFormatter fmt) {
|
||||
validateActivityDateFallOnAWorkingDay(transactionDate, clientCharge.getOfficeId(), ClientApiConstants.transactionDateParamName,
|
||||
"transaction.not.allowed.transaction.date.is.on.holiday", "transaction.not.allowed.transaction.date.is.a.non.workingday",
|
||||
fmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date
|
||||
* @param officeId
|
||||
* @param jsonPropertyName
|
||||
* @param errorMessageFragment
|
||||
* @param fmt
|
||||
*/
|
||||
private void validateActivityDateFallOnAWorkingDay(final LocalDate date, final Long officeId, final String jsonPropertyName,
|
||||
final String errorMessageFragmentForActivityOnHoliday, final String errorMessageFragmentForActivityOnNonWorkingDay,
|
||||
final DateTimeFormatter fmt) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
if (date != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled() && this.holidayRepository.isHoliday(officeId, date)) {
|
||||
baseDataValidator.reset().parameter(jsonPropertyName).value(date.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode(errorMessageFragmentForActivityOnHoliday);
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(date)) {
|
||||
baseDataValidator.reset().parameter(jsonPropertyName).value(date.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode(errorMessageFragmentForActivityOnNonWorkingDay);
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public interface ClientTransactionReadPlatformService {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Collection<ClientTransactionData> retrieveAllTransactions(final Long clientId);
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public ClientTransactionData retrieveTransaction(Long clientId, Long transactionId);
|
||||
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientTransactionType;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
import org.mifosplatform.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
public class ClientTransactionReadPlatformServiceImpl implements ClientTransactionReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final ClientTransactionMapper clientTransactionMapper;
|
||||
|
||||
@Autowired
|
||||
public ClientTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.clientTransactionMapper = new ClientTransactionMapper();
|
||||
|
||||
}
|
||||
|
||||
private static final class ClientTransactionMapper implements RowMapper<ClientTransactionData> {
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
public ClientTransactionMapper() {
|
||||
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
||||
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount, ");
|
||||
sqlBuilder.append("tr.created_date as submittedOnDate, tr.is_reversed as reversed, ");
|
||||
sqlBuilder.append("tr.external_id as externalId, o.name as officeName, o.id as officeId, ");
|
||||
sqlBuilder.append("c.id as clientId, c.account_no as accountNo, ");
|
||||
sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
||||
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
|
||||
sqlBuilder.append(
|
||||
"tr.currency_code as currencyCode, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("pt.value as paymentTypeName ");
|
||||
sqlBuilder.append("from m_client c ");
|
||||
sqlBuilder.append("join m_client_transaction tr on tr.client_id = c.id ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = tr.currency_code ");
|
||||
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
|
||||
sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id ");
|
||||
sqlBuilder.append("left join m_office o on o.id = tr.office_id ");
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long id = rs.getLong("transactionId");
|
||||
final Long officeId = rs.getLong("officeId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
||||
final EnumOptionData transactionType = ClientEnumerations.clientTransactionType(transactionTypeInt);
|
||||
|
||||
final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate");
|
||||
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
|
||||
final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount");
|
||||
final boolean reversed = rs.getBoolean("reversed");
|
||||
|
||||
PaymentDetailData paymentDetailData = null;
|
||||
if (ClientTransactionType.fromInt(transactionType.getId().intValue()).equals(ClientTransactionType.PAY_CHARGE)) {
|
||||
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentType");
|
||||
if (paymentTypeId != null) {
|
||||
final String typeName = rs.getString("paymentTypeName");
|
||||
final PaymentTypeData paymentType = PaymentTypeData.instance(paymentTypeId, typeName);
|
||||
final String accountNumber = rs.getString("accountNumber");
|
||||
final String checkNumber = rs.getString("checkNumber");
|
||||
final String routingCode = rs.getString("routingCode");
|
||||
final String receiptNumber = rs.getString("receiptNumber");
|
||||
final String bankNumber = rs.getString("bankNumber");
|
||||
paymentDetailData = new PaymentDetailData(id, paymentType, accountNumber, checkNumber, routingCode, receiptNumber,
|
||||
bankNumber);
|
||||
}
|
||||
}
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
return ClientTransactionData.create(id, officeId, officeName, transactionType, date, currency, paymentDetailData, amount,
|
||||
externalId, submittedOnDate, reversed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientTransactionData> retrieveAllTransactions(Long clientId) {
|
||||
final String sql = "select " + this.clientTransactionMapper.schema()
|
||||
+ " where c.id = ? order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC";
|
||||
return this.jdbcTemplate.query(sql, this.clientTransactionMapper, new Object[] { clientId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTransactionData retrieveTransaction(Long clientId, Long transactionId) {
|
||||
final String sql = "select " + this.clientTransactionMapper.schema() + " where c.id = ? and tr.id= ?";
|
||||
return this.jdbcTemplate.queryForObject(sql, this.clientTransactionMapper, new Object[] { clientId, transactionId });
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -2208,7 +2208,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
if (DateUtils.isDateInTheFuture(transactionDate)) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(getSubmittedOnLocalDate().toString(formatter))
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate.toString(formatter))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.is.futureDate");
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
+50
-43
@@ -41,6 +41,7 @@ import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
|
||||
import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
|
||||
import org.mifosplatform.infrastructure.jobs.service.JobName;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
@@ -48,6 +49,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.workingdays.service.WorkingDaysWritePlatformService;
|
||||
import org.mifosplatform.portfolio.account.PortfolioAccountType;
|
||||
import org.mifosplatform.portfolio.account.data.AccountTransferDTO;
|
||||
@@ -119,13 +121,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
|
||||
private final ChargeRepositoryWrapper chargeRepository;
|
||||
private final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository;
|
||||
private final HolidayWritePlatformService holidayWritePlatformService;
|
||||
private final WorkingDaysWritePlatformService workingDaysWritePlatformService;
|
||||
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
|
||||
private final AccountTransfersWritePlatformService accountTransfersWritePlatformService;
|
||||
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final HolidayRepositoryWrapper holidayRepository;
|
||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
||||
|
||||
@Autowired
|
||||
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
@@ -139,9 +141,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||
final DepositAccountDomainService depositAccountDomainService, final NoteRepository noteRepository,
|
||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService, final ChargeRepositoryWrapper chargeRepository,
|
||||
final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository,
|
||||
final HolidayWritePlatformService holidayWritePlatformService,
|
||||
final WorkingDaysWritePlatformService workingDaysWritePlatformService,
|
||||
final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository, final HolidayRepositoryWrapper holidayRepository,
|
||||
final WorkingDaysRepositoryWrapper workingDaysRepository,
|
||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
|
||||
final DepositAccountReadPlatformService depositAccountReadPlatformService,
|
||||
@@ -161,8 +162,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
|
||||
this.chargeRepository = chargeRepository;
|
||||
this.savingsAccountChargeRepository = savingsAccountChargeRepository;
|
||||
this.holidayWritePlatformService = holidayWritePlatformService;
|
||||
this.workingDaysWritePlatformService = workingDaysWritePlatformService;
|
||||
this.holidayRepository = holidayRepository;
|
||||
this.workingDaysRepository = workingDaysRepository;
|
||||
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
|
||||
this.accountTransfersWritePlatformService = accountTransfersWritePlatformService;
|
||||
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
|
||||
@@ -318,7 +319,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final boolean isInterestTransfer = false;
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
@@ -364,8 +366,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate depositAmountUpdateEffectiveFromDate = command
|
||||
.localDateValueOfParameterNamed(DepositsApiConstants.effectiveDateParamName);
|
||||
|
||||
final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(
|
||||
savingsId, DepositAccountType.RECURRING_DEPOSIT);
|
||||
final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler
|
||||
.assembleFrom(savingsId, DepositAccountType.RECURRING_DEPOSIT);
|
||||
DepositAccountRecurringDetail recurringDetail = recurringDepositAccount.getRecurringDetail();
|
||||
Map<String, Object> changes = recurringDetail.updateMandatoryRecommendedDepositAmount(mandatoryRecommendedDepositAmount,
|
||||
depositAmountUpdateEffectiveFromDate, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
@@ -419,7 +421,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, final DepositAccountType depositAccountType) {
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command,
|
||||
final DepositAccountType depositAccountType) {
|
||||
|
||||
boolean isRegularTransaction = true;
|
||||
|
||||
@@ -560,10 +563,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.findOneByIdAndSavingsAccountId(transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!allowAccountTransferModification
|
||||
&& this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed", "Recurring deposit account transaction:"
|
||||
+ transactionId + " update not allowed as it involves in account transfer", transactionId); }
|
||||
if (!allowAccountTransferModification && this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed",
|
||||
"Recurring deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -584,7 +588,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
||||
// account.activateAccountBasedOnBalance();
|
||||
final boolean isPreMatureClosure = false;
|
||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
|
||||
final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
@@ -627,12 +632,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.findOneByIdAndSavingsAccountId(transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(
|
||||
savingsId, transactionId); }
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
|
||||
|| savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(savingsId, transactionId); }
|
||||
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Deposit account transaction:" + transactionId
|
||||
+ " update not allowed as it involves in account transfer", transactionId); }
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed",
|
||||
"Deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
@@ -995,15 +1002,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -1050,15 +1057,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -1088,8 +1095,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
// Get Savings account from savings charge
|
||||
final SavingsAccount account = savingsAccountCharge.savingsAccount();
|
||||
@@ -1134,8 +1141,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsAccountId, depositAccountType);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
savingsAccount.removeCharge(savingsAccountCharge);
|
||||
this.savingAccountRepository.saveAndFlush(savingsAccount);
|
||||
@@ -1161,23 +1168,23 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccountCharge.savingsAccount().officeId(), transactionDate)) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccountCharge.savingsAccount().officeId(), transactionDate)) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.not.allowed.transaction.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(transactionDate)) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(transactionDate)) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.not.allowed.transaction.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -1200,8 +1207,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
// always use current date as transaction date for batch job
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
|
||||
@@ -1289,8 +1296,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction mandatorySavingsAccountDeposit(final SavingsAccountTransactionDTO accountTransactionDTO) {
|
||||
boolean isRegularTransaction = false;
|
||||
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(
|
||||
accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT);
|
||||
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler
|
||||
.assembleFrom(accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT);
|
||||
final PaymentDetail paymentDetail = accountTransactionDTO.getPaymentDetail();
|
||||
if (paymentDetail != null && paymentDetail.getId() == null) {
|
||||
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
|
||||
|
||||
+59
-55
@@ -40,7 +40,7 @@ import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
|
||||
import org.mifosplatform.infrastructure.jobs.service.JobName;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
@@ -48,7 +48,7 @@ import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.workingdays.service.WorkingDaysWritePlatformService;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.account.PortfolioAccountType;
|
||||
import org.mifosplatform.portfolio.account.service.AccountAssociationsReadPlatformService;
|
||||
import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||
@@ -111,8 +111,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
|
||||
private final ChargeRepositoryWrapper chargeRepository;
|
||||
private final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository;
|
||||
private final HolidayWritePlatformService holidayWritePlatformService;
|
||||
private final WorkingDaysWritePlatformService workingDaysWritePlatformService;
|
||||
private final HolidayRepositoryWrapper holidayRepository;
|
||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
|
||||
@Autowired
|
||||
@@ -126,11 +126,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||
final SavingsAccountDomainService savingsAccountDomainService, final NoteRepository noteRepository,
|
||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService,
|
||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService, final HolidayRepositoryWrapper holidayRepository,
|
||||
final WorkingDaysRepositoryWrapper workingDaysRepository,
|
||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||
final ChargeRepositoryWrapper chargeRepository, final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository,
|
||||
final HolidayWritePlatformService holidayWritePlatformService,
|
||||
final WorkingDaysWritePlatformService workingDaysWritePlatformService,
|
||||
final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountRepositoryWrapper savingsRepository,
|
||||
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService) {
|
||||
this.context = context;
|
||||
@@ -148,8 +147,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
|
||||
this.chargeRepository = chargeRepository;
|
||||
this.savingsAccountChargeRepository = savingsAccountChargeRepository;
|
||||
this.holidayWritePlatformService = holidayWritePlatformService;
|
||||
this.workingDaysWritePlatformService = workingDaysWritePlatformService;
|
||||
this.holidayRepository = holidayRepository;
|
||||
this.workingDaysRepository = workingDaysRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.savingsRepository = savingsRepository;
|
||||
this.staffRepository = staffRepository;
|
||||
@@ -296,8 +295,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
AppUser user = getAppUserIfPresent();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
|
||||
@@ -389,8 +388,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@CronTarget(jobName = JobName.POST_INTEREST_FOR_SAVINGS)
|
||||
@Override
|
||||
public void postInterestForAccounts() {
|
||||
final List<SavingsAccount> savingsAccounts = this.savingAccountRepository.findSavingAccountByStatus(SavingsAccountStatusType.ACTIVE
|
||||
.getValue());
|
||||
final List<SavingsAccount> savingsAccounts = this.savingAccountRepository
|
||||
.findSavingAccountByStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
for (final SavingsAccount savingsAccount : savingsAccounts) {
|
||||
this.savingAccountAssembler.assignSavingAccountHelpers(savingsAccount);
|
||||
postInterest(savingsAccount);
|
||||
@@ -415,13 +414,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!allowAccountTransferModification
|
||||
&& this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId
|
||||
+ " update not allowed as it involves in account transfer", transactionId); }
|
||||
&& this.accountTransfersReadPlatformService
|
||||
.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:"
|
||||
+ transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
|
||||
if (!account.allowModify()) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId
|
||||
+ " update not allowed for this savings type", transactionId); }
|
||||
if (!account
|
||||
.allowModify()) { throw new PlatformServiceUnavailableException("error.msg.saving.account.transaction.update.not.allowed",
|
||||
"Savings account transaction:" + transactionId + " update not allowed for this savings type", transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
||||
@@ -475,12 +477,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.findOneByIdAndSavingsAccountId(transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(
|
||||
savingsId, transactionId); }
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
|
||||
|| savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(savingsId, transactionId); }
|
||||
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId
|
||||
+ " update not allowed as it involves in account transfer", transactionId); }
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed",
|
||||
"Savings account transaction:" + transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validate(command);
|
||||
|
||||
@@ -490,9 +494,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
if (account.isNotActive()) {
|
||||
throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction);
|
||||
}
|
||||
if (!account.allowModify()) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId
|
||||
+ " update not allowed for this savings type", transactionId); }
|
||||
if (!account
|
||||
.allowModify()) { throw new PlatformServiceUnavailableException("error.msg.saving.account.transaction.update.not.allowed",
|
||||
"Savings account transaction:" + transactionId + " update not allowed for this savings type", transactionId); }
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -762,15 +766,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -817,15 +821,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -854,8 +858,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
// Get Savings account from savings charge
|
||||
final SavingsAccount account = savingsAccountCharge.savingsAccount();
|
||||
@@ -900,8 +904,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsAccountId);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
savingsAccount.removeCharge(savingsAccountCharge);
|
||||
this.savingAccountRepository.saveAndFlush(savingsAccount);
|
||||
@@ -926,23 +930,23 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.holidayWritePlatformService.isTransactionAllowedOnHoliday()
|
||||
&& this.holidayWritePlatformService.isHoliday(savingsAccountCharge.savingsAccount().officeId(), transactionDate)) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccountCharge.savingsAccount().officeId(), transactionDate)) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.not.allowed.transaction.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
if (!this.workingDaysWritePlatformService.isTransactionAllowedOnNonWorkingDay()
|
||||
&& !this.workingDaysWritePlatformService.isWorkingDay(transactionDate)) {
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(transactionDate)) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate.toString(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.not.allowed.transaction.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
@@ -966,8 +970,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
AppUser user = null;
|
||||
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
fmt.withZone(DateUtils.getDateTimeZoneOfTenant());
|
||||
@@ -1032,8 +1036,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
final SavingsAccount account = savingsAccountCharge.savingsAccount();
|
||||
this.savingAccountAssembler.assignSavingAccountHelpers(account);
|
||||
@@ -1111,16 +1115,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final LocalDate dateOfSavingsOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate");
|
||||
|
||||
if (fromSavingsOfficerId != null) {
|
||||
fromSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(fromSavingsOfficerId, savingsForUpdate
|
||||
.office().getHierarchy());
|
||||
fromSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(fromSavingsOfficerId,
|
||||
savingsForUpdate.office().getHierarchy());
|
||||
}
|
||||
if (toSavingsOfficerId != null) {
|
||||
toSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(toSavingsOfficerId, savingsForUpdate
|
||||
.office().getHierarchy());
|
||||
toSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(toSavingsOfficerId,
|
||||
savingsForUpdate.office().getHierarchy());
|
||||
actualChanges.put("toSavingsOfficerId", toSavingsOfficer.getId());
|
||||
}
|
||||
if (!savingsForUpdate.hasSavingsOfficer(fromSavingsOfficer)) { throw new SavingsOfficerAssignmentException(savingsAccountId,
|
||||
fromSavingsOfficerId); }
|
||||
if (!savingsForUpdate.hasSavingsOfficer(
|
||||
fromSavingsOfficer)) { throw new SavingsOfficerAssignmentException(savingsAccountId, fromSavingsOfficerId); }
|
||||
|
||||
savingsForUpdate.reassignSavingsOfficer(toSavingsOfficer, dateOfSavingsOfficerAssignment);
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
-- add permissions for Client Fees
|
||||
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'CREATE_CLIENTCHARGE', 'CLIENTCHARGE', 'CREATE', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'DELETE_CLIENTCHARGE', 'CLIENTCHARGE', 'DELETE', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'WAIVE_CLIENTCHARGE', 'CLIENTCHARGE', 'WAIVE', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'PAY_CLIENTCHARGE', 'CLIENTCHARGE', 'PAY', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'INACTIVATE_CLIENTCHARGE', 'CLIENTCHARGE', 'INACTIVATE', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UPDATE_CLIENTCHARGE', 'CLIENTCHARGE', 'UPDATE', 0);
|
||||
|
||||
Reference in New Issue
Block a user