Statement of Account (Акт звірки)¶
Тип: звіт у складі essentials
Backend: backend/essentials/views/reports.py — StatementOfAccountView
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}
}
Алгоритм¶
- Opening balance =
running_balanceостанньогоPartyLedgerрядка зdate < date_from(для того ж client + direction + organization). - Якщо
directionне заданий → сума opening поreceivable− opening поpayable(чистий вигляд) - Entries = всі
PartyLedgerрядки в[date_from, date_to], відсортовані поdate, id - Closing balance =
running_balanceостаннього рядка в періоді. Якщо рядків немає — дорівнює opening - 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 відкривається, форма рендериться.