backbone_inventory/presentation/dto/
delivery_note_item_dto.rs1use serde::{Deserialize, Serialize};
9use uuid::Uuid;
10use chrono::{DateTime, Utc};
11use rust_decimal::Decimal;
12
13#[cfg(feature = "openapi")]
14#[cfg(feature = "openapi")]
15use utoipa::ToSchema;
16
17use crate::domain::entity::DeliveryNoteItem;
18use crate::domain::entity::AuditMetadata;
19
20#[derive(Debug, Clone, Deserialize)]
29#[cfg_attr(feature = "openapi", derive(ToSchema))]
30#[serde(rename_all = "camelCase")]
31pub struct CreateDeliveryNoteItemDto {
32 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
33 #[serde(alias = "delivery_id")]
34 pub delivery_id: Uuid,
35 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
36 #[serde(alias = "item_id")]
37 pub item_id: Uuid,
38 pub quantity: Decimal,
39 #[serde(alias = "valuation_rate")]
40 pub valuation_rate: Decimal,
41 #[serde(alias = "cogs_amount")]
42 pub cogs_amount: Decimal,
43}
44
45#[derive(Debug, Clone, Deserialize)]
54#[cfg_attr(feature = "openapi", derive(ToSchema))]
55#[serde(rename_all = "camelCase")]
56pub struct UpdateDeliveryNoteItemDto {
57 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
58 #[serde(alias = "delivery_id")]
59 pub delivery_id: Uuid,
60 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
61 #[serde(alias = "item_id")]
62 pub item_id: Uuid,
63 pub quantity: Decimal,
64 #[serde(alias = "valuation_rate")]
65 pub valuation_rate: Decimal,
66 #[serde(alias = "cogs_amount")]
67 pub cogs_amount: Decimal,
68}
69
70#[derive(Debug, Clone, Default, Deserialize)]
79#[cfg_attr(feature = "openapi", derive(ToSchema))]
80#[serde(rename_all = "camelCase")]
81pub struct PatchDeliveryNoteItemDto {
82 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
83 #[serde(skip_serializing_if = "Option::is_none", alias = "delivery_id")]
84 pub delivery_id: Option<Uuid>,
85 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
86 #[serde(skip_serializing_if = "Option::is_none", alias = "item_id")]
87 pub item_id: Option<Uuid>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub quantity: Option<Decimal>,
90 #[serde(skip_serializing_if = "Option::is_none", alias = "valuation_rate")]
91 pub valuation_rate: Option<Decimal>,
92 #[serde(skip_serializing_if = "Option::is_none", alias = "cogs_amount")]
93 pub cogs_amount: Option<Decimal>,
94}
95
96impl PatchDeliveryNoteItemDto {
97 pub fn has_changes(&self) -> bool {
99 self.delivery_id.is_some() || self.item_id.is_some() || self.quantity.is_some() || self.valuation_rate.is_some() || self.cogs_amount.is_some()
100 }
101}
102
103#[derive(Debug, Clone, Serialize)]
112#[cfg_attr(feature = "openapi", derive(ToSchema))]
113#[serde(rename_all = "camelCase")]
114pub struct DeliveryNoteItemResponseDto {
115 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
116 pub id: Uuid,
117 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
118 pub delivery_id: Uuid,
119 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
120 pub item_id: Uuid,
121 pub quantity: Decimal,
122 pub valuation_rate: Decimal,
123 pub cogs_amount: Decimal,
124 pub metadata: AuditMetadata,
125}
126
127#[derive(Debug, Clone, Serialize)]
136#[cfg_attr(feature = "openapi", derive(ToSchema))]
137#[serde(rename_all = "camelCase")]
138pub struct DeliveryNoteItemListResponseDto {
139 pub items: Vec<DeliveryNoteItemResponseDto>,
141 pub total: u64,
143 pub page: u32,
145 pub per_page: u32,
147 pub total_pages: u32,
149 pub has_next: bool,
151 pub has_prev: bool,
153}
154
155impl DeliveryNoteItemListResponseDto {
156 pub fn new(items: Vec<DeliveryNoteItemResponseDto>, total: u64, page: u32, per_page: u32) -> Self {
158 let total_pages = if per_page > 0 {
159 ((total as f64) / (per_page as f64)).ceil() as u32
160 } else {
161 0
162 };
163 Self {
164 items,
165 total,
166 page,
167 per_page,
168 total_pages,
169 has_next: page < total_pages,
170 has_prev: page > 1,
171 }
172 }
173}
174
175#[derive(Debug, Clone, Serialize)]
177#[cfg_attr(feature = "openapi", derive(ToSchema))]
178#[serde(rename_all = "camelCase")]
179pub struct DeliveryNoteItemSummaryDto {
180 pub id: Uuid,
181 pub delivery_id: Uuid,
182 pub item_id: Uuid,
183 pub quantity: Decimal,
184 pub created_at: Option<DateTime<Utc>>,
185}
186
187impl From<DeliveryNoteItem> for DeliveryNoteItemResponseDto {
192 fn from(entity: DeliveryNoteItem) -> Self {
193 Self {
194 id: entity.id,
195 delivery_id: entity.delivery_id,
196 item_id: entity.item_id,
197 quantity: entity.quantity,
198 valuation_rate: entity.valuation_rate,
199 cogs_amount: entity.cogs_amount,
200 metadata: entity.metadata,
201 }
202 }
203}
204
205impl From<DeliveryNoteItem> for DeliveryNoteItemSummaryDto {
206 fn from(entity: DeliveryNoteItem) -> Self {
207 let created_at = backbone_core::PersistentEntity::created_at(&entity);
208 Self {
209 id: entity.id,
210 delivery_id: entity.delivery_id,
211 item_id: entity.item_id,
212 quantity: entity.quantity,
213 created_at,
214 }
215 }
216}
217
218impl From<CreateDeliveryNoteItemDto> for DeliveryNoteItem {
219 fn from(dto: CreateDeliveryNoteItemDto) -> Self {
220 Self {
221 id: Uuid::new_v4(),
222 delivery_id: dto.delivery_id,
223 item_id: dto.item_id,
224 quantity: dto.quantity,
225 valuation_rate: dto.valuation_rate,
226 cogs_amount: dto.cogs_amount,
227 metadata: AuditMetadata::default(),
228 }
229 }
230}
231
232impl From<&DeliveryNoteItem> for DeliveryNoteItemResponseDto {
233 fn from(entity: &DeliveryNoteItem) -> Self {
234 Self {
235 id: entity.id.clone(),
236 delivery_id: entity.delivery_id.clone(),
237 item_id: entity.item_id.clone(),
238 quantity: entity.quantity.clone(),
239 valuation_rate: entity.valuation_rate.clone(),
240 cogs_amount: entity.cogs_amount.clone(),
241 metadata: entity.metadata.clone(),
242 }
243 }
244}
245
246impl backbone_core::FromCreateDto<CreateDeliveryNoteItemDto> for DeliveryNoteItem {
247 fn from_create_dto(dto: CreateDeliveryNoteItemDto) -> backbone_core::ServiceResult<Self> {
248 Ok(DeliveryNoteItem::from(dto))
249 }
250}
251
252impl backbone_core::ApplyUpdateDto<UpdateDeliveryNoteItemDto> for DeliveryNoteItem {
253 fn apply_update(mut self, dto: UpdateDeliveryNoteItemDto) -> backbone_core::ServiceResult<Self> {
254 self.delivery_id = dto.delivery_id;
255 self.item_id = dto.item_id;
256 self.quantity = dto.quantity;
257 self.valuation_rate = dto.valuation_rate;
258 self.cogs_amount = dto.cogs_amount;
259 Ok(self)
260 }
261}
262
263