CSV и правила отчёта
Напишите CLI-анализатор CSV-файла продаж. Обязательные заголовки: date, order_id, product, channel, quantity, unit_price, status. Заголовки могут идти в любом порядке, но не могут дублироваться. Используйте запятую как разделитель и стандартное CSV-экранирование двойными кавычками. Дата имеет формат YYYY-MM-DD, идентификаторы и названия непусты, quantity — положительное целое до 1 000 000, unit_price — сумма в RUB с точностью до копейки и неотрицательным значением. status принимает paid или refunded; channel — произвольное непустое значение.
Каждая строка является одной строкой позиции заказа. Вычислите валовую сумму позиции как quantity, умноженное на unit_price. Для paid включите сумму и количество в продажи. Для refunded включите стоимость и количество только в отдельную сумму возвратов; возврат не вычитается из валовых продаж. Формируйте агрегаты по месяцу, товару и каналу, показывая количество оплаченных единиц, валовую сумму и сумму возвращённых позиций. Не объединяйте одинаковые order_id: в файле может быть несколько строк одного заказа. Значения сумм храните в целых копейках. Не применяйте налоги, скидки или курсы валют.
Невалидные строки выводятся в диагностике с физическим номером и причиной, пропускаются и вызывают ненулевой итоговый статус после публикации частичного корректного отчёта. Ошибка чтения, неверные заголовки или невалидная CSV-структура файла фатальны и запрещают вывод агрегаций. Отчёт сортируется по месяцу по возрастанию, затем по товару и каналу лексикографически. Путь к входу обязателен; stdout содержит результат, stderr — диагностики. Файл не меняется. Документируйте точные определения показателей, покрывайте агрегацию, возвраты, CSV-кавычки и сортировку тестами.
Структура программы
В internal/sales разместите правила статусов paid/refunded, расчёт позиции и агрегацию по месяцу, товару и каналу. CSV-чтение и проверка схемы должны возвращать записи или диагностики отдельно от этих правил. Оставьте main.go аргументы, связь частей и вывод. Тестируйте суммы и возвраты передачей готовых записей, без CLI и реального файла.