13 мая 2025 г.·7 мин

Автоматизация трёхсторонней сверки: таблицы и рабочий процесс для удержаний в AP

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

Автоматизация трёхсторонней сверки: таблицы и рабочий процесс для удержаний в AP

Какую проблему на самом деле решает трёхстороннее сопоставление

Трёхсторонняя автоматизация сопоставления проста: вы оплачиваете счёт только тогда, когда он совпадает с тем, что вы заказали, и тем, что фактически получили. Три документа — это заказ на покупку (PO), запись о приёме (receipt) и счёт от поставщика.

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

Такие ошибки редко выглядят драматично в первый день. Они проявляются как мелкие течи: строка списана дважды, партия недопоставлена на несколько единиц, повышение цены, которое не было согласовано, или добавленная доставка, когда её не должно быть. Со временем эти мелкие ошибки превращаются в реальные потери.

Цель не просто «утвердить счета». Цель — блокировать платёж до тех пор, пока ключевые поля, которые вы выберете (обычно количество, цена за единицу и суммы), не совпадут в PO, receipt и invoice. Если они не совпадают, счёт не должен теряться в почте. Он должен попадать в очередь исключений с понятным кодом причины и точными полями, которые отличаются.

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

Ожидания нужно задать заранее: это проблема процесса и данных, а не кнопки «одобрить». Если строки PO расплывчаты, приёмы не фиксируются или счета нельзя связать со строкой PO, автоматизация не спасёт.

Документы и роли: PO, receipt, invoice и кто за что отвечает

Трёхсторонняя сверка работает только тогда, когда каждый документ имеет понятного владельца. Если «кто что обновляет» неясно, система либо будет блокировать корректные платежи, либо пропускать плохие.

Практичная модель ответственности выглядит так:

  • Инициатор (requester) создаёт запрос на закупку и подтверждает необходимость.
  • Закупки (procurement) создают и ведут PO (поставщик, цена, условия).
  • Склад/приёмщик (или владелец услуги) фиксирует receipt или акт приёмки.
  • AP/Финансы регистрируют invoice и контролируют оплату.

Каждому документу также нужен минимальный набор полей, чтобы сопоставление не было в духе «угадай-ка».

PO (purchase order) должен содержать supplier ID, номер PO, строки (SKU или услуга), заказанное количество, цену за единицу, валюту, правила налогообложения и условия оплаты.

Receipt должен содержать ссылку на PO, дату приёма, принятые количества по строкам PO и кто принимал. Для услуг рассматривайте это как акт приёмки и фиксируйте утверждающего.

Invoice должен содержать номер счёта поставщика, дату счёта, ссылку на PO (или надёжный способ найти PO), детали по строкам (qty, unit price), налоги/доставку и итоговую сумму.

Также определите, когда запускается сверка. Это не одноразовое событие. Запускайте её при изменении реальности:

  1. Когда счёт попадает в систему (чтобы сразу решить — платить или удержать).
  2. Когда фиксируется receipt (чтобы счёт на удержании мог стать доступным к оплате).
  3. Когда меняется PO (чтобы открытые счета были перепроверены).

Частичные приёмы и несколько счетов — норма. Строка PO может прийти тремя поставками и быть фактурирована двумя счетами. Логика должна сравнивать накопительно полученное и накопительно выставленное по каждой строке PO, а не только отдельные документы.

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

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

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

Определите «жёсткие блокировки» и предупреждения. Жёсткая блокировка означает, что платёж не может быть проведён, пока проблема не решена. Предупреждение позволяет документу идти дальше, но кто-то должен признать риск.

Типичные отправные точки:

  • Жёсткая блокировка: количество, выставленное на оплату, превышает полученное (для товаров).
  • Жёсткая блокировка: цена за единицу превышает PO больше допустимого отклонения.
  • Предупреждение: небольшие округления.
  • Предупреждение: ожидаемые отличия в налогах или доставке, вынесенные в отдельные правила.

Держите правила толерантности явными. Определите метод (процент, абсолютная сумма или максимум из двух) и кто за это отвечает. Пример: допускается +/- 1% или +/- $5 по строке, изменение толеранса доступно только финансам с обязательной записью в аудите.

Используйте небольшой, общий набор статусов. Избегайте кастомных статусов для каждой команды. Чистый набор обычно таков: Matched, Hold, Exception, Approved. «Hold» означает, что платёж заблокирован. «Exception» — нужна проверка человеком. «Approved» — конкретный человек принял отклонение и записал причину.

