source: src-tauri/src/commands/order.rs@ a4ca79c

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

Initial commit

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[a4ca79c]1use sqlx::PgPool;
2use tauri::State;
3use rust_decimal::Decimal;
4
5use crate::commands::inventory::update_stock;
6use crate::commands::table::{set_table_status, STATUS_FREE, STATUS_OCCUPIED};
7
8#[tauri::command]
9pub async fn create_order(
10 user_id: i32,
11 table_id: i32,
12 pool: State<'_, PgPool>
13) -> Result<i32, String> {
14
15 let mut tx = pool.begin()
16 .await
17 .map_err(|e| e.to_string())?;
18
19 let order_id: i32 = sqlx::query_scalar(
20 "
21 INSERT INTO orders
22 (
23 user_id,
24 table_id,
25 status
26 )
27 VALUES
28 (
29 $1,
30 $2,
31 'АКТИВНА'
32 )
33 RETURNING order_id
34 "
35 )
36 .bind(user_id)
37 .bind(table_id)
38 .fetch_one(&mut *tx)
39 .await
40 .map_err(|e| e.to_string())?;
41
42 set_table_status(table_id, STATUS_OCCUPIED, &mut *tx)
43 .await?;
44
45 tx.commit()
46 .await
47 .map_err(|e| e.to_string())?;
48
49 Ok(order_id)
50}
51
52#[tauri::command]
53pub async fn get_active_order(
54 table_id: i32,
55 pool: State<'_, PgPool>
56) -> Result<Option<i32>, String> {
57
58 let order_id = sqlx::query_scalar::<_, i32>(
59 "
60 SELECT order_id
61 FROM orders
62 WHERE table_id = $1
63 AND status = 'АКТИВНА'
64 LIMIT 1
65 "
66 )
67 .bind(table_id)
68 .fetch_optional(pool.inner())
69 .await
70 .map_err(|e| e.to_string())?;
71
72 Ok(order_id)
73}
74
75#[tauri::command]
76pub async fn get_order_total(
77 order_id: i32,
78 pool: State<'_, PgPool>
79) -> Result<Decimal, String> {
80
81 let total = sqlx::query_scalar(
82 "
83 SELECT COALESCE(SUM(quantity * unit_price), 0)
84 FROM order_item
85 WHERE order_id = $1
86 "
87 )
88 .bind(order_id)
89 .fetch_one(pool.inner())
90 .await
91 .map_err(|e| e.to_string())?;
92
93 Ok(total)
94}
95
96#[tauri::command]
97pub async fn pay_order(
98 order_id: i32,
99 method: String,
100 pool: State<'_, PgPool>
101) -> Result<String, String> {
102
103 let mut tx = pool.begin()
104 .await
105 .map_err(|e| e.to_string())?;
106
107 let existing: Option<i32> = sqlx::query_scalar(
108 "
109 SELECT payment_id
110 FROM payment
111 WHERE order_id = $1
112 "
113 )
114 .bind(order_id)
115 .fetch_optional(&mut *tx)
116 .await
117 .map_err(|e| e.to_string())?;
118
119 if existing.is_some() {
120 return Err("Нарачката е веќе платена".to_string());
121 }
122
123 let table_id: i32 = sqlx::query_scalar(
124 "
125 SELECT table_id
126 FROM orders
127 WHERE order_id = $1
128 "
129 )
130 .bind(order_id)
131 .fetch_one(&mut *tx)
132 .await
133 .map_err(|e| e.to_string())?;
134
135 let total: Decimal = sqlx::query_scalar(
136 "
137 SELECT COALESCE(SUM(quantity * unit_price), 0)
138 FROM order_item
139 WHERE order_id = $1
140 "
141 )
142 .bind(order_id)
143 .fetch_one(&mut *tx)
144 .await
145 .map_err(|e| e.to_string())?;
146
147 if total == Decimal::ZERO {
148 return Err("Нарачката е празна".to_string());
149 }
150
151 let payment_id: i32 = sqlx::query_scalar(
152 "
153 INSERT INTO payment
154 (
155 order_id,
156 amount,
157 method
158 )
159 VALUES
160 (
161 $1,
162 $2,
163 $3
164 )
165 RETURNING payment_id
166 "
167 )
168 .bind(order_id)
169 .bind(total)
170 .bind(method)
171 .fetch_one(&mut *tx)
172 .await
173 .map_err(|e| e.to_string())?;
174
175 sqlx::query(
176 "
177 UPDATE orders
178 SET status = 'ПЛАТЕНА'
179 WHERE order_id = $1
180 "
181 )
182 .bind(order_id)
183 .execute(&mut *tx)
184 .await
185 .map_err(|e| e.to_string())?;
186
187 update_stock(order_id, &mut tx)
188 .await?;
189
190 set_table_status(table_id, STATUS_FREE, &mut *tx)
191 .await?;
192
193 let invoice_number = format!("INV-{}", order_id);
194
195 sqlx::query(
196 "
197 INSERT INTO invoice
198 (
199 payment_id,
200 invoice_number
201 )
202 VALUES
203 (
204 $1,
205 $2
206 )
207 "
208 )
209 .bind(payment_id)
210 .bind(&invoice_number)
211 .execute(&mut *tx)
212 .await
213 .map_err(|e| e.to_string())?;
214
215 tx.commit()
216 .await
217 .map_err(|e| e.to_string())?;
218
219 Ok(invoice_number)
220}
221
222#[tauri::command]
223pub async fn update_order_quantity(
224 order_id: i32,
225 product_id: i32,
226 quantity: i32,
227 pool: State<'_, PgPool>
228) -> Result<(), String> {
229
230 if quantity <= 0 {
231 return Err("Количината мора да биде поголема од 0".to_string());
232 }
233
234 sqlx::query(
235 "
236 UPDATE order_item
237 SET quantity = $1
238 WHERE order_id = $2
239 AND product_id = $3
240 "
241 )
242 .bind(quantity)
243 .bind(order_id)
244 .bind(product_id)
245 .execute(pool.inner())
246 .await
247 .map_err(|e| e.to_string())?;
248
249 Ok(())
250}
251
252#[tauri::command]
253pub async fn delete_order_item(
254 order_id: i32,
255 product_id: i32,
256 pool: State<'_, PgPool>
257) -> Result<(), String> {
258
259 sqlx::query(
260 "
261 DELETE FROM order_item
262 WHERE order_id = $1
263 AND product_id = $2
264 "
265 )
266 .bind(order_id)
267 .bind(product_id)
268 .execute(pool.inner())
269 .await
270 .map_err(|e| e.to_string())?;
271
272 Ok(())
273}
Note: See TracBrowser for help on using the repository browser.