backbone_payroll/domain/entity/
mod.rs1pub mod compensation_change;
6pub mod payroll_entry;
7pub mod salary_slip;
8pub mod salary_slip_line;
9pub mod salary_structure;
10pub mod salary_component;
11pub mod compensation_change_type;
12pub mod payroll_status;
13pub mod salary_structure_status;
14pub mod component_type;
15
16pub use compensation_change::CompensationChange;
18pub use compensation_change::CompensationChangeBuilder;
19pub use compensation_change::CompensationChangeId;
20pub use payroll_entry::PayrollEntry;
21pub use payroll_entry::PayrollEntryBuilder;
22pub use payroll_entry::PayrollEntryId;
23pub use salary_slip::SalarySlip;
24pub use salary_slip::SalarySlipBuilder;
25pub use salary_slip::SalarySlipId;
26pub use salary_slip_line::SalarySlipLine;
27pub use salary_slip_line::SalarySlipLineBuilder;
28pub use salary_slip_line::SalarySlipLineId;
29pub use salary_structure::SalaryStructure;
30pub use salary_structure::SalaryStructureBuilder;
31pub use salary_structure::SalaryStructureId;
32pub use salary_component::SalaryComponent;
33pub use salary_component::SalaryComponentBuilder;
34pub use salary_component::SalaryComponentId;
35pub use compensation_change_type::CompensationChangeType;
36pub use payroll_status::PayrollStatus;
37pub use salary_structure_status::SalaryStructureStatus;
38pub use component_type::ComponentType;
39
40use std::fmt::Debug;
45
46pub trait Entity: Debug + Clone {
51 type Id: Debug + Clone + PartialEq;
53
54 fn entity_id(&self) -> &Self::Id;
56
57 fn entity_type() -> &'static str;
59}
60
61use chrono::{DateTime, Utc};
66use serde::{Deserialize, Serialize};
67use uuid::Uuid;
68#[cfg(feature = "openapi")]
69use utoipa::ToSchema;
70
71#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
76#[cfg_attr(feature = "openapi", derive(ToSchema))]
77pub struct AuditMetadata {
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub created_at: Option<DateTime<Utc>>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub updated_at: Option<DateTime<Utc>>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub deleted_at: Option<DateTime<Utc>>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub created_by: Option<Uuid>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub updated_by: Option<Uuid>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 pub deleted_by: Option<Uuid>,
101}
102
103impl AuditMetadata {
104 pub fn new() -> Self {
106 Self {
107 created_at: Some(Utc::now()),
108 ..Default::default()
109 }
110 }
111
112 pub fn with_creator(creator_id: Uuid) -> Self {
114 Self {
115 created_at: Some(Utc::now()),
116 created_by: Some(creator_id),
117 ..Default::default()
118 }
119 }
120
121 pub fn touch(&mut self) {
123 self.updated_at = Some(Utc::now());
124 }
125
126 pub fn touch_by(&mut self, updater_id: Uuid) {
128 self.updated_at = Some(Utc::now());
129 self.updated_by = Some(updater_id);
130 }
131
132 pub fn soft_delete(&mut self) {
134 self.deleted_at = Some(Utc::now());
135 }
136
137 pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
139 self.deleted_at = Some(Utc::now());
140 self.deleted_by = Some(deleter_id);
141 }
142
143 pub fn restore(&mut self) {
145 self.deleted_at = None;
146 self.deleted_by = None;
147 }
148
149 pub fn is_deleted(&self) -> bool {
151 self.deleted_at.is_some()
152 }
153
154 pub fn is_active(&self) -> bool {
156 self.deleted_at.is_none()
157 }
158}