backbone-payroll 0.3.47

Payroll: salary structures, payroll runs and computed salary slips over effective-dated statutory tables, plus compensation changes
Documentation
//! Domain Entities
//!
//! Generated by metaphor-schema. Do not edit manually.

pub mod compensation_change;
pub mod payroll_entry;
pub mod salary_slip;
pub mod salary_slip_line;
pub mod salary_structure;
pub mod salary_component;
pub mod compensation_change_type;
pub mod payroll_status;
pub mod salary_structure_status;
pub mod component_type;

// Re-exports
pub use compensation_change::CompensationChange;
pub use compensation_change::CompensationChangeBuilder;
pub use compensation_change::CompensationChangeId;
pub use payroll_entry::PayrollEntry;
pub use payroll_entry::PayrollEntryBuilder;
pub use payroll_entry::PayrollEntryId;
pub use salary_slip::SalarySlip;
pub use salary_slip::SalarySlipBuilder;
pub use salary_slip::SalarySlipId;
pub use salary_slip_line::SalarySlipLine;
pub use salary_slip_line::SalarySlipLineBuilder;
pub use salary_slip_line::SalarySlipLineId;
pub use salary_structure::SalaryStructure;
pub use salary_structure::SalaryStructureBuilder;
pub use salary_structure::SalaryStructureId;
pub use salary_component::SalaryComponent;
pub use salary_component::SalaryComponentBuilder;
pub use salary_component::SalaryComponentId;
pub use compensation_change_type::CompensationChangeType;
pub use payroll_status::PayrollStatus;
pub use salary_structure_status::SalaryStructureStatus;
pub use component_type::ComponentType;

// ==========================================================================
// Entity Trait
// ==========================================================================

use std::fmt::Debug;

/// Trait for domain entities
///
/// All generated entities implement this trait, providing
/// a common interface for working with domain objects.
pub trait Entity: Debug + Clone {
    /// The type of the entity's unique identifier
    type Id: Debug + Clone + PartialEq;

    /// Get the entity's unique identifier
    fn entity_id(&self) -> &Self::Id;

    /// Get the entity type name
    fn entity_type() -> &'static str;
}

// ==========================================================================
// Audit Metadata
// ==========================================================================

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[cfg(feature = "openapi")]
use utoipa::ToSchema;

/// Audit metadata stored as JSONB in the database
///
/// This struct consolidates audit fields (timestamps and actors) into a single
/// JSONB column for efficient storage and flexible querying.
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
pub struct AuditMetadata {
    /// Timestamp when the record was created
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_at: Option<DateTime<Utc>>,

    /// Timestamp when the record was last updated
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_at: Option<DateTime<Utc>>,

    /// Timestamp when the record was soft-deleted
    #[serde(skip_serializing_if = "Option::is_none")]
    pub deleted_at: Option<DateTime<Utc>>,

    /// User ID who created the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_by: Option<Uuid>,

    /// User ID who last updated the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_by: Option<Uuid>,

    /// User ID who deleted the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub deleted_by: Option<Uuid>,
}

impl AuditMetadata {
    /// Create new audit metadata with created_at set to now
    pub fn new() -> Self {
        Self {
            created_at: Some(Utc::now()),
            ..Default::default()
        }
    }

    /// Create with creator ID
    pub fn with_creator(creator_id: Uuid) -> Self {
        Self {
            created_at: Some(Utc::now()),
            created_by: Some(creator_id),
            ..Default::default()
        }
    }

    /// Touch the record (update updated_at)
    pub fn touch(&mut self) {
        self.updated_at = Some(Utc::now());
    }

    /// Touch with updater ID
    pub fn touch_by(&mut self, updater_id: Uuid) {
        self.updated_at = Some(Utc::now());
        self.updated_by = Some(updater_id);
    }

    /// Soft delete the record
    pub fn soft_delete(&mut self) {
        self.deleted_at = Some(Utc::now());
    }

    /// Soft delete with deleter ID
    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
        self.deleted_at = Some(Utc::now());
        self.deleted_by = Some(deleter_id);
    }

    /// Restore a soft-deleted record
    pub fn restore(&mut self) {
        self.deleted_at = None;
        self.deleted_by = None;
    }

    /// Check if record is deleted
    pub fn is_deleted(&self) -> bool {
        self.deleted_at.is_some()
    }

    /// Check if record is active (not deleted)
    pub fn is_active(&self) -> bool {
        self.deleted_at.is_none()
    }
}