Модель данных: таблицы, которые вам понадобятся (и почему)

Трёхстороннее сопоставление работает только если модель данных может связать строку PO, то, что было получено, и то, что было выставлено в счёте. Каждая строка счёта должна быть сопоставима с конкретной строкой PO (или явно отмечена как non-PO), а каждая строка приёма должна уменьшать оставшееся количество по строке PO.

Начните с основных таблиц закупок:

  • Vendors: одна строка на поставщика (имя, условия, налоговая информация).
  • ItemsServices: опционально, но помогает согласованности (SKU, описание, единица измерения).
  • PurchaseOrders: заголовок PO (vendor_id, currency, requested_by, status).
  • PO_Lines: якорь для сопоставления (po_id, item_id/description, ordered_qty, unit_price).

Приёмы должны иметь свои записи, даже если "receipt" — просто подтверждение. Держите receipts отдельно от invoices, чтобы можно было доказать, что и когда прибыло:

  • Receipts: заголовок приёма (vendor_id, received_date, location, status).
  • Receipt_Lines: каждая строка ссылается на PO line (receipt_id, po_line_id, received_qty, notes).

Выставление счётов зеркалит приёмы. Сохраняйте, что поставщик выставил по строкам и связывайте это со строкой PO:

  • Invoices: заголовок счёта (vendor_id, invoice_number, invoice_date, due_date, status).
  • Invoice_Lines: (invoice_id, po_line_id когда применимо, invoiced_qty, unit_price, tax, line_total).

Наконец, создайте запись, с которой платёжный ран будет работать и которую можно блокировать. Некоторые команды называют это bill, payment request или pay run item:

  • PaymentRequests (или Bills): связь с invoice_id, поле payment_hold (true/false) и hold_reason.

Для аудита и корректной обработки исключений добавьте стандартные поля жизненного цикла для заголовков (PO, receipts, invoices, payments): status, created_at/created_by, approved_at/approved_by, posted_at и (опционально) source_document_id для импортов.

Ключевые поля и связи, которые делают сопоставление надёжным

Deploy your AP app your way
Run on AppMaster Cloud or export source code for self-hosting.
Deploy Now

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

Убедитесь, что в каждой таблице есть как внутренний стабильный ID, так и внешний номер, по которому люди ищут:

  • PO header: po_id, po_number, vendor_id, currency, status, po_date
  • PO lines: po_line_id, po_id, item_id или description, ordered_qty, unit_price, tax_rate, line_total
  • Receipts: receipt_id, receipt_number, vendor_id, received_date; receipt_line_id, receipt_id, po_line_id, received_qty
  • Invoices: invoice_id, vendor_id, vendor_invoice_number, invoice_date, currency, subtotal, tax_total, total; invoice_line_id, invoice_id, po_line_id, qty, unit_price, tax_amount, line_total
  • Vendors и items: vendor_id, payment_terms, default_currency; item_id, uom, tax_code

Самые важные связи — на уровне строк:

  • invoice_line.po_line_id должен ссылаться на строку PO.
  • receipt_line.po_line_id должен ссылаться на ту же строку PO.

Именно это позволяет сравнивать количество и цену без догадок.

Чтобы обрабатывать частичные поставки, вычисляйте накопительные итоги по строке PO: received_qty (сумма receipt lines) и invoiced_qty (сумма invoice lines). Затем remaining_qty = ordered_qty - received_qty и open_to_invoice_qty = received_qty - invoiced_qty. Эти значения делают очевидным, является ли счёт преждевременным, запоздалым или переплаченным.

Не перезаписывайте историю, когда PO меняется. Храните номер ревизии PO и либо сохраняйте старые строки PO (с флагом active), либо ведите лог изменений (кто, когда, старое значение, новое значение).

Добавьте базовые ограничения, чтобы предотвратить дубли и неверные связи:

  • Unique (vendor_id, vendor_invoice_number)
  • Unique receipt_number и po_number
  • Not null на currency, quantities и unit_price
  • Check constraints вроде qty >= 0 и unit_price >= 0
  • Foreign keys от invoice_line и receipt_line к po_line

Пошаговый рабочий процесс: от приёма счёта до удержания платежа

