С 1 июля 2017 года на территории Российской Федерации стало обязательным использование контрольно-кассовых машин (ККМ), отправляющих все свои транзакции прямо в Федеральную налоговую службу. Так называемых онлайн-касс. Введение этого новшества уже успели обсудить со всех сторон или по крайней мере со всех серьезных сторон. Могут ли у федерального закона быть не слишком серьезные стороны и какой простор для творчества это нам дает – об этом под катом.


Все ККМ теперь сообщают в ФНС о наших транзакциях, а ФНС, желая убедиться в честности каждой онлайн-кассы, выпустила специальное мобильное приложение (Google Play, App Store), которое позволяет пользователю проверить любой предоставленный ему чек и сообщить в компетентные органы, если проверка завершилась неудачей.


Когда я слышу о том, что кто-то начинает собирать большие объемы информации, я думаю не о потенциальной прибыли от этого и не о затратах на внедрение. И даже не о том, что Большой брат наблюдает. У меня в голове сразу рисуются таблички, которые можно фильтровать и джойнить, кубики, которые можно вертеть, диаграммки, которые можно строить и т.д. Можем ли мы как-то приклеиться к потоку наших же собственных данных, идущих от продавца к государству? Можем. (В виде небольшого бантика приложение ФНС также дает возможность получить электронную версию этого самого чека.)

Когда я узнал об этой возможности, я загорелся. Более внимательный взгляд на возможности приложения меня не разочаровал: чек можно получить не только в html или png, но и в json.


Дело в том, что я стараюсь вести учет всех своих расходов. Стараюсь делать это регулярно, но, конечно, постоянно оказывается, что несколько недель я это делать забывал. И начинается сеанс эриксонианского гипноза с погружением в прошлое и заполнением белых пятен.

Вот от этого мучительного процесса ФНС и поможет нам избавиться.

Получается, теоретически, вместо того, чтобы в конце месяца (или двух) анализировать выписки из нескольких банков и ворох бумажных чеков, пытаясь понять, куда же опять слились все деньги, можно анализировать гору писем в ящике с json во вложениях. Перспектива тоже так себе, но в отличие от первой она куда лучше поддается автоматизации.

Итак, совершая покупку, мы можем получать на почту наш чек в формате JSON. Причем, в теории, при покупке для этого нам даже не нужно приложение от ФНС: мы можем заранее сгенерировать в приложении визитку с qr-кодом нашей почты и предъявлять ее кассиру в момент покупки. Тогда мы можем запросить вместо бумажного чека электронный,  который должен будет сразу падать в почту. Как при интернет покупке.


Но даже ФНС прямо пишет об этой функции – «Не обольщайтесь». Ее поддерживают не все ККМ. И даже там, где ее поддерживают ККМ, совсем не факт, что ее поддерживают сами кассиры. Так что пока это для сильных духом.

Получив чек на почту, нам остается только автоматизировать его разбор и выгрузку в удобное для нас хранилище.

Нужно выбрать, куда все это выгружать так, чтобы дальше было удобно с этим работать.

Не знаю, как вы, а лично я, пользуясь теми или иными бюджетницами, в итоге всегда экспортирую данные из них для анализа в старый добрый Excel. Какие бы графики и диаграммы разработчики не включили в свой продукт заранее, они никогда не смогут предугадать всего, что я захочу вытянуть из данных. Какие транзакции учитывать, какие — не учитывать, сопоставить с фазами луны, сгруппировать,  поделить на сегодняшнее число… Excel все это может.

Причем, если мы положим наш Excel в OneDrive, то он будет прекрасно доступен через веб, в том числе и с мобильных ОС.  И, в отличие от GoogleDrive, здесь будут прекрасно работать формулы, в том числе те, что позволят нам организовать каскадные выпадающие списки для категории и подкатегории каждой покупки.


Дело за малым – разобраться с парсером. Нам нужен механизм, получающий из почтового ящика письмо с вложением, разбирающий json вложения и записывающий результат в табличку Excel, лежащую в OneDrive.

В идеальном мире я вижу этот парсер чем-то вроде степа для IFTTT. Тогда наше решение жило бы полностью в сети и не требовало от пользователя вообще ничего (раз уж мы про идеальный мир, то в нем и «визитки» ФНС работают идеально).

Однако сходу понять, как человеку с улицы написать свой степ для IFTTT, – равно как и понять, возможно ли это вообще. Мне не удалось. Если кто-то сможет подсказать толковый гайд или альтернативную платформу, буду весьма признателен.

