From 0635e3bf10e905289668a9c937e7007eb7fb2304 Mon Sep 17 00:00:00 2001 From: Priec Date: Tue, 4 Aug 2026 09:31:25 +0200 Subject: [PATCH] moving balances of accounts between profiles - also other things in proto files --- common/proto/accounting.proto | 93 ++++- common/proto/ecb.proto | 13 +- common/src/proto/descriptor.bin | Bin 133630 -> 139631 bytes common/src/proto/komp_ac.accounting.rs | 489 ++++++++++++++++++++++++- common/src/proto/komp_ac.ecb.rs | 13 +- server | 2 +- 6 files changed, 587 insertions(+), 23 deletions(-) diff --git a/common/proto/accounting.proto b/common/proto/accounting.proto index 18d5b3ad..c6af402a 100644 --- a/common/proto/accounting.proto +++ b/common/proto/accounting.proto @@ -7,6 +7,9 @@ package komp_ac.accounting; // without replacing the live accounts projection. Closed periods can be reopened; // approved periods are final. service Accounting { + // Resolve or atomically create every node in a parsed account path. + rpc EnsureAccount(EnsureAccountRequest) returns (Account); + // 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); @@ -53,6 +56,34 @@ service Accounting { rpc ListAccountingPeriods(ListAccountingPeriodsRequest) returns (ListAccountingPeriodsResponse); rpc ListPeriodBalances(ListPeriodBalancesRequest) returns (ListPeriodBalancesResponse); + + // Administratively map one account in a predecessor profile to one account + // in the current profile. Existing activity on the target account is allowed. + rpc MapOpeningBalanceAccount(MapOpeningBalanceAccountRequest) + returns (OpeningBalanceAccountMapping); + rpc UnmapOpeningBalanceAccount(UnmapOpeningBalanceAccountRequest) + returns (UnmapOpeningBalanceAccountResponse); + rpc ListOpeningBalanceAccounts(ListOpeningBalanceAccountsRequest) + returns (ListOpeningBalanceAccountsResponse); +} + +message EnsureAccountRequest { + string profile_name = 1; + repeated string segments = 2; + // Currency accepted by source postings to the leaf account. Empty uses the + // profile accounting currency. Missing ancestors are created in the profile + // accounting currency. + string denomination_currency = 3; +} + +message Account { + int64 id = 1; + optional int64 parent_account_id = 2; + string segment = 3; + // Root-to-leaf path of this account. Same shape as the request that created + // it; the server never joins segments into a delimited code. + repeated string segments = 4; + string denomination_currency = 5; } enum JournalSide { @@ -91,8 +122,9 @@ message PostJournalRequest { // 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. + // Currency of the amounts supplied by this request. Required when creating; + // empty uses the profile accounting currency when appending. Journal amounts + // are stored and returned in the profile accounting currency. string currency = 3; // Applied when creating and required to be empty when appending. @@ -242,7 +274,8 @@ message JournalLine { int64 id = 1; int32 line_number = 2; JournalSide side = 3; - string account_code = 4; + // Root-to-leaf path of the posted account, as sent on JournalLineInput. + repeated string account_segments = 4; string amount = 5; string description = 6; bool deleted = 7; @@ -339,7 +372,8 @@ message ListPeriodBalancesRequest { message PeriodBalance { int64 period_id = 1; - string account_code = 2; + // Root-to-leaf path of the account this frozen balance belongs to. + repeated string account_segments = 2; string currency = 3; // Signed nets use debit-positive convention. string opening_balance = 4; @@ -351,3 +385,54 @@ message PeriodBalance { message ListPeriodBalancesResponse { repeated PeriodBalance balances = 1; } + +message MapOpeningBalanceAccountRequest { + // Open period whose profile receives the opening balance. Its configured + // previous_period_id identifies the source profile and period. + int64 target_period_id = 1; + repeated string source_account_segments = 2; + repeated string target_account_segments = 3; +} + +message UnmapOpeningBalanceAccountRequest { + int64 target_period_id = 1; + repeated string target_account_segments = 2; +} + +message UnmapOpeningBalanceAccountResponse { + bool removed = 1; +} + +message ListOpeningBalanceAccountsRequest { + int64 target_period_id = 1; +} + +enum OpeningBalanceStatus { + OPENING_BALANCE_STATUS_UNSPECIFIED = 0; + // The predecessor is still open, so its closed journal activity can change. + OPENING_BALANCE_STATUS_PROVISIONAL = 1; + // The value comes from the predecessor's frozen period snapshot. + OPENING_BALANCE_STATUS_FINAL = 2; +} + +message OpeningBalanceAccountMapping { + int64 target_period_id = 1; + int64 source_period_id = 2; + string source_profile_name = 3; + repeated string source_account_segments = 4; + string target_profile_name = 5; + repeated string target_account_segments = 6; + string currency = 7; + // Signed balances use the debit-positive convention. + string opening_balance = 8; + string period_debit = 9; + string period_credit = 10; + string current_balance = 11; + OpeningBalanceStatus status = 12; + string created_at = 13; + string created_by_user_id = 14; +} + +message ListOpeningBalanceAccountsResponse { + repeated OpeningBalanceAccountMapping mappings = 1; +} diff --git a/common/proto/ecb.proto b/common/proto/ecb.proto index 7c8e34be..a3f81b42 100644 --- a/common/proto/ecb.proto +++ b/common/proto/ecb.proto @@ -18,7 +18,7 @@ service EcbService { returns (ListEcbConversionEvidenceResponse); } -// Accounting date rule used to select an ECB publication. +// Conversion basis rule used to select an ECB publication. enum EcbConversionContext { ECB_CONVERSION_CONTEXT_UNSPECIFIED = 0; ECB_CONVERSION_CONTEXT_ORDINARY_TRANSACTION = 1; @@ -33,9 +33,10 @@ message PreviewEcbConversionRequest { string original_currency = 2; EcbConversionContext conversion_context = 3; - // ISO calendar date (YYYY-MM-DD). Its meaning is selected by - // conversion_context: transaction, statement, or decisive date. - string anchor_date = 4; + // ISO calendar date (YYYY-MM-DD) from which the applicable publication date + // is derived. Its meaning is selected by conversion_context: transaction, + // statement, or decisive date. + string conversion_basis_date = 4; // Required. Profile whose rates apply. Only consulted when use_custom_rate is // set, but always required so a preview names the books it describes. @@ -54,7 +55,7 @@ message PreviewEcbConversionResponse { string original_currency = 2; string eur_amount = 3; EcbConversionContext conversion_context = 4; - string anchor_date = 5; + string conversion_basis_date = 5; string determination_method = 6; string rounding_method = 7; optional string rate_date = 8; @@ -107,7 +108,7 @@ message EcbConversionEvidence { string original_currency = 4; string eur_amount = 5; string conversion_context = 6; - string anchor_date = 7; + string conversion_basis_date = 7; string determination_method = 8; string rounding_method = 9; optional string rate_date = 10; diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index bc7427fac876a35be31608c397f1bdde07ebfb37..d894e81fcc8543068c5afcc5c6b940623d586630 100644 GIT binary patch delta 19038 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 OUfj9=#hu<^eg6kz3mfhL delta 13486 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, + /// Currency accepted by source postings to the leaf account. Empty uses the + /// profile accounting currency. Missing ancestors are created in the profile + /// accounting currency. + #[prost(string, tag = "3")] + pub denomination_currency: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Account { + #[prost(int64, tag = "1")] + pub id: i64, + #[prost(int64, optional, tag = "2")] + pub parent_account_id: ::core::option::Option, + #[prost(string, tag = "3")] + pub segment: ::prost::alloc::string::String, + /// Root-to-leaf path of this account. Same shape as the request that created + /// it; the server never joins segments into a delimited code. + #[prost(string, repeated, tag = "4")] + pub segments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag = "5")] + pub denomination_currency: ::prost::alloc::string::String, +} #[derive(Clone, PartialEq, ::prost::Message)] pub struct PostJournalRequest { #[prost(string, tag = "1")] @@ -7,8 +34,9 @@ pub struct PostJournalRequest { /// an unknown id is never treated as a request to create one. #[prost(int64, optional, tag = "2")] pub journal_id: ::core::option::Option, - /// Required when creating. When appending, empty uses the journal currency; - /// a supplied value must match it exactly. + /// Currency of the amounts supplied by this request. Required when creating; + /// empty uses the profile accounting currency when appending. Journal amounts + /// are stored and returned in the profile accounting currency. #[prost(string, tag = "3")] pub currency: ::prost::alloc::string::String, /// Applied when creating and required to be empty when appending. @@ -210,8 +238,9 @@ pub struct JournalLine { pub line_number: i32, #[prost(enumeration = "JournalSide", tag = "3")] pub side: i32, - #[prost(string, tag = "4")] - pub account_code: ::prost::alloc::string::String, + /// Root-to-leaf path of the posted account, as sent on JournalLineInput. + #[prost(string, repeated, tag = "4")] + pub account_segments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, #[prost(string, tag = "5")] pub amount: ::prost::alloc::string::String, #[prost(string, tag = "6")] @@ -357,8 +386,9 @@ pub struct ListPeriodBalancesRequest { pub struct PeriodBalance { #[prost(int64, tag = "1")] pub period_id: i64, - #[prost(string, tag = "2")] - pub account_code: ::prost::alloc::string::String, + /// Root-to-leaf path of the account this frozen balance belongs to. + #[prost(string, repeated, tag = "2")] + pub account_segments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, #[prost(string, tag = "3")] pub currency: ::prost::alloc::string::String, /// Signed nets use debit-positive convention. @@ -376,6 +406,81 @@ pub struct ListPeriodBalancesResponse { #[prost(message, repeated, tag = "1")] pub balances: ::prost::alloc::vec::Vec, } +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct MapOpeningBalanceAccountRequest { + /// Open period whose profile receives the opening balance. Its configured + /// previous_period_id identifies the source profile and period. + #[prost(int64, tag = "1")] + pub target_period_id: i64, + #[prost(string, repeated, tag = "2")] + pub source_account_segments: ::prost::alloc::vec::Vec< + ::prost::alloc::string::String, + >, + #[prost(string, repeated, tag = "3")] + pub target_account_segments: ::prost::alloc::vec::Vec< + ::prost::alloc::string::String, + >, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct UnmapOpeningBalanceAccountRequest { + #[prost(int64, tag = "1")] + pub target_period_id: i64, + #[prost(string, repeated, tag = "2")] + pub target_account_segments: ::prost::alloc::vec::Vec< + ::prost::alloc::string::String, + >, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct UnmapOpeningBalanceAccountResponse { + #[prost(bool, tag = "1")] + pub removed: bool, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ListOpeningBalanceAccountsRequest { + #[prost(int64, tag = "1")] + pub target_period_id: i64, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct OpeningBalanceAccountMapping { + #[prost(int64, tag = "1")] + pub target_period_id: i64, + #[prost(int64, tag = "2")] + pub source_period_id: i64, + #[prost(string, tag = "3")] + pub source_profile_name: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "4")] + pub source_account_segments: ::prost::alloc::vec::Vec< + ::prost::alloc::string::String, + >, + #[prost(string, tag = "5")] + pub target_profile_name: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "6")] + pub target_account_segments: ::prost::alloc::vec::Vec< + ::prost::alloc::string::String, + >, + #[prost(string, tag = "7")] + pub currency: ::prost::alloc::string::String, + /// Signed balances use the debit-positive convention. + #[prost(string, tag = "8")] + pub opening_balance: ::prost::alloc::string::String, + #[prost(string, tag = "9")] + pub period_debit: ::prost::alloc::string::String, + #[prost(string, tag = "10")] + pub period_credit: ::prost::alloc::string::String, + #[prost(string, tag = "11")] + pub current_balance: ::prost::alloc::string::String, + #[prost(enumeration = "OpeningBalanceStatus", tag = "12")] + pub status: i32, + #[prost(string, tag = "13")] + pub created_at: ::prost::alloc::string::String, + #[prost(string, tag = "14")] + pub created_by_user_id: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListOpeningBalanceAccountsResponse { + #[prost(message, repeated, tag = "1")] + pub mappings: ::prost::alloc::vec::Vec, +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum JournalSide { @@ -476,6 +581,37 @@ impl AccountingPeriodType { } } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum OpeningBalanceStatus { + Unspecified = 0, + /// The predecessor is still open, so its closed journal activity can change. + Provisional = 1, + /// The value comes from the predecessor's frozen period snapshot. + Final = 2, +} +impl OpeningBalanceStatus { + /// 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 => "OPENING_BALANCE_STATUS_UNSPECIFIED", + Self::Provisional => "OPENING_BALANCE_STATUS_PROVISIONAL", + Self::Final => "OPENING_BALANCE_STATUS_FINAL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "OPENING_BALANCE_STATUS_UNSPECIFIED" => Some(Self::Unspecified), + "OPENING_BALANCE_STATUS_PROVISIONAL" => Some(Self::Provisional), + "OPENING_BALANCE_STATUS_FINAL" => Some(Self::Final), + _ => None, + } + } +} /// Generated client implementations. pub mod accounting_client { #![allow( @@ -572,6 +708,30 @@ pub mod accounting_client { self.inner = self.inner.max_encoding_message_size(limit); self } + /// Resolve or atomically create every node in a parsed account path. + pub async fn ensure_account( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.accounting.Accounting/EnsureAccount", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("komp_ac.accounting.Accounting", "EnsureAccount"), + ); + self.inner.unary(req, path, codec).await + } /// 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. pub async fn post_journal( @@ -1016,6 +1176,95 @@ pub mod accounting_client { ); self.inner.unary(req, path, codec).await } + /// Administratively map one account in a predecessor profile to one account + /// in the current profile. Existing activity on the target account is allowed. + pub async fn map_opening_balance_account( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.accounting.Accounting/MapOpeningBalanceAccount", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.accounting.Accounting", + "MapOpeningBalanceAccount", + ), + ); + self.inner.unary(req, path, codec).await + } + pub async fn unmap_opening_balance_account( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.accounting.Accounting/UnmapOpeningBalanceAccount", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.accounting.Accounting", + "UnmapOpeningBalanceAccount", + ), + ); + self.inner.unary(req, path, codec).await + } + pub async fn list_opening_balance_accounts( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.accounting.Accounting/ListOpeningBalanceAccounts", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.accounting.Accounting", + "ListOpeningBalanceAccounts", + ), + ); + self.inner.unary(req, path, codec).await + } } } /// Generated server implementations. @@ -1031,6 +1280,11 @@ pub mod accounting_server { /// Generated trait containing gRPC methods that should be implemented for use with AccountingServer. #[async_trait] pub trait Accounting: std::marker::Send + std::marker::Sync + 'static { + /// Resolve or atomically create every node in a parsed account path. + async fn ensure_account( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// 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. async fn post_journal( @@ -1139,6 +1393,29 @@ pub mod accounting_server { tonic::Response, tonic::Status, >; + /// Administratively map one account in a predecessor profile to one account + /// in the current profile. Existing activity on the target account is allowed. + async fn map_opening_balance_account( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn unmap_opening_balance_account( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn list_opening_balance_accounts( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; } /// Mutable informational journals. A journal may contain only debits, only /// credits, or any non-zero balance. Balance is reported but never enforced. @@ -1221,6 +1498,51 @@ pub mod accounting_server { } fn call(&mut self, req: http::Request) -> Self::Future { match req.uri().path() { + "/komp_ac.accounting.Accounting/EnsureAccount" => { + #[allow(non_camel_case_types)] + struct EnsureAccountSvc(pub Arc); + impl< + T: Accounting, + > tonic::server::UnaryService + for EnsureAccountSvc { + type Response = super::Account; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::ensure_account(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = EnsureAccountSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/komp_ac.accounting.Accounting/PostJournal" => { #[allow(non_camel_case_types)] struct PostJournalSvc(pub Arc); @@ -1957,6 +2279,161 @@ pub mod accounting_server { }; Box::pin(fut) } + "/komp_ac.accounting.Accounting/MapOpeningBalanceAccount" => { + #[allow(non_camel_case_types)] + struct MapOpeningBalanceAccountSvc(pub Arc); + impl< + T: Accounting, + > tonic::server::UnaryService + for MapOpeningBalanceAccountSvc { + type Response = super::OpeningBalanceAccountMapping; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::MapOpeningBalanceAccountRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::map_opening_balance_account( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = MapOpeningBalanceAccountSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/komp_ac.accounting.Accounting/UnmapOpeningBalanceAccount" => { + #[allow(non_camel_case_types)] + struct UnmapOpeningBalanceAccountSvc(pub Arc); + impl< + T: Accounting, + > tonic::server::UnaryService< + super::UnmapOpeningBalanceAccountRequest, + > for UnmapOpeningBalanceAccountSvc { + type Response = super::UnmapOpeningBalanceAccountResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::UnmapOpeningBalanceAccountRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::unmap_opening_balance_account( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = UnmapOpeningBalanceAccountSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/komp_ac.accounting.Accounting/ListOpeningBalanceAccounts" => { + #[allow(non_camel_case_types)] + struct ListOpeningBalanceAccountsSvc(pub Arc); + impl< + T: Accounting, + > tonic::server::UnaryService< + super::ListOpeningBalanceAccountsRequest, + > for ListOpeningBalanceAccountsSvc { + type Response = super::ListOpeningBalanceAccountsResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::ListOpeningBalanceAccountsRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::list_opening_balance_accounts( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = ListOpeningBalanceAccountsSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } _ => { Box::pin(async move { let mut response = http::Response::new( diff --git a/common/src/proto/komp_ac.ecb.rs b/common/src/proto/komp_ac.ecb.rs index dc18e28f..a46977ab 100644 --- a/common/src/proto/komp_ac.ecb.rs +++ b/common/src/proto/komp_ac.ecb.rs @@ -9,10 +9,11 @@ pub struct PreviewEcbConversionRequest { pub original_currency: ::prost::alloc::string::String, #[prost(enumeration = "EcbConversionContext", tag = "3")] pub conversion_context: i32, - /// ISO calendar date (YYYY-MM-DD). Its meaning is selected by - /// conversion_context: transaction, statement, or decisive date. + /// ISO calendar date (YYYY-MM-DD) from which the applicable publication date + /// is derived. Its meaning is selected by conversion_context: transaction, + /// statement, or decisive date. #[prost(string, tag = "4")] - pub anchor_date: ::prost::alloc::string::String, + pub conversion_basis_date: ::prost::alloc::string::String, /// Required. Profile whose rates apply. Only consulted when use_custom_rate is /// set, but always required so a preview names the books it describes. #[prost(string, tag = "5")] @@ -36,7 +37,7 @@ pub struct PreviewEcbConversionResponse { #[prost(enumeration = "EcbConversionContext", tag = "4")] pub conversion_context: i32, #[prost(string, tag = "5")] - pub anchor_date: ::prost::alloc::string::String, + pub conversion_basis_date: ::prost::alloc::string::String, #[prost(string, tag = "6")] pub determination_method: ::prost::alloc::string::String, #[prost(string, tag = "7")] @@ -109,7 +110,7 @@ pub struct EcbConversionEvidence { #[prost(string, tag = "6")] pub conversion_context: ::prost::alloc::string::String, #[prost(string, tag = "7")] - pub anchor_date: ::prost::alloc::string::String, + pub conversion_basis_date: ::prost::alloc::string::String, #[prost(string, tag = "8")] pub determination_method: ::prost::alloc::string::String, #[prost(string, tag = "9")] @@ -157,7 +158,7 @@ pub struct ListEcbConversionEvidenceResponse { #[prost(bool, tag = "3")] pub has_more: bool, } -/// Accounting date rule used to select an ECB publication. +/// Conversion basis rule used to select an ECB publication. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EcbConversionContext { diff --git a/server b/server index 4204f743..e09b0b4c 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 4204f743738302176cd0e870249a2afbd2fed41a +Subproject commit e09b0b4c37f1069b7b7790f5ff01b286a938b190