К каждому из пяти сканов приложен файл с правильными значениями — это эталон, с ним мы сравниваем то, что прочитала программа. Ниже — все поля эталона простыми словами, с примерами из ваших настоящих файлов. Выдуманных значений на этой странице нет: каждое взято из конкретного примера, номер примера указан.
Набор полей у всех пяти эталонов одинаковый — ни одно поле не «пропадает».
Если значения в документе нет, поле остаётся пустым (в файле это null,
пустая строка или пустой список). Поэтому «поле есть / поля нет» тут не бывает —
бывает «заполнено / пусто», и это разное у разных документов (см. раздел
«Чем эталоны отличаются друг от друга»).
Файл состоит из четырёх частей: шапка документа, продавец, покупатель и таблица товаров. Пятая часть — служебные поля, которые в этих документах не встретились.
| Поле | Что означает | Настоящий пример |
|---|---|---|
type | Вид документа | UTD — универсальный передаточный документ (УПД). Так во всех пяти |
number.value | Номер документа — как есть, вместе с буквами | ЦБ-444 (пример 4), 1189/4 (пример 5), 25 (пример 1) |
date.value | Дата документа в машинном виде: год-месяц-день | 2024-05-23 — это 23 мая 2024 (пример 4) |
date.rawValue | Та же дата, но как она написана в самом документе. Нужна, чтобы понять, откуда взялась дата | 25февраля2025 (пример 3). В остальных четырёх — пусто |
currency | Валюта сумм | RUB — рубли. Так во всех пяти |
Два одинаковых по составу блока: supplierData — продавец (кто отгрузил),
customerData — покупатель (кто получил).
| Поле | Что означает | Настоящий пример |
|---|---|---|
name | Название организации или ФИО предпринимателя — как в документе | продавец: ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ "ФРЕГАТ" (пример 2);
покупатель: Индивидуальный предприниматель Гурьянов Антон Игоревич (пример 4) |
inn | ИНН. У организаций 10 цифр, у предпринимателей 12 | 1660282762 — ООО «ФРЕГАТ» (пример 2); 773373089219 —
предприниматель (пример 4) |
kpp | КПП. У предпринимателей его не бывает — там пустая строка | 165701001 (пример 2); пусто у покупателей в примерах 3 и 4 |
countryAlpha3Code | Страна тремя буквами | RUS — Россия. Так у всех десяти сторон в пяти документах |
taxId | Налоговый номер иностранного контрагента | Пусто во всех пяти — иностранных сторон нет |
address.fullAddress | Адрес одной строкой | 142100, Подольск, — покупатель (пример 3);
150539, Лесная Поляна, 41 — продавец (пример 3);
101000, Москва, — покупатель (пример 4) |
address.zipCode | Индекс | 142100 — покупатель в примере 3, больше нигде не заполнен |
address.region | Код региона | 50 — Московская область (пример 3) |
address.city | Город | Подольск (пример 3) |
address.street, building, block,
apartment, locality, territory |
Улица, дом, корпус, квартира/офис, населённый пункт, территория (СНТ, промзона) | Пусто во всех пяти — в эталонах адрес разобран только до города |
142100, Подольск, обрывается запятой — улицы и дома в ней нет.
Значит, по адресу качество распознавания измерять нельзя: эталону тут доверять не в чем.
Сверять имеет смысл ИНН, КПП, название и таблицу товаров.Главная часть — блок itemsTable. Сначала итоги по всей таблице, потом
список строк items: одна строка = одна товарная позиция.
| Поле | Что означает | Настоящий пример |
|---|---|---|
itemsTable.amount | Всего к оплате, с НДС | 623478.34 ₽ (пример 5) |
itemsTable.amountWithoutVat | Всего без НДС | 519565.26 ₽ (пример 5) |
itemsTable.vat | Всего НДС | 103913.08 ₽ (пример 5) |
В примере 4 все три итога пустые — их в эталоне просто не заполнили, хотя строки в таблице есть.
| Поле | Что означает | Настоящий пример |
|---|---|---|
serialNumber | Порядковый номер строки. Счёт идёт с нуля: первая строка — 0, вторая — 1 | 0 … 19 у 20 строк примера 1 |
name | Наименование товара, как напечатано | Автошина Pirelli-Formula 225/55R18 102T XL Formula Ice шип (пример 2) |
goodCode | Артикул (код товара у продавца) | ЦБ-00000039 (пример 4), 00000000007 (пример 5).
Иногда распознан с мусором: — 00-00001455- 1 (пример 2) |
unit | Единица измерения словами | шт, упак, рул, пар (пример 1),
м2 (пример 4), пог. м, компл (пример 5) |
unitCode | Код той же единицы по государственному классификатору ОКЕИ | 796 — штука, 778 — упаковка, 736 — рулон,
715 — пара, 055 — кв. метр, 018 — погонный метр,
839 — комплект |
quantity | Количество. Бывает дробным | 384 (пример 3), 5.796 кв. м (пример 4) |
price | Цена за единицу, без НДС | 9375.0 ₽ за шину (пример 2), 85 ₽ за основу для пиццы
(пример 3) |
amountWithoutVat | Стоимость строки без НДС | 37500 ₽ (пример 2: 4 шины по 9 375 ₽) |
vatRate | Ставка НДС | PERCENT_20 — 20 % (в четырёх примерах),
PERCENT_10 — 10 % (пример 3, продукты) |
vat | Сумма НДС по строке | 7500 ₽ (пример 2), 173.88 ₽ (пример 4) |
amount | Стоимость строки с НДС | 45000 ₽ (пример 2), 1043.28 ₽ (пример 4) |
excise | Акциз | Пусто во всех 47 строках — подакцизных товаров нет |
discount | Скидка по строке | Пусто во всех 47 строках |
countryCode | Страна происхождения товара | Пусто во всех 47 строках |
goodTypeCode | Вид операции: товар, работа, услуга | Пусто во всех 47 строках |
customsDeclaration | Номер таможенной декларации | Пусто во всех 47 строках |
Эти поля предусмотрены форматом, но в ваших пяти документах пустые. Их перечисляем, чтобы список был полным.
| Поле | Что означает | Что в эталонах |
|---|---|---|
documentShipments | Отгрузки: транспортные документы, привязанные к УПД | Пустой список во всех пяти |
transferBases | Основания передачи — договор, заказ | Пустой список во всех пяти |
amountModifiers | Надбавки и скидки на весь документ | Пустой список во всех пяти |
customFields | Дополнительные поля под конкретную задачу | Пусто во всех пяти |
supplierAccountDetails | Банковские реквизиты продавца | Пусто во всех пяти |
receiptQR | QR-код кассового чека | Пусто во всех пяти |
paymentOrderId | Ссылка на платёжное поручение | Пусто во всех пяти |
Состав полей одинаковый, а вот заполнены они по-разному. Проверено по всем пяти файлам — вот полный список различий.
| Поле | Заполнено | Где именно и чем это грозит |
|---|---|---|
itemsTable.amount, amountWithoutVat, vat |
4 из 5 | Нет итогов в примере 4 (№ ЦБ-444). Сверять итоговые суммы на этом примере не с чем — только построчно |
customerData.kpp | 3 из 5 | Пусто в примерах 3 и 4 — там покупатели индивидуальные предприниматели, у них КПП нет. Это не ошибка эталона |
goodCode в строках | 24 строки из 47 | Артикулов нет совсем в примерах 1 (0 из 20) и 3 (0 из 1); в примере 2 — 4 из 5, в примере 4 — 3 из 3, в примере 5 — 17 из 18 |
customerData.address.fullAddress | 2 из 5 | Примеры 3 и 4, и в обоих строка оборвана на городе |
customerData.address по частям (индекс, регион, город) |
1 из 5 | Только пример 3 |
supplierData.address.fullAddress | 1 из 5 | Только пример 3. У остальных четырёх продавцов адреса нет вообще |
date.rawValue | 1 из 5 | Только пример 3 (25февраля2025) |
Ещё одно расхождение — не в полях, а в записи чисел: одна и та же величина в разных
файлах записана то целым числом, то с копейками. В примере 2 итог 171600,
в примере 5 — 623478.34. Для сравнения это неважно, если сравнивать
как числа, а не как текст.
Пересчитали все 47 строк — это полезно знать, потому что по этим правилам можно ловить ошибки распознавания автоматически.
Сходится не всегда. Цена, умноженная на количество, в 26 строках из 47 чуть-чуть не даёт стоимость без НДС. Причина — цена в документе округлена до копеек. Самое большое расхождение: строка «S-358.20 Штапик для с/п 24 мм» в примере 5 — 48,31 ₽ × 1040 = 50 242,40 ₽, а в эталоне 50 245 ₽, разница 2,60 ₽ (это 0,005 % строки). Вывод: «цена × количество» как проверку использовать можно, но с допуском в несколько рублей, иначе будут ложные тревоги.
Эталон считаем правильным. Всё, что не совпало, записываем в ошибки распознавания — кроме случаев из раздела про расхождения выше: пустой КПП у предпринимателя или отсутствующий артикул ошибкой не считаются.
Пояснение составлено по фактическому содержимому пяти файлов из вашей папки «Файлы»: все примеры на этой странице взяты оттуда. То же самое текстом — в файле README.md рядом с набором.