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

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

Initial commit

  • Property mode set to 100644
File size: 3.6 KB
RevLine 
[a4ca79c]1use sqlx::{PgPool, Row};
2use tauri::State;
3use rust_decimal::Decimal;
4use crate::commands::auth::ActiveSessions;
5
6#[tauri::command]
7pub async fn create_invoice(
8 token: String,
9 payment_id: i32,
10 invoice_number: String,
11 pool: State<'_, PgPool>,
12 sessions: State<'_, ActiveSessions>,
13) -> Result<(), String> {
14 {
15 let lock = sessions.0.lock().map_err(|_| "Системска грешка со сесијата".to_string())?;
16 if !lock.contains_key(&token) {
17 return Err("Невалидна сесија.".to_string());
18 }
19 }
20
21 sqlx::query(
22 "
23 INSERT INTO invoice (payment_id, invoice_number)
24 VALUES ($1, $2)
25 "
26 )
27 .bind(payment_id)
28 .bind(invoice_number)
29 .execute(pool.inner())
30 .await
31 .map_err(|e| e.to_string())?;
32
33 Ok(())
34}
35
36#[tauri::command]
37pub async fn get_invoice(
38 token: String,
39 invoice_number: String,
40 pool: State<'_, PgPool>,
41 sessions: State<'_, ActiveSessions>,
42) -> Result<serde_json::Value, String> {
43 {
44 let lock = sessions.0.lock().map_err(|_| "Системска грешка со сесијата".to_string())?;
45 if !lock.contains_key(&token) {
46 return Err("Невалидна сесија за пристап до фактури.".to_string());
47 }
48 }
49
50 let settings_row = sqlx::query(
51 "SELECT restaurant_name, currency, vat_rate FROM app_settings LIMIT 1"
52 )
53 .fetch_optional(pool.inner())
54 .await
55 .map_err(|e| e.to_string())?;
56
57 let mut restaurant_name = "Ресторан".to_string();
58 let mut currency = "MKD".to_string();
59 let mut vat_rate_str = "0".to_string();
60
61 if let Some(row) = settings_row {
62 restaurant_name = row.get::<String, _>("restaurant_name");
63 currency = row.get::<String, _>("currency");
64 vat_rate_str = row.get::<Decimal, _>("vat_rate").to_string();
65 }
66
67 let rows = sqlx::query(
68 r#"
69 SELECT
70 i.invoice_number,
71 i.issued_at,
72 pay.method,
73 pay.amount,
74 p.name as product_name,
75 oi.quantity,
76 oi.unit_price
77 FROM invoice i
78 JOIN payment pay ON i.payment_id = pay.payment_id
79 JOIN orders o ON pay.order_id = o.order_id
80 JOIN order_item oi ON o.order_id = oi.order_id
81 JOIN product p ON oi.product_id = p.product_id
82 WHERE i.invoice_number = $1
83 ORDER BY oi.item_number
84 "#
85 )
86 .bind(&invoice_number)
87 .fetch_all(pool.inner())
88 .await
89 .map_err(|e| e.to_string())?;
90
91 if rows.is_empty() {
92 return Err("Фактурата не е пронајдена".to_string());
93 }
94
95 let issued_at: chrono::DateTime<chrono::Utc> = rows[0].get("issued_at");
96 let issued_at_str = issued_at.to_rfc3339();
97 let method = rows[0].get::<String, _>("method");
98 let total_amount = rows[0].get::<Decimal, _>("amount").to_string();
99
100 let mut items = Vec::new();
101 for row in rows {
102 let p_name = row.get::<String, _>("product_name");
103 let qty = row.get::<i32, _>("quantity");
104 let u_price = row.get::<Decimal, _>("unit_price").to_string();
105
106 items.push(serde_json::json!({
107 "name": p_name,
108 "quantity": qty,
109 "unit_price": u_price
110 }));
111 }
112
113 Ok(serde_json::json!({
114 "restaurant_name": restaurant_name,
115 "currency": currency,
116 "vat_rate": vat_rate_str,
117 "invoice_number": invoice_number,
118 "issued_at": issued_at_str,
119 "method": method,
120 "total_amount": total_amount,
121 "items": items
122 }))
123}
Note: See TracBrowser for help on using the repository browser.