@Transactional @Override public EntityIdentifier waiveLoanCharge(final LoanChargeCommand command) { this.context.authenticatedUser(); // LoanChargeCommandValidator validator = new // LoanChargeCommandValidator(command); // validator.validateForUpdate(); final Long loanId = command.getLoanId(); final Loan loan = retrieveLoanBy(loanId); final Long loanChargeId = command.getId(); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine()); this.loanTransactionRepository.save(waiveTransaction); this.loanRepository.save(loan); final String noteText = ""; // command.getNote(); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.loanTransactionNote(loan, waiveTransaction, noteText); this.noteRepository.save(note); } return new EntityIdentifier(loanCharge.getId()); }
@Transactional @Override public EntityIdentifier waiveInterestOnLoan(final LoanTransactionCommand command) { context.authenticatedUser(); final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command); validator.validate(); final Loan loan = this.loanRepository.findOne(command.getLoanId()); if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); } final LoanTransaction waiveTransaction = loan.waiveInterest( command.getTransactionAmount(), command.getTransactionDate(), defaultLoanLifecycleStateMachine()); this.loanTransactionRepository.save(waiveTransaction); this.loanRepository.save(loan); final String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.loanTransactionNote(loan, waiveTransaction, noteText); this.noteRepository.save(note); } return new EntityIdentifier(loan.getId()); }
@Transactional @Override public EntityIdentifier closeAsRescheduled(final LoanTransactionCommand command) { context.authenticatedUser(); final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command); validator.validateNonMonetaryTransaction(); final Loan loan = this.loanRepository.findOne(command.getLoanId()); if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); } loan.closeAsMarkedForReschedule( command.getTransactionDate(), defaultLoanLifecycleStateMachine()); this.loanRepository.save(loan); final String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } return new EntityIdentifier(loan.getId()); }
@Transactional @Override public EntityIdentifier disburseLoan(final Long loanId, final JsonCommand command) { final AppUser currentUser = context.authenticatedUser(); final LoanStateTransitionCommand disburseLoan = this.loanStateTransitionCommandFromApiJsonDeserializer.commandFromApiJson(command.json()); disburseLoan.validate(); final Loan loan = retrieveLoanBy(loanId); final String noteText = command.stringValueOfParameterNamed("note"); final LocalDate actualDisbursementDate = disburseLoan.getDisbursedOnDate(); if (this.isBeforeToday(actualDisbursementDate) && currentUser.canNotDisburseLoanInPast()) { throw new NoAuthorizationException( "User has no authority to disburse loan with a date in the past."); } final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode()); final Map<String, Object> changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency); this.loanRepository.save(loan); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } return EntityIdentifier.resourceResult(loanId, command.commandId(), changes); }
@Transactional @Override public EntityIdentifier applicantWithdrawsFromLoanApplication( final Long loanId, final JsonCommand command) { final AppUser currentUser = context.authenticatedUser(); final LoanStateTransitionCommand applicantWithdrawsFromLoanApplication = this.loanStateTransitionCommandFromApiJsonDeserializer.commandFromApiJson(command.json()); applicantWithdrawsFromLoanApplication.validate(); final Loan loan = retrieveLoanBy(loanId); final LocalDate eventDate = applicantWithdrawsFromLoanApplication.getWithdrawnOnDate(); if (this.isBeforeToday(eventDate) && currentUser.canNotWithdrawByClientLoanInPast()) { throw new NoAuthorizationException( "User has no authority to mark loan as withdrawn by applicant with a date in the past."); } final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine()); this.loanRepository.save(loan); String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } return EntityIdentifier.resourceResult(loanId, command.commandId(), changes); }
@Transactional @Override public EntityIdentifier submitLoanApplication(final JsonCommand command) { context.authenticatedUser(); LoanApplicationCommand loanApplicationCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); loanApplicationCommand.validate(); CalculateLoanScheduleQuery calculateLoanScheduleQuery = this.calculateLoanScheduleQueryFromApiJsonDeserializer.commandFromApiJson(command.json()); calculateLoanScheduleQuery.validate(); final Loan newLoanApplication = loanAssembler.assembleFrom(command); this.loanRepository.save(newLoanApplication); final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote"); if (StringUtils.isNotBlank(submittedOnNote)) { Note note = Note.loanNote(newLoanApplication, submittedOnNote); this.noteRepository.save(note); } return EntityIdentifier.resourceResult(newLoanApplication.getId(), command.commandId()); }
@Transactional @Override public EntityIdentifier adjustLoanTransaction(final AdjustLoanTransactionCommand command) { context.authenticatedUser(); AdjustLoanTransactionCommandValidator validator = new AdjustLoanTransactionCommandValidator(command); validator.validate(); Loan loan = this.loanRepository.findOne(command.getLoanId()); if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); } LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(command.getTransactionId()); if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(command.getTransactionId()); } final MonetaryCurrency currency = loan.repaymentScheduleDetail().getPrincipal().getCurrency(); final Money transactionAmount = Money.of(currency, command.getTransactionAmount()); // adjustment is only supported for repayments and waivers at present LocalDate transactionDate = command.getTransactionDate(); LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmount, transactionDate); if (transactionToAdjust.isInterestWaiver()) { newTransactionDetail = LoanTransaction.waiver(loan, transactionAmount, transactionDate); } loan.adjustExistingTransaction( transactionToAdjust, newTransactionDetail, defaultLoanLifecycleStateMachine()); if (newTransactionDetail.isGreaterThanZero(currency)) { this.loanTransactionRepository.save(newTransactionDetail); } this.loanRepository.save(loan); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanTransactionNote(loan, newTransactionDetail, noteText); this.noteRepository.save(note); } return new EntityIdentifier(loan.getId()); }
@Transactional @Override public EntityIdentifier approveDepositApplication( final DepositStateTransitionApprovalCommand command) { // AppUser currentUser = context.authenticatedUser(); DepositStateTransitionApprovalCommandValidator validator = new DepositStateTransitionApprovalCommandValidator(command); validator.validate(); DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } // FIXME - madhukar - you are checking for loan permission here instead // of some specific deposit account permission. // removing check for now until rules dealing with creating and // maintaining deposit accounts in the past is clarified LocalDate eventDate = command.getEventDate(); // if (this.isBeforeToday(eventDate) && // currentUser.canNotApproveLoanInPast()) { // throw new // NoAuthorizationException("User has no authority to approve deposit with a date in the // past."); // } account.approve( eventDate, defaultDepositLifecycleStateMachine(), command, this.fixedTermDepositInterestCalculator); this.depositAccountRepository.save(account); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } return new EntityIdentifier(account.getId()); }
@Transactional @Override public EntityIdentifier withdrawDepositAccountMoney( final DepositAccountWithdrawalCommand command) { context.authenticatedUser(); DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command); validator.validate(); DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } LocalDate eventDate = command.getMaturesOnDate(); Integer lockinPeriod = account.getLockinPeriod(); LocalDate lockinPeriodExpDate = account.getActualCommencementDate().plusMonths(Integer.valueOf(lockinPeriod)); if (account.isLockinPeriodAllowed()) { if (eventDate.isBefore(lockinPeriodExpDate)) { throw new DepositAccountTransactionsException( "deposit.transaction.canot.withdraw.before.lockinperiod.reached", "You can not withdraw your application before maturity date reached"); } } // if (eventDate.isBefore(account.maturesOnDate())) { // this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account, // eventDate); // } account.withdrawDepositAccountMoney( defaultDepositLifecycleStateMachine(), fixedTermDepositInterestCalculator, eventDate); this.depositAccountRepository.save(account); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } return new EntityIdentifier(account.getId()); }
@Transactional @Override public EntityIdentifier undoLoanDisbursal(final Long loanId, final JsonCommand command) { context.authenticatedUser(); final Loan loan = retrieveLoanBy(loanId); final Map<String, Object> changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine()); this.loanRepository.save(loan); final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } return EntityIdentifier.resourceResult(loanId, command.commandId(), changes); }
@Transactional @Override public EntityIdentifier undoDepositApproval(UndoStateTransitionCommand command) { context.authenticatedUser(); DepositAccount account = this.depositAccountRepository.findOne(command.getLoanId()); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getLoanId()); } account.undoDepositApproval(defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } return new EntityIdentifier(account.getId()); }
@Transactional @Override public EntityIdentifier makeLoanRepayment(final LoanTransactionCommand command) { AppUser currentUser = context.authenticatedUser(); LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command); validator.validate(); Loan loan = this.loanRepository.findOne(command.getLoanId()); if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); } LocalDate transactionDate = command.getTransactionDate(); if (this.isBeforeToday(transactionDate) && currentUser.canNotMakeRepaymentOnLoanInPast()) { throw new NoAuthorizationException( "error.msg.no.permission.to.make.repayment.on.loan.in.past"); } Money repayment = Money.of( loan.repaymentScheduleDetail().getPrincipal().getCurrency(), command.getTransactionAmount()); LoanTransaction loanRepayment = LoanTransaction.repayment(repayment, transactionDate); loan.makeRepayment(loanRepayment, defaultLoanLifecycleStateMachine()); this.loanTransactionRepository.save(loanRepayment); this.loanRepository.save(loan); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.loanTransactionNote(loan, loanRepayment, noteText); this.noteRepository.save(note); } return new EntityIdentifier(loan.getId()); }
@Transactional @Override public EntityIdentifier withdrawDepositApplication(DepositStateTransitionCommand command) { // AppUser currentUser = context.authenticatedUser(); DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); validator.validate(); DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } // removing check for now until rules dealing with creating and // maintaining deposit accounts in the past is clarified LocalDate eventDate = command.getEventDate(); // if (this.isBeforeToday(eventDate) && // currentUser.canNotApproveLoanInPast()) { // throw new // NoAuthorizationException("User has no authority to approve deposit with a date in the // past."); // } account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } return new EntityIdentifier(account.getId()); }
@Transactional @Override public EntityIdentifier modifyLoanApplication(final Long loanId, final JsonCommand command) { context.authenticatedUser(); LoanApplicationCommand loanApplicationCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); loanApplicationCommand.validate(); CalculateLoanScheduleQuery calculateLoanScheduleQuery = this.calculateLoanScheduleQueryFromApiJsonDeserializer.commandFromApiJson(command.json()); calculateLoanScheduleQuery.validate(); final Loan existingLoanApplication = retrieveLoanBy(loanId); final Map<String, Object> changes = existingLoanApplication.modifyLoanApplication( command, loanApplicationCommand.getCharges(), this.aprCalculator); final String clientIdParamName = "clientId"; if (changes.containsKey(clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(clientIdParamName); final Client client = this.clientRepository.findOne(clientId); if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } existingLoanApplication.updateClient(client); } final String productIdParamName = "productId"; if (changes.containsKey(productIdParamName)) { final Long productId = command.longValueOfParameterNamed(productIdParamName); final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } existingLoanApplication.updateLoanProduct(loanProduct); } final String fundIdParamName = "fundId"; if (changes.containsKey(fundIdParamName)) { final Long fundId = command.longValueOfParameterNamed(fundIdParamName); final Fund fund = this.loanAssembler.findFundByIdIfProvided(fundId); existingLoanApplication.updateFund(fund); } final String strategyIdParamName = "transactionProcessingStrategyId"; if (changes.containsKey(strategyIdParamName)) { final Long strategyId = command.longValueOfParameterNamed(strategyIdParamName); final LoanTransactionProcessingStrategy strategy = this.loanAssembler.findStrategyByIdIfProvided(strategyId); existingLoanApplication.updateTransactionProcessingStrategy(strategy); } final String chargesParamName = "charges"; if (changes.containsKey(chargesParamName)) { final Set<LoanCharge> loanCharges = this.loanChargeAssembler.fromParsedJson(command.parsedJson()); existingLoanApplication.updateLoanCharges(loanCharges); } if (changes.containsKey("recalculateLoanSchedule")) { changes.remove("recalculateLoanSchedule"); final JsonElement parsedQuery = this.fromJsonHelper.parse(command.json()); final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper); final LoanScheduleData loanSchedule = this.calculationPlatformService.calculateLoanSchedule(query); existingLoanApplication.updateLoanSchedule(loanSchedule); existingLoanApplication.updateLoanScheduleDependentDerivedFields(); } this.loanRepository.save(existingLoanApplication); final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote"); if (StringUtils.isNotBlank(submittedOnNote)) { Note note = Note.loanNote(existingLoanApplication, submittedOnNote); this.noteRepository.save(note); } return EntityIdentifier.resourceResult(loanId, command.commandId(), changes); }