diff --git a/migration.sql b/migration.sql index 2cc86d4..2bbf1c9 100644 --- a/migration.sql +++ b/migration.sql @@ -15,7 +15,12 @@ CREATE TABLE IF NOT EXISTS "user" ( "nickname" text, "notes" text, "phone" text, - "address" text + "address" text, + "family_id" INTEGER REFERENCES family(id) +); + +CREATE TABLE IF NOT EXISTS "family" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT ); CREATE TABLE IF NOT EXISTS "role" ( diff --git a/src/model/family.rs b/src/model/family.rs new file mode 100644 index 0000000..89944d1 --- /dev/null +++ b/src/model/family.rs @@ -0,0 +1,55 @@ +use serde::Serialize; +use sqlx::{sqlite::SqliteQueryResult, FromRow, SqlitePool}; + +#[derive(FromRow, Serialize, Clone)] +pub struct Family { + id: i64, +} + +#[derive(Serialize, Clone)] +pub struct FamilyWithMembers { + id: i64, + names: Option, +} + +impl Family { + pub async fn all(db: &SqlitePool) -> Vec { + sqlx::query_as!(Self, "SELECT id FROM role") + .fetch_all(db) + .await + .unwrap() + } + + pub async fn new(db: &SqlitePool) -> i64 { + let result: SqliteQueryResult = sqlx::query("INSERT INTO family DEFAULT VALUES") + .execute(db) + .await + .unwrap(); + + result.last_insert_rowid() + } + + pub async fn all_with_members(db: &SqlitePool) -> Vec { + sqlx::query_as!( + FamilyWithMembers, + " +SELECT + family.id as id, + GROUP_CONCAT(user.name, ', ') as names +FROM family +LEFT JOIN + user ON family.id = user.family_id +GROUP BY family.id;" + ) + .fetch_all(db) + .await + .unwrap() + } + + pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option { + sqlx::query_as!(Self, "SELECT id FROM family WHERE id like ?", id) + .fetch_one(db) + .await + .ok() + } +} diff --git a/src/model/mod.rs b/src/model/mod.rs index 367fb57..44f1df9 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -9,6 +9,7 @@ use self::{ pub mod boat; pub mod boatdamage; +pub mod family; pub mod location; pub mod log; pub mod logbook; diff --git a/src/model/rower.rs b/src/model/rower.rs index 88675dd..796a2ad 100644 --- a/src/model/rower.rs +++ b/src/model/rower.rs @@ -16,7 +16,7 @@ impl Rower { sqlx::query_as!( User, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?) ", diff --git a/src/model/user.rs b/src/model/user.rs index eb7edbd..30f5ebd 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -13,7 +13,7 @@ use rocket::{ use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; -use super::{log::Log, tripdetails::TripDetails, Day}; +use super::{family::Family, log::Log, tripdetails::TripDetails, Day}; use crate::tera::admin::user::UserEditForm; #[derive(FromRow, Debug, Serialize, Deserialize)] @@ -33,6 +33,7 @@ pub struct User { pub notes: Option, pub phone: Option, pub address: Option, + pub family_id: Option, } #[derive(Debug, Serialize, Deserialize)] @@ -161,7 +162,7 @@ impl User { sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id like ? ", @@ -176,7 +177,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id like ? ", @@ -191,7 +192,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE name like ? ", @@ -233,7 +234,7 @@ WHERE name like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 ORDER BY last_access DESC @@ -248,7 +249,7 @@ ORDER BY last_access DESC sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 AND dob != '' and weight != '' and sex != '' ORDER BY name @@ -263,7 +264,7 @@ ORDER BY name sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 AND (SELECT COUNT(*) FROM user_role WHERE user_id=user.id AND role_id = (SELECT id FROM role WHERE name = 'cox')) > 0 ORDER BY last_access DESC @@ -282,8 +283,14 @@ ORDER BY last_access DESC } pub async fn update(&self, db: &SqlitePool, data: UserEditForm) { + let mut family_id = data.family_id; + + if family_id.is_some_and(|x| x == -1) { + family_id = Some(Family::new(db).await) + } + sqlx::query!( - "UPDATE user SET dob = ?, weight = ?, sex = ?, member_since_date=?, birthdate=?, mail=?, nickname=?, notes=?, phone=?, address=? where id = ?", + "UPDATE user SET dob = ?, weight = ?, sex = ?, member_since_date=?, birthdate=?, mail=?, nickname=?, notes=?, phone=?, address=?, family_id = ? where id = ?", data.dob, data.weight, data.sex, @@ -294,6 +301,7 @@ ORDER BY last_access DESC data.notes, data.phone, data.address, + family_id, self.id ) .execute(db) @@ -714,6 +722,7 @@ mod test { notes: None, phone: None, address: None, + family_id: None, }, ) .await; diff --git a/src/tera/admin/user.rs b/src/tera/admin/user.rs index 46a621f..01c6808 100644 --- a/src/tera/admin/user.rs +++ b/src/tera/admin/user.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use crate::model::{ + family::Family, role::Role, user::{AdminUser, User, UserWithRoles}, }; @@ -30,6 +31,7 @@ async fn index( let users: Vec = join_all(user_futures).await; let roles = Role::all(db).await; + let families = Family::all_with_members(db).await; let mut context = Context::new(); if let Some(msg) = flash { @@ -37,6 +39,7 @@ async fn index( } context.insert("users", &users); context.insert("roles", &roles); + context.insert("families", &families); context.insert( "loggedin_user", &UserWithRoles::from_user(admin.user, db).await, @@ -89,6 +92,7 @@ pub struct UserEditForm { pub(crate) notes: Option, pub(crate) phone: Option, pub(crate) address: Option, + pub(crate) family_id: Option, } #[post("/user", data = "")] diff --git a/staging-diff.sql b/staging-diff.sql index e69de29..d93cc72 100644 --- a/staging-diff.sql +++ b/staging-diff.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS "family" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, +); + +ALTER TABLE "user" ADD COLUMN "family_id" INTEGER REFERENCES family(id); diff --git a/templates/admin/user/index.html.tera b/templates/admin/user/index.html.tera index 12795b8..496e5c9 100644 --- a/templates/admin/user/index.html.tera +++ b/templates/admin/user/index.html.tera @@ -72,6 +72,7 @@ {{ macros::input(label='Notizen', name='notes', id=loop.index, type="text", value=user.notes) }} {{ macros::input(label='Telefon', name='phone', id=loop.index, type="text", value=user.phone) }} {{ macros::input(label='Adresse', name='address', id=loop.index, type="text", value=user.address) }} + {{ macros::select(label="Familie", data=families, name='family_id', selected_id=user.family_id, display=['names'], default="Keine Familie", new_last_entry='Neue Familie anlegen') }}
diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index c1adb2d..226d310 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -164,7 +164,7 @@ {% endmacro checkbox %} -{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false) %} +{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false, new_last_entry='') %}
{% if display == '' %} @@ -185,11 +185,13 @@ {%- endfor %} {% endfor %} + {% if new_last_entry %} + + {% endif %}
{% endmacro select %} - {% macro alert(message, type, class='') %}
{{ message }}