From 5f910fb07121b3c6711942c1551fa64212b1934a Mon Sep 17 00:00:00 2001 From: Priec Date: Sun, 26 Jul 2026 17:29:54 +0200 Subject: [PATCH] accounting period --- common/proto/accounting.proto | 26 ++++++++- common/proto/table_definition.proto | 14 +++++ common/src/proto/descriptor.bin | Bin 129881 -> 132315 bytes common/src/proto/komp_ac.accounting.rs | 54 +++++++++++++++++-- common/src/proto/komp_ac.table_definition.rs | 14 +++++ graphs/src/pages/add_table/state.rs | 2 + server | 2 +- 7 files changed, 106 insertions(+), 6 deletions(-) diff --git a/common/proto/accounting.proto b/common/proto/accounting.proto index 10fc82a..78c30a4 100644 --- a/common/proto/accounting.proto +++ b/common/proto/accounting.proto @@ -63,6 +63,22 @@ enum AccountingPeriodStatus { 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; @@ -244,11 +260,16 @@ message Journal { message ConfigureAccountingPeriodRequest { string profile_name = 1; - // Inclusive range in YYYY-MM-DD. + // First day of the period, YYYY-MM-DD. Must be the first day of a month. string period_start = 2; - string period_end = 3; + 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 { @@ -286,6 +307,7 @@ message AccountingPeriod { string closed_by_user_id = 8; string approved_at = 9; string approved_by_user_id = 10; + AccountingPeriodType period_type = 11; } message ListPeriodBalancesRequest { diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index ec65284..ec44c56 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -89,6 +89,20 @@ message PostTableDefinitionRequest { // Column whose value identifies a row to users in pickers. "id" is always // valid; otherwise this must name one of the user-defined columns above. string row_display_column = 7; + + // ISO-4217 currency the profile keeps its accounting in. A profile is one + // accounting entity and keeps one set of books, so this is required only when + // the request creates the profile, and is ignored afterwards. It is unrelated + // to base_currency: tables may hold money in any currency, and amounts convert + // to this one when they reach the ledger. + string accounting_currency = 8; + + // Month the profile's fiscal year begins, 1-12. Like accounting_currency, + // this describes the entity rather than the table, so it is required only + // when the request creates the profile and ignored afterwards. January means + // the calendar year; any other month means a business year (hospodársky + // rok), which may be used only after notifying the tax office. + uint32 fiscal_year_start_month = 9; } // Defines the input for explicitly creating a table backed by one invoice diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 2c09d325fca16a0735ff728eb486771184344e0b..1b1555ed9dfd54fb01705cbf34c64f72e728933b 100644 GIT binary patch delta 15707 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 B<1GLH delta 13289 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 rXzON+I7Pkzx, + /// Required. Decides the length of the period. + #[prost(enumeration = "AccountingPeriodType", tag = "5")] + pub period_type: i32, + /// Last day of the period, YYYY-MM-DD. Required for PARTIAL and rejected for + /// every other type, whose end follows from the start. + #[prost(string, tag = "6")] + pub period_end: ::prost::alloc::string::String, } #[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] pub struct CloseAccountingPeriodRequest { @@ -317,6 +322,8 @@ pub struct AccountingPeriod { pub approved_at: ::prost::alloc::string::String, #[prost(string, tag = "10")] pub approved_by_user_id: ::prost::alloc::string::String, + #[prost(enumeration = "AccountingPeriodType", tag = "11")] + pub period_type: i32, } #[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] pub struct ListPeriodBalancesRequest { @@ -407,6 +414,47 @@ impl AccountingPeriodStatus { } } } +/// 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. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AccountingPeriodType { + Unspecified = 0, + /// One calendar month. + 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). + 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. + Partial = 3, +} +impl AccountingPeriodType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ACCOUNTING_PERIOD_TYPE_UNSPECIFIED", + Self::Month => "ACCOUNTING_PERIOD_TYPE_MONTH", + Self::Year => "ACCOUNTING_PERIOD_TYPE_YEAR", + Self::Partial => "ACCOUNTING_PERIOD_TYPE_PARTIAL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ACCOUNTING_PERIOD_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "ACCOUNTING_PERIOD_TYPE_MONTH" => Some(Self::Month), + "ACCOUNTING_PERIOD_TYPE_YEAR" => Some(Self::Year), + "ACCOUNTING_PERIOD_TYPE_PARTIAL" => Some(Self::Partial), + _ => None, + } + } +} /// Generated client implementations. pub mod accounting_client { #![allow( diff --git a/common/src/proto/komp_ac.table_definition.rs b/common/src/proto/komp_ac.table_definition.rs index 4c4be5a..2b45fe2 100644 --- a/common/src/proto/komp_ac.table_definition.rs +++ b/common/src/proto/komp_ac.table_definition.rs @@ -49,6 +49,20 @@ pub struct PostTableDefinitionRequest { /// valid; otherwise this must name one of the user-defined columns above. #[prost(string, tag = "7")] pub row_display_column: ::prost::alloc::string::String, + /// ISO-4217 currency the profile keeps its accounting in. A profile is one + /// accounting entity and keeps one set of books, so this is required only when + /// the request creates the profile, and is ignored afterwards. It is unrelated + /// to base_currency: tables may hold money in any currency, and amounts convert + /// to this one when they reach the ledger. + #[prost(string, tag = "8")] + pub accounting_currency: ::prost::alloc::string::String, + /// Month the profile's fiscal year begins, 1-12. Like accounting_currency, + /// this describes the entity rather than the table, so it is required only + /// when the request creates the profile and ignored afterwards. January means + /// the calendar year; any other month means a business year (hospodársky + /// rok), which may be used only after notifying the tax office. + #[prost(uint32, tag = "9")] + pub fiscal_year_start_month: u32, } /// Defines the input for explicitly creating a table backed by one invoice /// template. typst_source must contain exactly one declaration of the form: diff --git a/graphs/src/pages/add_table/state.rs b/graphs/src/pages/add_table/state.rs index d6fe457..173f952 100644 --- a/graphs/src/pages/add_table/state.rs +++ b/graphs/src/pages/add_table/state.rs @@ -114,6 +114,8 @@ impl CreateTableForm { } Ok(PostTableDefinitionRequest { + accounting_currency: String::new(), + fiscal_year_start_month: 0, table_name, links, columns, diff --git a/server b/server index 454acc6..14346db 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 454acc6f2b0286b165188236f64b436dfa4a5555 +Subproject commit 14346dbc36b29731c01d0be631e156f456bb82a5