backbone_inventory/infrastructure/persistence/
scrap_door_repository.rs1use rust_decimal::Decimal;
15use sqlx::{PgConnection, Row};
16use uuid::Uuid;
17
18pub struct NewScrapRow<'a> {
21 pub id: Uuid,
22 pub name: &'a str,
23 pub origin: Option<&'a str>,
24 pub item_id: Uuid,
25 pub scrap_qty: Decimal,
26 pub location_id: Uuid,
27 pub scrap_location_id: Uuid,
28 pub lot_id: Option<Uuid>,
29 pub package_id: Option<Uuid>,
30 pub owner_id: Option<Uuid>,
31 pub picking_id: Option<Uuid>,
32 pub scrap_reason_tag_ids: Vec<Uuid>,
33}
34
35#[derive(Debug, Clone)]
37pub struct ScrapRow {
38 pub id: Uuid,
39 pub name: String,
40 pub state: String,
42 pub origin: Option<String>,
43 pub item_id: Uuid,
44 pub scrap_qty: Decimal,
45 pub location_id: Uuid,
46 pub scrap_location_id: Uuid,
47 pub lot_id: Option<Uuid>,
48 pub package_id: Option<Uuid>,
49 pub owner_id: Option<Uuid>,
50 pub picking_id: Option<Uuid>,
51 pub move_id: Option<Uuid>,
53 pub scrap_reason_tag_ids: Vec<Uuid>,
54}
55
56#[derive(Default)]
59pub struct ScrapDoorRepository;
60
61impl ScrapDoorRepository {
62 pub fn new() -> Self {
63 Self
64 }
65
66 pub async fn insert_scrap(
70 &self,
71 conn: &mut PgConnection,
72 s: &NewScrapRow<'_>,
73 ) -> Result<(), sqlx::Error> {
74 sqlx::query(
75 r#"INSERT INTO inventory.scraps
76 (id, name, state, origin, item_id, scrap_qty, location_id,
77 scrap_location_id, lot_id, package_id, owner_id, picking_id,
78 scrap_reason_tag_ids)
79 VALUES ($1, $2, 'draft'::scrap_state, $3, $4, $5, $6,
80 $7, $8, $9, $10, $11, $12)"#,
81 )
82 .bind(s.id)
83 .bind(s.name)
84 .bind(s.origin)
85 .bind(s.item_id)
86 .bind(s.scrap_qty)
87 .bind(s.location_id)
88 .bind(s.scrap_location_id)
89 .bind(s.lot_id)
90 .bind(s.package_id)
91 .bind(s.owner_id)
92 .bind(s.picking_id)
93 .bind(&s.scrap_reason_tag_ids)
94 .execute(&mut *conn)
95 .await?;
96 Ok(())
97 }
98
99 pub async fn fetch_scrap(
101 &self,
102 conn: &mut PgConnection,
103 scrap_id: Uuid,
104 ) -> Result<Option<ScrapRow>, sqlx::Error> {
105 let row = sqlx::query(
106 r#"SELECT id, name, state::text AS state, origin, item_id, scrap_qty,
107 location_id, scrap_location_id, lot_id, package_id, owner_id, picking_id,
108 move_id, scrap_reason_tag_ids
109 FROM inventory.scraps
110 WHERE id = $1 AND (metadata->>'deleted_at') IS NULL"#,
111 )
112 .bind(scrap_id)
113 .fetch_optional(&mut *conn)
114 .await?;
115 Ok(row.map(|r| ScrapRow {
116 id: r.get("id"),
117 name: r.get("name"),
118 state: r.get("state"),
119 origin: r.get("origin"),
120 item_id: r.get("item_id"),
121 scrap_qty: r.get("scrap_qty"),
122 location_id: r.get("location_id"),
123 scrap_location_id: r.get("scrap_location_id"),
124 lot_id: r.get("lot_id"),
125 package_id: r.get("package_id"),
126 owner_id: r.get("owner_id"),
127 picking_id: r.get("picking_id"),
128 move_id: r.get("move_id"),
129 scrap_reason_tag_ids: r.get("scrap_reason_tag_ids"),
130 }))
131 }
132
133 pub async fn mark_scrap_done(
137 &self,
138 conn: &mut PgConnection,
139 scrap_id: Uuid,
140 move_id: Uuid,
141 ) -> Result<bool, sqlx::Error> {
142 let res = sqlx::query(
143 r#"UPDATE inventory.scraps
144 SET state = 'done'::scrap_state, move_id = $2
145 WHERE id = $1 AND state = 'draft'::scrap_state"#,
146 )
147 .bind(scrap_id)
148 .bind(move_id)
149 .execute(&mut *conn)
150 .await?;
151 Ok(res.rows_affected() == 1)
152 }
153}