Billing

Issue settlements, freeze tickets, and track project budgets

The Settlements module lets you combine tickets from multiple projects into a single settlement, drive it through a status workflow (draft → sent → paid), and manage attachments (invoices, reports, acceptance protocols). Once a settlement is sent, linked tickets are frozen — editing is locked, but status changes on the Kanban board still work.

Key features

Cross-project M2M

A single settlement can span multiple projects. Link tickets from any of the related projects — perfect for freelancers and agencies.

Bidirectional status workflow

Draft → Sent → Paid with automatic timestamps (sent_at, paid_at). Reverse transitions allowed — admins can unfreeze tickets when needed.

Ticket freezing

After sending a settlement, linked tickets are frozen — full editing (title, description, priority) is locked. Status changes via Kanban drag-drop still work.

Categorized attachments

Upload invoices, reports, acceptance protocols to MinIO with categories (invoice, report, acceptance_protocol, other) and state (draft/signed). 200MB limit, 10 files per settlement.

Granular RBAC

rozliczenia:read/write/delete permissions per project. Users without permission don't see the section on tickets (hidden in HTML and MCP) — not just disabled.

Global cross-project view

The /dashboard/rozliczenia page shows settlements across all projects you have access to. Filter by projects, status, and date.

How it works

1

Create a settlement

New settlement (ROZ-N) with period, name, and selected projects. Requires rozliczenia:write in each project.

2

Link tickets

HTMX autocomplete search — find by number (MNX-12) or title. Only tickets from settlement's projects are shown.

3

Attach files

Upload invoices, reports, or acceptance protocols. Choose category and state (draft/signed). Preview/download/delete.

4

Send and freeze

Change status to 'Sent' — tickets become frozen (editing returns 403), but Kanban status updates still work.

5

Mark as paid

After payment — click 'Mark as paid'. paid_at is set, sent_at preserved. Tickets stay frozen.

6

Revert if needed

Admins can revert status (paid → sent → draft). Tickets automatically unfreeze when settlement returns to draft.

AI & MCP

All settlement operations are exposed via MCP — the AI agent can create settlements, link tickets, upload attachments (base64), and change statuses. RBAC is enforced by each tool.

Available MCP tools

list_settlements List project settlements with filters (status, period, page).
get_settlement Settlement details: projects, tickets, attachments, status, timestamps.
create_settlement Create a cross-project settlement (write permission validated in all projects).
update_settlement Edit a draft settlement (name, period, projects, notes).
delete_settlement Soft delete a draft settlement.
change_settlement_status Draft ↔ sent ↔ paid workflow with transition validation and timestamps.
link_ticket_to_settlement Link a ticket (draft only + cross-project validation).
unlink_ticket_from_settlement Unlink a ticket from a settlement.
list_settlement_tickets List linked tickets (keys + titles + statuses).
add_settlement_attachment Upload a file as base64 → MinIO. Categories: invoice/report/acceptance_protocol/other.
get_settlement_attachment Download attachment as base64 with mime_type and filename.
list_settlement_attachments List attachment metadata (no bytes).
delete_settlement_attachment Delete attachment (draft only).

Technical details

Data model
Settlement + M2M SettlementProject + M2M SettlementTicket + 1:N SettlementAttachment. Soft delete (is_active=False).
Workflow
ALLOWED_SETTLEMENT_TRANSITIONS: dict[str, frozenset[str]] — state machine with transition validation and timestamps (sent_at, paid_at).
Storage
MinIO for attachments, PostgreSQL for metadata. Upload and download run in ThreadPoolExecutor (async-friendly).
Freeze logic
is_ticket_frozen(ticket) — dynamic function checks if a ticket is linked to a settlement in sent/paid status. Automatic unfreeze when settlement returns to draft.
RBAC
New 'rozliczenia' key in PERMISSION_MODULES (read/write/delete). Per-project validation — cross-project settlements require write permission in all projects.
MON-62 regression
Freezing protects the integrity of sent settlements. Status-only updates are allowed on frozen tickets (Kanban drag-drop) — full editing is blocked.

Other modules

Try Monolynx

Free, open source, self-hosted. Deploy on your infrastructure in minutes.