Skip to content

Документы поставщиков ​

Документ поставщика — счёт, акт, УПД или чек сторонней компании, у которой мы что-то берём для проекта: субаренда оборудования, закупка, площадка, подрядчик. Это реальные расходы по ходу проекта. Смета считается до проекта, и расходы в ней номинальные: документы поставщиков смету не меняют. Раздел сметы у документа нужен, чтобы сравнить факт с планом и заметить перерасход. Этап 6 ТЗ «смета → документы → расходы → план и факт».

Путь документа ​

получен ──(руководитель проекта: «это наш расход», в пределах сметы раздела)──▶ согласован
   │                                                                              │
   ├──(сверх сметы раздела или вне сметы: ждёт финансов)──▶ финансы согласуют ─────┤
   │                                                                              ▼
   └──▶ отклонён (не наш расход) ──▶ «вернуть в работу»         оплата платежами: частично оплачен → оплачен
СтатусЧто значит
received — полученЗаведён, ждёт подтверждения. awaiting_finance — руководитель подтвердил, но расход сверх сметы: ждёт финансов
approved — согласованМожно оплачивать
partially_paid — частично оплаченПроведена часть оплаты
paid — оплаченПроведённые платежи покрыли сумму документа
rejected — отклонёнНе наш расход (причина — reject_reason)

Править можно только полученный документ; правка снимает подтверждение руководителя. Один и тот же документ дважды не заводится: у поставщика не бывает двух документов одного вида с тем же номером и датой, если они не отклонены (409 supplier_document_duplicate).

Кто что делает ​

  • Финансы: затраты «все», accounting.manage или глобальный администратор, capability supplier_documents_manage. Видят все документы на странице «Финансы → Документы поставщиков». Заводят документы, согласуют (в том числе сверх сметы), оплачивают. Удаляют документ без платежей.
  • Руководитель проекта (projects.manager_id): документы своего проекта на вкладке «ТЗ и смета → Бюджет», карточка «Расходы поставщиков». Заводит документ, подтверждает «это наш расход», отклоняет. Может запланировать оплату, провести её — финансы. Удаляет полученный или отклонённый документ без платежей.
  • Читать документы проекта может ещё тот, у кого открыт раздел финансов проекта (бюджет клиента или затраты).

Перерасход ​

Руководитель нажимает «Подтвердить расход», и сервер сравнивает раздел с планом:

  • факт раздела — согласованные и оплаченные документы раздела плюс этот документ;
  • план раздела — плановая себестоимость раздела действующей сметы (согласованной, иначе последней).

Раздел документа — вид раздела сметы плюс его название: у каждой версии сметы свои строки разделов, поэтому id раздела не годится.

  • Факт в пределах плана — документ согласован сразу.
  • Факт выше плана — документ остаётся «получен» с overrun_amount (на сколько документ выводит раздел за план) и awaiting_finance. Финансовому директору уходит уведомление «Расход сверх сметы ждёт согласования».
  • Документ без раздела или проект без сметы — расход вне сметы, весь он сверх плана.

Оплата ​

«Оплатить» создаёт исходящий платёж с supplier_document_id, контрагент — поставщик (counterparty_type=supplier). Правила:

  • документ согласован или частично оплачен;
  • сумма не больше outstanding_amount — это сумма документа минус проведённые и запланированные платежи;
  • для проекта действуют обычные ворота «без ТЗ — нет денег».

После проведения платежа:

  • статус документа пересчитывается по проведённым платежам;
  • в факт проекта пишется оплаченная сумма: строка project_cost_items с source_type='supplier_document' и статьёй по разделу сметы. Виды разделов переводятся в статьи так: оборудование → tech, перевозки → logistics, командировки → travel, команда → labor, подрядчики → contractors, материалы → materials, креатив → creative, прочее и свои разделы → other.

При старте сервера оплата и факт пересчитываются по всем документам с проведёнными платежами.

Скан и распознавание ​

Скан (PDF, фото, DOCX, XLSX, до 15 МБ) ложится в папку «Счета» проекта, а у документа без проекта — к поставщику.

«Загрузить скан и распознать» (POST /ai/extract/supplier-document, нужна функция помощника «Документы») заполняет форму: вид, номер, дату, поставщика, суммы без НДС, НДС и итог, строки. Код проверяет результат:

  • приводит числа и даты к единому виду;
  • проверяет ИНН по контрольным цифрам;
  • сверяет суммы: без НДС + НДС = итог, строки = итог;
  • ищет поставщика в справочнике по ИНН.

Нет такого поставщика — форма предлагает «Добавить поставщика» (POST /supplier-documents/suppliers: с тем же ИНН возвращается существующий). Ничего не сохраняется, пока сотрудник не нажмёт «Добавить документ».

Справочник поставщиков по матрице прав открыт складу, а финансам и руководителям проектов нужен только выбор. Для этого — GET /supplier-documents/suppliers.

API ​

МетодПутьЧто делает
GET/supplier-documentsсписок: финансы — все, остальные — своих проектов; фильтры project_id, status, supplier_id, q, awaiting=finance
POST/supplier-documentsзавести: multipart payload (JSON) + file, или JSON
GET/PUT/DELETE/supplier-documents/:idдокумент, правка полученного, удаление без платежей
POST/supplier-documents/:id/approveсогласовать или подтвердить (см. «Перерасход»)
POST/supplier-documents/:id/rejectотклонить (reason)
POST/supplier-documents/:id/reopenвернуть отклонённый в работу
GET/supplier-documents/:id/fileссылка на скан
GET/projects/:id/supplier-documentsдокументы проекта
GET/POST/supplier-documents/suppliersпоставщики для выбора, поставщик из документа
POST/ai/extract/supplier-documentраспознать скан

Живые обновления: действия с документами и платежи рассылают entity_changed с частью проекта expenses. Списки на странице и в карточке проекта обновляются сами.

Где в коде ​

  • internal/modules/supplierdocs — модель, правила, хранилище, HTTP;
  • internal/app/supplier_documents.go — связки: план из сметы (estimates.SectionCosts), факт в finance, скан в files, платежи, обязательства, уведомление финансовому директору;
  • internal/modules/payments/gates.go — оплата по документу, PaymentObserver;
  • internal/modules/assistant/supplier_extract.go — распознавание;
  • миграция 0169_supplier_documents.sql.

Загружаем документацию…