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

Так как песочницей для наших планов выступили Google Docs, а конкретнее Таблицы, то мне захотелось разместить фото всех чеков на отдельном листе. Первая попытка вставить картинку в таблицу через привычный пункт меню «Вставка > Изображение» привела к тому что чек оказался поверх ячеек таблицы и моим друзьям IT-шникам такое оформление точно бы не приглянулось:



«Должен же быть способ вставить картинку в ячейку...», — подумал я. Google нашел этот способ с первого запроса: функция IMAGE(URL), как значение ячейки. Ну что ж, дело сделано:



Можно дальше идти смотреть лыжные уроки. Хотя…

...Google моментально среагировал на мой запрос «Online FineReader API» и выдал несколько статей с хабра о ABBYY Cloud OCR SDK. Быстрый просмотр доступных методов платформы подтвердил мои надежды и желанный ocrsdk.com/documentation/apireference/processReceipt был найден. Для осуществления задуманного недоставало понимания как вставить в ячейку таблицы пользовательскую функцию, которая будет вызывать методы обработки чека. Но и тут поиск меня не подвел и был найден Редактор скриптов Google.

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

Далее в нашей Таблице выбираем пункт меню «Инструменты > Редактор скриптов» и создаем функцию processReceipt(imageUrl):

function processReceipt(imageUrl) {
    
    // Загружаем картинку чека
    var image =      UrlFetchApp.fetch(imageUrl);
  
    // Формируем заголовок авторизации, который состоит из имени приложения и пароля
    var pass = "GoogleDriveTest" + ":" + "********************"
    
    // Формируем POST запрос на обработку чека
    var url = "http://cloud.ocrsdk.com/processReceipt";
    var headers = {
        "Content-Type":"image/png",
        "Authorization" : "Basic " + Utilities.base64Encode(pass)
    };
    
    var options = {
        "method":"POST",
        "headers": headers,
        "payload" : image.getContent()
    };
    var response = UrlFetchApp.fetch(url, options);
    
  
    // Парсим XML ответа и находим в нем ID задачи по обработке нашего чека (больше деталей тут http://ocrsdk.com/documentation/apireference/processReceipt/)
    var document = XmlService.parse(response.getContentText())
    var id = document.getRootElement().getChildren()[0].getAttribute('id').getValue()
    
    var resultUrl
    
    // Ждем успешного завершения задачи и получаем url по которому можно получить результат обработки чека
    do {
        Utilities.sleep(3000)
        
        url = "http://cloud.ocrsdk.com/getTaskStatus" + "?taskId=" + id;
        headers = {
            "Authorization" : "Basic " + Utilities.base64Encode(pass)
        };
        
        options = {
            "method":"GET",
            "headers": headers,
        };
        
        response = UrlFetchApp.fetch(url, options);
        
        document = XmlService.parse(response.getContentText());
        if (document.getRootElement().getChildren()[0].getAttribute('status').getValue() == 'Completed') {
            resultUrl = document.getRootElement().getChildren()[0].getAttribute('resultUrl').getValue()
            break
        }
    } while(true)
        
    // Получаем результат обработки чека
    options = {
        "method":"GET",
    };
    
    response = UrlFetchApp.fetch(resultUrl, options);
    document = XmlService.parse(response.getContentText());
    
    // document содаржит XML нашего чека. Из-за моральных принципов реализацию функции findTotalPriceInReceiptXML я скрыл :)
    result = findTotalPriceInReceiptXML(document)
    
    return result
}

Всё сохраняем и идем обратно в таблицу. Чтоб сие чудо заработало, пришлось вынести в отдельную ячейку таблицы URL картинки чека. Наша функция теперь доступна как =processReceipt(ячейка с URL).