Раз уж с полностью сетевым решением не заладилось, реализуем одно звено парсера на десктопе. В компании НОРБИТ я занимаюсь внедрением Dynamics CRM, так что стек Microsoft для меня самый привычный. Да и мы уже начали им пользоваться, выбрав Excel и OneDrive. Реализуем плагин для Outlook, куда поместим всю требуемую нам логику.

Здесь я пошел по пути наименьшего сопротивления.

Для начала взял полученный от ФНС JSON и скормил его в json2csharp.com. Получил структуру классов для десериализации:

public class Item
{
    public string name { get; set; }
    public int nds18 { get; set; }
    public int price { get; set; }
    public double quantity { get; set; }
    public int sum { get; set; }
    public int? nds10 { get; set; }
}

public class Receipt
{
    public List<Item> items { get; set; }
    public string retailPlaceAddress { get; set; }
    public string userInn { get; set; }
    public int requestNumber { get; set; }
    public int nds18 { get; set; }
    public string fiscalDriveNumber { get; set; }
    public string user { get; set; }
    public string @operator { get; set; }
    public int fiscalDocumentNumber { get; set; }
    public int taxationType { get; set; }
    public int ecashTotalSum { get; set; }
    public string kktRegId { get; set; }
    public DateTime dateTime { get; set; }
    public int operationType { get; set; }
    public int cashTotalSum { get; set; }
    public int receiptCode { get; set; }
    public int nds10 { get; set; }
    public int totalSum { get; set; }
    public int shiftNumber { get; set; }
    public int fiscalSign { get; set; }
}

Теперь нужно получить письмо, десериализовать аттач в полученные выше классы и превратить их в XLSX.

Для десериализации я взял Newtonsoft.Json, а для записи в эксель — ClosedXML. Впоследствие оказалось, что можно было не заморачиваться с записью прямо в XLSX, а спокойно писать в CSV — почему-то ClosedXML крашится при работе с файлами, имеющими сводные таблицы. Так что статистику пока что пришлось вынести в отдельный эксель-файл, а выгрузку из плагина ему подсунуть как источник данных.

Сам плагин очень простой. Чтобы он не обрабатывал все входящие письма, я завел отдельный ящик именно для чеков и проверяю, что письмо пришло именно в него. Дальше нужно, конечно, вынести это в настраиваемые параметры, как и все адреса папок.

        void Items_ItemAdd(object Item)
        {
            Outlook.MailItem mail = (Outlook.MailItem)Item;
            if (Item != null)
            {    
                if (mail.Attachments.Count == 1 & mail.To.Equals("my@mail.address"))
                {
                    
                    Outlook.Attachment attach = mail.Attachments[1];
                    string path = "C:\\_Data\\_tmp\\" + attach.FileName;
                    attach.SaveAsFile(path);

                    string text = System.IO.File.ReadAllText(path);

                    System.IO.File.Delete(path);
                    List<TableRow> objectList = GetBillsData(text);
                    WriteBillsToXLSX(objectList);

                }
            }
        }
        private static void WriteBillsToXLSX(List<TableRow> objectList)
        {
            var workbook = new XLWorkbook(tablePath);
            var ws = workbook.Worksheet("Products");
            int startrow = ws.LastRowUsed().RowNumber();
            if (ws.CellsUsed().Count() != 0)
                startrow = ws.CellsUsed().Last().Address.RowNumber;
             foreach (var item in objectList)
            {
                startrow++;
                ws.Cell(startrow, 1).Value = item.dateTime;
                ws.Cell(startrow, 2).Value = item.sum;
                ws.Cell(startrow, 3).Value = item.quantity;
                ws.Cell(startrow, "J").Value = item.user;
                ws.Cell(startrow, "S").Value = item.name;
            }

            workbook.SaveAs(tablePath);
        }


        private static List<TableRow> GetBillsData(string bill)
        {
            Receipt doc = JsonConvert.DeserializeObject<Receipt>(bill);
            List<TableRow> objectList = new List<TableRow>();
            foreach (var item in doc.items)
            {
                objectList.Add(new TableRow(item, doc));
            }
            return objectList;
        }

Вся трансформация данных от JSON к строке таблицы убрана в конструктор TableRow.

