Помощь с написанием метода сверки отчётов

Пользователь

от allaselenginskaa , в категории: Java , год назад

Создается приложение бухгалтерии. там программа должна предлагать 6 действий. 1) считать все месячные ответы 

2) считать годовой отчет 

3) сверить отчеты 

4) вывести информацию обо всех месячных отчетах (название месяца, самый прибыльный товар и самая большая трата)

5) вывести информацию о годовом отчете (год, прибыль, средних расход и средних доход) 

6) выход из приложения


Меню должно лежать в классе Main


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.util.Scanner;

public class Main {

  public static void main(String[] args) {

    ReportEngine reportEngine = new ReportEngine();
    Scanner scanner = new Scanner(System.in);


    while (true) {
      printMenu();

      int userInput = scanner.nextInt();
      if (userInput == 1) {
        System.out.println("Выполняется ко***** 1");

      } else if (userInput == 2) {
        System.out.println("Выполняется ко***** 2");

      } else if (userInput == 3) {
        System.out.println("Выполняется ко***** 3");
        reportEngine.check();
      } else if (userInput == 4) {
      System.out.println("Выполняется ко***** 4");
        System.out.println("Самый прибыльный товар " + reportEngine.getTopProduct());
        System.out.println(reportEngine.biggerExpense());
      } else if (userInput == 5) {
        System.out.println("Выполняется ко***** 5");
        System.out.println("Прибыль по каждому месяцу составляет: " + reportEngine.profit());
        System.out.println("Средний расход в год составляет: " + reportEngine.averageExpense());
        System.out.println("Средний доход в год составляет: " + reportEngine.averageIncome());
      } else if (userInput == 6) {
        System.out.println("Пока!");
        scanner.close();
        return;
      } else {
        System.out.println("Такой команды нет");
      }
    }
  }

  public static void printMenu() {
    System.out.println("1) Считать все месячные отчёты ");
    System.out.println("2) Считать годовой отчёт");
    System.out.println("3) Сверить отчёты");
    System.out.println("4) Вывести информацию обо всех месячных отчётах");
    System.out.println("5) Вывести информацию о годовом отчёте");
    System.out.println("6) Выход из приложения");
  }

}

[/JAVA]


Класс FileReader для чтения данных


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;

public class FileReader {
  ArrayList<String> readFileContents(String fileName) {
    String path = "./resources/" + fileName;
    try {
      return new ArrayList<>(Files.readAllLines(Path.of(path)));
    } catch (IOException e) {
      System.out.println("Невозможно прочитать файл с отчётом. Возможно, файл отсутствует в нужной директории.");
      return new ArrayList<>();
    }
  }
}

[/JAVA]


Для считывания месячных отчетов пользуюсь классом MonthlyReport


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.ArrayList;

public class MonthlyReport {
  FileReader fileReader = new FileReader();
  public ArrayList<MonthTotalPerYear> monthTotalPerYears = new ArrayList<>();

  public MonthlyReport() {
    for (int i = 1; i <= 3; i++) {
      String paths = "m.20210" + i + ".csv";
      ArrayList<String> lines = fileReader.readFileContents(paths);
      String[] lineContents = lines.get(i).split("\n");
      for (int j = 1; j < lineContents.length; j++) {
        String line = lineContents[j]; //Коньки,TRUE,2,2000
        String[] parts = line.split(",");
        String name = parts[0];
        boolean is_expense = Boolean.parseBoolean(parts[1]);
        int quantity = Integer.parseInt(parts[2]);
        int price = Integer.parseInt(parts[3]);

        MonthTotalPerYear monthTotalPerYear = new MonthTotalPerYear(name, is_expense, quantity, price);
        monthTotalPerYears.add(monthTotalPerYear);

      }
    }

  }

}

[/JAVA]


И классом MonthlyTotalPerYear, где создаю конструктор в соответствии с отчетом


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class MonthTotalPerYear {
  public String name;
  public boolean is_expense;
  public int quantity;
  public int price;

  public MonthTotalPerYear(String name, boolean is_expense, int quantity, int price) {
    this.name = name;
    this.is_expense = is_expense;
    this.quantity = quantity;
    this.price = price;
  }
}

