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}