@Transactional @Override public CommandProcessingResult rejectApplication( final Long savingsId, final JsonCommand command) { final AppUser currentUser = this.context.authenticatedUser(); this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json()); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); checkClientOrGroupActive(savingsAccount); final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); if (!changes.isEmpty()) { this.savingAccountRepository.save(savingsAccount); final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.savingNote(savingsAccount, noteText); changes.put("note", noteText); this.noteRepository.save(note); } } return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(savingsId) // .withOfficeId(savingsAccount.officeId()) // .withClientId(savingsAccount.clientId()) // .withGroupId(savingsAccount.groupId()) // .withSavingsId(savingsId) // .with(changes) // .build(); }
@Transactional @Override public CommandProcessingResult activate(final Long savingsId, final JsonCommand command) { this.context.authenticatedUser(); this.savingsAccountTransactionDataValidator.validateActivation(command); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate"); final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); account.activate( fmt, activationDate, existingReversedTransactionIds, existingReversedTransactionIds); this.savingAccountRepository.save(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); }
@Transactional @Override public CommandProcessingResult submitApplication(final JsonCommand command) { try { this.savingsAccountDataValidator.validateForSubmit(command.json()); final AppUser submittedBy = this.context.authenticatedUser(); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, submittedBy); this.savingAccountRepository.save(account); if (account.isAccountNumberRequiresAutoGeneration()) { final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory.determineSavingsAccountNoGenerator( account.getId()); account.updateAccountNo(accountNoGenerator.generate()); this.savingAccountRepository.save(account); } final Long savingsId = account.getId(); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); } catch (final DataAccessException dve) { handleDataIntegrityIssues(command, dve); return CommandProcessingResult.empty(); } }
private void postJournalEntries( final SavingsAccount savingsAccount, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) { final MonetaryCurrency currency = savingsAccount.getCurrency(); final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepositoryWrapper.findOneWithNotFoundDetection(currency); final Map<String, Object> accountingBridgeData = savingsAccount.deriveAccountingBridgeData( applicationCurrency.toData(), existingTransactionIds, existingReversedTransactionIds); journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData); }
@Transactional @Override public CommandProcessingResult deposit(final Long savingsId, final JsonCommand command) { this.context.authenticatedUser(); this.savingsAccountTransactionDataValidator.validate(command); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); 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 SavingsAccountTransaction deposit = account.deposit( fmt, transactionDate, transactionAmount, existingTransactionIds, existingReversedTransactionIds, paymentDetail); final Long transactionId = saveTransactionToGenerateTransactionId(deposit); this.savingAccountRepository.save(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // .withEntityId(transactionId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .with(changes) // .build(); }
@Override @Transactional public Long transferFunds(final AccountTransferDTO accountTransferDTO) { Long transferTransactionId = null; if (isSavingsToLoanAccountTransfer( accountTransferDTO.getFromAccountType(), accountTransferDTO.getToAccountType())) { // final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(accountTransferDTO.getFromAccountId()); final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal( fromSavingsAccount, accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer()); final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(accountTransferDTO.getToAccountId()); final LoanTransaction loanRepaymentTransaction = this.loanAccountDomainService.makeChargePayment( toLoanAccount, accountTransferDTO.getChargeId(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(), null, null, accountTransferDTO.getToTransferType(), accountTransferDTO.getLoanInstallmentNumber()); final AccountTransfer transferTransaction = this.accountTransferAssembler.assembleSavingsToLoanTransfer( accountTransferDTO, fromSavingsAccount, toLoanAccount, withdrawal, loanRepaymentTransaction); this.accountTransferRepository.saveAndFlush(transferTransaction); transferTransactionId = transferTransaction.getId(); } return transferTransactionId; }
private void checkClientOrGroupActive(final SavingsAccount account) { final Client client = account.getClient(); if (client != null) { if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); } } final Group group = account.group(); if (group != null) { if (group.isNotActive()) { if (group.isCenter()) { throw new CenterNotActiveException(group.getId()); } throw new GroupNotActiveException(group.getId()); } } }
@Transactional @Override public CommandProcessingResult deleteSavingAccount(final Long savingsId) { this.context.authenticatedUser(); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); this.savingAccountRepository.delete(account); return new CommandProcessingResultBuilder() // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); }
@Override public CommandProcessingResult calculateInterest( final Long savingsId, final JsonCommand command) { this.context.authenticatedUser(); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterest(today); this.savingAccountRepository.save(account); return new CommandProcessingResultBuilder() // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); }
@Override public CommandProcessingResult createActiveApplication( final SavingsAccountDataDTO savingsAccountDataDTO) { final CommandWrapper commandWrapper = new CommandWrapperBuilder().savingsAccountActivation(null).build(); boolean rollbackTransaction = this.commandProcessingService.validateCommand( commandWrapper, savingsAccountDataDTO.getAppliedBy()); final SavingsAccount account = this.savingAccountAssembler.assembleFrom( savingsAccountDataDTO.getClient(), savingsAccountDataDTO.getGroup(), savingsAccountDataDTO.getSavingsProduct(), savingsAccountDataDTO.getApplicationDate(), savingsAccountDataDTO.getAppliedBy()); account.approveAndActivateApplication( savingsAccountDataDTO.getApplicationDate().toDate(), savingsAccountDataDTO.getAppliedBy(), savingsAccountDataDTO.getFmt()); this.savingAccountRepository.save(account); if (account.isAccountNumberRequiresAutoGeneration()) { final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory.determineSavingsAccountNoGenerator( account.getId()); account.updateAccountNo(accountNoGenerator.generate()); this.savingAccountRepository.save(account); } return new CommandProcessingResultBuilder() // .withSavingsId(account.getId()) // .setRollbackTransaction(rollbackTransaction) // .build(); }
@Transactional @Override public CommandProcessingResult deleteApplication(final Long savingsId) { final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); checkClientOrGroupActive(account); if (account.isNotSubmittedAndPendingApproval()) { final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) .resource( SAVINGS_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.deleteApplicationAction); baseDataValidator .reset() .parameter(SavingsApiConstants.activatedOnDateParamName) .failWithCodeNoParameterAddedToErrorCode("not.in.submittedandpendingapproval.state"); if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } final List<Note> relatedNotes = this.noteRepository.findBySavingsAccountId(savingsId); this.noteRepository.deleteInBatch(relatedNotes); this.savingAccountRepository.delete(account); return new CommandProcessingResultBuilder() // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); }
@Transactional @Override public CommandProcessingResult postInterest(final Long savingsId, final JsonCommand command) { this.context.authenticatedUser(); final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); final LocalDate today = DateUtils.getLocalDateOfTenant(); account.postInterest(today, existingTransactionIds, existingReversedTransactionIds); this.savingAccountRepository.save(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); }
@Transactional @Override public CommandProcessingResult createSavingAccount(final JsonCommand command) { try { this.context.authenticatedUser(); this.savingsAccountDataValidator.validateForCreate(command.json()); final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); final SavingsAccount account = this.savingAccountAssembler.assembleFrom( command, existingTransactionIds, existingReversedTransactionIds); this.savingAccountRepository.save(account); if (account.isAccountNumberRequiresAutoGeneration()) { final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory.determineLoanAccountNoGenerator(account.getId()); account.updateAccountNo(accountNoGenerator.generate()); this.savingAccountRepository.save(account); } postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); final Long savingsId = account.getId(); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); } catch (DataAccessException dve) { handleDataIntegrityIssues(command, dve); return CommandProcessingResult.empty(); } }
@Transactional @Override public CommandProcessingResult modifyApplication( final Long savingsId, final JsonCommand command) { try { this.savingsAccountDataValidator.validateForUpdate(command.json()); final Map<String, Object> changes = new LinkedHashMap<String, Object>(20); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); checkClientOrGroupActive(account); account.modifyApplication(command, changes); account.validateNewApplicationState(DateUtils.getLocalDateOfTenant()); account.validateAccountValuesWithProduct(); if (!changes.isEmpty()) { if (changes.containsKey(SavingsApiConstants.clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); if (clientId != null) { final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); if (client.isNotActive()) { throw new ClientNotActiveException(clientId); } account.update(client); } else { final Client client = null; account.update(client); } } if (changes.containsKey(SavingsApiConstants.groupIdParamName)) { final Long groupId = command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName); if (groupId != null) { final Group group = this.groupRepository.findOne(groupId); if (group == null) { throw new GroupNotFoundException(groupId); } if (group.isNotActive()) { if (group.isCenter()) { throw new CenterNotActiveException(groupId); } throw new GroupNotActiveException(groupId); } account.update(group); } else { final Group group = null; account.update(group); } } if (changes.containsKey(SavingsApiConstants.productIdParamName)) { final Long productId = command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName); final SavingsProduct product = this.savingsProductRepository.findOne(productId); if (product == null) { throw new SavingsProductNotFoundException(productId); } account.update(product); } if (changes.containsKey(SavingsApiConstants.fieldOfficerIdParamName)) { final Long fieldOfficerId = command.longValueOfParameterNamed(SavingsApiConstants.fieldOfficerIdParamName); Staff fieldOfficer = null; if (fieldOfficerId != null) { fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId); } else { changes.put(SavingsApiConstants.fieldOfficerIdParamName, ""); } account.update(fieldOfficer); } if (changes.containsKey("charges")) { final Set<SavingsAccountCharge> charges = this.savingsAccountChargeAssembler.fromParsedJson( command.parsedJson(), account.getCurrency().getCode()); final boolean updated = account.update(charges); if (!updated) { changes.remove("charges"); } } this.savingAccountRepository.saveAndFlush(account); } return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .with(changes) // .build(); } catch (final DataAccessException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); } }
@Transactional @Override public CommandProcessingResult updateSavingAccount( final Long savingsId, final JsonCommand command) { try { this.context.authenticatedUser(); this.savingsAccountDataValidator.validateForUpdate(command.json()); final Map<String, Object> changes = new LinkedHashMap<String, Object>(20); final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId); account.update(command, changes); if (!changes.isEmpty()) { if (changes.containsKey(SavingsApiConstants.clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); if (clientId != null) { final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); account.update(client); } else { final Client client = null; account.update(client); } } if (changes.containsKey(SavingsApiConstants.groupIdParamName)) { final Long groupId = command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName); if (groupId != null) { final Group group = this.groupRepository.findOne(groupId); if (group == null) { throw new GroupNotFoundException(groupId); } account.update(group); } else { final Group group = null; account.update(group); } } if (changes.containsKey(SavingsApiConstants.productIdParamName)) { final Long productId = command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName); final SavingsProduct product = this.savingsProductRepository.findOne(productId); if (product == null) { throw new SavingsProductNotFoundException(productId); } account.update(product); } this.savingAccountRepository.saveAndFlush(account); } return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(savingsId) // .withOfficeId(account.officeId()) // .withClientId(account.clientId()) // .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .with(changes) // .build(); } catch (DataAccessException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); } }
@Transactional @Override public CommandProcessingResult create(final JsonCommand command) { this.accountTransfersDataValidator.validate(command); final LocalDate transactionDate = command.localDateValueOfParameterNamed(transferDateParamName); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed(transferAmountParamName); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final Integer fromAccountTypeId = command.integerValueSansLocaleOfParameterNamed(fromAccountTypeParamName); final PortfolioAccountType fromAccountType = PortfolioAccountType.fromInt(fromAccountTypeId); final Integer toAccountTypeId = command.integerValueSansLocaleOfParameterNamed(toAccountTypeParamName); final PortfolioAccountType toAccountType = PortfolioAccountType.fromInt(toAccountTypeId); final PaymentDetail paymentDetail = null; Long fromSavingsAccountId = null; Long transferTransactionId = null; if (isSavingsToSavingsAccountTransfer(fromAccountType, toAccountType)) { fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId); final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal( fromSavingsAccount, fmt, transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer()); final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName); final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId); final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit( toSavingsAccount, fmt, transactionDate, transactionAmount, paymentDetail); final AccountTransfer transferTransaction = this.accountTransferAssembler.assembleSavingsToSavingsTransfer( command, withdrawal, deposit); this.accountTransferRepository.saveAndFlush(transferTransaction); transferTransactionId = transferTransaction.getId(); } else if (isSavingsToLoanAccountTransfer(fromAccountType, toAccountType)) { // fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId); final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal( fromSavingsAccount, fmt, transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer()); final Long toLoanAccountId = command.longValueOfParameterNamed(toAccountIdParamName); final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId); final LoanTransaction loanRepaymentTransaction = this.loanAccountDomainService.makeRepayment( toLoanAccount, new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null); final AccountTransfer transferTransaction = this.accountTransferAssembler.assembleSavingsToLoanTransfer( command, fromSavingsAccount, toLoanAccount, withdrawal, loanRepaymentTransaction); this.accountTransferRepository.saveAndFlush(transferTransaction); transferTransactionId = transferTransaction.getId(); } else if (isLoanToSavingsAccountTransfer(fromAccountType, toAccountType)) { // FIXME - kw - ADD overpaid loan to savings account transfer // support. // final Long fromLoanAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); final Loan fromLoanAccount = this.loanAccountAssembler.assembleFrom(fromLoanAccountId); final LoanTransaction loanRefundTransaction = this.loanAccountDomainService.makeRefund( fromLoanAccountId, new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null); final Long toSavingsAccountId = command.longValueOfParameterNamed(toAccountIdParamName); final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsAccountId); final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit( toSavingsAccount, fmt, transactionDate, transactionAmount, paymentDetail); final AccountTransfer transferTransaction = this.accountTransferAssembler.assembleLoanToSavingsTransfer( command, fromLoanAccount, toSavingsAccount, deposit, loanRefundTransaction); this.accountTransferRepository.saveAndFlush(transferTransaction); transferTransactionId = transferTransaction.getId(); } else { } final CommandProcessingResultBuilder builder = new CommandProcessingResultBuilder().withEntityId(transferTransactionId); if (fromAccountType.isSavingsAccount()) { builder.withSavingsId(fromSavingsAccountId); } return builder.build(); }