List of usage examples for org.joda.time.format DateTimeFormat forPattern
public static DateTimeFormatter forPattern(String pattern)
From source file:com.gst.portfolio.client.service.ClientWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
@Transactional @Override// ww w . ja va 2s.c o m public CommandProcessingResult activateClient(final Long clientId, final JsonCommand command) { try { this.fromApiJsonDeserializer.validateActivation(command); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId, true); validateParentGroupRulesBeforeClientActivation(client); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate"); runEntityDatatableCheck(clientId); final AppUser currentUser = this.context.authenticatedUser(); client.activate(currentUser, fmt, activationDate); CommandProcessingResult result = openSavingsAccount(client, fmt); this.clientRepository.saveAndFlush(client); this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.CLIENTS_ACTIVATE, constructEntityMap(BUSINESS_ENTITY.CLIENT, client)); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withOfficeId(client.officeId()) // .withClientId(clientId) // .withEntityId(clientId) // .withSavingsId(result.getSavingsId())// .setRollbackTransaction(result.isRollbackTransaction())// .build(); } catch (final DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } }
From source file:com.gst.portfolio.loanaccount.domain.Loan.java
License:Apache License
public Map<String, Object> loanApplicationRejection(final AppUser currentUser, final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine) { validateAccountStatus(LoanEvent.LOAN_REJECTED); final Map<String, Object> actualChanges = new LinkedHashMap<>(); final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REJECTED, LoanStatus.fromInt(this.loanStatus)); if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); final LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate"); final Locale locale = new Locale(command.locale()); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); this.rejectedOnDate = rejectedOn.toDate(); this.rejectedBy = currentUser; this.closedOnDate = rejectedOn.toDate(); this.closedBy = currentUser; actualChanges.put("locale", command.locale()); actualChanges.put("dateFormat", command.dateFormat()); actualChanges.put("rejectedOnDate", rejectedOn.toString(fmt)); actualChanges.put("closedOnDate", rejectedOn.toString(fmt)); if (rejectedOn.isBefore(getSubmittedOnDate())) { final String errorMessage = "The date on which a loan is rejected cannot be before its submittal date: " + getSubmittedOnDate().toString(); throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn, getSubmittedOnDate()); }//from www. j a v a2s. c o m validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REJECTED, rejectedOn); if (rejectedOn.isAfter(DateUtils.getLocalDateOfTenant())) { final String errorMessage = "The date on which a loan is rejected cannot be in the future."; throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn); } } else { final String errorMessage = "Only the loan applications with status 'Submitted and pending approval' are allowed to be rejected."; throw new InvalidLoanStateTransitionException("reject", "cannot.reject", errorMessage); } return actualChanges; }
From source file:com.gst.portfolio.loanaccount.domain.Loan.java
License:Apache License
public Map<String, Object> loanApplicationWithdrawnByApplicant(final AppUser currentUser, final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine) { final Map<String, Object> actualChanges = new LinkedHashMap<>(); final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_WITHDRAWN, LoanStatus.fromInt(this.loanStatus)); if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate"); if (withdrawnOn == null) { withdrawnOn = command.localDateValueOfParameterNamed("eventDate"); }//from w w w . j a v a 2 s . co m final Locale locale = new Locale(command.locale()); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); this.withdrawnOnDate = withdrawnOn.toDate(); this.withdrawnBy = currentUser; this.closedOnDate = withdrawnOn.toDate(); this.closedBy = currentUser; actualChanges.put("locale", command.locale()); actualChanges.put("dateFormat", command.dateFormat()); actualChanges.put("withdrawnOnDate", withdrawnOn.toString(fmt)); actualChanges.put("closedOnDate", withdrawnOn.toString(fmt)); if (withdrawnOn.isBefore(getSubmittedOnDate())) { final String errorMessage = "The date on which a loan is withdrawn cannot be before its submittal date: " + getSubmittedOnDate().toString(); throw new InvalidLoanStateTransitionException("withdraw", "cannot.be.before.submittal.date", errorMessage, command, getSubmittedOnDate()); } validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_WITHDRAWN, withdrawnOn); if (withdrawnOn.isAfter(DateUtils.getLocalDateOfTenant())) { final String errorMessage = "The date on which a loan is withdrawn cannot be in the future."; throw new InvalidLoanStateTransitionException("withdraw", "cannot.be.a.future.date", errorMessage, command); } } else { final String errorMessage = "Only the loan applications with status 'Submitted and pending approval' are allowed to be withdrawn by applicant."; throw new InvalidLoanStateTransitionException("withdraw", "cannot.withdraw", errorMessage); } return actualChanges; }
From source file:com.gst.portfolio.loanaccount.rescheduleloan.service.LoanRescheduleRequestWritePlatformServiceImpl.java
License:Apache License
@Override @Transactional/*from w ww. j a va2 s .c o m*/ public CommandProcessingResult approve(JsonCommand jsonCommand) { try { final Long loanRescheduleRequestId = jsonCommand.entityId(); final LoanRescheduleRequest loanRescheduleRequest = this.loanRescheduleRequestRepository .findOne(loanRescheduleRequestId); if (loanRescheduleRequest == null) { throw new LoanRescheduleRequestNotFoundException(loanRescheduleRequestId); } // validate the request in the JsonCommand object passed as // parameter this.loanRescheduleRequestDataValidator.validateForApproveAction(jsonCommand, loanRescheduleRequest); final AppUser appUser = this.platformSecurityContext.authenticatedUser(); final Map<String, Object> changes = new LinkedHashMap<>(); LocalDate approvedOnDate = jsonCommand.localDateValueOfParameterNamed("approvedOnDate"); final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(jsonCommand.dateFormat()) .withLocale(jsonCommand.extractLocale()); changes.put("locale", jsonCommand.locale()); changes.put("dateFormat", jsonCommand.dateFormat()); changes.put("approvedOnDate", approvedOnDate.toString(dateTimeFormatter)); changes.put("approvedByUserId", appUser.getId()); Loan loan = loanRescheduleRequest.getLoan(); final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds()); final List<Long> existingReversedTransactionIds = new ArrayList<>( loan.findExistingReversedTransactionIds()); ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, loanRescheduleRequest.getRescheduleFromDate()); Collection<LoanRepaymentScheduleHistory> loanRepaymentScheduleHistoryList = this.loanScheduleHistoryWritePlatformService .createLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), loan, loanRescheduleRequest); final LoanApplicationTerms loanApplicationTerms = loan .constructLoanApplicationTerms(scheduleGeneratorDTO); LocalDate rescheduleFromDate = null; Set<LoanTermVariations> activeLoanTermVariations = loan.getActiveLoanTermVariations(); LoanTermVariations dueDateVariationInCurrentRequest = loanRescheduleRequest .getDueDateTermVariationIfExists(); if (dueDateVariationInCurrentRequest != null && activeLoanTermVariations != null) { LocalDate fromScheduleDate = dueDateVariationInCurrentRequest.fetchTermApplicaDate(); LocalDate currentScheduleDate = fromScheduleDate; LocalDate modifiedScheduleDate = dueDateVariationInCurrentRequest.fetchDateValue(); Map<LocalDate, LocalDate> changeMap = new HashMap<>(); changeMap.put(currentScheduleDate, modifiedScheduleDate); for (LoanTermVariations activeLoanTermVariation : activeLoanTermVariations) { if (activeLoanTermVariation.getTermType().isDueDateVariation() && activeLoanTermVariation .fetchDateValue().equals(dueDateVariationInCurrentRequest.fetchTermApplicaDate())) { activeLoanTermVariation.markAsInactive(); rescheduleFromDate = activeLoanTermVariation.fetchTermApplicaDate(); dueDateVariationInCurrentRequest.setTermApplicableFrom(rescheduleFromDate.toDate()); } else if (!activeLoanTermVariation.fetchTermApplicaDate().isBefore(fromScheduleDate)) { while (currentScheduleDate.isBefore(activeLoanTermVariation.fetchTermApplicaDate())) { currentScheduleDate = this.scheduledDateGenerator.generateNextRepaymentDate( currentScheduleDate, loanApplicationTerms, false, loanApplicationTerms.getHolidayDetailDTO()); modifiedScheduleDate = this.scheduledDateGenerator.generateNextRepaymentDate( modifiedScheduleDate, loanApplicationTerms, false, loanApplicationTerms.getHolidayDetailDTO()); changeMap.put(currentScheduleDate, modifiedScheduleDate); } if (changeMap.containsKey(activeLoanTermVariation.fetchTermApplicaDate())) { activeLoanTermVariation.setTermApplicableFrom( changeMap.get(activeLoanTermVariation.fetchTermApplicaDate()).toDate()); } } } } if (rescheduleFromDate == null) { rescheduleFromDate = loanRescheduleRequest.getRescheduleFromDate(); } for (LoanRescheduleRequestToTermVariationMapping mapping : loanRescheduleRequest .getLoanRescheduleRequestToTermVariationMappings()) { mapping.getLoanTermVariations().updateIsActive(true); } BigDecimal annualNominalInterestRate = null; List<LoanTermVariationsData> loanTermVariations = new ArrayList<>(); loan.constructLoanTermVariations(scheduleGeneratorDTO.getFloatingRateDTO(), annualNominalInterestRate, loanTermVariations); loanApplicationTerms.getLoanTermVariations().setExceptionData(loanTermVariations); /*for (LoanTermVariationsData loanTermVariation : loanApplicationTerms.getLoanTermVariations().getDueDateVariation()) { if (rescheduleFromDate.isBefore(loanTermVariation.getTermApplicableFrom())) { LocalDate applicableDate = this.scheduledDateGenerator.generateNextRepaymentDate(rescheduleFromDate, loanApplicationTerms, false, loanApplicationTerms.getHolidayDetailDTO()); if (loanTermVariation.getTermApplicableFrom().equals(applicableDate)) { LocalDate adjustedDate = this.scheduledDateGenerator.generateNextRepaymentDate(adjustedApplicableDate, loanApplicationTerms, false, loanApplicationTerms.getHolidayDetailDTO()); loanTermVariation.setApplicableFromDate(adjustedDate); } } }*/ final RoundingMode roundingMode = MoneyHelper.getRoundingMode(); final MathContext mathContext = new MathContext(8, roundingMode); final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.loanRepaymentScheduleTransactionProcessorFactory .determineProcessor(loan.transactionProcessingStrategy()); final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory .create(loanApplicationTerms.getInterestMethod()); final LoanLifecycleStateMachine loanLifecycleStateMachine = null; loan.setHelpers(loanLifecycleStateMachine, this.loanSummaryWrapper, this.loanRepaymentScheduleTransactionProcessorFactory); final LoanScheduleDTO loanSchedule = loanScheduleGenerator.rescheduleNextInstallments(mathContext, loanApplicationTerms, loan, loanApplicationTerms.getHolidayDetailDTO(), loanRepaymentScheduleTransactionProcessor, rescheduleFromDate); loan.updateLoanSchedule(loanSchedule.getInstallments(), appUser); loan.recalculateAllCharges(); ChangedTransactionDetail changedTransactionDetail = loan.processTransactions(); for (LoanRepaymentScheduleHistory loanRepaymentScheduleHistory : loanRepaymentScheduleHistoryList) { this.loanRepaymentScheduleHistoryRepository.save(loanRepaymentScheduleHistory); } loan.updateRescheduledByUser(appUser); loan.updateRescheduledOnDate(new LocalDate()); // update the status of the request loanRescheduleRequest.approve(appUser, approvedOnDate); // update the loan object saveAndFlushLoanWithDataIntegrityViolationChecks(loan); if (changedTransactionDetail != null) { for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail .getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created // transactions loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); this.loanAccountDomainService.recalculateAccruals(loan, true); return new CommandProcessingResultBuilder().withCommandId(jsonCommand.commandId()) .withEntityId(loanRescheduleRequestId).withLoanId(loanRescheduleRequest.getLoan().getId()) .with(changes).build(); } catch (final DataIntegrityViolationException dve) { // handle the data integrity violation handleDataIntegrityViolation(dve); // return an empty command processing result object return CommandProcessingResult.empty(); } }
From source file:com.gst.portfolio.loanaccount.rescheduleloan.service.LoanRescheduleRequestWritePlatformServiceImpl.java
License:Apache License
@Override @Transactional/*w w w . ja v a2 s. c o m*/ public CommandProcessingResult reject(JsonCommand jsonCommand) { try { final Long loanRescheduleRequestId = jsonCommand.entityId(); final LoanRescheduleRequest loanRescheduleRequest = loanRescheduleRequestRepository .findOne(loanRescheduleRequestId); if (loanRescheduleRequest == null) { throw new LoanRescheduleRequestNotFoundException(loanRescheduleRequestId); } // validate the request in the JsonCommand object passed as // parameter this.loanRescheduleRequestDataValidator.validateForRejectAction(jsonCommand, loanRescheduleRequest); final AppUser appUser = this.platformSecurityContext.authenticatedUser(); final Map<String, Object> changes = new LinkedHashMap<>(); LocalDate rejectedOnDate = jsonCommand.localDateValueOfParameterNamed("rejectedOnDate"); final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(jsonCommand.dateFormat()) .withLocale(jsonCommand.extractLocale()); changes.put("locale", jsonCommand.locale()); changes.put("dateFormat", jsonCommand.dateFormat()); changes.put("rejectedOnDate", rejectedOnDate.toString(dateTimeFormatter)); changes.put("rejectedByUserId", appUser.getId()); if (!changes.isEmpty()) { loanRescheduleRequest.reject(appUser, rejectedOnDate); Set<LoanRescheduleRequestToTermVariationMapping> loanRescheduleRequestToTermVariationMappings = loanRescheduleRequest .getLoanRescheduleRequestToTermVariationMappings(); for (LoanRescheduleRequestToTermVariationMapping loanRescheduleRequestToTermVariationMapping : loanRescheduleRequestToTermVariationMappings) { loanRescheduleRequestToTermVariationMapping.getLoanTermVariations().markAsInactive(); } } return new CommandProcessingResultBuilder().withCommandId(jsonCommand.commandId()) .withEntityId(loanRescheduleRequestId).withLoanId(loanRescheduleRequest.getLoan().getId()) .with(changes).build(); } catch (final DataIntegrityViolationException dve) { // handle the data integrity violation handleDataIntegrityViolation(dve); // return an empty command processing result object return CommandProcessingResult.empty(); } }
From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
@Transactional @Override/*from w ww . j a v a 2s .co m*/ public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand command, Boolean isAccountTransfer) { final AppUser currentUser = getAppUserIfPresent(); this.loanEventApiJsonValidator.validateDisbursement(command.json(), isAccountTransfer); final Loan loan = this.loanAssembler.assembleFrom(loanId); final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate"); // validate ActualDisbursement Date Against Expected Disbursement Date LoanProduct loanProduct = loan.loanProduct(); if (loanProduct.syncExpectedWithDisbursementDate()) { syncExpectedDateWithActualDisbursementDate(loan, actualDisbursementDate); } checkClientOrGroupActive(loan); final LocalDate nextPossibleRepaymentDate = loan.getNextPossibleRepaymentDateForRescheduling(); final Date rescheduledRepaymentDate = command.DateValueOfParameterNamed("adjustRepaymentDate"); entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(), StatusEnum.DISBURSE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId()); // check for product mix validations checkForProductMixRestrictions(loan); LocalDate recalculateFrom = null; ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); // validate actual disbursement date against meeting date final CalendarInstance calendarInstance = this.calendarInstanceRepository .findCalendarInstaneByEntityId(loan.getId(), CalendarEntityType.LOANS.getValue()); if (loan.isSyncDisbursementWithMeeting()) { this.loanEventApiJsonValidator.validateDisbursementDateWithMeetingDate(actualDisbursementDate, calendarInstance, scheduleGeneratorDTO.isSkipRepaymentOnFirstDayofMonth(), scheduleGeneratorDTO.getNumberOfdays()); } this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL, constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); final List<Long> existingTransactionIds = new ArrayList<>(); final List<Long> existingReversedTransactionIds = new ArrayList<>(); final Map<String, Object> changes = new LinkedHashMap<>(); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService .createAndPersistPaymentDetail(command, changes); final Boolean isPaymnetypeApplicableforDisbursementCharge = configurationDomainService .isPaymnetypeApplicableforDisbursementCharge(); // Recalculate first repayment date based in actual disbursement date. updateLoanCounters(loan, actualDisbursementDate); Money amountBeforeAdjust = loan.getPrincpal(); loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED); boolean canDisburse = loan.canDisburse(actualDisbursementDate); ChangedTransactionDetail changedTransactionDetail = null; if (canDisburse) { Money disburseAmount = loan.adjustDisburseAmount(command, actualDisbursementDate); Money amountToDisburse = disburseAmount.copy(); boolean recalculateSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincpal()); final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId"); if (loan.isTopup() && loan.getClientId() != null) { final Long loanIdToClose = loan.getTopupLoanDetails().getLoanIdToClose(); final Loan loanToClose = this.loanRepositoryWrapper .findNonClosedLoanThatBelongsToClient(loanIdToClose, loan.getClientId()); if (loanToClose == null) { throw new GeneralPlatformDomainRuleException( "error.msg.loan.to.be.closed.with.topup.is.not.active", "Loan to be closed with this topup is not active."); } final LocalDate lastUserTransactionOnLoanToClose = loanToClose.getLastUserTransactionDate(); if (!loan.getDisbursementDate().isAfter(lastUserTransactionOnLoanToClose)) { throw new GeneralPlatformDomainRuleException( "error.msg.loan.disbursal.date.should.be.after.last.transaction.date.of.loan.to.be.closed", "Disbursal date of this loan application " + loan.getDisbursementDate() + " should be after last transaction date of loan to be closed " + lastUserTransactionOnLoanToClose); } BigDecimal loanOutstanding = this.loanReadPlatformService .retrieveLoanPrePaymentTemplate(loanIdToClose, actualDisbursementDate).getAmount(); final BigDecimal firstDisbursalAmount = loan.getFirstDisbursalAmount(); if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) { throw new GeneralPlatformDomainRuleException( "error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed", "Topup loan amount should be greater than outstanding amount of loan to be closed."); } amountToDisburse = disburseAmount.minus(loanOutstanding); disburseLoanToLoan(loan, command, loanOutstanding); } if (isAccountTransfer) { disburseLoanToSavings(loan, command, amountToDisburse, paymentDetail); existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); } else { existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amountToDisburse, paymentDetail, actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); disbursementTransaction.updateLoan(loan); loan.addLoanTransaction(disbursementTransaction); } regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO); } if (isPaymnetypeApplicableforDisbursementCharge) { changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, paymentDetail); } else { changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null); } } if (!changes.isEmpty()) { saveAndFlushLoanWithDataIntegrityViolationChecks(loan); final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } if (changedTransactionDetail != null) { for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail .getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } // auto create standing instruction createStandingInstruction(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); } final Set<LoanCharge> loanCharges = loan.charges(); final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>(); for (final LoanCharge loanCharge : loanCharges) { if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer() && loanCharge.isChargePending()) { disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding()); } } final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) { final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService .retriveLoanLinkedAssociation(loanId); final SavingsAccount fromSavingsAccount = null; final boolean isRegularTransaction = true; final boolean isExceptionForBalanceCheck = false; final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null, AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } updateRecurringCalendarDatesForInterestRecalculation(loan); this.loanAccountDomainService.recalculateAccruals(loan); this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL, constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(loan.getId()) // .withOfficeId(loan.getOfficeId()) // .withClientId(loan.getClientId()) // .withGroupId(loan.getGroupId()) // .withLoanId(loanId) // .with(changes) // .build(); }
From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
/**** * TODO Vishwas: Pair with Ashok and re-factor collection sheet code-base * /* w w w . ja v a 2 s.co m*/ * May of the changes made to disburseLoan aren't being made here, should * refactor to reuse disburseLoan ASAP *****/ @Transactional @Override public Map<String, Object> bulkLoanDisbursal(final JsonCommand command, final CollectionSheetBulkDisbursalCommand bulkDisbursalCommand, Boolean isAccountTransfer) { final AppUser currentUser = getAppUserIfPresent(); final SingleDisbursalCommand[] disbursalCommand = bulkDisbursalCommand.getDisburseTransactions(); final Map<String, Object> changes = new LinkedHashMap<>(); if (disbursalCommand == null) { return changes; } final LocalDate nextPossibleRepaymentDate = null; final Date rescheduledRepaymentDate = null; for (int i = 0; i < disbursalCommand.length; i++) { final SingleDisbursalCommand singleLoanDisbursalCommand = disbursalCommand[i]; final Loan loan = this.loanAssembler.assembleFrom(singleLoanDisbursalCommand.getLoanId()); final LocalDate actualDisbursementDate = command .localDateValueOfParameterNamed("actualDisbursementDate"); // validate ActualDisbursement Date Against Expected Disbursement Date LoanProduct loanProduct = loan.loanProduct(); if (loanProduct.syncExpectedWithDisbursementDate()) { syncExpectedDateWithActualDisbursementDate(loan, actualDisbursementDate); } checkClientOrGroupActive(loan); this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL, constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); final List<Long> existingTransactionIds = new ArrayList<>(); final List<Long> existingReversedTransactionIds = new ArrayList<>(); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService .createAndPersistPaymentDetail(command, changes); // Bulk disbursement should happen on meeting date (mostly from // collection sheet). // FIXME: AA - this should be first meeting date based on // disbursement date and next available meeting dates // assuming repayment schedule won't regenerate because expected // disbursement and actual disbursement happens on same date loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED); updateLoanCounters(loan, actualDisbursementDate); boolean canDisburse = loan.canDisburse(actualDisbursementDate); ChangedTransactionDetail changedTransactionDetail = null; if (canDisburse) { Money amountBeforeAdjust = loan.getPrincpal(); Money disburseAmount = loan.adjustDisburseAmount(command, actualDisbursementDate); boolean recalculateSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincpal()); final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId"); if (isAccountTransfer) { disburseLoanToSavings(loan, command, disburseAmount, paymentDetail); existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); } else { existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail, actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); disbursementTransaction.updateLoan(loan); loan.addLoanTransaction(disbursementTransaction); } LocalDate recalculateFrom = null; final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService .buildScheduleGeneratorDTO(loan, recalculateFrom); regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO); } if (configurationDomainService.isPaymnetypeApplicableforDisbursementCharge()) { changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, paymentDetail); } else { changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null); } } if (!changes.isEmpty()) { saveAndFlushLoanWithDataIntegrityViolationChecks(loan); final String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { final Note note = Note.loanNote(loan, noteText); this.noteRepository.save(note); } if (changedTransactionDetail != null) { for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail .getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); } final Set<LoanCharge> loanCharges = loan.charges(); final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>(); for (final LoanCharge loanCharge : loanCharges) { if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer() && loanCharge.isChargePending()) { disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding()); } } final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) { final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService .retriveLoanLinkedAssociation(loan.getId()); final SavingsAccount fromSavingsAccount = null; final boolean isRegularTransaction = true; final boolean isExceptionForBalanceCheck = false; final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(), "Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null, AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } updateRecurringCalendarDatesForInterestRecalculation(loan); this.loanAccountDomainService.recalculateAccruals(loan); this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL, constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); } return changes; }
From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
@Override @Transactional/*from w w w. j ava 2 s . c om*/ public CommandProcessingResult payLoanCharge(final Long loanId, Long loanChargeId, final JsonCommand command, final boolean isChargeIdIncludedInJson) { this.loanEventApiJsonValidator.validateChargePaymentTransaction(command.json(), isChargeIdIncludedInJson); if (isChargeIdIncludedInJson) { loanChargeId = command.longValueOfParameterNamed("chargeId"); } final Loan loan = this.loanAssembler.assembleFrom(loanId); checkClientOrGroupActive(loan); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); // Charges may be waived only when the loan associated with them are // active if (!loan.status().isActive()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.LOAN_INACTIVE, loanCharge.getId()); } // validate loan charge is not already paid or waived if (loanCharge.isWaived()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId()); } else if (loanCharge.isPaid()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId()); } if (!loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) { throw new LoanChargeCannotBePayedException( LOAN_CHARGE_CANNOT_BE_PAYED_REASON.CHARGE_NOT_ACCOUNT_TRANSFER, loanCharge.getId()); } final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); Integer loanInstallmentNumber = null; BigDecimal amount = loanCharge.amountOutstanding(); if (loanCharge.isInstalmentFee()) { LoanInstallmentCharge chargePerInstallment = null; final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate"); final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber"); if (dueDate != null) { chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate); } else if (installmentNumber != null) { chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber); } if (chargePerInstallment == null) { chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge(); } if (chargePerInstallment.isWaived()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_WAIVED, loanCharge.getId()); } else if (chargePerInstallment.isPaid()) { throw new LoanChargeCannotBePayedException(LOAN_CHARGE_CANNOT_BE_PAYED_REASON.ALREADY_PAID, loanCharge.getId()); } loanInstallmentNumber = chargePerInstallment.getRepaymentInstallment().getInstallmentNumber(); amount = chargePerInstallment.getAmountOutstanding(); } final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService .retriveLoanLinkedAssociation(loanId); if (portfolioAccountData == null) { final String errorMessage = "Charge with id:" + loanChargeId + " requires linked savings account for payment"; throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId); } final SavingsAccount fromSavingsAccount = null; final boolean isRegularTransaction = true; final boolean isExceptionForBalanceCheck = false; final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber, AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(loanChargeId) // .withOfficeId(loan.getOfficeId()) // .withClientId(loan.getClientId()) // .withGroupId(loan.getGroupId()) // .withLoanId(loanId) // .withSavingsId(portfolioAccountData.accountId()).build(); }
From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
public void disburseLoanToLoan(final Loan loan, final JsonCommand command, final BigDecimal amount) { final LocalDate transactionDate = command.localDateValueOfParameterNamed("actualDisbursementDate"); final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId"); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.LOAN, PortfolioAccountType.LOAN, loan.getId(), loan.getTopupLoanDetails().getLoanIdToClose(), "Loan Topup", locale, fmt, LoanTransactionType.DISBURSEMENT.getValue(), LoanTransactionType.REPAYMENT.getValue(), txnExternalId, loan, null);//w w w. j a v a 2 s . com AccountTransferDetails accountTransferDetails = this.accountTransfersWritePlatformService .repayLoanWithTopup(accountTransferDTO); loan.getTopupLoanDetails().setAccountTransferDetails(accountTransferDetails.getId()); loan.getTopupLoanDetails().setTopupAmount(amount); }
From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java
License:Apache License
public void disburseLoanToSavings(final Loan loan, final JsonCommand command, final Money amount, final PaymentDetail paymentDetail) { final LocalDate transactionDate = command.localDateValueOfParameterNamed("actualDisbursementDate"); final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId"); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService .retriveLoanLinkedAssociation(loan.getId()); if (portfolioAccountData == null) { final String errorMessage = "Disburse Loan with id:" + loan.getId() + " requires linked savings account for payment"; throw new LinkedAccountRequiredException("loan.disburse.to.savings", errorMessage, loan.getId()); }/*from www . j a v a 2s. c om*/ final SavingsAccount fromSavingsAccount = null; final boolean isExceptionForBalanceCheck = false; final boolean isRegularTransaction = true; final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount.getAmount(), PortfolioAccountType.LOAN, PortfolioAccountType.SAVINGS, loan.getId(), portfolioAccountData.accountId(), "Loan Disbursement", locale, fmt, paymentDetail, LoanTransactionType.DISBURSEMENT.getValue(), null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, txnExternalId, loan, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); }