Implemented admin overview.
This commit is contained in:
@@ -447,6 +447,22 @@ pub struct Reservation {
|
||||
pub summary: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
|
||||
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
|
||||
pub struct ResPropertyView {
|
||||
pub name: String,
|
||||
pub description: String
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
|
||||
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
|
||||
pub struct ResWithProperty {
|
||||
#[cfg_attr(feature = "ssr", sqlx(flatten))]
|
||||
pub reservation: Reservation,
|
||||
#[cfg_attr(feature = "ssr", sqlx(flatten))]
|
||||
pub property: ResPropertyView
|
||||
}
|
||||
|
||||
pub struct Reservations(Vec<Reservation>);
|
||||
|
||||
// Transform slots to reservations
|
||||
@@ -515,6 +531,13 @@ impl ReservationSum {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
|
||||
pub struct ResSumWithItems {
|
||||
pub summary: ReservationSum,
|
||||
pub customer: Customer,
|
||||
pub reservations: Vec<ResWithProperty>
|
||||
}
|
||||
|
||||
/*
|
||||
pub enum MessageType {
|
||||
NewReservation,
|
||||
|
||||
+116
-3
@@ -1,18 +1,19 @@
|
||||
use leptos::*;
|
||||
use validator::Validate;
|
||||
use crate::backend::data::{ApiResponse, CrReservation, Reservation, PublicFormData};
|
||||
use crate::backend::data::{ApiResponse, CrReservation, Reservation, PublicFormData, ResSumWithItems};
|
||||
use crate::components::data_form::ForValidation;
|
||||
use cfg_if::cfg_if;
|
||||
use chrono::{NaiveDate, NaiveTime};
|
||||
|
||||
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
use sqlx::{Postgres, Transaction};
|
||||
use sqlx::{Postgres, Transaction, query};
|
||||
use sqlx::query_as;
|
||||
use sqlx::Error;
|
||||
use uuid::Uuid;
|
||||
use std::ops::DerefMut;
|
||||
use std::str::FromStr;
|
||||
use crate::backend::data::ReservationSum;
|
||||
use futures_util::future::join_all;
|
||||
use crate::backend::data::{ReservationSum, ReservationState, ResWithProperty, Customer};
|
||||
use crate::backend::get_pool;
|
||||
|
||||
async fn find_sum_by_uuid(uuid: &Uuid, tx: &mut Transaction<'_, Postgres>) -> Result<ReservationSum, Error> {
|
||||
@@ -41,6 +42,70 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
Ok(reservations?)
|
||||
}
|
||||
}
|
||||
|
||||
async fn reservations_in_range(from: &NaiveDate, to: &NaiveDate, state: Option<ReservationState>) -> Result<Vec<ResSumWithItems>, ServerFnError> {
|
||||
let pool = get_pool().await?;
|
||||
let sums = if let Some(s) = state {
|
||||
query_as::<_, ReservationSum>("SELECT * FROM reservation_sum WHERE date >= $1 AND date <= $2 AND state = $3 ORDER BY date")
|
||||
.bind(from)
|
||||
.bind(to)
|
||||
.bind(s)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
} else {
|
||||
query_as::<_, ReservationSum>("SELECT * FROM reservation_sum WHERE date >= $1 AND date <= $2 ORDER BY date")
|
||||
.bind(from)
|
||||
.bind(to)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
};
|
||||
|
||||
let sums = if let Err(ref e) = sums {
|
||||
if matches!(e, Error::RowNotFound) {
|
||||
vec![]
|
||||
} else {
|
||||
sums?
|
||||
}
|
||||
} else {
|
||||
sums?
|
||||
};
|
||||
|
||||
if sums.is_empty() {
|
||||
return Ok(vec![])
|
||||
}
|
||||
|
||||
let res: Result<Vec<ResSumWithItems>, Error> = join_all(sums.into_iter().map(|s| async {
|
||||
let reservations = query_as::<_, ResWithProperty>(
|
||||
"SELECT r.id, r.from, r.to, r.property, r.summary, p.name, p,description \
|
||||
FROM reservation as r \
|
||||
JOIN property as p ON r.property = p.id WHERE r.summary = $1")
|
||||
.bind(s.id())
|
||||
.fetch_all(&pool)
|
||||
.await?;
|
||||
let customer = query_as::<_, Customer>("SELECT * FROM customer WHERE id = $1")
|
||||
.bind(s.customer)
|
||||
.fetch_one(&pool)
|
||||
.await?;
|
||||
Ok(ResSumWithItems {
|
||||
summary: s,
|
||||
customer,
|
||||
reservations
|
||||
})
|
||||
})).await.into_iter().collect();
|
||||
|
||||
Ok(res?)
|
||||
}
|
||||
|
||||
async fn set_state(uuid: Uuid, state: ReservationState) -> Result<(), ServerFnError> {
|
||||
let pool = get_pool().await?;
|
||||
query("UPDATE reservation_sum SET state = $1 WHERE uuid = $2")
|
||||
.bind(state)
|
||||
.bind(uuid)
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}}
|
||||
|
||||
#[server]
|
||||
@@ -148,4 +213,52 @@ impl ForValidation for CreateReservation {
|
||||
fn entity(&self) -> &dyn Validate {
|
||||
&self.reservation
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_new_reservations() -> Result<ApiResponse<Vec<ResSumWithItems>>, ServerFnError> {
|
||||
use crate::perm_check;
|
||||
use chrono::{Days, Local};
|
||||
use crate::backend::data::ReservationState;
|
||||
|
||||
perm_check!(is_logged_in);
|
||||
|
||||
Ok(ApiResponse::Data(reservations_in_range(&Local::now().date_naive(),
|
||||
&Local::now().checked_add_days(Days::new(7)).unwrap().date_naive(),
|
||||
Some(ReservationState::New)).await?))
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_next_reservations() -> Result<ApiResponse<Vec<ResSumWithItems>>, ServerFnError> {
|
||||
use crate::perm_check;
|
||||
use chrono::{Days, Local};
|
||||
use crate::backend::data::ReservationState;
|
||||
|
||||
perm_check!(is_logged_in);
|
||||
|
||||
Ok(ApiResponse::Data(reservations_in_range(&Local::now().date_naive(),
|
||||
&Local::now().checked_add_days(Days::new(7)).unwrap().date_naive(),
|
||||
Some(ReservationState::Approved)).await?))
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn approve(uuid: String) -> Result<ApiResponse<()>, ServerFnError> {
|
||||
use crate::perm_check;
|
||||
use crate::backend::data::ReservationState;
|
||||
|
||||
perm_check!(is_logged_in);
|
||||
set_state(Uuid::parse_str(&uuid)?, ReservationState::Approved).await?;
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn cancel(uuid: String) -> Result<ApiResponse<()>, ServerFnError> {
|
||||
use crate::perm_check;
|
||||
use crate::backend::data::ReservationState;
|
||||
|
||||
perm_check!(is_logged_in);
|
||||
set_state(Uuid::parse_str(&uuid)?, ReservationState::Canceled).await?;
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
}
|
||||
Reference in New Issue
Block a user