Теперь, совершив покупку, нам достаточно отсканировать чек, и все его строчки сами попадут в наш лежащий в облаке файл. Просмотреть этот файл мы сможем тут же, не отходя от кассы. Просмотр доступен нам на любой ОС, поддерживающей работу современных браузеров.

Останется только проставить категории и подкатегории для загруженных строк и можно строить любую угодную нашей душе аналитику. Еще пара строк кода, и плагин научится сам проставлять категории/подкатегории для строк, если в файле уже есть строка с таким же описанием и заполненной ранее категорией.


Вот такой круговорот данных в природе.

Комментарии (45)


  1. cypok
    26.03.2019 11:38

    Один момент: а как собственно чеки попадают на почту? Каждый чек сканируется?
    Я на данный момент чеки складываю в бумажник, это звучит быстрее чем сканировать чек.


    1. dth_apostle
      26.03.2019 11:49

      Вообще шлет то ли оператор онлайн-платежей (контур.офд некий для такси, например), то ли кто он. Но суть в том, что не по каждому платежу приходит сообщение, т.к., например, в продуктовом магазине вы не указываете свой email, а они услугами посредника для отправки данных в ФНС не пользуются. Получается некий gap (вот не могу найти синоним адекватный на родном языке) — какие-то чеки придут, какие-то — нет. Т.к. платежи могут быть как наличными, так и различными картами, то свести их в один источник данных проблематично, или, скажем так, ничуть не проще. чем сделать это с смс банков или их банк-клиентов.
      Есть, конечно, вариант, фотографировать/сканировать чек, но, имхо, в таком случае уж проще его уж просто распознать.


      1. batyrmastyr
        26.03.2019 13:24

        gap — прогал, провал.


        1. dth_apostle
          26.03.2019 13:30

          перевод-то ясен, но вот смысл — провал (не в смысле «все рухнуло», а «разрыв, к-рый приводит к невозможности продолжения движения») в процессе, пропуск этапа в описании. Для слова «провал» требуется добавление комментария/контекста.

          Еще вариант хороший — когда писал 1й коммент в голову не пришел, — «разрыв».


          1. eugenius_nsk
            27.03.2019 06:01

            Пробел


          1. vladkorotnev
            27.03.2019 07:57

            Как вариант — зазор


          1. sf7_uz
            27.03.2019 10:25

            лаг


        1. martin_wanderer
          27.03.2019 10:40

          И даже «пробел». В знаниях, например


          1. batyrmastyr
            28.03.2019 08:45

            Например, в моих )
            Но названные выше «зазор» и «разрыв» лучше подходят к ситуации, как мне кажется.


    1. lohmatii
      26.03.2019 12:08

      Чек из ККМ уходит в ФНС.
      На самом чеке есть QR-код, грубо говоря, с его ИД.
      Мобильное приложение ФНС сканирует только этот код и запрашивает все данные по нему сервера ФНС. И может потом скинуть эти данные в почту.


    1. VitGun
      27.03.2019 08:41

      отправкой чеков на e-mail занимается ОФД. Если в тэгах чека указан e-mail, то автоматом идет отправка. По крайней мере в такскоме эта опция бесплатная. Отправка на SMS стоит денег.


  1. BerkutEagle
    26.03.2019 12:22

    Множество приложений для учёта расходов из Google Play/App Store уже умеют сканировать QR-коды на чеках и загружать информацию с серверов ФНС. Без промежуточного звена в виде почты. Некоторые даже бесплатные и могут экспортировать данные в различные форматы.


    1. Antojgo
      26.03.2019 13:36

      в почте есть плюс, ее можно использовать как триггер, т.е. на почту попадут готовые результаты. А из QR-кода не всегда оперативно можно получить список из чека. Данные из ККМ в ФНС у многих магазинов уходят только в конце дня.


      1. philya
        26.03.2019 18:34

        А у некоторых через 30 дней, когда касса перестает работать.


    1. AndrewVlz
      27.03.2019 10:24

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


      1. BerkutEagle
        27.03.2019 12:44

        Из тех, которыми пользовался, FinGen вроде подходит. Импорт/экспорт/парсинг смс/скан чеков — всё в базовом функционале. Одна платная функция — отчёты, но можно сделать экспорт в csv и построить какие угодно отчёты в Excel. Даже исходники на гитхабе имеются. У меня, правда, финансовый учёт не прижился — самодисциплина хромает :) Поэтому пользовался приложением не очень долго.


      1. kotlomoy
        28.03.2019 10:36

        Год пользуюсь приложением Finpix. Единственное приложение в Google Play, которое обладает следующим минимально необходимым (для меня) функционалом:
        — Сканирование чеков по QR-коду. Сканер отличный, легко сканирует в т.ч. синие коды Пятерочки (кто-то выше писал, что это может быть проблемой).
        — Добавление расходов/доходов/переводов из банковских СМС.
        — Ручное добавление расходов/доходов.
        — Импорт/экспорт в форматах xlsx, sqlite.
        — Категории, подкатегории и т.д.
        — Справочник товаров и категорий, благодаря которому работает автоопределение категорий и автодополнение полей.
        — Справочник магазинов с возможностью добавления псевдонимов — полезно, если хочется заменить всякие ИНН на читаемые названия. Автодополнение полей.
        — Диаграммы, тэги.
        — Всё это бесплатно.

        Из минусов: приложение сейчас поддерживается не особо активно, поэтому долго и мучительно ищу ему адекватную замену, пока безрезультатно. Буду благодарен, если кто-нибудь подскажет.


  1. FiLunder7
    26.03.2019 12:36

    А не проще ли использовать для контроля расходов, интернет клиент банка в котором вы все покупки и совершаете? У всех популярных банков вполне приличные инструменты для этого. Или кто-то еще пользуется наличкой? В любом случае там можно обычно и бумажные чеки вносить.


    1. lohmatii
      26.03.2019 12:46

      Банков может быть несколько. Плюс иногда бывает и наличка. Т.е. придется в итоге сводить воедино статистику разных мест.
      И, если я правильно понимаю, банк же будет видеть только саму транзакцию целиком, а не строчки чека в ней. Все 10К в гипермаркете будут одной строкой. И посмотреть, что в прошлом году в них был в основном алкоголь, а в этом — молоко, не получится.


      1. FiLunder7
        26.03.2019 12:48

        Ну если такая точность необходимо, то конечно.


      1. Fedcomp
        26.03.2019 22:36

        Тем не менее тинькофф к концу года знал что я больше всего покупал кефир. Значит у них как минимум есть партнерство.


        1. kSx
          27.03.2019 09:24

          Интересно, а каким образом об этом узнали вы?


          1. johndow
            27.03.2019 09:40

            Они присылали письмо полушуточное. Что-то вроде, вот ваш год в ваших покупках.


          1. chersanya
            27.03.2019 11:24

            Они вообще про покупки в супермаркете прямо в мобильном и интернет банке пишут подробности из чека — полный список того, что было куплено.


      1. Anastasia_K
        27.03.2019 11:36

        приложение тинькова из большинства супермаркетов подтягивает полный чек со списком покупок


    1. shalm
      27.03.2019 07:38

      Жена большую часть продуктов, а летом — осенью почти все покупает на рынках и там нет ни касс, ни платежей с кредиток. Так что кто-то пользуется наличкой.


      1. FiLunder7
        27.03.2019 10:29

        Хм. У нас на рынке есть.


    1. shilovav
      27.03.2019 11:03

      не проще, удобных вменяемых интернет банков нет.

      удобство, это возможность самому придумывать категорию, менять местами, отменять, разбивать и т.д.


      1. FiLunder7
        27.03.2019 11:11

        Категорию можно в любом самому сделать. Менять местами – в смысле, не понял. Отменять, то же не понятно. Транзакцию если вы отмените — она исчезнет. Разбивать: часто такое может понадобиться?


        1. shilovav
          28.03.2019 12:05
          +1

          купил в супермаркете продукты и машинное масло, общую сумму нужно разбить на несколько

          в кабаке заплатил со своей карты за всех, а друзья дали наликом


  1. serge_levin
    26.03.2019 13:07

    Немного саморекламы копрокода — около года назад для собственных нужд начал https://github.com/sergelevin/pyofd. Выделен некий интерфейс для добавления работы с новыми провайдерами. Но т.к. сейчас все мои нужды покрывает непосредственный запрос с nalog.ru, отслеживание постоянно меняющегося формата вывода различных провайдеров уже давно не осуществляется.
    Там же в качестве примеров экспорт в xlsx в том числе по строке отсканированного QR-кода. Проблема регистрации для доступа к данным nalog.ru скриптами не решалась, ибо задачи такой не ставилось — поставил на телефон их приложение, один раз получил пароль и доволен аки слон.


  1. ProRunner
    26.03.2019 14:40

    Используем 54 ФЗ на благо домашней бухгалтерии
    Из похожих статей с большим количеством комментариев


    1. ProRunner
      26.03.2019 15:26

      Кстати, лучи ненависти в сторону пятерочки, чьи бледно-синие qr-коды не распознаются телефоном (по крайней мере в нашем городе)


      1. Wernisag
        27.03.2019 07:06

        Попробуйте QR Scanner от Касперского. Только что проверил, Samsung A8 такой чек берет без проблем. В целом по софтине, ничего лучше пока не встречал (вот они чудеса мобильной разработки, где даже сканнер приходится искать годами).


        1. kreo_OL
          27.03.2019 07:36

          Ну мы же программисты. Надо свой писать)))


        1. ProRunner
          27.03.2019 08:55

          Я пользуюсь приложением FinGen для ведения домашней бухгалтерии, сканирую им же — другие сканеры туда, к сожалению, не прикрутишь. Да и это единственные чеки, которые или не сканируются вообще или сканируются через раз. Ни с кем другим проблем не возникало.


  1. olchip
    26.03.2019 15:11

    Есть ещё вариант: приложение, которое обрабатывает смс или push (я пользуюсь www.drebedengi.ru). И немного дисциплины в части проведения операций по налу :)


    1. seventh
      27.03.2019 15:26

      Я пользуюсь zenmoney — не только приложение, но и сайт, поддержка подключения популярных онлайн-банков.


  1. kbaa
    26.03.2019 20:26

    Когда игрался с библиотеками распознавания символов, подумал что можно ради интереса и тренировки накатать приложение типа домашней бухгалтерии.
    Когда начались внедрения онлайн касс, подумал, что без всякого распознавания уже всё готовое, точно надо пилить бухгалтерию.
    Вобщем, блокнотик для идей пополнился новой записью, ничего не сделано.
    Хорошо, что есть такие как автор, у кого руки всё-таки доходят до реализации :)


  1. Chuvi
    27.03.2019 09:15

    Чеки можно получать с сервера ФНС как в одиночку по QR-коду, так и все сразу (за какое-то время, правда), которые получал данный пользователь.
    Примеры запросов чеков можно глянуть здесь. habr.com/ru/post/358966
    Запрос на получение всех ранее сканированных чеков такой:
    proverkacheka.nalog.ru:9999/v1/extract?sendToEmail=0&fileType=json
    HTTP-авторизация также обязательна. В ответ придёт ссылка на JSON-файл.

    Если слать много запросов на чеки, которых у ФНС-а нет, то можно наткнуться на ошибку «Исчерпан дневной лимит для пользователя». Код ошибки, к сожалению, не помню.


  1. AnnA-S
    27.03.2019 10:24

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

    Ух, фантазия разыгралась!


  1. SaintMortum
    27.03.2019 10:24

    Слишком сложно. Мне как 1с-нику было проще развернуть 1С: Деньги и дописать в него веб-сервис, куда через Automate отправляются смс с разных банков. Но об оплате наличкой лучше забыть, если нужно учесть все расходы.
    Получать чек на e-mail не то что не всегда возможно, так и неудобно. Слишком много времени тратится на оплату, т.к. кассир даже если знает как это сделать, то просто забудет. Будет тупить и ошибаться.


  1. beatleboy
    27.03.2019 16:38

    Самое наверное лучшее из того что я видел это дзен мани, там и сканер чеков и ручной ввод платежей и интеграция банков из коробки. Плюс под все моб. платформы клиент и веб версия. Удобно, и изобретать ничего не надо.


  1. AndreDeBonk
    28.03.2019 00:53

    Обожаю анализ данных и всевозможные виды статистики, но не понимаю, зачем заниматься этой возней с категоризацией расходов, фотографированием чеков и прочим.

    Решение по поводу целесообразности траты средств я принимаю до покупки. Время потраченное на подобное крохоборство стоит гораздо дороже.


    1. BerkutEagle
      28.03.2019 06:34

      Возможно, если денежный оборот описывается формулой по-сложнее, чем: зарплата-(ипотека+коммуналка+покушать)=~0, такой учёт помогает и почти необходим.
      Ну и хобби никто не отменял! Одни, для достижения внутренней гармонии, на йогу ходят, другие просто бухают, третьи марки собирают, кто-то перфоратором узоры на стене выводит по ночам, а кто-то домашнюю бухгалтерию ведёт :)