From 0996a81d52a696de391abe3e3959e1291aabba27 Mon Sep 17 00:00:00 2001 From: Philipp Hofer Date: Thu, 24 Jul 2025 08:52:26 +0200 Subject: [PATCH] families only have to pay einschriebgebuehr once + half price applies --- src/model/user/basic.rs | 30 ++++++++++++++- src/model/user/fee.rs | 83 ++++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/src/model/user/basic.rs b/src/model/user/basic.rs index bceee2d..bf883ca 100644 --- a/src/model/user/basic.rs +++ b/src/model/user/basic.rs @@ -8,7 +8,7 @@ use crate::model::{ notification::Notification, role::Role, }; -use chrono::NaiveDate; +use chrono::{Datelike, Local, NaiveDate}; use rocket::{fs::TempFile, tokio::io::AsyncReadExt}; use sqlx::SqlitePool; @@ -578,4 +578,32 @@ impl User { Ok(()) } + + pub(crate) async fn has_to_pay_einschreibgebuehr_this_year(&self, db: &SqlitePool) -> bool { + if !self.has_role(db, "schnupperant").await { + if let Some(member_since_date) = &self.member_since_date { + if let Ok(member_since_date) = + NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d") + { + if member_since_date.year() == Local::now().year() + && !self.has_role(db, "no-einschreibgebuehr").await + { + return true; + } + } + } + } + false + } + pub(crate) fn has_to_pay_only_half(&self) -> bool { + if let Some(member_since_date) = &self.member_since_date { + if let Ok(member_since_date) = NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d") + { + let halfprice_startdate = + NaiveDate::from_ymd_opt(Local::now().year(), 7, 1).unwrap(); + return member_since_date >= halfprice_startdate; + } + } + false + } } diff --git a/src/model/user/fee.rs b/src/model/user/fee.rs index 6f6914c..b8be012 100644 --- a/src/model/user/fee.rs +++ b/src/model/user/fee.rs @@ -1,10 +1,9 @@ use super::User; use crate::{ - BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO, FOERDERND, - REGULAR, RENNRUDERBEITRAG, SCHECKBUCH, STUDENT_OR_PUPIL, TRIAL_ROWING, TRIAL_ROWING_REDUCED, - UNTERSTUETZEND, model::family::Family, + model::family::Family, BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, + FAMILY_TWO, FOERDERND, REGULAR, RENNRUDERBEITRAG, SCHECKBUCH, STUDENT_OR_PUPIL, TRIAL_ROWING, + TRIAL_ROWING_REDUCED, UNTERSTUETZEND, }; -use chrono::{Datelike, Local, NaiveDate}; use serde::Serialize; use sqlx::SqlitePool; @@ -81,30 +80,52 @@ impl User { let mut fee = Fee::new(); if let Some(family) = Family::find_by_opt_id(db, self.family_id).await { + let mut einschreibgebuehr = false; + let mut half_price = true; for member in family.members(db).await { fee.add_person(&member); if member.has_role(db, "paid").await { fee.paid(); } - fee.merge(member.fee_without_families(db).await); + fee.merge(member.fee_without_families(db, true).await); + if member.has_to_pay_einschreibgebuehr_this_year(db).await { + einschreibgebuehr = true; + } + if !member.has_to_pay_only_half() { + half_price = false; + } } if family.amount_family_members(db).await > 2 { - fee.add("Familie 3+ Personen".into(), FAMILY_THREE_OR_MORE); + if half_price { + fee.add( + "Familie 3+ Personen (Halbpreis)".into(), + FAMILY_THREE_OR_MORE / 2, + ); + } else { + fee.add("Familie 3+ Personen".into(), FAMILY_THREE_OR_MORE); + } } else { - fee.add("Familie 2 Personen".into(), FAMILY_TWO); + if half_price { + fee.add("Familie 2 Personen (Halbpreis)".into(), FAMILY_TWO / 2); + } else { + fee.add("Familie 2 Personen".into(), FAMILY_TWO); + } + } + if einschreibgebuehr { + fee.add("Einschreibgebühr (Familie)".into(), EINSCHREIBGEBUEHR); } } else { fee.add_person(self); if self.has_role(db, "paid").await { fee.paid(); } - fee.merge(self.fee_without_families(db).await); + fee.merge(self.fee_without_families(db, false).await); } Some(fee) } - async fn fee_without_families(&self, db: &SqlitePool) -> Fee { + async fn fee_without_families(&self, db: &SqlitePool, entry_fee_paid_with_family: bool) -> Fee { let mut fee = Fee::new(); if !self.has_role(db, "Donau Linz").await @@ -125,38 +146,24 @@ impl User { let amount_boats = self.amount_boats(db).await; if amount_boats > 0 { - fee.add( - format!("{}x Bootsplatz", amount_boats), - amount_boats * BOAT_STORAGE, - ); - } - - if !self.has_role(db, "schnupperant").await { - if let Some(member_since_date) = &self.member_since_date { - if let Ok(member_since_date) = - NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d") - { - if member_since_date.year() == Local::now().year() - && !self.has_role(db, "no-einschreibgebuehr").await - { - fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR); - } - } + if self.has_to_pay_only_half() { + fee.add( + format!("{}x Bootsplatz (Halbpreis)", amount_boats), + amount_boats * BOAT_STORAGE / 2, + ); + } else { + fee.add( + format!("{}x Bootsplatz", amount_boats), + amount_boats * BOAT_STORAGE, + ); } } - let halfprice = if let Some(member_since_date) = &self.member_since_date { - match NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d") { - Ok(member_since_date) => { - let halfprice_startdate = - NaiveDate::from_ymd_opt(Local::now().year(), 7, 1).unwrap(); - member_since_date >= halfprice_startdate - } - Err(_) => false, - } - } else { - false - }; + if self.has_to_pay_einschreibgebuehr_this_year(db).await && !entry_fee_paid_with_family { + fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR); + } + + let halfprice = self.has_to_pay_only_half(); if self.has_role(db, "schnupperant").await { if self.has_role(db, "Student").await || self.has_role(db, "Schüler").await {