source: src-tauri/src/commands/inventory.rs

main
Last change on this file was a4ca79c, checked in by Georgi Paunkov <paunkovgeorgi@…>, 5 days ago

Initial commit

  • Property mode set to 100644
File size: 4.7 KB
RevLine 
[a4ca79c]1use sqlx::{PgPool, Row};
2use tauri::State;
3
4use crate::commands::auth::{require_manager_session, ActiveSessions};
5
6pub async fn update_stock(
7 order_id: i32,
8 conn: &mut sqlx::PgConnection
9) -> Result<(), String> {
10 let rows = sqlx::query(
11 "SELECT product_id, quantity FROM order_item WHERE order_id = $1"
12 )
13 .bind(order_id)
14 .fetch_all(&mut *conn)
15 .await
16 .map_err(|e| e.to_string())?;
17
18 for row in rows {
19 let p_id: i32 = row.get("product_id");
20 let order_qty: i32 = row.get("quantity");
21
22 let recipe_row = sqlx::query(
23 "SELECT recipe_id FROM recipe WHERE product_id = $1"
24 )
25 .bind(p_id)
26 .fetch_optional(&mut *conn)
27 .await
28 .map_err(|e| e.to_string())?;
29
30 if let Some(r) = recipe_row {
31 let r_id: i32 = r.get("recipe_id");
32
33 let ings = sqlx::query(
34 "SELECT ingredient_id, quantity_needed FROM recipe_item WHERE recipe_id = $1"
35 )
36 .bind(r_id)
37 .fetch_all(&mut *conn)
38 .await
39 .map_err(|e| e.to_string())?;
40
41 for ing in ings {
42 let ing_id: i32 = ing.get("ingredient_id");
43 let qty_needed: rust_decimal::Decimal = ing.get("quantity_needed");
44
45 sqlx::query(
46 "UPDATE ingredient SET current_stock = current_stock - ($1 * $2) WHERE ingredient_id = $3"
47 )
48 .bind(qty_needed)
49 .bind(order_qty as f64)
50 .bind(ing_id)
51 .execute(&mut *conn)
52 .await
53 .map_err(|e| e.to_string())?;
54 }
55 } else {
56 sqlx::query(
57 "INSERT INTO inventory (product_id, quantity_change, operation_type) VALUES ($1, -$2, 'ПРОДАЖБА')"
58 )
59 .bind(p_id)
60 .bind(order_qty)
61 .execute(&mut *conn)
62 .await
63 .map_err(|e| e.to_string())?;
64 }
65 }
66 Ok(())
67}
68
69#[tauri::command]
70pub async fn get_inventory(
71 pool: State<'_, PgPool>
72) -> Result<Vec<serde_json::Value>, String> {
73 let rows = sqlx::query(
74 "
75 SELECT
76 p.product_id,
77 p.name,
78 COALESCE(SUM(i.quantity_change), 0) as quantity,
79 p.min_stock
80 FROM product p
81 LEFT JOIN inventory i ON p.product_id = i.product_id
82 WHERE p.active = true
83 GROUP BY p.product_id, p.name, p.min_stock
84 ORDER BY p.name
85 "
86 )
87 .fetch_all(pool.inner())
88 .await
89 .map_err(|e| e.to_string())?;
90
91 let mut result = Vec::new();
92 for row in rows {
93 result.push(serde_json::json!({
94 "product_id": row.get::<i32, _>("product_id"),
95 "name": row.get::<String, _>("name"),
96 "quantity": row.get::<i64, _>("quantity"),
97 "min_stock": row.get::<i32, _>("min_stock")
98 }));
99 }
100
101 Ok(result)
102}
103
104#[tauri::command]
105pub async fn get_low_stock(
106 pool: State<'_, PgPool>
107) -> Result<Vec<serde_json::Value>, String> {
108 let rows = sqlx::query(
109 "
110 SELECT
111 p.product_id,
112 p.name,
113 COALESCE(SUM(i.quantity_change), 0) as quantity,
114 p.min_stock
115 FROM product p
116 LEFT JOIN inventory i ON p.product_id = i.product_id
117 WHERE p.active = true
118 GROUP BY p.product_id, p.name, p.min_stock
119 HAVING COALESCE(SUM(i.quantity_change), 0) <= p.min_stock
120 ORDER BY p.name
121 "
122 )
123 .fetch_all(pool.inner())
124 .await
125 .map_err(|e| e.to_string())?;
126
127 let mut result = Vec::new();
128 for row in rows {
129 result.push(serde_json::json!({
130 "product_id": row.get::<i32, _>("product_id"),
131 "name": row.get::<String, _>("name"),
132 "quantity": row.get::<i64, _>("quantity"),
133 "min_stock": row.get::<i32, _>("min_stock")
134 }));
135 }
136
137 Ok(result)
138}
139
140#[tauri::command]
141pub async fn restock_product(
142 token: String,
143 product_id: i32,
144 quantity: i32,
145 pool: State<'_, PgPool>,
146 sessions: State<'_, ActiveSessions>,
147) -> Result<(), String> {
148 require_manager_session(&token, sessions.inner()).await?;
149
150 if quantity <= 0 {
151 return Err("Количината мора да биде поголема од 0".to_string());
152 }
153
154 sqlx::query(
155 "
156 INSERT INTO inventory
157 (
158 product_id,
159 quantity_change,
160 operation_type
161 )
162 VALUES
163 ($1, $2, 'НАДОПОЛНУВАЊЕ_ЗАЛИХИ')
164 "
165 )
166 .bind(product_id)
167 .bind(quantity)
168 .execute(pool.inner())
169 .await
170 .map_err(|e| e.to_string())?;
171
172 Ok(())
173}
Note: See TracBrowser for help on using the repository browser.