//! Ledger DTOs (Data Transfer Objects)
//!
//! Generated by metaphor-schema. Do not edit manually.
//!
//! DTOs provide a clean separation between domain entities and API
//! representations, with OpenAPI documentation support.
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use chrono::{DateTime, Utc, NaiveDate};
use rust_decimal::Decimal;
#[cfg(feature = "openapi")]
#[cfg(feature = "openapi")]
use utoipa::ToSchema;
use crate::domain::entity::Ledger;
use crate::domain::entity::AuditMetadata;
use crate::domain::entity::AccountType;
use crate::domain::entity::NormalBalance;
use crate::domain::entity::PartyType;
// =============================================================================
// Create DTO
// =============================================================================
/// Request DTO for creating a new Ledger
///
/// Used in POST requests to create new entities.
/// Excludes auto-generated fields (id, created_at, updated_at, deleted_at).
#[derive(Debug, Clone, Deserialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct CreateLedgerDto {
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "account_id")]
pub account_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "account_number")]
pub account_number: String,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "account_name")]
pub account_name: String,
#[serde(alias = "account_type")]
pub account_type: AccountType,
#[serde(alias = "normal_balance")]
pub normal_balance: NormalBalance,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "journal_id")]
pub journal_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "journal_number")]
pub journal_number: String,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "journal_line_id")]
pub journal_line_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(alias = "transaction_date")]
pub transaction_date: NaiveDate,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(alias = "posting_date")]
pub posting_date: NaiveDate,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "fiscal_period_id")]
pub fiscal_period_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "fiscal_year")]
pub fiscal_year: i32,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "fiscal_month")]
pub fiscal_month: i32,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub description: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub currency: String,
#[serde(alias = "debit_amount")]
pub debit_amount: Decimal,
#[serde(alias = "credit_amount")]
pub credit_amount: Decimal,
#[serde(alias = "balance_before")]
pub balance_before: Decimal,
#[serde(alias = "balance_after")]
pub balance_after: Decimal,
#[serde(alias = "balance_change")]
pub balance_change: Decimal,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "sequence_number")]
pub sequence_number: i32,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "branch_id")]
pub branch_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "party_type")]
pub party_type: Option<PartyType>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "party_id")]
pub party_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "cost_center_id")]
pub cost_center_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "project_id")]
pub project_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "department_id")]
pub department_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dimensions: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_type")]
pub source_type: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_id")]
pub source_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_reference")]
pub source_reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_reconciled")]
pub is_reconciled: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reconciliation_id")]
pub reconciliation_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reconciled_at")]
pub reconciled_at: Option<DateTime<Utc>>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_opening_balance")]
pub is_opening_balance: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_closing_entry")]
pub is_closing_entry: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_adjustment")]
pub is_adjustment: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_reversed")]
pub is_reversed: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reversed_by_id")]
pub reversed_by_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reverses_id")]
pub reverses_id: Option<Uuid>,
}
// =============================================================================
// Update DTO
// =============================================================================
/// Request DTO for full update of a Ledger
///
/// Used in PUT requests for full entity replacement.
/// All fields are required (except auto-generated ones).
#[derive(Debug, Clone, Deserialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct UpdateLedgerDto {
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "account_id")]
pub account_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "account_number")]
pub account_number: String,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "account_name")]
pub account_name: String,
#[serde(alias = "account_type")]
pub account_type: AccountType,
#[serde(alias = "normal_balance")]
pub normal_balance: NormalBalance,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "journal_id")]
pub journal_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(alias = "journal_number")]
pub journal_number: String,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(alias = "journal_line_id")]
pub journal_line_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(alias = "transaction_date")]
pub transaction_date: NaiveDate,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(alias = "posting_date")]
pub posting_date: NaiveDate,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "fiscal_period_id")]
pub fiscal_period_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "fiscal_year")]
pub fiscal_year: i32,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "fiscal_month")]
pub fiscal_month: i32,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub description: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub currency: String,
#[serde(alias = "debit_amount")]
pub debit_amount: Decimal,
#[serde(alias = "credit_amount")]
pub credit_amount: Decimal,
#[serde(alias = "balance_before")]
pub balance_before: Decimal,
#[serde(alias = "balance_after")]
pub balance_after: Decimal,
#[serde(alias = "balance_change")]
pub balance_change: Decimal,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(alias = "sequence_number")]
pub sequence_number: i32,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "branch_id")]
pub branch_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "party_type")]
pub party_type: Option<PartyType>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "party_id")]
pub party_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "cost_center_id")]
pub cost_center_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "project_id")]
pub project_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "department_id")]
pub department_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dimensions: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_type")]
pub source_type: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_id")]
pub source_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "source_reference")]
pub source_reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_reconciled")]
pub is_reconciled: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reconciliation_id")]
pub reconciliation_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reconciled_at")]
pub reconciled_at: Option<DateTime<Utc>>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_opening_balance")]
pub is_opening_balance: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_closing_entry")]
pub is_closing_entry: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_adjustment")]
pub is_adjustment: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(alias = "is_reversed")]
pub is_reversed: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reversed_by_id")]
pub reversed_by_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "reverses_id")]
pub reverses_id: Option<Uuid>,
}
// =============================================================================
// Patch DTO
// =============================================================================
/// Request DTO for partial update of a Ledger
///
/// Used in PATCH requests for partial updates.
/// All fields are optional - only provided fields will be updated.
#[derive(Debug, Clone, Default, Deserialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct PatchLedgerDto {
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "account_id")]
pub account_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "account_number")]
pub account_number: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "account_name")]
pub account_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", alias = "account_type")]
pub account_type: Option<AccountType>,
#[serde(skip_serializing_if = "Option::is_none", alias = "normal_balance")]
pub normal_balance: Option<NormalBalance>,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "journal_id")]
pub journal_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "journal_number")]
pub journal_number: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "journal_line_id")]
pub journal_line_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "transaction_date")]
pub transaction_date: Option<NaiveDate>,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
#[serde(skip_serializing_if = "Option::is_none", alias = "posting_date")]
pub posting_date: Option<NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none", alias = "fiscal_period_id")]
pub fiscal_period_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(skip_serializing_if = "Option::is_none", alias = "fiscal_year")]
pub fiscal_year: Option<i32>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(skip_serializing_if = "Option::is_none", alias = "fiscal_month")]
pub fiscal_month: Option<i32>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub currency: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", alias = "debit_amount")]
pub debit_amount: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none", alias = "credit_amount")]
pub credit_amount: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none", alias = "balance_before")]
pub balance_before: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none", alias = "balance_after")]
pub balance_after: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none", alias = "balance_change")]
pub balance_change: Option<Decimal>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
#[serde(skip_serializing_if = "Option::is_none", alias = "sequence_number")]
pub sequence_number: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none", alias = "branch_id")]
pub branch_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "party_type")]
pub party_type: Option<PartyType>,
#[serde(skip_serializing_if = "Option::is_none", alias = "party_id")]
pub party_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "cost_center_id")]
pub cost_center_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "project_id")]
pub project_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "department_id")]
pub department_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dimensions: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none", alias = "source_type")]
pub source_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", alias = "source_id")]
pub source_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "source_reference")]
pub source_reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(skip_serializing_if = "Option::is_none", alias = "is_reconciled")]
pub is_reconciled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none", alias = "reconciliation_id")]
pub reconciliation_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "reconciled_at")]
pub reconciled_at: Option<DateTime<Utc>>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(skip_serializing_if = "Option::is_none", alias = "is_opening_balance")]
pub is_opening_balance: Option<bool>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(skip_serializing_if = "Option::is_none", alias = "is_closing_entry")]
pub is_closing_entry: Option<bool>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(skip_serializing_if = "Option::is_none", alias = "is_adjustment")]
pub is_adjustment: Option<bool>,
#[cfg_attr(feature = "openapi", schema(example = true))]
#[serde(skip_serializing_if = "Option::is_none", alias = "is_reversed")]
pub is_reversed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none", alias = "reversed_by_id")]
pub reversed_by_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none", alias = "reverses_id")]
pub reverses_id: Option<Uuid>,
}
impl PatchLedgerDto {
/// Check if any field is set
pub fn has_changes(&self) -> bool {
self.account_id.is_some() || self.account_number.is_some() || self.account_name.is_some() || self.account_type.is_some() || self.normal_balance.is_some() || self.journal_id.is_some() || self.journal_number.is_some() || self.journal_line_id.is_some() || self.transaction_date.is_some() || self.posting_date.is_some() || self.fiscal_period_id.is_some() || self.fiscal_year.is_some() || self.fiscal_month.is_some() || self.description.is_some() || self.reference.is_some() || self.currency.is_some() || self.debit_amount.is_some() || self.credit_amount.is_some() || self.balance_before.is_some() || self.balance_after.is_some() || self.balance_change.is_some() || self.sequence_number.is_some() || self.branch_id.is_some() || self.party_type.is_some() || self.party_id.is_some() || self.cost_center_id.is_some() || self.project_id.is_some() || self.department_id.is_some() || self.dimensions.is_some() || self.source_type.is_some() || self.source_id.is_some() || self.source_reference.is_some() || self.is_reconciled.is_some() || self.reconciliation_id.is_some() || self.reconciled_at.is_some() || self.is_opening_balance.is_some() || self.is_closing_entry.is_some() || self.is_adjustment.is_some() || self.is_reversed.is_some() || self.reversed_by_id.is_some() || self.reverses_id.is_some()
}
}
// =============================================================================
// Response DTO
// =============================================================================
/// Response DTO for Ledger entity
///
/// Used in API responses for single entity.
/// Includes all fields including metadata.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct LedgerResponseDto {
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
pub id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
pub account_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub account_number: String,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub account_name: String,
pub account_type: AccountType,
pub normal_balance: NormalBalance,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
pub journal_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub journal_number: String,
#[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
pub journal_line_id: Uuid,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
pub transaction_date: NaiveDate,
#[cfg_attr(feature = "openapi", schema(example = "2024-01-01"))]
pub posting_date: NaiveDate,
pub fiscal_period_id: Option<Uuid>,
#[cfg_attr(feature = "openapi", schema(example = 42))]
pub fiscal_year: i32,
#[cfg_attr(feature = "openapi", schema(example = 42))]
pub fiscal_month: i32,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub description: String,
pub reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = "example"))]
pub currency: String,
pub debit_amount: Decimal,
pub credit_amount: Decimal,
pub balance_before: Decimal,
pub balance_after: Decimal,
pub balance_change: Decimal,
#[cfg_attr(feature = "openapi", schema(example = 42))]
pub sequence_number: i32,
pub branch_id: Option<Uuid>,
pub party_type: Option<PartyType>,
pub party_id: Option<Uuid>,
pub cost_center_id: Option<Uuid>,
pub project_id: Option<Uuid>,
pub department_id: Option<Uuid>,
pub dimensions: Option<serde_json::Value>,
pub source_type: Option<String>,
pub source_id: Option<Uuid>,
pub source_reference: Option<String>,
#[cfg_attr(feature = "openapi", schema(example = true))]
pub is_reconciled: bool,
pub reconciliation_id: Option<Uuid>,
pub reconciled_at: Option<DateTime<Utc>>,
#[cfg_attr(feature = "openapi", schema(example = true))]
pub is_opening_balance: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
pub is_closing_entry: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
pub is_adjustment: bool,
#[cfg_attr(feature = "openapi", schema(example = true))]
pub is_reversed: bool,
pub reversed_by_id: Option<Uuid>,
pub reverses_id: Option<Uuid>,
pub metadata: AuditMetadata,
}
// =============================================================================
// List Response DTO
// =============================================================================
/// Paginated list response for Ledger entities
///
/// Used in API responses for list endpoints.
/// Includes pagination metadata.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct LedgerListResponseDto {
/// List of items
pub items: Vec<LedgerResponseDto>,
/// Total number of items (across all pages)
pub total: u64,
/// Current page number (1-indexed)
pub page: u32,
/// Number of items per page
pub per_page: u32,
/// Total number of pages
pub total_pages: u32,
/// Whether there is a next page
pub has_next: bool,
/// Whether there is a previous page
pub has_prev: bool,
}
impl LedgerListResponseDto {
/// Create a new list response from items and pagination info
pub fn new(items: Vec<LedgerResponseDto>, total: u64, page: u32, per_page: u32) -> Self {
let total_pages = if per_page > 0 {
((total as f64) / (per_page as f64)).ceil() as u32
} else {
0
};
Self {
items,
total,
page,
per_page,
total_pages,
has_next: page < total_pages,
has_prev: page > 1,
}
}
}
/// Summary DTO for list views (compact version)
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct LedgerSummaryDto {
pub id: Uuid,
pub account_id: Uuid,
pub account_number: String,
pub account_name: String,
pub created_at: Option<DateTime<Utc>>,
}
// =============================================================================
// Conversions
// =============================================================================
impl From<Ledger> for LedgerResponseDto {
fn from(entity: Ledger) -> Self {
Self {
id: entity.id,
account_id: entity.account_id,
account_number: entity.account_number,
account_name: entity.account_name,
account_type: entity.account_type,
normal_balance: entity.normal_balance,
journal_id: entity.journal_id,
journal_number: entity.journal_number,
journal_line_id: entity.journal_line_id,
transaction_date: entity.transaction_date,
posting_date: entity.posting_date,
fiscal_period_id: entity.fiscal_period_id,
fiscal_year: entity.fiscal_year,
fiscal_month: entity.fiscal_month,
description: entity.description,
reference: entity.reference,
currency: entity.currency,
debit_amount: entity.debit_amount,
credit_amount: entity.credit_amount,
balance_before: entity.balance_before,
balance_after: entity.balance_after,
balance_change: entity.balance_change,
sequence_number: entity.sequence_number,
branch_id: entity.branch_id,
party_type: entity.party_type,
party_id: entity.party_id,
cost_center_id: entity.cost_center_id,
project_id: entity.project_id,
department_id: entity.department_id,
dimensions: entity.dimensions,
source_type: entity.source_type,
source_id: entity.source_id,
source_reference: entity.source_reference,
is_reconciled: entity.is_reconciled,
reconciliation_id: entity.reconciliation_id,
reconciled_at: entity.reconciled_at,
is_opening_balance: entity.is_opening_balance,
is_closing_entry: entity.is_closing_entry,
is_adjustment: entity.is_adjustment,
is_reversed: entity.is_reversed,
reversed_by_id: entity.reversed_by_id,
reverses_id: entity.reverses_id,
metadata: entity.metadata,
}
}
}
impl From<Ledger> for LedgerSummaryDto {
fn from(entity: Ledger) -> Self {
let created_at = backbone_core::PersistentEntity::created_at(&entity);
Self {
id: entity.id,
account_id: entity.account_id,
account_number: entity.account_number,
account_name: entity.account_name,
created_at,
}
}
}
impl From<CreateLedgerDto> for Ledger {
fn from(dto: CreateLedgerDto) -> Self {
Self {
id: Uuid::new_v4(),
account_id: dto.account_id,
account_number: dto.account_number,
account_name: dto.account_name,
account_type: dto.account_type,
normal_balance: dto.normal_balance,
journal_id: dto.journal_id,
journal_number: dto.journal_number,
journal_line_id: dto.journal_line_id,
transaction_date: dto.transaction_date,
posting_date: dto.posting_date,
fiscal_period_id: dto.fiscal_period_id,
fiscal_year: dto.fiscal_year,
fiscal_month: dto.fiscal_month,
description: dto.description,
reference: dto.reference,
currency: dto.currency,
debit_amount: dto.debit_amount,
credit_amount: dto.credit_amount,
balance_before: dto.balance_before,
balance_after: dto.balance_after,
balance_change: dto.balance_change,
sequence_number: dto.sequence_number,
branch_id: dto.branch_id,
party_type: dto.party_type,
party_id: dto.party_id,
cost_center_id: dto.cost_center_id,
project_id: dto.project_id,
department_id: dto.department_id,
dimensions: dto.dimensions,
source_type: dto.source_type,
source_id: dto.source_id,
source_reference: dto.source_reference,
is_reconciled: dto.is_reconciled,
reconciliation_id: dto.reconciliation_id,
reconciled_at: dto.reconciled_at,
is_opening_balance: dto.is_opening_balance,
is_closing_entry: dto.is_closing_entry,
is_adjustment: dto.is_adjustment,
is_reversed: dto.is_reversed,
reversed_by_id: dto.reversed_by_id,
reverses_id: dto.reverses_id,
metadata: AuditMetadata::default(),
}
}
}
impl From<&Ledger> for LedgerResponseDto {
fn from(entity: &Ledger) -> Self {
Self {
id: entity.id.clone(),
account_id: entity.account_id.clone(),
account_number: entity.account_number.clone(),
account_name: entity.account_name.clone(),
account_type: entity.account_type.clone(),
normal_balance: entity.normal_balance.clone(),
journal_id: entity.journal_id.clone(),
journal_number: entity.journal_number.clone(),
journal_line_id: entity.journal_line_id.clone(),
transaction_date: entity.transaction_date.clone(),
posting_date: entity.posting_date.clone(),
fiscal_period_id: entity.fiscal_period_id.clone(),
fiscal_year: entity.fiscal_year.clone(),
fiscal_month: entity.fiscal_month.clone(),
description: entity.description.clone(),
reference: entity.reference.clone(),
currency: entity.currency.clone(),
debit_amount: entity.debit_amount.clone(),
credit_amount: entity.credit_amount.clone(),
balance_before: entity.balance_before.clone(),
balance_after: entity.balance_after.clone(),
balance_change: entity.balance_change.clone(),
sequence_number: entity.sequence_number.clone(),
branch_id: entity.branch_id.clone(),
party_type: entity.party_type.clone(),
party_id: entity.party_id.clone(),
cost_center_id: entity.cost_center_id.clone(),
project_id: entity.project_id.clone(),
department_id: entity.department_id.clone(),
dimensions: entity.dimensions.clone(),
source_type: entity.source_type.clone(),
source_id: entity.source_id.clone(),
source_reference: entity.source_reference.clone(),
is_reconciled: entity.is_reconciled.clone(),
reconciliation_id: entity.reconciliation_id.clone(),
reconciled_at: entity.reconciled_at.clone(),
is_opening_balance: entity.is_opening_balance.clone(),
is_closing_entry: entity.is_closing_entry.clone(),
is_adjustment: entity.is_adjustment.clone(),
is_reversed: entity.is_reversed.clone(),
reversed_by_id: entity.reversed_by_id.clone(),
reverses_id: entity.reverses_id.clone(),
metadata: entity.metadata.clone(),
}
}
}
impl backbone_core::FromCreateDto<CreateLedgerDto> for Ledger {
fn from_create_dto(dto: CreateLedgerDto) -> backbone_core::ServiceResult<Self> {
Ok(Ledger::from(dto))
}
}
impl backbone_core::ApplyUpdateDto<UpdateLedgerDto> for Ledger {
fn apply_update(mut self, dto: UpdateLedgerDto) -> backbone_core::ServiceResult<Self> {
self.account_id = dto.account_id;
self.account_number = dto.account_number;
self.account_name = dto.account_name;
self.account_type = dto.account_type;
self.normal_balance = dto.normal_balance;
self.journal_id = dto.journal_id;
self.journal_number = dto.journal_number;
self.journal_line_id = dto.journal_line_id;
self.transaction_date = dto.transaction_date;
self.posting_date = dto.posting_date;
self.fiscal_period_id = dto.fiscal_period_id;
self.fiscal_year = dto.fiscal_year;
self.fiscal_month = dto.fiscal_month;
self.description = dto.description;
self.reference = dto.reference;
self.currency = dto.currency;
self.debit_amount = dto.debit_amount;
self.credit_amount = dto.credit_amount;
self.balance_before = dto.balance_before;
self.balance_after = dto.balance_after;
self.balance_change = dto.balance_change;
self.sequence_number = dto.sequence_number;
self.branch_id = dto.branch_id;
self.party_type = dto.party_type;
self.party_id = dto.party_id;
self.cost_center_id = dto.cost_center_id;
self.project_id = dto.project_id;
self.department_id = dto.department_id;
self.dimensions = dto.dimensions;
self.source_type = dto.source_type;
self.source_id = dto.source_id;
self.source_reference = dto.source_reference;
self.is_reconciled = dto.is_reconciled;
self.reconciliation_id = dto.reconciliation_id;
self.reconciled_at = dto.reconciled_at;
self.is_opening_balance = dto.is_opening_balance;
self.is_closing_entry = dto.is_closing_entry;
self.is_adjustment = dto.is_adjustment;
self.is_reversed = dto.is_reversed;
self.reversed_by_id = dto.reversed_by_id;
self.reverses_id = dto.reverses_id;
Ok(self)
}
}
// =============================================================================
// Custom DTOs
// =============================================================================
// Add custom DTOs specific to Ledger here.
// This section will be preserved during regeneration.
// >>> END CUSTOM DTOs