Трёхсторонняя автоматизация обычно имеет три точки входа: приход счёта (email, загрузка, EDI), запись приёма или изменение PO (цена, количество, статус). Рабочий процесс должен реагировать на любое из этих событий, чтобы счёт мог выйти с удержания, как только появится недостающая часть.

  1. Сначала валидируйте базовые данные счёта. Убедитесь, что поставщик активен, PO существует, валюта совпадает с PO, и суммы внутренне согласованы (итоги строк складываются, налог разумен, нет отрицательных количеств, если вы не поддерживаете кредиты). Если это провал, отправляйте счёт сразу в Hold с понятной причиной.

  2. Сопоставляйте по строкам, а не только по заголовку. Для каждой строки счёта найдите соответствующую строку PO и накопленные приёмы. Сравните:

  • Количество, выставленное в счёте, с количеством, полученным (или полученным минус уже выставленное)
  • Цена за единицу в счёте с ценой в PO
  • Правила толерантности
  • Открыта ли строка PO для выставления счёта
  1. Установите статус и обеспечьте блокировку. Обычный паттерн:
  • Matched: все строки прошли проверки, нет открытых исключений.
  • Hold: хотя бы одна строка не прошла или данных недостаточно.

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

  1. Записывайте коды причин, которым финансы могут доверять. Избегайте только свободного текста для удержаний. Используйте коды вроде PRICE_OVER_TOLERANCE, QTY_NOT_RECEIVED, PO_CLOSED, VENDOR_MISMATCH, CURRENCY_MISMATCH и короткую заметку.

Дизайн очереди исключений для финансов (что хранить и что показывать)

Drag-and-drop matching logic
Build line-level checks, tolerances, and re-run triggers in a visual process.
Build Logic

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

Обычный подход — специальная таблица типа ExceptionCases. Каждая строка представляет один заблокированный счёт (или строку счёта) и ссылается на invoice, PO и receipt. Движок совпадений делает данные только для чтения здесь. Очередь предназначена для решений и документации.

Что хранить в ExceptionCases

Храните, что не так, насколько это серьёзно, кто владелец и что дальше происходит:

  • Type (missing receipt, price variance, quantity variance, PO not found, duplicate invoice)
  • Severity (info, warning, block) плюс пользовательская причина
  • Owner (человек или команда) и status (open, waiting on vendor, waiting on warehouse, resolved, overridden)
  • Снимок вариации как сортируемые числа (invoice amount, matched amount, price delta, quantity delta)
  • Поля SLA (due date, escalation flag, reassigned_at, reassignment_reason)

Также храните данные для сотрудничества и аудита: комментарии (author, timestamp) и метаданные вложений (file name, type, uploaded_by, uploaded_at). Даже если файлы хранятся отдельно, метаданные должны быть в деле, чтобы история была целой.

Что должно видеть и делать финансы

Вид очереди должен быть компактным рабочим списком: vendor, номер счёта, тип исключения, серьёзность, сумма, срок, владелец и понятное сообщение «почему блокируется».

Открывая дело, пользователь должен видеть сводку в развёрнутом виде: строки PO, принятые количества, строки счёта и точные поля, которые не прошли проверку.

Ограничьте действия и сделайте их безопасными:

  • Request receipt (маршрутизируется в приём, статус становится waiting)
  • Request credit memo (направляется поставщику, фиксируется ожидаемая корректировка)
  • Approve override (требуется причина, фиксируется утверждающий и время)
  • Reassign (обновляет владельца, хранит историю переназначений)
  • Close as resolved (только после того, как изменения приведут к успешной сверке)

Пример: счёт заблокирован, потому что получено 8 единиц, а выставлено 10. Финансы могут запросить корректный счёт у поставщика или одобрить override на 8 полученных единиц, оставив 2 единицы на удержании.

Реалистичный пример: частичный приём и несоответствие в счёте

Automate holds before payment
Block payment requests until your match rules pass, then release automatically.
Set Holds

Покупатель создаёт PO на 100 единиц товара A по $10.00 за штуку. Сумма PO — $1,000. Через два дня склад фиксирует receipt на 80 единиц.

Затем приходит счёт на 100 единиц по $10.00 за штуку. Сверка должна сравнивать строки счёта с тем, что получено, а не только с тем, что заказано.

Для этой строки:

  • Заказано: 100 единиц
  • Получено: 80 единиц
  • Выставлено: 100 единиц
  • Совпадающее количество: min(Received, Invoiced) = 80 единиц
  • Несовпадающее количество: Invoiced - Matched = 20 единиц

