Merge pull request #514 from pramodn02/MIFOSX-586
added savings transaction adjustment API
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('transaction_savings', 'ADJUSTTRANSACTION_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'ADJUSTTRANSACTION', 0);
|
||||
@@ -478,6 +478,10 @@ public class CommandWrapper {
|
||||
return this.actionName.equalsIgnoreCase("UNDOTRANSACTION") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isAdjustSavingsAccountTransaction() {
|
||||
return this.actionName.equalsIgnoreCase("ADJUSTTRANSACTION") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isCalendarResource() {
|
||||
return this.entityName.equalsIgnoreCase("CALENDAR");
|
||||
}
|
||||
|
||||
+44
-33
@@ -342,7 +342,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/clients/" + clientId + "?command=activate&template=true";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder closeClient(final Long clientId) {
|
||||
this.actionName = "CLOSE";
|
||||
this.entityName = "CLIENT";
|
||||
@@ -372,30 +372,30 @@ public class CommandWrapperBuilder {
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDBDatatable(final String json) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/";
|
||||
this.json = json;
|
||||
return this;
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/";
|
||||
this.json = json;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateDBDatatable(final String datatable, final String json) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/" + datatable;
|
||||
this.json = json;
|
||||
return this;
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/" + datatable;
|
||||
this.json = json;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteDBDatatable(final String datatable, final String json) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/" + datatable;
|
||||
this.json = json;
|
||||
return this;
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DATATABLE";
|
||||
this.entityId = null;
|
||||
this.href = "/datatables/" + datatable;
|
||||
this.json = json;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDatatable(final String datatable, final Long apptableId, final Long datatableId) {
|
||||
@@ -845,6 +845,17 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder adjustSavingsAccountTransaction(final Long accountId, final Long transactionId) {
|
||||
this.actionName = "ADJUSTTRANSACTION";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.savingsId = accountId;
|
||||
this.entityId = accountId;
|
||||
this.subentityId = transactionId;
|
||||
this.transactionId = transactionId.toString();
|
||||
this.href = "/savingsaccounts/" + accountId + "/transactions/" + transactionId + "?command=modify";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder savingsAccountInterestCalculation(final Long accountId) {
|
||||
this.actionName = "CALCULATEINTEREST";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
@@ -953,7 +964,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/groups/" + groupId + "?command=activate";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder saveGroupCollectionSheet(final Long groupId) {
|
||||
this.actionName = "SAVECOLLECTIONSHEET";
|
||||
this.entityName = "GROUP";
|
||||
@@ -962,7 +973,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/groups/" + groupId + "?command=saveCollectionSheet";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder deleteGroup(final Long groupId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "GROUP";
|
||||
@@ -998,16 +1009,16 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/groups/" + groupId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder assignGroupStaff(final Long groupId) {
|
||||
this.actionName = "ASSIGNSTAFF";
|
||||
this.entityName = "GROUP";
|
||||
this.entityId = groupId;
|
||||
this.groupId = groupId;
|
||||
this.href = "/groups/" + groupId +"?command=assignStaff";
|
||||
this.href = "/groups/" + groupId + "?command=assignStaff";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createCollateral(final Long loanId) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "COLLATERAL";
|
||||
@@ -1106,7 +1117,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/accountingrules/" + accountingRuleId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createHoliday() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "HOLIDAY";
|
||||
@@ -1120,7 +1131,7 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "GROUP";
|
||||
this.groupId = groupId;
|
||||
this.entityId = null;
|
||||
this.href = "/groups/"+groupId+"?command=assignRole";
|
||||
this.href = "/groups/" + groupId + "?command=assignRole";
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1129,7 +1140,7 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "GROUP";
|
||||
this.groupId = groupId;
|
||||
this.entityId = roleId;
|
||||
this.href = "/groups/"+groupId+"?command=unassignRole";
|
||||
this.href = "/groups/" + groupId + "?command=unassignRole";
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1138,10 +1149,10 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "GROUP";
|
||||
this.groupId = groupId;
|
||||
this.entityId = roleId;
|
||||
this.href = "/groups/"+groupId+"?command=updateRole";
|
||||
this.href = "/groups/" + groupId + "?command=updateRole";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder unassignClientStaff(final Long clientId) {
|
||||
this.actionName = "UNASSIGNSTAFF";
|
||||
this.entityName = "CLIENT";
|
||||
@@ -1177,7 +1188,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/loanproducts/" + productId + "/productmix";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder deleteProductMix(final Long productId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "PRODUCTMIX";
|
||||
@@ -1186,17 +1197,17 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/loanproducts/" + productId + "/productmix";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder withProduct(final Long productId) {
|
||||
this.productId = productId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder updateJobDetail(final Long jobId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "SCHEDULER";
|
||||
this.entityId = jobId;
|
||||
this.href = "/updateJobDetail/" + jobId+"/updateJobDetail";
|
||||
this.href = "/updateJobDetail/" + jobId + "/updateJobDetail";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+2
@@ -412,6 +412,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = this.applicationContext.getBean("applyAnnualFeeSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingsAccountUndoTransaction()) {
|
||||
handler = this.applicationContext.getBean("undoTransactionSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isAdjustSavingsAccountTransaction()) {
|
||||
handler = this.applicationContext.getBean("savingsTransactionAdjustmentCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+11
-1
@@ -30,6 +30,11 @@ public class SavingsApiConstants {
|
||||
public static String deleteApplicationAction = ".delete";
|
||||
public static String undoTransactionAction = ".undotransaction";
|
||||
public static String applyAnnualFeeTransactionAction = ".applyannualfee";
|
||||
public static String adjustTransactionAction = ".adjusttransaction";
|
||||
|
||||
// command
|
||||
public static String COMMAND_UNDO_TRANSACTION = "undo";
|
||||
public static String COMMAND_ADJUST_TRANSACTION = "modify";
|
||||
|
||||
// general
|
||||
public static final String localeParamName = "locale";
|
||||
@@ -81,6 +86,10 @@ public class SavingsApiConstants {
|
||||
// transaction parameters
|
||||
public static final String transactionDateParamName = "transactionDate";
|
||||
public static final String transactionAmountParamName = "transactionAmount";
|
||||
public static final String paymentDetailDataParamName = "paymentDetailData";
|
||||
public static final String runningBalanceParamName = "runningBalance";
|
||||
public static final String reversedParamName = "reversed";
|
||||
public static final String dateParamName = "date";
|
||||
|
||||
public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
monthDayFormatParamName, nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName,
|
||||
@@ -135,7 +144,8 @@ public class SavingsApiConstants {
|
||||
transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
"accountId", accountNoParamName, "currency", "amount"));
|
||||
"accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName, runningBalanceParamName,
|
||||
reversedParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, activatedOnDateParamName));
|
||||
|
||||
+26
-2
@@ -91,6 +91,27 @@ public class SavingsAccountTransactionsApiResource {
|
||||
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveOne(@PathParam("savingsId") final Long savingsId, @PathParam("transactionId") final Long transactionId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
SavingsAccountTransactionData transactionData = this.savingsAccountReadPlatformService.retrieveSavingsTransaction(savingsId,
|
||||
transactionId);
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
if (settings.isTemplate()) {
|
||||
final Collection<CodeValueData> paymentTypeOptions = codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
|
||||
transactionData = SavingsAccountTransactionData.templateOnTop(transactionData, paymentTypeOptions);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, transactionData,
|
||||
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@@ -120,7 +141,7 @@ public class SavingsAccountTransactionsApiResource {
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String undoTransaction(@PathParam("savingsId") final Long savingsId, @PathParam("transactionId") final Long transactionId,
|
||||
public String adjustTransaction(@PathParam("savingsId") final Long savingsId, @PathParam("transactionId") final Long transactionId,
|
||||
@QueryParam("command") final String commandParam, final String apiRequestBodyAsJson) {
|
||||
|
||||
String jsonApiRequest = apiRequestBodyAsJson;
|
||||
@@ -131,9 +152,12 @@ public class SavingsAccountTransactionsApiResource {
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "undo")) {
|
||||
if (is(commandParam, SavingsApiConstants.COMMAND_UNDO_TRANSACTION)) {
|
||||
final CommandWrapper commandRequest = builder.undoSavingsAccountTransaction(savingsId, transactionId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_ADJUST_TRANSACTION)) {
|
||||
final CommandWrapper commandRequest = builder.adjustSavingsAccountTransaction(savingsId, transactionId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
|
||||
+6
-9
@@ -719,8 +719,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateAccountBalanceDoesNotBecomeNegativeDueToUndoAction(final List<SavingsAccountTransaction> transactionsSortedByDate) {
|
||||
public void validateAccountBalanceDoesNotBecomeNegative(String transactionAction) {
|
||||
|
||||
final List<SavingsAccountTransaction> transactionsSortedByDate = retreiveListOfTransactions();
|
||||
Money runningBalance = Money.zero(this.currency);
|
||||
|
||||
for (final SavingsAccountTransaction transaction : transactionsSortedByDate) {
|
||||
@@ -734,7 +735,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
//
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SAVINGS_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.undoTransactionAction);
|
||||
.resource(SAVINGS_ACCOUNT_RESOURCE_NAME + transactionAction);
|
||||
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("results.in.balance.going.negative");
|
||||
|
||||
@@ -1396,8 +1397,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public void undoTransaction(final Long transactionId, final List<Long> reversedTransactionIds, final MathContext mc,
|
||||
final LocalDate upToInterestCalculationDate) {
|
||||
public void undoTransaction(final Long transactionId, final List<Long> reversedTransactionIds) {
|
||||
|
||||
SavingsAccountTransaction transactionToUndo = null;
|
||||
for (final SavingsAccountTransaction transaction : this.transactions) {
|
||||
@@ -1424,9 +1424,6 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
calculateInterestUsing(mc, upToInterestCalculationDate);
|
||||
|
||||
validateAccountBalanceDoesNotBecomeNegativeDueToUndoAction(retreiveListOfTransactions());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1616,8 +1613,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.activatedOnDateParamName).value(dateAsString)
|
||||
.failWithCodeNoParameterAddedToErrorCode("cannot.be.before.client.activation.date");
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.group != null && this.group.isActivatedAfter(activationDate)) {
|
||||
final DateTimeFormatter formatter = DateTimeFormat.forPattern(command.dateFormat()).withLocale(command.extractLocale());
|
||||
final String dateAsString = formatter.print(this.client.getActivationLocalDate());
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class SavingsAccountTransactionNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public SavingsAccountTransactionNotFoundException(final Long savingsId, final Long transactionId) {
|
||||
super("error.msg.saving.account.trasaction.id.invalid", "Savings account with savings identifier " + savingsId
|
||||
+ " and trasaction identifier " + transactionId + " does not exist", savingsId, transactionId);
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformServiceUnavailableException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when update not allowed.
|
||||
*/
|
||||
public class TransactionUpdateNotAllowedException extends AbstractPlatformServiceUnavailableException {
|
||||
|
||||
public TransactionUpdateNotAllowedException(final Long savingsId, final Long transactionId) {
|
||||
super("error.msg.saving.account.trasaction.update.notallowed",
|
||||
"Savings Account transaction update not allowed with savings identifier " + savingsId + " and trasaction identifier "
|
||||
+ transactionId, savingsId, transactionId);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class SavingsTransactionAdjustmentCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public SavingsTransactionAdjustmentCommandHandler(final SavingsAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
final Long transactionId = Long.valueOf(command.getTransactionId());
|
||||
return this.writePlatformService.adjustSavingsTransaction(command.getSavingsId(), transactionId, command);
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -28,4 +28,6 @@ public interface SavingsAccountReadPlatformService {
|
||||
Collection<SavingsAccountTransactionData> retrieveAllTransactions(Long savingsId);
|
||||
|
||||
Collection<SavingsAccountAnnualFeeData> retrieveAccountsWithAnnualFeeDue();
|
||||
|
||||
SavingsAccountTransactionData retrieveSavingsTransaction(Long savingsId, Long transactionId);
|
||||
}
|
||||
+8
@@ -507,6 +507,14 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
return this.jdbcTemplate.query(sql, this.transactionsMapper, new Object[] { savingsId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountTransactionData retrieveSavingsTransaction(final Long savingsId, final Long transactionId) {
|
||||
|
||||
final String sql = "select " + this.transactionsMapper.schema() + " where sa.id = ? and tr.id= ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, this.transactionsMapper, new Object[] { savingsId, transactionId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountAnnualFeeData> retrieveAccountsWithAnnualFeeDue() {
|
||||
final String sql = "select " + annualFeeMapper.schema()
|
||||
|
||||
+2
@@ -26,4 +26,6 @@ public interface SavingsAccountWritePlatformService {
|
||||
CommandProcessingResult undoTransaction(Long savingsId, Long transactionId);
|
||||
|
||||
void postInterestForAccounts();
|
||||
|
||||
CommandProcessingResult adjustSavingsTransaction(Long savingsId, Long transactionId, JsonCommand command);
|
||||
}
|
||||
+66
-4
@@ -30,6 +30,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||
@@ -38,6 +39,8 @@ import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountStatusType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountTransactionNotFoundException;
|
||||
import org.mifosplatform.portfolio.savings.exception.TransactionUpdateNotAllowedException;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -274,15 +277,20 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
SavingsAccountTransaction savingsAccountTransaction = this.savingsAccountTransactionRepository.findOneByIdAndSavingsAccountId(
|
||||
transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) {
|
||||
// throw new not found exception
|
||||
}
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
account.undoTransaction(transactionId, reversedTransactionIds, mc, today);
|
||||
account.undoTransaction(transactionId, reversedTransactionIds);
|
||||
if ((savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, newTransactionIds, reversedTransactionIds);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today);
|
||||
}
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
||||
|
||||
postJournalEntries(account, newTransactionIds, reversedTransactionIds);
|
||||
|
||||
@@ -295,6 +303,60 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult adjustSavingsTransaction(final Long savingsId, final Long transactionId, final JsonCommand command) {
|
||||
|
||||
SavingsAccountTransaction savingsAccountTransaction = this.savingsAccountTransactionRepository.findOneByIdAndSavingsAccountId(
|
||||
transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(
|
||||
savingsId, transactionId); }
|
||||
this.savingsAccountTransactionDataValidator.validate(command);
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed(SavingsApiConstants.transactionDateParamName);
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed(SavingsApiConstants.transactionAmountParamName);
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
account.undoTransaction(transactionId, existingReversedTransactionIds);
|
||||
SavingsAccountTransaction transaction = null;
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
transaction = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds, existingReversedTransactionIds,
|
||||
paymentDetail);
|
||||
} else {
|
||||
transaction = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds, existingReversedTransactionIds,
|
||||
paymentDetail);
|
||||
}
|
||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, existingTransactionIds, existingReversedTransactionIds);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today);
|
||||
}
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(newtransactionId) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.withSavingsId(savingsId) //
|
||||
.with(changes)//
|
||||
.build();
|
||||
}
|
||||
|
||||
private void postJournalEntries(final SavingsAccount savingsAccount, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user