Всем хорошей зимней погоды и удачи на лыжных склонах!
Поделиться с друзьями
-->

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


  1. and7ey
    06.01.2017 18:52

    After the registration Customer will automatically receive a Free Test Set through his account. This test set consists of Free 50 Customer’s A4 Images – any 50 images which are valid for 90 days after the registration has been completed.

    Receipt is considered to be an image processed with processReceipt method. Every Receipt recognition is charged as a recognition of two A4 pages.

    Т.е. лишь 25 чеков можно распознать бесплатно. Печально.


    1. and7ey
      06.01.2017 19:00
      +1

      Хотя можно 100 страниц в месяц получить бесплатно — http://blog.ocrsdk.com/get-the-best-ocr-technology-for-free. Уже лучше :).


    1. apelsyn
      07.01.2017 11:59

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


      Недавно обновились натренированные модели для многих языков


  1. DistortNeo
    06.01.2017 19:30
    +3

    Что-то мне подсказывает, что просто вбить «134.36» руками было бы быстрее, чем фотографировать чек, вставлять его в документ и распознавать. Здесь нужно писать приложение для телефона, которое само фотографирует чек и распознаёт его.


    1. vlad_br
      06.01.2017 20:06

      Вы правы в том что приложение решит задачу организации базы фотографий чеков с их распознаванием более качественно. Более того, таких приложений написано предостаточно. А вот метод продемонстрированный в статье, хоть и не оптимален, но достаточно оригинален. Его плюс в том, что всё что вам надо сделать — написать логику по обработке изображения, а вот о визуальной составляющей уже позаботились инженеры google.


  1. Leopotam
    07.01.2017 01:00

    Проблема в том, что у каждого магазина свой чек и свой лейаут данных, часто с невообразимыми переносами. Буквально на днях решал такую же задачу — занесение данных с чеков в домашнюю бухгалтерию. Был написан бот в телеграме, который принимает потоком позиции расхода / прихода в виде «хлеб 123 еда» (товар, стоимость, категория), причем эти данные вносятся голосовым набором с мобильного устройства (распознавание идет средствами android / ios автоматически, распознанная команда отправляется как текст). Есть возможность посмотреть статистику за указанный год / месяц / день и выгрузить это все в виде csv, который уже потом можно залить в google docs и построить всевозможные графики. Жена говорит, что нравится и что стало гораздо удобнее заносить данные, чем вручную вбивать в таблицу.


    1. vlad_br
      07.01.2017 01:16
      +1

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


      1. Leopotam
        07.01.2017 13:53
        +1

        То, что описал выше, выглядит примерно вот так:

        Длинный скриншот


    1. sviterov
      08.01.2017 01:34

      О, а не дадите ссылку на бота?


      1. Leopotam
        08.01.2017 11:14

        Он «приватный», т.е. будет отбивать всех пользователей не из разрешенного списка. Возможно, когда подчищу говнокод — выложу в паблик. Но там все просто на самом деле — nodejs + node-telegram-bot-api. Если сильно надо, то пишите, отдам так.


  1. shasoft
    07.01.2017 01:10

    Нужно оплачивать с карточки, тогда такое распознование не понадобится. :)

    p.s.А есть вообще на Android приложения которые фоткают и распознают чеки? Искал пару лет назад — не нашел. Но может что-то уже появилось или искал плохо?


    1. Leopotam
      07.01.2017 01:13

      1. Не везде есть возможность выгрузки из ЛК банка
      2. Не везде есть терминалы, часто требуют платить в кассу наличкой, например, на шиномонтаже в замкадье такое часто встречается.
      3. Возможно карточек больше одной и они от разных банков — см. пункт 1 :)

      Чеки являются универсальным носителем нужной информации, пусть и не унифицированной.


      1. webpavilion
        07.01.2017 10:56

        Много лет пользуюсь одним из сервисов для ведения домашней бухгалтерии.
        1. ЛК банка не нужен. Всё работает через СМС информирование о операциях по картам, на смартфоне в фоне приложение которое распознает и отправляет на сервер всё операции.
        2. Живу в 80км от дефолтсити, 93% всех расходов с банковских карт.
        3. Карт у меня 7 штук от 4 разных банков, в разных валютах, всё работает без каких либо проблем.

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


        1. Leopotam
          07.01.2017 13:35

          Чеки не удобны для долгосрочного хранения

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

          Всё работает через СМС информирование о операциях по картам, на смартфоне в фоне приложение которое распознает и отправляет на сервер всё операции.

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

          93% всех расходов с банковских карт

          Примерно так же, apple pay принимается практически в 100% терминалов (сбербанк постарался — обновил практически все терминалы), но все-равно приходится с собой таскать 2-3к наличкой.


          1. immaculate
            07.01.2017 21:18
            +1

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


            Мой опыт такой, что разбивка по массе узких категорий — это большие затраты труда, которые не приносят ощутимых дивидендов. Например, часто в супермаркете покупаю вместе с продуктами несколько журналов. Можно конечно каждый раз разбивать чек на две категории: продукты и журналы. На практике же, никакой пользы от такой разбивки нет. Что я, журналы вдруг перестану покупать. Я покупаю три журнала: «Мото», «Мотоэксперт» и «Наука и жизнь». Каждый год трачу на это приблизительно одинаковую сумму, в пределах 400-600 рублей в месяц. Зачем мне эта информация в отдельной категории?


            Изначально я тоже пытался каждый чек бить и каждую категорию учитывать отдельно. Но это превращает учет в пытку, а пользы — ровно 0.


            1. Leopotam
              07.01.2017 22:20

              Это позволяет делать выборку по категориям по приходу / расходу. Возможно может показаться бесполезным, но это используется в дальнейшем при фильтрации для рисования графиков и прочего. Позволяет в размышлениях, что на что было потрачено. :)


              1. immaculate
                07.01.2017 22:35
                +1

                Ценность этой информации минимальна, на самом деле. И без того количество категорий достаточно большое, чтобы еще и чеки из супермаркета бить. Никакой информации для принятия решений из этого не извлечь.


                Допустим, меня интересуют в домашнем учете следующие вопросы:


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

                Первые два вопроса — самые важные, так как позволяют принимать какие-то долгосрочные решения. Например, сколько в месяц я могу откладывать на какую-то очень большую затрату и сколько месяцев/лет мне понадобится (путешествие, новый мотоцикл, еще что-то из этой категории). Ответ на третий вопрос часто бывает нужен, чтобы принять решение о какой-то внезапной трате. Ответ на последний вопрос — чтобы скорректировать какие-то ежемесячные траты, например, на мобильную связь.


                Большой уровень детализации возможно позволяет строить более красивые графики, но он очень быстро утомляет и забрасываешь ведение бухгалтерии вообще. А извлекаемая информация никогда не нужна, во всяком случае, мне. Конечно, у всех разные цели, мотивации, уровни доходов и расходов. Допустим, если бы доход у меня был в 10 раз выше, чем сейчас, я бы вообще не заморачивался, скажем, теми же расходами на мобильную связь.


                1. Leopotam
                  07.01.2017 22:43

                  Еще раз — эта информация важна в моем конкретном случае, даже если это не важно кому-то еще. Ну и это все автоматизировано — сказать одно короткое слово в конце фразы — ничего утомительного. Доход позволяет не думать о мелких расходах, но возможность разбивки по категориям ничего фактически не стоит в плане занесения, а так же было в списке требуемых фич в ТЗ основного пользователя — жены.


                1. Spunreal
                  11.01.2017 00:30

                  Например, потратил в магазине продуктовом 20к в месяц. Понял. что что-то многовато. Построил по категориям, выявил существенные расходы и выяснил, что оказывается каждый день покупалась баночка колы (вот просто так), а так же какой-то дорогой сырок, от которого ни холодно ни жарко, но который сожрал 2000р за месяц (а его аналог уже 1000 всего лишь). В итоге уже экономия в 2000 — 3000 рублей.

                  Вручную заносить действительно сложно, но когда есть автоматизированный инструмент, то почему бы и нет. Если бы по такой схеме (сколько всего зарабатываю / сколько всего трачу) работали в рекламных сетях, то все бы разорились. Сотни рекламных кампаний, тысячи объявлений, брать в расчёт нужно конкретное объявление или кампанию, а не весь аккаунт.

                  P.S. это естественно актуально до определённого уровня заработка. Дальше просто смысла нет пытаться сэкономить 5-10% (хотя кто знает). Но учитывая средний уровень заработка по России, то всем очень даже пригодится автоматическое разбиение по категории.

                  P.P.S. Таким образом можно избавить себя от внезапных ненужных трат — поход по магазинам, когда всё есть и выброс 5-10к на вещи. Поход куда угодно, что не особо то и нужно было. Как раз в этом случае детализация позволит выявить такие траты, а в сколько всего тратится будет только общая информация, но никак не полезность покупок или трат.


                  1. DistortNeo
                    11.01.2017 01:51

                    На эту тему есть хороший анекдот:


                    Стоит прилично одетый мужчина в Нью-Йорке возле небоскреба и курит.
                    Подходит к нему журналист и говорит:
                    — Здравствуйте. я корреспондент газеты «Нью-Йорк Таймс». Можно задать
                    вам несколько вопросов?
                    — Да задавайте, я в принципе не спешу.
                    — Вот вы курите. А, простите, как долго вы курите?
                    — Мне сейчас 43, и курю я с 16 лет.
                    — А какие сигареты вы курите, если не секрет?
                    — Да не секрет — «Мальборо».
                    — И последний вопрос — сколько сигарет в день?
                    — Пачки полторы — две.
                    Журналист достает калькулятор, что-то считает и снова обращается
                    к мужчине:
                    — Вот вы знаете, если бы вы не курили, то на сэкономленные деньги
                    вы могли бы купить вот этот вот небоскреб?
                    — Серьезно?.. А вот вы сами курите?
                    — Нет, я не курю.
                    — И что, небоскреб у вас есть?
                    — Нет, небоскреба у меня нет.
                    — А я курю, и небоскреб мой…


                  1. malbaron
                    11.01.2017 10:40

                    Пример с едой показателен, но только для начала карьеры.
                    Я во время учебы в ВУЗе и сразу после окончания вел такую штуку…

                    В иные месяца:
                    50% уходило на аренду квартиры,
                    25% уходило на печенки и 25% уходило на пиво…
                    ;)

                    Потом аналитику забросил, так как стало хвать как этому курящему мужику с небоскребом.

                    В середине декабря получил 270 тыс. руб.
                    Но они куда-то делись до 5 января (не пил).
                    Решил, что пора снова, как в студенческие годы, вести аналитику.

                    P.S.:
                    Все хорошо по ситуации.
                    Считать каждую булочку важно только когда ты студент.


                    1. Leopotam
                      11.01.2017 11:07

                      А еще можно просто ужасаться, куда делось 300к за 2 месяца, хотя вроде ничего такого серьезного не покупалось :) Статистика в первую очередь носит информационный характер, а принимаются решения или нет — это другой вопрос.


                      1. malbaron
                        11.01.2017 19:41

                        Связанный.
                        Решения ты принимаешь на основе чего либо.


      1. pyhtin
        07.01.2017 13:32

        1) У многих банков есть мобильные приложения, а они доступаются к данным через API, вот и получаем простой способ импортировать в свою систему все траты. Например вот https://rockapipreview.surge.sh/operations/, еще ковырялся в API tinkoff.ru, там тоже все просто. На 99% уверен что сбербанк, альфабанк, втб, юникредит тоже можно импортировать.
        2) внести пару покупок в месяц руками не так сложно
        3) см. п. 1


        1. Leopotam
          07.01.2017 13:36

          См. комментарий выше — сумма, к сожалению, приезжает одним куском, без разбивки на товары.


          1. bevice
            07.01.2017 17:42

            Тоже не сильно страшно, как правило: один магазин — одна категория, причем заранее известная. Бывают исключения, но редко.


            1. Leopotam
              07.01.2017 18:07

              Ну вот, например, алкоголь хочется считать отдельно от «еды», как быть? Ну и т.п. случаи. :)


      1. bevice
        07.01.2017 17:52

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


    1. Garrett
      07.01.2017 17:53

      Наоборот!
      Можно взять выписку из банка (желательно CAMT) и привязывать к расходам чеки!


    1. andreyle
      08.01.2017 16:16

      Попробуйте Office Lens (https://play.google.com/store/apps/details?id=com.microsoft.office.officelens&hl=ru) умеет исправлять перспективу документа и экспортировать в OneNote который уже в свою очередь распознает документ. Есть под все основные платформы.


  1. ivanbolhovitinov
    07.01.2017 05:37

    А в Казахстане многие (а может даже и все) кассы подвели к общей системе.
    В чеке пишут URL и контрольный номер. Через сайт и контрольный номер можно этот чек пробить через сайт обратно: https://consumer.oofd.kz/.
    Причем некоторые магазины предоставляют более подробную информацию о покупке чем другие (номенклатура).
    Только как-то оно всё непонятно зачем. API нет, чтоб пробить чек надо вбить все данные (включая контрольный код, время и общую сумму). Видимо сделано, чтоб можно было убедиться, что магазин не скручивает чеки или другим способом уклоняется от уплаты налогов. И если покупатель чека не найдет в базе, то он может магазин заложить.


    1. BalinTomsk
      07.01.2017 08:27

      В Канаде всего один магазин Home Depot разпознает дебитовую кароточку и посылает на зарегистрированный email версию чека


  1. Morosus
    07.01.2017 13:31

    Просто хочу напомнить, сто с 2017 года на территории РФ действует новая редакция ФЗ-54, согласно которой для большинства ритейл операций онлайн фискализация является обязательной. Так что теперь на чеке должен ьыть qr код со ссылкой на чек в электронном виде.


    1. malbaron
      08.01.2017 01:34

      То есть все магазины обязаны быть подключены к интернету?
      И если интернет пропадает — продавать товары нельзя?


      1. Morosus
        09.01.2017 18:55

        Да, за исключением «труднодоступных мест», список которых будет обудликован позднее, все должны иметь доступ к интернет. Если саязь разорвана, то продажи можно осущетвлять в течение определенного времени (в законе данный промежуток не указан, но производители оборудования ориентируются на приблизительно 30 дней), при восстановлении связи данные будут переданы Оператору Фискальных Данных


    1. Sersoftin
      09.01.2017 02:44

      Уже для всего сделали? Раньше точно было для некоторых видов алкоголя. На чеке выбивали qr код и сразу url, где можно было посмотреть все это.


      1. Morosus
        09.01.2017 18:52

        Да, теперь для практически всех видов товаров.

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


  1. Badja
    07.01.2017 13:31

    Прикольно, но вроде были такие приложения, хотя могу и ошибаться



  1. Stas911
    09.01.2017 02:20

    По работе пользуемся сервисом Expensify для заполнения трат — там в мобильном клиенте есть такой функционал: сфоткал чек и готово.


  1. playaaa
    11.01.2017 00:30

    Как насчет просто воспользоваться Expensify, доступным для частным лиц по бесплатной подписке?