Skip to main content

datasynth_core/models/
cycle_count.rs

1//! Cycle count models for warehouse inventory management.
2//!
3//! These models represent cycle counting activities used to verify
4//! inventory accuracy without performing a full physical inventory.
5
6use chrono::NaiveDate;
7use rust_decimal::Decimal;
8use serde::{Deserialize, Serialize};
9
10/// Status of a cycle count through the counting lifecycle.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
12#[serde(rename_all = "snake_case")]
13pub enum CycleCountStatus {
14    /// Count has been planned but not yet started
15    #[default]
16    Planned,
17    /// Count is currently in progress
18    InProgress,
19    /// Physical count has been completed
20    Counted,
21    /// Variances have been investigated and reconciled
22    Reconciled,
23    /// Count has been closed and adjustments posted
24    Closed,
25}
26
27/// Classification of count variance severity.
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
29#[serde(rename_all = "snake_case")]
30pub enum CountVarianceType {
31    /// No variance between book and counted quantities
32    #[default]
33    None,
34    /// Minor variance within acceptable tolerance
35    Minor,
36    /// Major variance requiring investigation
37    Major,
38    /// Critical variance requiring immediate action
39    Critical,
40}
41
42/// A cycle count event covering one or more inventory items.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct CycleCount {
45    /// Unique cycle count identifier
46    pub count_id: String,
47    /// Company code this count belongs to
48    pub company_code: String,
49    /// Warehouse where the count takes place
50    pub warehouse_id: String,
51    /// Date the count is performed
52    pub count_date: NaiveDate,
53    /// Current status of the cycle count
54    pub status: CycleCountStatus,
55    /// Employee performing the count
56    pub counter_id: Option<String>,
57    /// Supervisor overseeing the count
58    pub supervisor_id: Option<String>,
59    /// Individual items counted
60    pub items: Vec<CycleCountItem>,
61    /// Total number of items counted
62    pub total_items_counted: u32,
63    /// Total number of items with variances
64    pub total_variances: u32,
65    /// Overall variance rate (total_variances / total_items_counted)
66    pub variance_rate: f64,
67}
68
69/// A single item within a cycle count.
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct CycleCountItem {
72    /// Material being counted
73    pub material_id: String,
74    /// Storage location within the warehouse
75    pub storage_location: String,
76    /// Quantity recorded in the system
77    #[serde(with = "rust_decimal::serde::str")]
78    pub book_quantity: Decimal,
79    /// Quantity physically counted
80    #[serde(with = "rust_decimal::serde::str")]
81    pub counted_quantity: Decimal,
82    /// Difference between counted and book quantities
83    #[serde(with = "rust_decimal::serde::str")]
84    pub variance_quantity: Decimal,
85    /// Unit cost of the material
86    #[serde(with = "rust_decimal::serde::str")]
87    pub unit_cost: Decimal,
88    /// Monetary value of the variance
89    #[serde(with = "rust_decimal::serde::str")]
90    pub variance_value: Decimal,
91    /// Classification of variance severity
92    pub variance_type: CountVarianceType,
93    /// Whether an inventory adjustment has been posted
94    pub adjusted: bool,
95    /// Reason for the adjustment (if adjusted)
96    pub adjustment_reason: Option<String>,
97}