[/JAVA]


Для считывания годового отчета использую класс YearlyReport


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.ArrayList;

public class YearlyReport {
  public ArrayList<Transaction> transactions = new ArrayList<>();
  FileReader fileReader = new FileReader();

  public YearlyReport() {
    ArrayList<String> lines = fileReader.readFileContents("y.2021.csv");
    for (int i = 1; i < lines.size(); i++){
      String[] lineContents = lines.get(i).split("\n");
      for (int j = 1; j < lineContents.length; j++) {
        String line = lineContents[j]; //01,1593150,false
        String[] parts = line.split(",");
        String month = parts[0];
        int amount = Integer.parseInt(parts[1]);
        boolean isExpense = Boolean.parseBoolean(parts[2]);

        Transaction transaction = new Transaction(month, amount, isExpense);
        transactions.add(transaction);
      }
    }


  }

}

[/JAVA]


И класс Transaction с созданием конструктора


[JAVA]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class Transaction {

  public String month;
  public int amount;
  public boolean isExpense;

  public Transaction(String month, int amount, boolean isExpense) {
    this.month = month;
    this.amount = amount;
    this.isExpense = isExpense;
  }


}

[/JAVA]


Конструктора созданы на основе того, как выглядят строки в отчетах. 


Отчет за январь:

item_name,is_expense,quantity,unit_price

Коньки,TRUE,50,2000

Новогодняя ёлка,TRUE,1,100000

Ларёк с кофе,TRUE,3,50000

Аренда коньков,FALSE,1000,180

Продажа билетов,FALSE,3500,300

Продажа кофе,FALSE,2421,150


Отчет за февраль:

item_name,is_expense,quantity,unit_price

Коньки,TRUE,2,2000

Заточка коньков,TRUE,50,200

Аренда коньков,FALSE,1000,180

Продажа билетов,FALSE,1500,300

Продажа кофе,FALSE,1200,150


Отчет за март:

item_name,is_expense,quantity,unit_price

Заточка коньков,TRUE,50,200

Разморозка ледопарка,TRUE,1,20000

Организация специального концерта,TRUE,1,60000

Продажа билетов,FALSE,2500,300

Продажа кофе,FALSE,1200,150

Билеты на специальный концерт,FALSE,300,5000


Годовой отчет:

month,amount,is_expense

01,1593150,false

01,350000,true

02,810000,false

02,14000,true

03,90000,true

03,2430000,false




Дальше описывала методы в классе ReportEngine 

(топовый продукт, самая большая трата, прибыль, средний доход и расход и сверка (check) но чек не дописан, я не понимаю как его писать)



[JAVA]

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import java.util.ArrayList;
import java.util.HashMap;

public class ReportEngine {
  public MonthlyReport monthlyReport;
  public YearlyReport yearlyReport;

  public ReportEngine() {
    monthlyReport = new MonthlyReport();
    yearlyReport = new YearlyReport();
  }

  public String getTopProduct() {
    HashMap<String, Integer> fregs = new HashMap<>();
    for (MonthTotalPerYear monthTotalPerYear : monthlyReport.monthTotalPerYears) {
      fregs.put(monthTotalPerYear.name, fregs.getOrDefault(monthTotalPerYear.name, 0) + monthTotalPerYear.quantity);
    }
    String maxName = null;
    for (String name : fregs.keySet()) {
      if (maxName == null) {
        maxName = name;
        continue;
      }
      if (fregs.get(maxName) < fregs.get(name)) {
        maxName = name;
      }
    }
    return maxName;
  }

  public String biggerExpense() {
    HashMap<String, Integer> expense = new HashMap<>();
    for (MonthTotalPerYear monthTotalPerYear : monthlyReport.monthTotalPerYears) {
      if (monthTotalPerYear.is_expense) {
        expense.put(monthTotalPerYear.name, monthTotalPerYear.price);
      }
    }
    String nameExpense = null;
    for (String name : expense.keySet()) {
      if (nameExpense == null) {
        nameExpense = name;
        continue;
      }
      if (expense.get(nameExpense) < expense.get(name)) {
        nameExpense = name;
      }
    }
    System.out.println("Самая большая сумма траты - " + expense.get(nameExpense));
    return nameExpense;
  }

