MIFOSX-2049 and fix failing test cases
This commit is contained in:
+21
-7
@@ -120,6 +120,20 @@ public final class SearchParameters {
|
||||
loanId, savingsId, orphansOnly);
|
||||
}
|
||||
|
||||
public static SearchParameters forPagination(final Integer offset, final Integer limit) {
|
||||
|
||||
final Integer maxLimitAllowed = getCheckedLimit(limit);
|
||||
final Long staffId = null;
|
||||
final Long loanId = null;
|
||||
final Long savingsId = null;
|
||||
final Boolean orphansOnly = false;
|
||||
final String orderBy = null;
|
||||
final String sortOrder = null;
|
||||
|
||||
return new SearchParameters(null, null, null, null, null, null, null, offset, maxLimitAllowed, orderBy, sortOrder, staffId, null,
|
||||
loanId, savingsId, orphansOnly);
|
||||
}
|
||||
|
||||
public static SearchParameters forSavings(final String sqlSearch, final String externalId, final Integer offset, final Integer limit,
|
||||
final String orderBy, final String sortOrder) {
|
||||
|
||||
@@ -171,10 +185,10 @@ public final class SearchParameters {
|
||||
this.currencyCode = null;
|
||||
}
|
||||
|
||||
public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
|
||||
final String hierarchy, final String firstname, final String lastname, final Integer offset, final Integer limit,
|
||||
final String orderBy, final String sortOrder, final Long staffId, final String accountNo, final Long loanId,
|
||||
final Long savingsId, final Boolean orphansOnly, final String currencyCode) {
|
||||
public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name, final String hierarchy,
|
||||
final String firstname, final String lastname, final Integer offset, final Integer limit, final String orderBy,
|
||||
final String sortOrder, final Long staffId, final String accountNo, final Long loanId, final Long savingsId,
|
||||
final Boolean orphansOnly, final String currencyCode) {
|
||||
this.sqlSearch = sqlSearch;
|
||||
this.officeId = officeId;
|
||||
this.externalId = externalId;
|
||||
@@ -245,11 +259,11 @@ public final class SearchParameters {
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String getCurrencyCode(){
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
|
||||
public String getExternalId() {
|
||||
return this.externalId;
|
||||
}
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||
@@ -89,9 +90,10 @@ public class ClientChargesApiResource {
|
||||
new Object[] { ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL,
|
||||
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE,
|
||||
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE }); }
|
||||
final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit);
|
||||
|
||||
final Page<ClientChargeData> clientCharges = this.clientChargeReadPlatformService.retrieveClientCharges(clientId, chargeStatus,
|
||||
pendingPayment, limit, offset);
|
||||
pendingPayment, searchParameters);
|
||||
return this.toApiJsonSerializer.serialize(settings, clientCharges, ClientApiConstants.CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -26,6 +26,7 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.mifosplatform.portfolio.client.service.ClientTransactionReadPlatformService;
|
||||
@@ -61,8 +62,10 @@ public class ClientTransactionsApiResource {
|
||||
public String retrieveAllClientTransactions(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo,
|
||||
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit) {
|
||||
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
|
||||
SearchParameters searchParameters = SearchParameters.forPagination(offset, limit);
|
||||
final Page<ClientTransactionData> clientTransactions = this.clientTransactionReadPlatformService.retrieveAllTransactions(clientId,
|
||||
limit, offset);
|
||||
searchParameters);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clientTransactions,
|
||||
|
||||
+7
-2
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -20,10 +21,12 @@ import org.springframework.stereotype.Service;
|
||||
public class ClientRepositoryWrapper {
|
||||
|
||||
private final ClientRepository repository;
|
||||
private final PlatformSecurityContext context;
|
||||
|
||||
@Autowired
|
||||
public ClientRepositoryWrapper(final ClientRepository repository) {
|
||||
public ClientRepositoryWrapper(final ClientRepository repository, final PlatformSecurityContext context) {
|
||||
this.repository = repository;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Client findOneWithNotFoundDetection(final Long id) {
|
||||
@@ -44,9 +47,11 @@ public class ClientRepositoryWrapper {
|
||||
this.repository.delete(client);
|
||||
}
|
||||
|
||||
public Client getActiveClient(Long clientId) {
|
||||
public Client getActiveClientInUserScope(Long clientId) {
|
||||
final Client client = this.findOneWithNotFoundDetection(clientId);
|
||||
if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); }
|
||||
this.context.validateAccessRights(client.getOffice().getHierarchy());
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -6,12 +6,12 @@
|
||||
package org.mifosplatform.portfolio.client.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.portfolio.client.data.ClientChargeData;
|
||||
|
||||
public interface ClientChargeReadPlatformService {
|
||||
|
||||
|
||||
Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean isPaid, Integer limit, Integer offset);
|
||||
Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment, SearchParameters parameters);
|
||||
|
||||
ClientChargeData retrieveClientCharge(Long clientId, Long clientChargeId);
|
||||
|
||||
|
||||
+15
-6
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
@@ -118,8 +119,8 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment, Integer limit,
|
||||
Integer offset) {
|
||||
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment,
|
||||
SearchParameters searchParameters) {
|
||||
final ClientChargeMapper rm = new ClientChargeMapper();
|
||||
final StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(rm.schema()).append(" where cc.client_id=? ");
|
||||
@@ -133,13 +134,21 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
|
||||
|
||||
// filter for paid charges
|
||||
if (pendingPayment != null && pendingPayment) {
|
||||
sqlBuilder.append(" and ( cc.is_paid_derived = 0 and cc.waived = 1) ");
|
||||
sqlBuilder.append(" and ( cc.is_paid_derived = 0 and cc.waived = 0) ");
|
||||
} else if (pendingPayment != null && !pendingPayment) {
|
||||
sqlBuilder.append(" and (cc.is_paid_derived = 1 or cc.waived = 0) ");
|
||||
sqlBuilder.append(" and (cc.is_paid_derived = 1 or cc.waived = 1) ");
|
||||
}
|
||||
|
||||
sqlBuilder.append(" order by cc.charge_time_enum ASC, cc.charge_due_date DESC, cc.is_penalty ASC ");
|
||||
|
||||
// apply limit and offsets
|
||||
if (searchParameters.isLimited()) {
|
||||
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
|
||||
if (searchParameters.isOffset()) {
|
||||
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
sqlBuilder.append(
|
||||
" order by cc.charge_time_enum ASC, cc.charge_due_date DESC, cc.is_penalty ASC " + "limit " + limit + " offset " + offset);
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { clientId },
|
||||
this.clientChargeMapper);
|
||||
|
||||
+126
-83
@@ -23,6 +23,7 @@ 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.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
|
||||
@@ -43,12 +44,17 @@ 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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements ClientChargeWritePlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ClientChargeWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ChargeRepositoryWrapper chargeRepository;
|
||||
private final ClientRepositoryWrapper clientRepository;
|
||||
@@ -84,74 +90,83 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult addCharge(Long clientId, JsonCommand command) {
|
||||
try {
|
||||
this.clientChargeDataValidator.validateAdd(command.json());
|
||||
|
||||
this.clientChargeDataValidator.validateAdd(command.json());
|
||||
final Client client = clientRepository.getActiveClientInUserScope(clientId);
|
||||
|
||||
final Client client = clientRepository.getActiveClient(clientId);
|
||||
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
|
||||
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
|
||||
|
||||
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
|
||||
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
|
||||
// validate for client charge
|
||||
if (!charge.isClientCharge()) {
|
||||
final String errorMessage = "Charge with identifier " + charge.getId() + " cannot be applied to a Client";
|
||||
throw new ChargeCannotBeAppliedToException("client", errorMessage, charge.getId());
|
||||
}
|
||||
|
||||
// validate for client charge
|
||||
if (!charge.isClientCharge()) {
|
||||
final String errorMessage = "Charge with identifier " + charge.getId() + " cannot be applied to a Client";
|
||||
throw new ChargeCannotBeAppliedToException("client", errorMessage, charge.getId());
|
||||
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
|
||||
validateDueDateOnWorkingDay(clientCharge, fmt);
|
||||
|
||||
this.clientChargeRepository.save(clientCharge);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(clientId, null, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
|
||||
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
|
||||
validateDueDateOnWorkingDay(clientCharge, fmt);
|
||||
|
||||
this.clientChargeRepository.save(clientCharge);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult payCharge(Long clientId, Long clientChargeId, JsonCommand command) {
|
||||
this.clientChargeDataValidator.validatePayCharge(command.json());
|
||||
try {
|
||||
this.clientChargeDataValidator.validatePayCharge(command.json());
|
||||
|
||||
final Client client = this.clientRepository.getActiveClient(clientId);
|
||||
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
||||
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
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 = Money.of(clientCharge.getCurrency(), amountPaid);
|
||||
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 = Money.of(clientCharge.getCurrency(), amountPaid);
|
||||
|
||||
// Validate business rules for payment
|
||||
validatePaymentTransaction(client, clientCharge, fmt, transactionDate, amountPaid);
|
||||
// Validate business rules for payment
|
||||
validatePaymentTransaction(client, clientCharge, fmt, transactionDate, amountPaid);
|
||||
|
||||
// pay the charge
|
||||
clientCharge.pay(chargePaid);
|
||||
// pay the charge
|
||||
clientCharge.pay(chargePaid);
|
||||
|
||||
// create Payment Transaction
|
||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
// 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.saveAndFlush(clientTransaction);
|
||||
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
|
||||
chargePaid, clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
||||
this.clientTransactionRepository.saveAndFlush(clientTransaction);
|
||||
|
||||
// update charge paid by associations
|
||||
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, amountPaid);
|
||||
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
|
||||
// update charge paid by associations
|
||||
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, amountPaid);
|
||||
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
|
||||
|
||||
// generate accounting entries
|
||||
generateAccountingEntries(clientTransaction);
|
||||
// generate accounting entries
|
||||
generateAccountingEntries(clientTransaction);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withTransactionId(clientTransaction.getId().toString())//
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()).build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withTransactionId(clientTransaction.getId().toString())//
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()).build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(clientId, clientChargeId, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -162,54 +177,65 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult waiveCharge(Long clientId, Long clientChargeId) {
|
||||
final Client client = this.clientRepository.getActiveClient(clientId);
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
try {
|
||||
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
// Validate business rules for payment
|
||||
validateWaiverTransaction(client, clientCharge);
|
||||
// Validate business rules for payment
|
||||
validateWaiverTransaction(client, clientCharge);
|
||||
|
||||
// waive the charge
|
||||
Money waivedAmount = clientCharge.waive();
|
||||
// waive the charge
|
||||
Money waivedAmount = clientCharge.waive();
|
||||
|
||||
// create Waiver Transaction
|
||||
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
|
||||
clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
||||
this.clientTransactionRepository.save(clientTransaction);
|
||||
// create Waiver Transaction
|
||||
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
|
||||
clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
||||
this.clientTransactionRepository.save(clientTransaction);
|
||||
|
||||
// update charge paid by associations
|
||||
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, waivedAmount.getAmount());
|
||||
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
|
||||
// update charge paid by associations
|
||||
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, waivedAmount.getAmount());
|
||||
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
|
||||
|
||||
return new CommandProcessingResultBuilder().withTransactionId(clientTransaction.getId().toString())//
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
return new CommandProcessingResultBuilder().withTransactionId(clientTransaction.getId().toString())//
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(clientId, clientChargeId, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult deleteCharge(Long clientId, Long clientChargeId) {
|
||||
final Client client = this.clientRepository.getActiveClient(clientId);
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
try {
|
||||
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||
|
||||
// Validate business rules for charge deletion
|
||||
validateChargeDeletion(client, clientCharge);
|
||||
// Validate business rules for charge deletion
|
||||
validateChargeDeletion(client, clientCharge);
|
||||
|
||||
// delete the charge
|
||||
clientChargeRepository.delete(clientCharge);
|
||||
// delete the charge
|
||||
clientChargeRepository.delete(clientCharge);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(clientCharge.getId()) //
|
||||
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
|
||||
.withClientId(clientCharge.getClient().getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(clientId, clientChargeId, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates transaction to ensure that <br>
|
||||
* charge is active <br>
|
||||
* transaction date is valid (between client activation and todays date) <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
|
||||
*
|
||||
@@ -304,14 +330,16 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CommandProcessingResult updateCharge(Long clientId, JsonCommand command) {
|
||||
// this.clientChargeDataValidator.validateAdd(command.json());
|
||||
public CommandProcessingResult updateCharge(@SuppressWarnings("unused") Long clientId,
|
||||
@SuppressWarnings("unused") JsonCommand command) {
|
||||
// functionality not yet supported
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public CommandProcessingResult inactivateCharge(Long clientId, Long clientChargeId) {
|
||||
// TODO Auto-generated method stub
|
||||
// functionality not yet supported
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -378,4 +406,19 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
||||
return user;
|
||||
}
|
||||
|
||||
private void handleDataIntegrityIssues(@SuppressWarnings("unused") final Long clientId, final Long clientChargeId,
|
||||
final DataIntegrityViolationException dve) {
|
||||
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("FK_m_client_charge_paid_by_m_client_charge")) {
|
||||
|
||||
throw new PlatformDataIntegrityException("error.msg.client.charge.cannot.be.deleted",
|
||||
"Client charge with id `" + clientChargeId + "` cannot be deleted as transactions have been made on the same",
|
||||
"clientChargeId", clientChargeId); }
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.client.charges.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -8,13 +8,14 @@ package org.mifosplatform.portfolio.client.service;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public interface ClientTransactionReadPlatformService {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset);
|
||||
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters parameters);
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Collection<ClientTransactionData> retrieveAllTransactions(final Long clientId, final Long chargeId);
|
||||
|
||||
+16
-4
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
|
||||
@@ -121,13 +122,24 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset) {
|
||||
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters searchParameters) {
|
||||
Object[] parameters = new Object[1];
|
||||
String sql = "select SQL_CALC_FOUND_ROWS " + this.clientTransactionMapper.schema() + " where c.id = ? ";
|
||||
final StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(this.clientTransactionMapper.schema()).append(" where c.id = ? ");
|
||||
parameters[0] = clientId;
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
sql = sql + " order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC limit " + limit + " offset " + offset;
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, parameters, this.clientTransactionMapper);
|
||||
sqlBuilder.append(" order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC ");
|
||||
|
||||
// apply limit and offsets
|
||||
if (searchParameters.isLimited()) {
|
||||
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
|
||||
if (searchParameters.isOffset()) {
|
||||
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), parameters,
|
||||
this.clientTransactionMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ public class ClientTransactionWritePlatformServiceJpaRepositoryImpl implements C
|
||||
@Override
|
||||
public CommandProcessingResult undo(Long clientId, Long transactionId) {
|
||||
|
||||
final Client client = this.clientRepository.getActiveClient(clientId);
|
||||
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
||||
|
||||
final ClientTransaction clientTransaction = this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, transactionId);
|
||||
|
||||
|
||||
+5
-4
@@ -19,6 +19,7 @@ public class DisbursementData implements Comparable<DisbursementData> {
|
||||
private final LocalDate expectedDisbursementDate;
|
||||
private final LocalDate actualDisbursementDate;
|
||||
private final BigDecimal principal;
|
||||
@SuppressWarnings("unused")
|
||||
private final String loanChargeId;
|
||||
private final BigDecimal chargeAmount;
|
||||
|
||||
@@ -43,11 +44,11 @@ public class DisbursementData implements Comparable<DisbursementData> {
|
||||
public BigDecimal amount() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
public BigDecimal getChargeAmount(){
|
||||
return this.chargeAmount;
|
||||
|
||||
public BigDecimal getChargeAmount() {
|
||||
return this.chargeAmount;
|
||||
}
|
||||
|
||||
|
||||
public boolean isDisbursed() {
|
||||
return this.actualDisbursementDate != null;
|
||||
}
|
||||
|
||||
+14
@@ -373,6 +373,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
this.summary = new SavingsAccountSummary();
|
||||
this.allowOverdraft = allowOverdraft;
|
||||
this.overdraftLimit = overdraftLimit;
|
||||
esnureOverdraftLimitsSetForOverdraftAccounts();
|
||||
|
||||
this.enforceMinRequiredBalance = enforceMinRequiredBalance;
|
||||
this.minRequiredBalance = minRequiredBalance;
|
||||
@@ -1110,7 +1111,20 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
validateLockinDetails(baseDataValidator);
|
||||
esnureOverdraftLimitsSetForOverdraftAccounts();
|
||||
}
|
||||
|
||||
/**
|
||||
* If overdrafts are allowed and the overdraft limit is not set, set the
|
||||
* same to Zero
|
||||
**/
|
||||
private void esnureOverdraftLimitsSetForOverdraftAccounts() {
|
||||
|
||||
if (this.allowOverdraft && this.overdraftLimit == null) {
|
||||
this.overdraftLimit = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void validateLockinDetails(final DataValidatorBuilder baseDataValidator) {
|
||||
|
||||
|
||||
+15
-1
@@ -141,7 +141,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
protected boolean withdrawalFeeApplicableForTransfer;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "m_savings_product_charge", joinColumns = @JoinColumn(name = "savings_product_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
|
||||
@JoinTable(name = "m_savings_product_charge", joinColumns = @JoinColumn(name = "savings_product_id") , inverseJoinColumns = @JoinColumn(name = "charge_id") )
|
||||
protected Set<Charge> charges;
|
||||
|
||||
@Column(name = "allow_overdraft")
|
||||
@@ -236,11 +236,24 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
this.allowOverdraft = allowOverdraft;
|
||||
this.overdraftLimit = overdraftLimit;
|
||||
|
||||
esnureOverdraftLimitsSetForOverdraftAccounts();
|
||||
|
||||
this.enforceMinRequiredBalance = enforceMinRequiredBalance;
|
||||
this.minRequiredBalance = minRequiredBalance;
|
||||
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
|
||||
}
|
||||
|
||||
/**
|
||||
* If overdrafts are allowed and the overdraft limit is not set, set the
|
||||
* same to Zero
|
||||
**/
|
||||
private void esnureOverdraftLimitsSetForOverdraftAccounts() {
|
||||
|
||||
if (this.allowOverdraft && this.overdraftLimit() == null) {
|
||||
this.overdraftLimit = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
public MonetaryCurrency currency() {
|
||||
return this.currency.copy();
|
||||
}
|
||||
@@ -448,6 +461,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
validateLockinDetails();
|
||||
esnureOverdraftLimitsSetForOverdraftAccounts();
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user