Приложение для бухгалтерии с возможностью создания месячного и годового отчетов, данные о которых считываются из файлов (загрузка которых необходима в определенную директорию проекта), а так же с возможностью сверки отчётов.
Техническое задание
Отдел бухгалтерии парка развлечений пользуется простыми excel-таблицами для ведения бюджета. В их работе постоянно возникают ошибки при вводе данных и подсчёте балансов. Руководство компании поставило перед вами сложную задачу — создать новое приложение для бухгалтерии.
- Иметь консольный интерфейс для управления программой.
- Считывать месячные и годовые отчёты бухгалтерии из файлов и приводить их в объекты приложения.
- Проводить сверку данных по месячным и годовым отчётам.
- Выводить информацию о месячных и годовом отчёте.
В настоящий момент бухгалтерия готова предоставить три месячных отчёта: за январь, февраль и март 2021 года, а также частичный годовой отчёт за эти же три месяца. Пока приложение должно обрабатывать только эти данные.
Бухгалтерия готова предоставить данные о своей деятельности в виде файлов в формате CSV — Comma-Separated Values (англ. «значения, разделённые запятыми»). Нужно разбить входящий файл на составляющие и преобразовать к объектам приложения. Приложение должно работать с двумя видами отчётов:
- Месячный отчёт, содержащий данные о доходах и расходах в рамках одного календарного месяца. В программе они представляются классом MonthlyReport.
- Годовой отчёт, содержащий ровно по 2 записи на каждый из 12 месяцев — общий доход и расход за этот месяц. Представлен классом YearlyReport.
Каждый файл в формате CSV состоит из набора строк. В самой первой строке идут заголовки полей. Далее каждая строка состоит из значений, разделённых символов-разделителем — запятой.
Файлы с отчётами именуются определённым образом, чтобы упростить их считывание и обработку.
Имена файлов с месячными отчётами имеют формат m.YYYYMM.csv, где:
- m — буква m в начале файла, чтобы отделить отчёты за месяц и отчёты за год;
- YYYY — год. Например, 2021;
- MM — месяц строго двумя цифрами. Счёт начинается с единицы, то есть 01 — «январь», а 11 — «ноябрь».
Имена файлов с годовым отчётом имеют формат y.YYYY.csv, где:
- y — буква y в начале файла, чтобы отделить отчёты за месяц и отчёты за год;
- YYYY — год. Например, 2021.
Пример именований: y.2020.csv — годовой отчёт за 2020 год, y.2018.csv — годовой отчёт за 2018 год.
Месячный отчёт содержит информацию о всех тратах, произведённых в течение календарного месяца. Сюда попадает информация как о доходах, так и о расходах парка развлечений.
Месячные отчёты состоят из четырёх полей:
- item_name — название товара;
- is_expense — одно из двух значений: TRUE или FALSE. Обозначает, является ли запись тратой (TRUE) или доходом (FALSE);
- quantity — количество закупленного или проданного товара;
- sum_of_one — стоимость одной единицы товара. Целое число.
Годовой отчёт содержит информацию о всех тратах, произведённых в течение года. Он содержит по две записи на каждый месяц. Месяц обозначается строго двумя цифрами, начиная с единицы, то есть 01 — «январь», а 11 — «ноябрь».
Строка годового отчёта состоит из трёх полей:
- month — месяц. Целое число;
- amount — сумма;
- is_expense — одно из двух значений: true или false. Обозначает, является ли запись тратой (true) или доходом (false).
Консольный интерфейс по работе с программной должен позволять оператору произвести одно из пяти действий по выбору:
- Считать все месячные отчёты
- Считать годовой отчёт
- Сверить отчёты
- Вывести информацию о всех месячных отчётах
- Вывести информацию о годовом отчёте
После выбора и исполнения действия, программа должна позволять оператору ввести следующее действие. Программа должна завершаться только при вводе оператором специальной последовательности символов. Придумать такую последовательность вы можете сами.
Программа позволяет считывать месячные и годовые отчёты. При выборе оператором действия «считать месячный отчёт» должно происходить считывание трёх файлов:
- m.202101.csv
- m.202102.csv
- m.202103.csv
При выборе действия «считать годовой отчёт» должно происходить считывание из одного файла:
- y.2021.csv
Содержимое файлов должно приводиться к объектам приложения для дальнейшей обработки.
В Java существует несколько способов считать файл. Вы можете использовать следующий код:
try {
return Files.readAllLines(Path.of(path));
} catch (IOException e) {
System.out.println("Невозможно прочитать файл с месячным отчётом. Возможно файл не находится в нужной директории.");
return Collections.emptyList();
}
}
Метод принимает в качестве параметра имя файла, который нужно считать, и возвращает либо список строк содержимое файла, либо пустой список, если файл не будет найден. Аргументом метода является полный или относительный путь до файла.
Так как месяцев несколько, обрабатывать месячные отчёты нужно в цикле. По заданию вам даётся формат данных. Вы можете преобразовать счётчик цикла i и несколько строковых констант в имя файла, например "m.20210" + i + ".csv".
При работе со строками известного формата удобно пользоваться методом split(). Он делит исходную строку по символу-разделителю и возвращает массив строк. Например, чтобы разбить нашу строку, из файла по столбцам нужно вызвать метод с аргументом «,»:
String[] lineContents = line.split(",");
Это позволит обращаться к конкретным значениями внутри строки. Например, к значениям столбца amount или month. Обратите внимание: CSV файл начинается со строки-заголовка, которую необязательно анализировать — вам нужны именно значения. Поэтому цикл по всем строкам из файла можно начать с 1, а не с 0.
Сверка данных — это проверка, что данные в двух и более разных источниках не противоречат друг другу. В данном случае при сверке данных вам нужно проверить, что информация по месяцу в годовом отчёте не противоречит информации в месячном отчёте.
При вызове сверки данных программа должна:
- Подсчитывать две суммы: общие доходы и общие расходы по каждому из месяцев.
- Сверять полученные суммы с суммой доходов и расходов в отчёте по году.
Если обнаружена ошибка, программа должна выводить месяц, в котором обнаружено несоответствие. Если ошибок не обнаружено, должна выводиться только информация об успешном завершении операции.
Для удобства вы можете создать дополнительные методы в классах отчётов MonthlyReport и YearlyReport, которые будут возвращать максимальные, минимальные и средние суммы по доходам и расходам. Перед сверкой не забудьте проверить, что пользователь уже вызвал методы по считыванию обоих видов отчётов. Для этого можно проверить значение отчётов на null, либо завести дополнительную приватную boolean переменную.
При вызове этой функции программа должна выводить следующие данные:
- Название месяца;
- Самый прибыльный товар, то есть товар для которого is_expense == false, а произведение количества (quantity) на сумму (sum_of_one) максимально. Вывести название товара и сумму;
- Самую большую трату. Вывести название товара и сумму.
Эта информация должна выводиться по каждому из месяцев.
При вызове этой функции программа должна выводить следующие данные:
- Рассматриваемый год;
- Прибыль по каждому месяцу. Прибыль — это разность доходов и расходов;
- Средний расход за все месяцы в году;
- Средний доход за все месяцы в году.
К моменту вызова этого метода пользователь уже должен был считать отчёты. Вам нужно использовать данные, которые сохранены в программе в удобном для работы виде. Считывание данных и их обработка — в общем случае не связанные операции. Разделение подобных функций на классы — один из способов упрощения программ. Метод по печати отчёта не должен задумываться о том, в каком отчёте данные хранятся в файлах. Точно так же метод по считыванию данных должен только их считывать, возможно, с минимальной обработкой, но не должен автоматически вычислять, к примеру, самый прибыльный товар.