@Transactional
  @Override
  public CommandProcessingResult officeTransaction(final JsonCommand command) {

    context.authenticatedUser();

    this.moneyTransferCommandFromApiJsonDeserializer.validateOfficeTransfer(command.json());

    Long officeId = null;
    Office fromOffice = null;
    final Long fromOfficeId = command.longValueOfParameterNamed("fromOfficeId");
    if (fromOfficeId != null) {
      fromOffice = this.officeRepository.findOne(fromOfficeId);
      officeId = fromOffice.getId();
    }
    Office toOffice = null;
    final Long toOfficeId = command.longValueOfParameterNamed("toOfficeId");
    if (toOfficeId != null) {
      toOffice = this.officeRepository.findOne(toOfficeId);
      officeId = toOffice.getId();
    }

    if (fromOffice == null && toOffice == null) {
      throw new OfficeNotFoundException(toOfficeId);
    }

    final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
    final ApplicationCurrency appCurrency =
        this.applicationCurrencyRepository.findOneByCode(currencyCode);
    if (appCurrency == null) {
      throw new CurrencyNotFoundException(currencyCode);
    }

    final MonetaryCurrency currency =
        new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces());
    final Money amount =
        Money.of(currency, command.bigDecimalValueOfParameterNamed("transactionAmount"));

    final OfficeTransaction entity =
        OfficeTransaction.fromJson(fromOffice, toOffice, amount, command);

    this.officeTransactionRepository.save(entity);

    return new CommandProcessingResultBuilder() //
        .withCommandId(command.commandId()) //
        .withEntityId(entity.getId()) //
        .withOfficeId(officeId) //
        .build();
  }
  @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();
  }
Пример #3
0
  public Map<String, Object> update(final JsonCommand command, final BigDecimal amount) {

    final Map<String, Object> actualChanges = new LinkedHashMap<>(7);

    final String dateFormatAsInput = command.dateFormat();
    final String localeAsInput = command.locale();

    final String dueDateParamName = "dueDate";
    if (command.isChangeInLocalDateParameterNamed(dueDateParamName, getDueLocalDate())) {
      final String valueAsInput = command.stringValueOfParameterNamed(dueDateParamName);
      actualChanges.put(dueDateParamName, valueAsInput);
      actualChanges.put("dateFormat", dateFormatAsInput);
      actualChanges.put("locale", localeAsInput);

      final LocalDate newValue = command.localDateValueOfParameterNamed(dueDateParamName);
      this.dueDate = newValue.toDate();
    }

    final String amountParamName = "amount";
    if (command.isChangeInBigDecimalParameterNamed(amountParamName, this.amount)) {
      final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountParamName);
      actualChanges.put(amountParamName, newValue);
      actualChanges.put("locale", localeAsInput);
      switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
        case INVALID:
          break;
        case FLAT:
          if (isInstalmentFee()) {
            this.amount =
                newValue.multiply(
                    BigDecimal.valueOf(
                        this.loan.repaymentScheduleDetail().getNumberOfRepayments()));
          } else {
            this.amount = newValue;
          }
          this.amountOutstanding = calculateOutstanding();
          break;
        case PERCENT_OF_AMOUNT:
        case PERCENT_OF_AMOUNT_AND_INTEREST:
        case PERCENT_OF_INTEREST:
          this.percentage = newValue;
          this.amountPercentageAppliedTo = amount;
          BigDecimal loanCharge = BigDecimal.ZERO;
          if (isInstalmentFee()) {
            loanCharge =
                this.loan.calculatePerInstallmentChargeAmount(
                    ChargeCalculationType.fromInt(this.chargeCalculation), this.percentage);
          }
          if (loanCharge.compareTo(BigDecimal.ZERO) == 0) {
            loanCharge = percentageOf(this.amountPercentageAppliedTo);
          }
          this.amount = minimumAndMaximumCap(loanCharge);
          this.amountOutstanding = calculateOutstanding();
          break;
      }
      this.amountOrPercentage = newValue;
      if (isInstalmentFee()) {
        final Set<LoanInstallmentCharge> chargePerInstallments =
            this.loan.generateInstallmentLoanCharges(this);
        if (this.loanInstallmentCharge.isEmpty()) {
          this.loanInstallmentCharge.addAll(chargePerInstallments);
        } else {
          int index = 0;
          final LoanInstallmentCharge[] loanChargePerInstallments =
              new LoanInstallmentCharge[chargePerInstallments.size()];
          final LoanInstallmentCharge[] loanChargePerInstallmentArray =
              chargePerInstallments.toArray(loanChargePerInstallments);
          for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
            chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
          }
        }
      }
    }
    return actualChanges;
  }
  @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();
  }
Пример #5
0
  public static LoanCharge createNewFromJson(
      final Loan loan,
      final Charge chargeDefinition,
      final JsonCommand command,
      final LocalDate dueDate) {
    final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount");

    final ChargeTimeType chargeTime = null;
    final ChargeCalculationType chargeCalculation = null;
    final ChargePaymentMode chargePaymentMode = null;
    BigDecimal amountPercentageAppliedTo = BigDecimal.ZERO;
    switch (ChargeCalculationType.fromInt(chargeDefinition.getChargeCalculation())) {
      case PERCENT_OF_AMOUNT:
        if (command.hasParameter("principal")) {
          amountPercentageAppliedTo = command.bigDecimalValueOfParameterNamed("principal");
        } else {
          amountPercentageAppliedTo = loan.getPrincpal().getAmount();
        }
        break;
      case PERCENT_OF_AMOUNT_AND_INTEREST:
        if (command.hasParameter("principal") && command.hasParameter("interest")) {
          amountPercentageAppliedTo =
              command
                  .bigDecimalValueOfParameterNamed("principal")
                  .add(command.bigDecimalValueOfParameterNamed("interest"));
        } else {
          amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getTotalInterest());
        }
        break;
      case PERCENT_OF_INTEREST:
        if (command.hasParameter("interest")) {
          amountPercentageAppliedTo = command.bigDecimalValueOfParameterNamed("interest");
        } else {
          amountPercentageAppliedTo = loan.getTotalInterest();
        }
        break;
      default:
        break;
    }

    BigDecimal loanCharge = BigDecimal.ZERO;
    if (ChargeTimeType.fromInt(chargeDefinition.getChargeTime())
        .equals(ChargeTimeType.INSTALMENT_FEE)) {
      BigDecimal percentage = amount;
      if (percentage == null) {
        percentage = chargeDefinition.getAmount();
      }
      loanCharge =
          loan.calculatePerInstallmentChargeAmount(
              ChargeCalculationType.fromInt(chargeDefinition.getChargeCalculation()), percentage);
    }

    return new LoanCharge(
        loan,
        chargeDefinition,
        amountPercentageAppliedTo,
        amount,
        chargeTime,
        chargeCalculation,
        dueDate,
        chargePaymentMode,
        null,
        loanCharge);
  }