Skip to main content

backbone_accounting/domain/entity/
mod.rs

1//! Domain Entities
2//!
3//! Generated by metaphor-schema. Do not edit manually.
4
5pub mod account;
6pub mod accounting_post;
7pub mod cost_center;
8pub mod emv_qr_config;
9pub mod bank_check_sequence;
10pub mod printed_check;
11pub mod tax_tag_repair_run;
12pub mod financial_statement;
13pub mod fiscal_period;
14pub mod journal;
15pub mod journal_line;
16pub mod ledger;
17pub mod reconciliation;
18pub mod reconciliation_item;
19pub mod full_reconcile;
20pub mod partial_reconcile;
21pub mod account_type;
22pub mod account_subtype;
23pub mod normal_balance;
24pub mod account_status;
25pub mod party_type;
26pub mod posting_source_type;
27pub mod posting_type;
28pub mod posting_status;
29pub mod cost_center_status;
30pub mod statement_type;
31pub mod statement_status;
32pub mod period_type;
33pub mod period_status;
34pub mod journal_type;
35pub mod journal_source;
36pub mod journal_status;
37pub mod reconciliation_type;
38pub mod reconciliation_status;
39pub mod reconciliation_item_status;
40pub mod reconcile_origin;
41
42// Re-exports
43pub use account::Account;
44pub use account::AccountBuilder;
45pub use account::AccountId;
46pub use accounting_post::AccountingPost;
47pub use accounting_post::AccountingPostBuilder;
48pub use accounting_post::AccountingPostId;
49pub use cost_center::CostCenter;
50pub use cost_center::CostCenterBuilder;
51pub use cost_center::CostCenterId;
52pub use emv_qr_config::EmvQrConfig;
53pub use emv_qr_config::EmvQrConfigBuilder;
54pub use emv_qr_config::EmvQrConfigId;
55pub use bank_check_sequence::BankCheckSequence;
56pub use bank_check_sequence::BankCheckSequenceBuilder;
57pub use bank_check_sequence::BankCheckSequenceId;
58pub use printed_check::PrintedCheck;
59pub use printed_check::PrintedCheckBuilder;
60pub use printed_check::PrintedCheckId;
61pub use tax_tag_repair_run::TaxTagRepairRun;
62pub use tax_tag_repair_run::TaxTagRepairRunBuilder;
63pub use tax_tag_repair_run::TaxTagRepairRunId;
64pub use financial_statement::FinancialStatement;
65pub use financial_statement::FinancialStatementBuilder;
66pub use financial_statement::FinancialStatementId;
67pub use fiscal_period::FiscalPeriod;
68pub use fiscal_period::FiscalPeriodBuilder;
69pub use fiscal_period::FiscalPeriodId;
70pub use journal::Journal;
71pub use journal::JournalBuilder;
72pub use journal::JournalId;
73pub use journal_line::JournalLine;
74pub use journal_line::JournalLineBuilder;
75pub use journal_line::JournalLineId;
76pub use ledger::Ledger;
77pub use ledger::LedgerBuilder;
78pub use ledger::LedgerId;
79pub use reconciliation::Reconciliation;
80pub use reconciliation::ReconciliationBuilder;
81pub use reconciliation::ReconciliationId;
82pub use reconciliation_item::ReconciliationItem;
83pub use reconciliation_item::ReconciliationItemBuilder;
84pub use reconciliation_item::ReconciliationItemId;
85pub use full_reconcile::FullReconcile;
86pub use full_reconcile::FullReconcileBuilder;
87pub use full_reconcile::FullReconcileId;
88pub use partial_reconcile::PartialReconcile;
89pub use partial_reconcile::PartialReconcileBuilder;
90pub use partial_reconcile::PartialReconcileId;
91pub use account_type::AccountType;
92pub use account_subtype::AccountSubtype;
93pub use normal_balance::NormalBalance;
94pub use account_status::AccountStatus;
95pub use party_type::PartyType;
96pub use posting_source_type::PostingSourceType;
97pub use posting_type::PostingType;
98pub use posting_status::PostingStatus;
99pub use cost_center_status::CostCenterStatus;
100pub use statement_type::StatementType;
101pub use statement_status::StatementStatus;
102pub use period_type::PeriodType;
103pub use period_status::PeriodStatus;
104pub use journal_type::JournalType;
105pub use journal_source::JournalSource;
106pub use journal_status::JournalStatus;
107pub use reconciliation_type::ReconciliationType;
108pub use reconciliation_status::ReconciliationStatus;
109pub use reconciliation_item_status::ReconciliationItemStatus;
110pub use reconcile_origin::ReconcileOrigin;
111
112// ==========================================================================
113// Entity Trait
114// ==========================================================================
115
116use std::fmt::Debug;
117
118/// Trait for domain entities
119///
120/// All generated entities implement this trait, providing
121/// a common interface for working with domain objects.
122pub trait Entity: Debug + Clone {
123    /// The type of the entity's unique identifier
124    type Id: Debug + Clone + PartialEq;
125
126    /// Get the entity's unique identifier
127    fn entity_id(&self) -> &Self::Id;
128
129    /// Get the entity type name
130    fn entity_type() -> &'static str;
131}
132
133// ==========================================================================
134// Audit Metadata
135// ==========================================================================
136
137use chrono::{DateTime, Utc};
138use serde::{Deserialize, Serialize};
139use uuid::Uuid;
140#[cfg(feature = "openapi")]
141use utoipa::ToSchema;
142
143/// Audit metadata stored as JSONB in the database
144///
145/// This struct consolidates audit fields (timestamps and actors) into a single
146/// JSONB column for efficient storage and flexible querying.
147#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
148#[cfg_attr(feature = "openapi", derive(ToSchema))]
149pub struct AuditMetadata {
150    /// Timestamp when the record was created
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub created_at: Option<DateTime<Utc>>,
153
154    /// Timestamp when the record was last updated
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub updated_at: Option<DateTime<Utc>>,
157
158    /// Timestamp when the record was soft-deleted
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub deleted_at: Option<DateTime<Utc>>,
161
162    /// User ID who created the record
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub created_by: Option<Uuid>,
165
166    /// User ID who last updated the record
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub updated_by: Option<Uuid>,
169
170    /// User ID who deleted the record
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub deleted_by: Option<Uuid>,
173}
174
175impl AuditMetadata {
176    /// Create new audit metadata with created_at set to now
177    pub fn new() -> Self {
178        Self {
179            created_at: Some(Utc::now()),
180            ..Default::default()
181        }
182    }
183
184    /// Create with creator ID
185    pub fn with_creator(creator_id: Uuid) -> Self {
186        Self {
187            created_at: Some(Utc::now()),
188            created_by: Some(creator_id),
189            ..Default::default()
190        }
191    }
192
193    /// Touch the record (update updated_at)
194    pub fn touch(&mut self) {
195        self.updated_at = Some(Utc::now());
196    }
197
198    /// Touch with updater ID
199    pub fn touch_by(&mut self, updater_id: Uuid) {
200        self.updated_at = Some(Utc::now());
201        self.updated_by = Some(updater_id);
202    }
203
204    /// Soft delete the record
205    pub fn soft_delete(&mut self) {
206        self.deleted_at = Some(Utc::now());
207    }
208
209    /// Soft delete with deleter ID
210    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
211        self.deleted_at = Some(Utc::now());
212        self.deleted_by = Some(deleter_id);
213    }
214
215    /// Restore a soft-deleted record
216    pub fn restore(&mut self) {
217        self.deleted_at = None;
218        self.deleted_by = None;
219    }
220
221    /// Check if record is deleted
222    pub fn is_deleted(&self) -> bool {
223        self.deleted_at.is_some()
224    }
225
226    /// Check if record is active (not deleted)
227    pub fn is_active(&self) -> bool {
228        self.deleted_at.is_none()
229    }
230}