Создается приложение бухгалтерии. там программа должна предлагать 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]
Главные вопросы как все-таки реализовать считку файлов, в чем ошибка и как сверить отчеты
@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, особенно в финансовых приложениях.