You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.8 KiB
Rust
176 lines
4.8 KiB
Rust
use std::collections::HashMap;
|
|
use cfg_if::cfg_if;
|
|
use chrono::Weekday;
|
|
use leptos::*;
|
|
use validator::Validate;
|
|
use crate::backend::data::{ApiResponse, ClosingTime, DayHour, WeekHours};
|
|
use crate::components::data_form::ForValidation;
|
|
|
|
cfg_if! { if #[cfg(feature = "ssr")] {
|
|
use crate::error::AppError;
|
|
use chrono::Local;
|
|
|
|
pub async fn hours_for_day(day: Weekday) -> Result<Vec<DayHour>, AppError> {
|
|
use crate::backend::get_pool;
|
|
use crate::backend::data::OpeningHour;
|
|
|
|
let pool = get_pool().await?;
|
|
let hours = sqlx::query_as::<_, OpeningHour>("SELECT * FROM opening_hour WHERE day = $1")
|
|
.bind(day.num_days_from_monday() as i32)
|
|
.fetch_all(&pool)
|
|
.await?;
|
|
|
|
Ok(hours.into_iter().map(|h| { DayHour::new(h.from, h.to, h.discount)}).collect())
|
|
}
|
|
|
|
async fn purge_closing_days() -> Result<(), AppError> {
|
|
use crate::backend::get_pool;
|
|
|
|
let pool = get_pool().await?;
|
|
sqlx::query("DELETE FROM closing_time WHERE to_date < $1")
|
|
.bind(Local::now())
|
|
.execute(&pool)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}}
|
|
|
|
#[server]
|
|
pub async fn get_hours() -> Result<HashMap<Weekday, Vec<DayHour>>, ServerFnError> {
|
|
use crate::backend::get_pool;
|
|
use crate::backend::data::OpeningHour;
|
|
|
|
let pool = get_pool().await?;
|
|
let hours = sqlx::query_as::<_, OpeningHour>("SELECT * FROM opening_hour").fetch_all(&pool).await?;
|
|
|
|
let mut ret: HashMap<Weekday, Vec<DayHour>> = hours.into_iter().fold(HashMap::new(), |mut map, v| {
|
|
map.entry(Weekday::try_from(v.day as u8).unwrap_or(Weekday::Mon))
|
|
.and_modify(|h| h.push(DayHour::new(v.from, v.to, v.discount)))
|
|
.or_insert(vec![DayHour::new(v.from, v.to, v.discount)]);
|
|
map
|
|
});
|
|
|
|
for d in 0..6 {
|
|
if let None = ret.get(&Weekday::try_from(d as u8).unwrap()) {
|
|
ret.insert(Weekday::try_from(d as u8).unwrap(), Vec::new());
|
|
}
|
|
}
|
|
|
|
Ok(ret)
|
|
}
|
|
|
|
#[server]
|
|
pub async fn get_hours_for_day(day: Weekday) -> Result<Vec<DayHour>, ServerFnError> {
|
|
Ok(hours_for_day(day).await?)
|
|
}
|
|
|
|
#[server]
|
|
pub async fn update_hours(hours: WeekHours) -> Result<ApiResponse<()>, ServerFnError> {
|
|
use crate::perm_check;
|
|
use crate::backend::get_pool;
|
|
use crate::backend::data::DayHours;
|
|
|
|
perm_check!(is_admin);
|
|
|
|
let hr = DayHours::try_new(hours.hours())?;
|
|
let pool = get_pool().await?;
|
|
let day = hours.day();
|
|
let mut tx = pool.begin().await?;
|
|
|
|
sqlx::query("DELETE FROM opening_hour WHERE day = $1")
|
|
.bind(day.num_days_from_monday() as i32)
|
|
.execute(&mut *tx)
|
|
.await?;
|
|
|
|
for h in hr.hours() {
|
|
sqlx::query(r#"INSERT INTO opening_hour(day, "from", "to", discount) VALUES($1, $2, $3, $4)"#)
|
|
.bind(day.num_days_from_monday() as i32)
|
|
.bind(h.from())
|
|
.bind(h.to())
|
|
.bind(h.discount())
|
|
.execute(&mut *tx)
|
|
.await?;
|
|
}
|
|
|
|
tx.commit().await?;
|
|
|
|
Ok(ApiResponse::Data(()))
|
|
}
|
|
|
|
impl ForValidation for UpdateHours {
|
|
fn entity(&self) -> &dyn Validate {
|
|
&self.hours
|
|
}
|
|
}
|
|
|
|
#[server]
|
|
pub async fn get_closing_time() -> Result<Option<ClosingTime>, ServerFnError> {
|
|
use crate::backend::get_pool;
|
|
use sqlx::{Error, query_as};
|
|
|
|
let pool = get_pool().await?;
|
|
let ct = query_as::<_, ClosingTime>("SELECT * FROM closing_time ORDER BY from_date")
|
|
.fetch_one(&pool)
|
|
.await;
|
|
|
|
Ok(if let Err(ref e) = ct {
|
|
if matches!(e, Error::RowNotFound) {
|
|
None
|
|
} else {
|
|
Some(ct?)
|
|
}
|
|
} else {
|
|
Some(ct?)
|
|
})
|
|
}
|
|
|
|
#[server]
|
|
pub async fn get_closing_times() -> Result<Vec<ClosingTime>, ServerFnError> {
|
|
use crate::backend::get_pool;
|
|
use sqlx::query_as;
|
|
|
|
let pool = get_pool().await?;
|
|
purge_closing_days().await?;
|
|
Ok(query_as::<_, ClosingTime>("SELECT * FROM closing_time ORDER BY from_date").fetch_all(&pool).await?)
|
|
}
|
|
|
|
#[server]
|
|
pub async fn insert_closing_time(time: ClosingTime) -> Result<ApiResponse<()>, ServerFnError> {
|
|
use crate::perm_check;
|
|
use crate::backend::get_pool;
|
|
|
|
perm_check!(is_admin);
|
|
|
|
let pool = get_pool().await?;
|
|
|
|
sqlx::query("INSERT INTO closing_time(from_date, to_date) VALUES($1, $2)")
|
|
.bind(time.from_date)
|
|
.bind(time.to_date)
|
|
.execute(&pool)
|
|
.await?;
|
|
|
|
Ok(ApiResponse::Data(()))
|
|
}
|
|
|
|
impl ForValidation for InsertClosingTime {
|
|
fn entity(&self) -> &dyn Validate {
|
|
&self.time
|
|
}
|
|
}
|
|
|
|
#[server]
|
|
pub async fn delete_closing_time(id: i32) -> Result<ApiResponse<()>, ServerFnError> {
|
|
use crate::perm_check;
|
|
use crate::backend::get_pool;
|
|
|
|
perm_check!(is_admin);
|
|
|
|
let pool = get_pool().await?;
|
|
sqlx::query("DELETE FROM closing_time WHERE id = $1")
|
|
.bind(id)
|
|
.execute(&pool)
|
|
.await?;
|
|
|
|
Ok(ApiResponse::Data(()))
|
|
} |