158 lines
5.0 KiB
Rust
158 lines
5.0 KiB
Rust
|
|
use argon2::Params;
|
|
use axum::{extract::{ws::{close_code::STATUS, Message}, Path, State}, http::StatusCode, response::IntoResponse};
|
|
use rusqlite::params;
|
|
use serde::Serialize;
|
|
use serde_json::json;
|
|
|
|
|
|
|
|
use crate::utils::{auth::AuthClaims, db_pool::AppState};
|
|
|
|
|
|
|
|
pub async fn create_inventory_item(
|
|
State(state): State<AppState>,
|
|
Path((item_name, item_amount)): Path<(String, i32)>,
|
|
AuthClaims{ user_id, hotel_id}: AuthClaims,
|
|
) -> impl IntoResponse {
|
|
|
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
|
|
|
let conn = match pool.get(){
|
|
Ok(conn) => conn,
|
|
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("couldn't open the connection"))
|
|
};
|
|
|
|
let result = conn.execute(
|
|
"INSERT INTO inventory (item_name, amount, user_id) VALUES (?1, ?2, ?3)",
|
|
params![&item_name,&item_amount,&user_id]
|
|
);
|
|
match result {
|
|
Ok(rows) => (StatusCode::OK, format!("inserted item {item_name}, with {item_amount} amount")),
|
|
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("couldn't add the new item, err: {}", err ))
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct InventoryItems {
|
|
id: i32,
|
|
amount: i32,
|
|
name: String,
|
|
user_id: i32,
|
|
updated_at: String,
|
|
}
|
|
|
|
pub async fn update_inventory_item(
|
|
State(state): State<AppState>,
|
|
Path((item_id, item_amount)): Path<(i32, i32)>,
|
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
|
) -> impl IntoResponse {
|
|
|
|
//TODO: make better error handling :
|
|
// if wrong param collumn targeted,
|
|
// if missing path param
|
|
|
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
|
|
|
let conn = match pool.get(){
|
|
Ok(conn) => conn,
|
|
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
|
};
|
|
|
|
let result: Result<String, rusqlite::Error> = conn.query_row(
|
|
"UPDATE inventory SET amount = ?1, user_id=?3 WHERE id = ?2 RETURNING item_name",
|
|
params![&item_amount, &item_id, &user_id],
|
|
|row| row.get(0),
|
|
);
|
|
|
|
match result {
|
|
Ok(item_name) => {
|
|
if let Err(err) = conn.execute(
|
|
"INSERT INTO inventory_history (item_id, amount, item_name, user_id) VALUES (?1,?2,?3,?4)",
|
|
params![&item_id,&item_amount,&item_name, &user_id]
|
|
){
|
|
return (StatusCode::INTERNAL_SERVER_ERROR, format!("failed to update inventory history"));
|
|
}
|
|
|
|
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
|
let update_msg = json!({
|
|
"event_type": "item_update",
|
|
"item_id": item_id,
|
|
"number": item_amount,
|
|
"updated_by": user_id,
|
|
})
|
|
.to_string();
|
|
|
|
for entry in hotel_users.iter() {
|
|
let sender = entry.value();
|
|
// ignore errors (client disconnected)
|
|
let _ = sender.send(Message::Text(update_msg.clone().into()));
|
|
}
|
|
}
|
|
|
|
|
|
(StatusCode::OK, format!("updated item history"))
|
|
}
|
|
|
|
Ok(_) => (StatusCode::NOT_FOUND, "No item found, err : {_}".to_string()),
|
|
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")),
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
match result {
|
|
Ok(row) => (StatusCode::OK, format!("Items updated")),
|
|
Ok(_) => (StatusCode::NOT_FOUND, format!("No item with this id exist")),
|
|
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("error updating the item with id :{} with amount: {}", item_id, item_amount))
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
pub async fn get_inventory_item(
|
|
State(state): State<AppState>,
|
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
|
) -> impl IntoResponse {
|
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
|
|
|
let conn = match pool.get() {
|
|
Ok(c) => c,
|
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()),
|
|
};
|
|
|
|
let mut stmt = match conn.prepare("SELECT id, amount, item_name, user_id, updated_at FROM inventory") {
|
|
Ok(s) => s,
|
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Statement error".to_string()),
|
|
};
|
|
|
|
let mut query_result = match stmt.query([]) {
|
|
Ok(r) => r,
|
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Query error".to_string()),
|
|
};
|
|
|
|
let mut items = Vec::new();
|
|
|
|
while let Ok(Some(row)) = query_result.next() {
|
|
let item = InventoryItems {
|
|
id: row.get("id").unwrap_or_default(),
|
|
amount: row.get("amount").unwrap_or_default(),
|
|
name: row.get("item_name").unwrap_or_default(),
|
|
user_id: row.get("user_id").unwrap_or_default(),
|
|
updated_at: row.get("updated_at").unwrap_or_default(),
|
|
};
|
|
items.push(item);
|
|
}
|
|
|
|
// Serialize to JSON
|
|
let json = match serde_json::to_string(&items) {
|
|
Ok(j) => j,
|
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Serialization error".to_string()),
|
|
};
|
|
|
|
(StatusCode::OK, json)
|
|
} |