Счёт переходит в статус On hold, потому что 20 единиц не подтверждены приёмом. Финансы видят дело с понятной причиной (Quantity variance: +20) и ключевыми числами рядом.

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

Когда оставшиеся 20 единиц приходят и склад фиксирует второй receipt на 20 единиц, система повторно запускает сверку: received становится 100, unmatched = 0, счёт переводится в Matched и удержание снимается.

Добавьте вариацию по цене. Если поставщик выставил 100 единиц по $10.50 вместо $10.00, количество совпадает, но цена нет. Ожидаемый результат: счёт остаётся на удержании и направляется с причиной «Price variance: +$0.50/ед. (+$50 в целом).»

Распространённые ошибки, которые ломают рабочие процессы трёхсторонней сверки

Большинство ошибок сопоставления — не про арифметику. Они про слабые связи данных и свободный контроль над опубликованными документами.

Сверка только по итогу счёта. Заголовок может выглядеть в порядке, хотя одна строка переплачена или неполна. Делайте сверку по строкам и явно указывайте, что может отличаться (обычно доставка), а что нет (полученное количество и цена за единицу).

Предположение, что по PO будет один receipt и один invoice. В реальности поставки разделяются, а счета приходят частями. Поддерживайте много receipts и много invoices на одну строку PO и отслеживайте оставшееся открытое количество по строке.

Разрешение редактировать опубликованные receipt или invoice без следа. Если кто-то может тихо менять количества, сверка перестанет быть доказательством. Блокируйте опубликованные записи и делайте корректировки через документы-ачивки, сохраняющие историю.

Отсутствие предотвращения дублей. Один и тот же номер счёта поставщика может быть введён дважды, или PDF может быть загружен повторно другим сотрудником. Введите уникальность рано (vendor + invoice number, опционально дата/сумма) и показывайте понятное сообщение при обнаружении дубликата.

Размытые причины исключений. Финансы не должны догадываться. Используйте коды причин, которые чётко маршрутизуют: price mismatch, quantity mismatch, missing receipt, duplicate suspected, PO not found, vendor mismatch.

Быстрый чек-лист перед включением блокировки платежей

Handle partial receipts cleanly
Track cumulative received vs invoiced per PO line so partials match correctly.
Build Workflow

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

Протестируйте небольшой набор разных счетов: чистое совпадение, частичный приём, изменение цены и различия в налогах. Если что-то не удаётся сопоставить корректно, сначала почините данные и правила.

Чек-лист:

  • Reference completeness: у каждого счёта есть поставщик и ссылка на PO, каждая строка счёта может быть сопоставлена с конкретной строкой PO (а не только «итог по PO»). Решите, что делать, когда поставщик присылает только номер PO в заголовке.
  • Consistent math: количества, цены и итоги пересчитываются одинаково каждый раз. Будьте явны по налогам, доставке, скидкам и округлениям (например, округление по строке или только по итогу счёта).
  • Statuses block early enough: ставьте «on hold» до создания любой записи о платеже или платёжного запроса.
  • Structured exceptions: каждое удержание хранит код причины и владельца (AP, закупщик, приёмщик). Добавьте сроки, чтобы удержания не стояли вечно.
  • Real audit trail: overrides фиксируют, кто и когда утвердил и что именно было утверждено (включая исходные значения). Если вы разрешаете правки, логируйте значения до и после.

Следующие шаги: пилот и визуальная реализация

Относитесь к автоматизации трёхсторонней сверки как к любому контролю: докажите, что она работает на небольшой части затрат, затем разворачивайте.

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

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

Если нужно быстро прототипировать, безкодовая платформа может помочь — вы смоделируете таблицы, правила сопоставления и маршрутизацию без написания кода. Например, в AppMaster (appmaster.io) можно построить таблицы PO, receipt, invoice и exception, а затем связать логику удержаний в визуальном бизнес-процессе, чтобы одни и те же правила запускались при каждом триггере.

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

Легко начать
Создай что-то невероятное

Экспериментируйте с AppMaster с бесплатной подпиской.
Как только вы будете готовы, вы сможете выбрать подходящий платный план.

Попробовать AppMaster
Автоматизация трёхсторонней сверки: таблицы и рабочий процесс для удержаний в AP | AppMaster