Files
komp_ac/common/proto/accounting.proto
2026-07-26 17:29:54 +02:00

331 lines
9.7 KiB
Protocol Buffer

syntax = "proto3";
package komp_ac.accounting;
// Mutable informational journals. A journal may contain only debits, only
// credits, or any non-zero balance. Balance is reported but never enforced.
// Accounting periods close date ranges inside a profile and freeze account sums
// without replacing the live accounts projection. Closed periods can be reopened;
// approved periods are final.
service Accounting {
// Create a journal with its first lines when journal_id is absent, or append
// all supplied lines atomically when journal_id identifies an existing one.
rpc PostJournal(PostJournalRequest) returns (Journal);
// Close a balanced journal. Closed journals can be reopened while their
// accounting period is open.
rpc CloseJournal(CloseJournalRequest) returns (Journal);
rpc ReopenJournal(ReopenJournalRequest) returns (Journal);
// Return journal lines and credits-minus-debits informational balance.
rpc GetJournal(GetJournalRequest) returns (Journal);
// Search profile journals by user-facing name while retaining journal ids
// as the stable relationship keys.
rpc SearchJournals(SearchJournalsRequest) returns (SearchJournalsResponse);
// Return the profile-wide count of balanced and unbalanced journals.
rpc GetAccountingStatus(GetAccountingStatusRequest) returns (AccountingStatus);
// Return an oldest-first, paginated queue of unbalanced journals.
rpc ListUnbalancedJournals(ListUnbalancedJournalsRequest)
returns (ListUnbalancedJournalsResponse);
// Soft-delete one line while retaining it for audit display.
rpc SoftDeleteJournalLine(SoftDeleteJournalLineRequest) returns (Journal);
// Create an open accounting period for a profile. Periods may be any length
// (month, half-year, year). Overlapping ranges for the same profile are rejected.
rpc ConfigureAccountingPeriod(ConfigureAccountingPeriodRequest)
returns (AccountingPeriod);
// Closing snapshots balances and blocks mutations through the period end.
// A closed period may be reopened; approval makes it final.
rpc CloseAccountingPeriod(CloseAccountingPeriodRequest) returns (AccountingPeriod);
rpc ReopenAccountingPeriod(ReopenAccountingPeriodRequest) returns (AccountingPeriod);
rpc ApproveAccountingPeriod(ApproveAccountingPeriodRequest) returns (AccountingPeriod);
rpc GetAccountingPeriod(GetAccountingPeriodRequest) returns (AccountingPeriod);
rpc ListAccountingPeriods(ListAccountingPeriodsRequest)
returns (ListAccountingPeriodsResponse);
rpc ListPeriodBalances(ListPeriodBalancesRequest) returns (ListPeriodBalancesResponse);
}
enum JournalSide {
JOURNAL_SIDE_UNSPECIFIED = 0;
JOURNAL_SIDE_DEBIT = 1;
JOURNAL_SIDE_CREDIT = 2;
}
enum AccountingPeriodStatus {
ACCOUNTING_PERIOD_STATUS_UNSPECIFIED = 0;
ACCOUNTING_PERIOD_STATUS_OPEN = 1;
ACCOUNTING_PERIOD_STATUS_CLOSED = 2;
ACCOUNTING_PERIOD_STATUS_APPROVED = 3;
}
// How long one accounting period lasts. MONTH and YEAR span whole months, so
// the caller states only the start and the end is derived. PARTIAL is the
// exception for periods real life cut short.
enum AccountingPeriodType {
ACCOUNTING_PERIOD_TYPE_UNSPECIFIED = 0;
// One calendar month.
ACCOUNTING_PERIOD_TYPE_MONTH = 1;
// Twelve consecutive months, aligned to the profile's fiscal year. Starting
// in January gives the calendar year; any other start month gives a business
// year (hospodársky rok).
ACCOUNTING_PERIOD_TYPE_YEAR = 2;
// Neither a whole month nor a whole year, because the entity was formed or
// terminated part-way through one. The only type carrying an explicit end.
ACCOUNTING_PERIOD_TYPE_PARTIAL = 3;
}
message PostJournalRequest {
string profile_name = 1;
// Absent creates a new journal. Present must identify an existing journal;
// an unknown id is never treated as a request to create one.
optional int64 journal_id = 2;
// Required when creating. When appending, empty uses the journal currency;
// a supplied value must match it exactly.
string currency = 3;
// Applied when creating and required to be empty when appending.
string description = 4;
// At least one line is required. The lines are inserted atomically and the
// journal is allowed to remain unbalanced.
repeated JournalLineInput lines = 5;
// Required, unique within the profile, and at most 10 characters when
// creating. Must be empty when appending to an existing journal selected by
// journal_id.
string journal_name = 6;
// Accounting date in YYYY-MM-DD. Empty defaults to the current UTC date when
// creating. Must be empty when appending. Rejected when it falls at or before
// the latest closed or approved accounting boundary for the profile.
string accounting_date = 7;
}
message JournalLineInput {
JournalSide side = 1;
string account_code = 2;
string amount = 3;
string description = 4;
}
message CloseJournalRequest {
string profile_name = 1;
int64 journal_id = 2;
}
message ReopenJournalRequest {
string profile_name = 1;
int64 journal_id = 2;
}
message GetJournalRequest {
string profile_name = 1;
int64 journal_id = 2;
// False by default. True is reserved for a future Casbin permission granted
// only to superadmin and is rejected until that permission is implemented.
bool include_deleted = 3;
}
message GetAccountingStatusRequest {
string profile_name = 1;
}
message SearchJournalsRequest {
string profile_name = 1;
// Case-insensitive literal substring. Empty returns all profile journals.
string name_query = 2;
// Zero uses 50. The maximum is 500.
int32 page_size = 3;
// Opaque cursor returned by the previous response.
string page_token = 4;
}
message JournalSummary {
int64 journal_id = 1;
string journal_name = 2;
string currency = 3;
string description = 4;
string total_debit = 5;
string total_credit = 6;
string balance = 7;
int64 active_line_count = 8;
bool closed = 9;
string created_at = 10;
string accounting_date = 11;
}
message SearchJournalsResponse {
repeated JournalSummary journals = 1;
int64 total_count = 2;
string next_page_token = 3;
}
message AccountingStatus {
bool all_journals_balanced = 1;
int64 journal_count = 2;
int64 balanced_journal_count = 3;
int64 unbalanced_journal_count = 4;
string calculated_at = 5;
}
message ListUnbalancedJournalsRequest {
string profile_name = 1;
// Zero uses 50. The maximum is 500.
int32 page_size = 2;
// Opaque cursor returned by the previous response. Empty starts at the
// oldest unbalanced journal.
string page_token = 3;
// Optional ISO 4217 currency filter. Empty includes every currency.
string currency = 4;
}
message UnbalancedJournalSummary {
int64 journal_id = 1;
string description = 2;
string currency = 3;
string total_debit = 4;
string total_credit = 5;
// Signed credits-minus-debits difference.
string balance = 6;
// Side and positive amount needed to make the journal balance zero.
JournalSide missing_side = 7;
string missing_amount = 8;
int64 active_line_count = 9;
string created_at = 10;
string journal_name = 11;
string accounting_date = 12;
}
message ListUnbalancedJournalsResponse {
repeated UnbalancedJournalSummary journals = 1;
int64 total_unbalanced_count = 2;
string next_page_token = 3;
}
message SoftDeleteJournalLineRequest {
string profile_name = 1;
int64 journal_id = 2;
int64 journal_line_id = 3;
}
message JournalLine {
int64 id = 1;
int32 line_number = 2;
JournalSide side = 3;
string account_code = 4;
string amount = 5;
string description = 6;
bool deleted = 7;
string created_at = 8;
string deleted_at = 9;
string source_table_name = 10;
int64 source_record_id = 11;
int64 source_row_revision = 12;
reserved 13;
}
message Journal {
int64 id = 1;
string profile_name = 2;
string currency = 3;
string description = 4;
string created_at = 5;
repeated JournalLine lines = 6;
string total_debit = 7;
string total_credit = 8;
// Informational difference calculated as credits minus debits.
string balance = 9;
bool closed = 10;
string closed_at = 11;
string closed_by_user_id = 12;
string journal_name = 13;
string accounting_date = 14;
}
message ConfigureAccountingPeriodRequest {
string profile_name = 1;
// First day of the period, YYYY-MM-DD. Must be the first day of a month.
string period_start = 2;
reserved 3;
// Optional link to the preceding period in a carry chain.
optional int64 previous_period_id = 4;
// Required. Decides the length of the period.
AccountingPeriodType period_type = 5;
// Last day of the period, YYYY-MM-DD. Required for PARTIAL and rejected for
// every other type, whose end follows from the start.
string period_end = 6;
}
message CloseAccountingPeriodRequest {
int64 period_id = 1;
}
message ReopenAccountingPeriodRequest {
int64 period_id = 1;
}
message ApproveAccountingPeriodRequest {
int64 period_id = 1;
}
message GetAccountingPeriodRequest {
int64 period_id = 1;
}
message ListAccountingPeriodsRequest {
string profile_name = 1;
}
message ListAccountingPeriodsResponse {
repeated AccountingPeriod periods = 1;
}
message AccountingPeriod {
int64 id = 1;
string profile_name = 2;
string period_start = 3;
string period_end = 4;
AccountingPeriodStatus status = 5;
int64 previous_period_id = 6;
string closed_at = 7;
string closed_by_user_id = 8;
string approved_at = 9;
string approved_by_user_id = 10;
AccountingPeriodType period_type = 11;
}
message ListPeriodBalancesRequest {
int64 period_id = 1;
}
message PeriodBalance {
int64 period_id = 1;
string account_code = 2;
string currency = 3;
// Signed nets use debit-positive convention.
string opening_balance = 4;
string period_debit = 5;
string period_credit = 6;
string closing_balance = 7;
}
message ListPeriodBalancesResponse {
repeated PeriodBalance balances = 1;
}