@Override
 public DepositOutcomeDocument requestEarlyOutcome(Deposit deposit, BigDecimal sum)
     throws RedSaldoException {
   DepositOutcomeDocument depositOutcomeDocument =
       billingSystemUtils.doDepositEarlyOutcomeRequest(deposit.getId(), sum);
   return depositOutcomeDocument;
 }
  @Override
  public DepositPayInAccountDocument requestAdditionalMoneyPayIn(Deposit deposit, BigDecimal sum) {
    DepositPayInAccountDocument depositPayInAccountDocument =
        billingSystemUtils.doDepositAdditionalPayInAccountRequest(deposit.getId(), sum);

    return depositPayInAccountDocument;
  }
  @Override
  public HashMap<String, Object> mainContractPdfPlaceholders(Deposit deposit) {
    HashMap<String, Object> pl = new LinkedHashMap<String, Object>();
    pl.put("$CONTRACT_NUMBER", deposit.getId());
    pl.put("$CITY", "Москва");
    SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy", new Locale("ru"));
    pl.put("$CONTRACT_DATE", sdf.format(deposit.getDtmCreate()));
    pl.put("$FIO", deposit.getDepositor().getFio());
    pl.put(
        "$ADDR",
        deposit
            .getDepositor()
            .getRegIndex()
            .concat(" ")
            .concat(deposit.getDepositor().getRegCity().toString()));
    pl.put(
        "$PASSPORT",
        deposit
            .getDepositor()
            .getPassportNum()
            .concat(", выдан ")
            .concat(deposit.getDepositor().getDepartmentName())
            .concat(" (")
            .concat(deposit.getDepositor().getDepartmentCode())
            .concat(") ")
            .concat(sdf.format(deposit.getDepositor().getPassportAccepted())));
    pl.put("$SUM_DIG", deposit.getSum().intValue());
    fwMoney fwMoney = new fwMoney(deposit.getSum().doubleValue());
    pl.put("$SUM_WORDS", fwMoney.num2str(true, false).trim());
    fwMoney fwMoneyPercents = new fwMoney(deposit.getPercent().doubleValue());
    pl.put(
        "$YEAR_PERCENTS_WORDS",
        fwMoneyPercents.num2str(false, true, com.mfodepositorsacc.util.fwMoney.Type.NUMBER).trim());
    pl.put("$YEAR_PERCENTS", deposit.getPercent().doubleValue());
    fwMoney fwMoneyLength = new fwMoney(deposit.getLength());
    pl.put("$LENGTH_MONTH_WORDS", fwMoneyLength.num2str(true, false).trim());
    pl.put("$LENGTH_MONTH", deposit.getLength());

    DepositCalculation depositCalculation = new DepositCalculation();
    depositCalculation.setLength(deposit.getLength());
    depositCalculation.setSum(deposit.getSum());
    depositCalculation.percents = deposit.getPercent();
    BigDecimal sumInTheEnd = depositCalculationService.calculateSumInTheEnd(depositCalculation);
    BigDecimal profit = sumInTheEnd.add(deposit.getSum().negate());

    BigDecimal profitInPercents =
        profit.multiply(BigDecimal.valueOf(100)).divide(deposit.getSum(), 2, RoundingMode.HALF_UP);
    fwMoney fwMoneyProfitPercents = new fwMoney(profitInPercents.doubleValue());
    pl.put(
        "$PROFIT_PERCENTS_WORDS",
        fwMoneyProfitPercents
            .num2str(false, true, com.mfodepositorsacc.util.fwMoney.Type.NUMBER)
            .trim());
    pl.put("$PROFIT_PERCENTS", profitInPercents.doubleValue());

    BigDecimal tax = profit.multiply(BigDecimal.valueOf(0.13));
    BigDecimal cleanProfit = profit.add(tax.negate());
    BigDecimal monthlyProfit =
        cleanProfit.divide(BigDecimal.valueOf(deposit.getLength()), 2, RoundingMode.HALF_UP);
    fwMoney fwMoneyTax = new fwMoney(tax.doubleValue());
    pl.put(
        "$TAX_ALL",
        fwMoneyTax.num2str(false, false, com.mfodepositorsacc.util.fwMoney.Type.NUMBER_AND_MONEY));
    fwMoney fwMoneyProfit = new fwMoney(cleanProfit.doubleValue());
    pl.put(
        "$CLEAN_PROFIT_ALL",
        fwMoneyProfit.num2str(
            false, false, com.mfodepositorsacc.util.fwMoney.Type.NUMBER_AND_MONEY));
    fwMoney fwMoneyMonthlyProfit = new fwMoney(monthlyProfit.doubleValue());
    pl.put(
        "$MONTHLY_PROFIT",
        fwMoneyMonthlyProfit.num2str(
            false, false, com.mfodepositorsacc.util.fwMoney.Type.NUMBER_AND_MONEY));

    return pl;
  }
 @Override
 public void updatePercent(Deposit deposit, BigDecimal percent) {
   deposit.setPercent(percent);
   depositRepository.save(deposit);
 }
  @Override
  public void dropCapitalizationDate(Deposit deposit) {
    deposit.setNextCapitalization(null);

    entityManager.merge(deposit);
  }
  @Override
  public void capitalize(Deposit deposit) throws DepositCapitalizationIllegalStateException {

    System.out.println(
        "capitalization of #"
            .concat(deposit.getId().toString())
            .concat(" next capitalization ")
            .concat(deposit.getNextCapitalization().toString()));

    BigDecimal saldo = billingSystemUtils.getDepositSaldo(deposit.getId());

    if (saldo.compareTo(BigDecimal.ZERO) < 1) {
      System.out.println("Нет денег - нет прибыли");
      throw new DepositCapitalizationIllegalStateException(
          "На счету нет денег. Капитализация невозможна");
    }

    if (deposit.getPercent() == null || deposit.getPercent().compareTo(BigDecimal.ZERO) < 1) {
      throw new DepositCapitalizationIllegalStateException(
          "Не задана процентная ставка. Каитализация невозможна");
    }

    DepositCalculation depositCalculationMonth =
        new DepositCalculation(saldo, 1, deposit.getDepositorFormType());
    depositCalculationMonth.percents = deposit.getPercent();

    BigDecimal sumToAdd =
        depositCalculationService.calculateSumInTheEnd(depositCalculationMonth).add(saldo.negate());

    billingSystemUtils.doDepositPayInMonthlyProfit(
        deposit.getId(), sumToAdd, deposit.getNextCapitalization());

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(deposit.getNextCapitalization());
    calendar.add(Calendar.MONTH, 1);

    deposit.setNextCapitalization(calendar.getTime());

    entityManager.merge(deposit);
  }