  public HashMap<String, Integer> profit() {
    HashMap<String, Integer> product = new HashMap<>();
    for (Transaction transaction : yearlyReport.transactions) {
      if (!(transaction.isExpense)) {
        product.put(transaction.month, transaction.amount);
      }
    }
    String maxTransaction = null;
    for (String name : product.keySet()) {
      if (maxTransaction == null) {
        maxTransaction = name;
        continue;
      }
      if (product.get(maxTransaction) < product.get(name)) {
        maxTransaction = name;
      }
    }
    return product;
  }

  public Integer averageIncome() {
    HashMap<String, Integer> product = new HashMap<>();
    for (Transaction transaction : yearlyReport.transactions) {
      if (!(transaction.isExpense)) {
        product.put(transaction.month, transaction.amount);
      }
    }
    Integer result = null;
    for (Integer sum : product.values()) {
      result += sum;
    }
    return result;
  }

  public Integer averageExpense() {
    HashMap<String, Integer> product = new HashMap<>();
    for (Transaction transaction : yearlyReport.transactions) {
      if (transaction.isExpense) {
        product.put(transaction.month, transaction.amount);
      }
    }
    Integer result = null;
    for (Integer sum : product.values()) {
      result += sum;
    }
    return result;
  }


  public boolean check() {
    if (monthlyReport.monthTotalPerYears.isEmpty()) {
      System.out.println("Ошибка! Для начала необходимо считать файлы! :)");
      return false;
    /* } else {

      if ((sum_income == sum_incomeYear) && (sum_expense == sum_expenseYear)){
        System.out.println("Успех! Сверка отчётов прошла успешно!");
      } else {
        System.out.println("Ошибка! Сверка отчётов обнаружела несоответствие в ");
      }
    }*/

    }
    return false;
  }
}

[/JAVA]



Главные вопросы как все-таки реализовать считку файлов, в чем ошибка и как сверить отчеты

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

1 ответ

Пользователь

от jaren , год назад

@allaselenginskaa В методе check вы просто проверяете, пустой ли список monthlyReport.monthTotalPerYears. Однако, чтобы сверить отчеты, вам необходимо сравнить данные из месячных и годовых отчетов. Вам нужно сохранять суммы доходов и расходов для каждого месяца и сравнивать их с соответствующими значениями в годовом отчете.

Примерно так:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public boolean check() {
    if (monthlyReport.monthTotalPerYears.isEmpty()) {
        System.out.println("Ошибка! Для начала необходимо считать файлы! :)");
        return false;
    }

    HashMap<String, Integer> monthlySumIncome = new HashMap<>();
    HashMap<String, Integer> monthlySumExpense = new HashMap<>();

    for (MonthTotalPerYear monthTotal : monthlyReport.monthTotalPerYears) {
        String month = monthTotal.name;  // Предполагается, что имя месяца совпадает
        int amount = monthTotal.quantity * monthTotal.price;

        if (monthTotal.is_expense) {
            monthlySumExpense.put(month, monthlySumExpense.getOrDefault(month, 0) + amount);
        } else {
            monthlySumIncome.put(month, monthlySumIncome.getOrDefault(month, 0) + amount);
        }
    }

    // Сравнение с годовым отчетом
    for (Transaction transaction : yearlyReport.transactions) {
        String month = transaction.month;
        int amount = transaction.amount;


        if (transaction.isExpense && amount != monthlySumExpense.getOrDefault(month, 0)) {
            System.out.println("Ошибка! Несоответствие в расходах для месяца " + month);
            return false;
        }

        if (!transaction.isExpense && amount != monthlySumIncome.getOrDefault(month, 0)) {
            System.out.println("Ошибка! Несоответствие в доходах для месяца " + month);
            return false;
        }
    }

    System.out.println("Успех! Сверка отчетов прошла успешно!");
    return true;
}


Также, я бы порекомендовал использовать BigDecimal для вычислений с денежными значениями, чтобы избежать проблем с округлением при работе с типом int, особенно в финансовых приложениях.