Перейти до змісту

Statement of Account (Акт звірки)

Тип: звіт у складі essentials Backend: backend/essentials/views/reports.pyStatementOfAccountView Frontend: frontend/erp/src/components/Essentials/StatementOfAccount/StatementOfAccountReport.tsx API: GET /api/v1/essentials/reports/statement-of-account/ Доданий: 2026-04-23, Phase F-6

Призначення

Звіт стану розрахунків з контрагентом за період. Відповідає на: - Який баланс на початок періоду? - Які документи (рахунки + платежі) змінили борг? - Який баланс на кінець періоду?

Джерело даних — registers.PartyLedger, який вже підтримується посту-сервісами для Invoice / IncomingPayment / PurchaseInvoice / OutgoingPayment.

Query параметри

Параметр Тип Обов'язковий Опис
client int так FK id essentials.Client
date_from YYYY-MM-DD так Початок періоду (inclusive)
date_to YYYY-MM-DD так Кінець періоду (inclusive)
direction enum ні receivable (наші продажі) або payable (наші купівлі). Без параметра — обидва
organization int ні Фільтр по своїй організації

Response

{
  "client": {"id": 1, "name": "ACME LLC", "edrpou": "12345678"},
  "organization": {"id": 2, "name": "Our LLC"} | null,
  "period": {"from": "2026-01-01", "to": "2026-12-31"},
  "direction": "receivable" | "payable" | "both",
  "opening_balance": 12500.00,
  "entries": [
    {
      "id": 42,
      "date": "2026-03-05",
      "direction": "receivable",
      "document_type": "Invoice",
      "document_id": 17,
      "description": "Invoice #INV-017 — receivable accrued",
      "currency_code": "980",
      "debit": 5000.00,
      "credit": 0,
      "running_balance": 17500.00
    }
  ],
  "closing_balance": 17500.00,
  "totals": {"debit": 5000.00, "credit": 0, "net": 5000.00}
}

Алгоритм

  1. Opening balance = running_balance останнього PartyLedger рядка з date < date_from (для того ж client + direction + organization).
  2. Якщо direction не заданий → сума opening по receivable − opening по payable (чистий вигляд)
  3. Entries = всі PartyLedger рядки в [date_from, date_to], відсортовані по date, id
  4. Closing balance = running_balance останнього рядка в періоді. Якщо рядків немає — дорівнює opening
  5. Totals = sum(debit), sum(credit), net = debit − credit за період

Знак балансу

  • receivable: positive = клієнт винен нам
  • payable: positive = ми винні постачальнику
  • both (без direction): receivable − payable (чистий результат)

Frontend

Компонент StatementOfAccountReport: - Select: Client (обов'язково), Organization (опційно) - Select: Direction (receivable / payable / both) - DatePickerInput: date_from, date_to (default = поточний рік) - Таблиця з колонками: Date, Document, Description, Debit, Credit, Balance - Summary картки: Opening, Debit, Credit, Closing

MVP scope

  • Один клієнт за запуск (без масового вивантаження всіх клієнтів)
  • HTML вивід (друк через браузер Ctrl+P; PDF — через friendly-format браузера)
  • Без Open Items / Clearing (MVP показує всі рядки — майбутнє: відмічати "cleared" vs "open")

🔮 Deferred

  • Генерація PDF — серверний рендеринг в Fortune Sheet або WeasyPrint
  • Експорт в Excel — xlsx з формулами
  • Масова звірка — таблиця по всім клієнтам на одну дату (AR aging + statement зразу)
  • Open Items marking — показувати, які invoice закриті якими платежами (потребує моделі Open Items + Clearing, див. audit-2026-04-22 §7.3)
  • Bilateral reconciliation — загрузка контрагентського акту + matching
  • Email delivery — авторозсилка актів контрагентам
  • Historical snapshots — фіксувати акт як документ у системі (для аудитного сліду)

Status

MVP Phase 1 — завершено 2026-04-23. Smoke-тест: 2 PartyLedger entries, debit=9600=credit, net=0. Frontend відкривається, форма рендериться.