public Optional postPayrollPayment()

in service/src/main/java/org/apache/fineract/cn/payroll/service/internal/service/adaptor/AccountingAdaptor.java [72:129]


  public Optional<String> postPayrollPayment(final PayrollCollectionEntity payrollCollectionEntity,
                                 final PayrollPayment payrollPayment,
                                 final PayrollConfiguration payrollConfiguration) {

    final MathContext mathContextAmount = new MathContext(2, RoundingMode.HALF_EVEN);
    final MathContext mathContextPercentage = new MathContext(5, RoundingMode.HALF_EVEN);

    final JournalEntry journalEntry = new JournalEntry();
    journalEntry.setTransactionIdentifier(UUID.randomUUID().toString());
    journalEntry.setTransactionDate(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
    journalEntry.setTransactionType("SALA");
    journalEntry.setClerk(payrollCollectionEntity.getCreatedBy());
    journalEntry.setNote("Payroll Distribution");

    final Debtor debtor = new Debtor();
    debtor.setAccountNumber(payrollCollectionEntity.getSourceAccountNumber());
    debtor.setAmount(payrollPayment.getSalary().toString());
    journalEntry.setDebtors(Sets.newHashSet(debtor));

    final HashSet<Creditor> creditors = new HashSet<>();
    journalEntry.setCreditors(creditors);

    payrollConfiguration.getPayrollAllocations().forEach(payrollAllocation -> {
      final Creditor allocationCreditor = new Creditor();
      allocationCreditor.setAccountNumber(payrollAllocation.getAccountNumber());
      if (!payrollAllocation.getProportional()) {
        allocationCreditor.setAmount(payrollAllocation.getAmount().toString());
      } else {
        final BigDecimal value = payrollPayment.getSalary().multiply(
            payrollAllocation.getAmount().divide(BigDecimal.valueOf(100.00D), mathContextPercentage)
        ).round(mathContextAmount);
        allocationCreditor.setAmount(value.toString());
      }
      creditors.add(allocationCreditor);
    });

    final BigDecimal currentCreditorSum =
        BigDecimal.valueOf(creditors.stream().mapToDouble(value -> Double.valueOf(value.getAmount())).sum());

    final int comparedValue = currentCreditorSum.compareTo(payrollPayment.getSalary());
    if (comparedValue > 0) {
      return Optional.of("Allocated amount would exceed posted salary.");
    }
    if (comparedValue < 0) {
      final Creditor mainCreditor = new Creditor();
      mainCreditor.setAccountNumber(payrollConfiguration.getMainAccountNumber());
      mainCreditor.setAmount(payrollPayment.getSalary().subtract(currentCreditorSum).toString());
      creditors.add(mainCreditor);
    }

    try {
      this.ledgerManager.createJournalEntry(journalEntry);
      return Optional.empty();
    } catch (final Throwable th) {
      this.logger.warn("Could not process journal entry for customer {}.", payrollPayment.getCustomerIdentifier(), th);
      return Optional.of("Error while processing journal entry.");
    }
  }