Issue
I have two classes, the meaning of which is to take the available values (date, amount and exchange rate). Next, fill in the gaps between dates, previous values
class ReportRow {
private LocalDate date;
private BigDecimal amount;
private BigDecimal rate;
public ReportRow(LocalDate date, BigDecimal amount, BigDecimal rate) {
this.date = date;
this.amount = amount;
this.rate = rate;
}
public LocalDate getDate() {
return date;
}
public BigDecimal getAmount() {
return amount;
}
public BigDecimal getRate() {
return rate;
}
@Override
public String toString() {
return date + " | " + amount + " | " + rate;
}
}
public class Main {
public static void main(String[] args) {
List<ReportRow> originalReport = List.of(
new ReportRow(LocalDate.of(2022, 6, 20), BigDecimal.valueOf(10000), BigDecimal.valueOf(3)),
new ReportRow(LocalDate.of(2023, 1, 15), BigDecimal.valueOf(8000), BigDecimal.valueOf(3)),
new ReportRow(LocalDate.of(2023, 7, 5), BigDecimal.valueOf(6500), BigDecimal.valueOf(3)));
System.out.println("Before:");
originalReport.forEach(System.out::println);
List<ReportRow> updatedReport = new ArrayList<>();
int size = originalReport.size();
updatedReport.add(originalReport.get(0));
for (int i = 1; i < size; i++) {
ReportRow lastRow = originalReport.get(i - 1);
ReportRow currentRow = originalReport.get(i);
BigDecimal rate = lastRow.getRate();
BigDecimal lastAmount = lastRow.getAmount();
LocalDate dateStart = lastRow.getDate();
LocalDate dateEnd = currentRow.getDate();
if (ChronoUnit.MONTHS.between(dateStart.withDayOfMonth(dateEnd.getDayOfMonth()), dateEnd) > 1) {
for (LocalDate date = dateStart.plusMonths(1); date.isBefore(dateEnd); date = date.plusMonths(1))
updatedReport.add(new ReportRow(date, lastAmount.divide(rate, RoundingMode.CEILING), rate));
}
updatedReport.add(currentRow);
}
System.out.println("After:");
updatedReport.forEach(System.out::println);
//for (ReportRow reportRow : originalReport) {
// BigDecimal newAmount = reportRow.getAmount().divide(reportRow.getRate(), //RoundingMode.CEILING);
// System.out.println(newAmount);
}
}
}
As a result, I get this result:
Before:
2022-06-20 | 10000 | 3
2023-01-15 | 8000 | 3
2023-07-05 | 6500 | 3
After:
2022-06-20 | 10000 | 3
2022-07-20 | 3334 | 3
2022-08-20 | 3334 | 3
2022-09-20 | 3334 | 3
2022-10-20 | 3334 | 3
2022-11-20 | 3334 | 3
2022-12-20 | 3334 | 3
2023-01-15 | 8000 | 3
2023-02-15 | 2667 | 3
2023-03-15 | 2667 | 3
2023-04-15 | 2667 | 3
2023-05-15 | 2667 | 3
2023-06-15 | 2667 | 3
2023-07-05 | 6500 | 3
As you can see from the result, the amounts that I divide by the exchange rate are divided only in the gaps to be filled, and the main amounts remain unchanged.
I'm trying to get the following result at the output, so that all amounts are divided by my exchange rate:
Before:
2022-06-20 | 10000 | 3
2023-01-15 | 8000 | 3
2023-07-05 | 6500 | 3
After:
2022-06-20 | 3334 | 3
2022-07-20 | 3334 | 3
2022-08-20 | 3334 | 3
2022-09-20 | 3334 | 3
2022-10-20 | 3334 | 3
2022-11-20 | 3334 | 3
2022-12-20 | 3334 | 3
2023-01-15 | 2667 | 3
2023-02-15 | 2667 | 3
2023-03-15 | 2667 | 3
2023-04-15 | 2667 | 3
2023-05-15 | 2667 | 3
2023-06-15 | 2667 | 3
2023-07-05 | 2167 | 3
Solution
To get the desired output your Main class should be:
public class Main {
public static void main(String[] args) {
List<ReportRow> originalReport = List.of(
new ReportRow(LocalDate.of(2022, 6, 20), BigDecimal.valueOf(10000), BigDecimal.valueOf(3)),
new ReportRow(LocalDate.of(2023, 1, 15), BigDecimal.valueOf(8000), BigDecimal.valueOf(3)),
new ReportRow(LocalDate.of(2023, 7, 5), BigDecimal.valueOf(6500), BigDecimal.valueOf(3)));
System.out.println("Before:");
originalReport.forEach(System.out::println);
List<ReportRow> updatedReport = new ArrayList<>();
int size = originalReport.size();
for (int i = 1; i < size; ++i) {
ReportRow lastRow = originalReport.get(i - 1);
ReportRow currentRow = originalReport.get(i);
BigDecimal rate = lastRow.getRate();
BigDecimal lastAmount = lastRow.getAmount();
LocalDate dateStart = lastRow.getDate();
LocalDate dateEnd = currentRow.getDate();
if (ChronoUnit.MONTHS.between(dateStart.withDayOfMonth(dateEnd.getDayOfMonth()), dateEnd) > 1) {
for (LocalDate date = dateStart; date.isBefore(dateEnd); date = date.plusMonths(1)) {
updatedReport.add(new ReportRow(date, lastAmount.divide(rate, RoundingMode.CEILING), rate));
}
}
if (i == (size - 1)) {
updatedReport.add(new ReportRow(dateEnd, currentRow.getAmount().divide(rate, RoundingMode.CEILING), rate));
}
}
System.out.println("After:");
updatedReport.forEach(System.out::println);
}
}
Answered By - Sandeep Kumar Nat
Answer Checked By - Willingham (JavaFixing Volunteer)