176 lines
5.5 KiB
Rust
176 lines
5.5 KiB
Rust
use super::User;
|
|
use crate::{
|
|
model::family::Family, BOAT_STORAGE, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO,
|
|
FOERDERND, REGULAR, RENNRUDERBEITRAG, STUDENT_OR_PUPIL, UNTERSTUETZEND,
|
|
};
|
|
use chrono::{Datelike, Local, NaiveDate};
|
|
use serde::Serialize;
|
|
use sqlx::SqlitePool;
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Fee {
|
|
pub sum_in_cents: i64,
|
|
pub parts: Vec<(String, i64)>,
|
|
pub name: String,
|
|
pub user_ids: String,
|
|
pub paid: bool,
|
|
pub users: Vec<User>,
|
|
}
|
|
|
|
impl Default for Fee {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Fee {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
sum_in_cents: 0,
|
|
name: "".into(),
|
|
parts: Vec::new(),
|
|
user_ids: "".into(),
|
|
users: Vec::new(),
|
|
paid: false,
|
|
}
|
|
}
|
|
|
|
pub fn add(&mut self, desc: String, price_in_cents: i64) {
|
|
self.sum_in_cents += price_in_cents;
|
|
|
|
self.parts.push((desc, price_in_cents));
|
|
}
|
|
|
|
pub fn add_person(&mut self, user: &User) {
|
|
if !self.name.is_empty() {
|
|
self.name.push_str(" + ");
|
|
self.user_ids.push('&');
|
|
}
|
|
self.name.push_str(&user.name);
|
|
|
|
self.user_ids.push_str(&format!("user_ids[]={}", user.id));
|
|
self.users.push(user.clone());
|
|
}
|
|
|
|
pub fn paid(&mut self) {
|
|
self.paid = true;
|
|
}
|
|
|
|
pub fn merge(&mut self, fee: Fee) {
|
|
for (desc, price_in_cents) in fee.parts {
|
|
self.add(desc, price_in_cents);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl User {
|
|
pub async fn fee(&self, db: &SqlitePool) -> Option<Fee> {
|
|
if !self.has_role(db, "Donau Linz").await
|
|
&& !self.has_role(db, "Unterstützend").await
|
|
&& !self.has_role(db, "Förderndes Mitglied").await
|
|
{
|
|
return None;
|
|
}
|
|
if self.deleted {
|
|
return None;
|
|
}
|
|
|
|
let mut fee = Fee::new();
|
|
|
|
if let Some(family) = Family::find_by_opt_id(db, self.family_id).await {
|
|
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);
|
|
}
|
|
if family.amount_family_members(db).await > 2 {
|
|
fee.add("Familie 3+ Personen".into(), FAMILY_THREE_OR_MORE);
|
|
} else {
|
|
fee.add("Familie 2 Personen".into(), FAMILY_TWO);
|
|
}
|
|
} else {
|
|
fee.add_person(self);
|
|
if self.has_role(db, "paid").await {
|
|
fee.paid();
|
|
}
|
|
fee.merge(self.fee_without_families(db).await);
|
|
}
|
|
|
|
Some(fee)
|
|
}
|
|
|
|
async fn fee_without_families(&self, db: &SqlitePool) -> Fee {
|
|
let mut fee = Fee::new();
|
|
|
|
if !self.has_role(db, "Donau Linz").await
|
|
&& !self.has_role(db, "Unterstützend").await
|
|
&& !self.has_role(db, "Förderndes Mitglied").await
|
|
{
|
|
return fee;
|
|
}
|
|
if self.has_role(db, "Rennrudern").await {
|
|
if self.has_role(db, "half-rennrudern").await {
|
|
fee.add("Rennruderbeitrag (1/2 Preis) ".into(), RENNRUDERBEITRAG / 2);
|
|
} else if !self.has_role(db, "renntrainer").await {
|
|
fee.add("Rennruderbeitrag".into(), RENNRUDERBEITRAG);
|
|
}
|
|
}
|
|
|
|
let amount_boats = self.amount_boats(db).await;
|
|
if amount_boats > 0 {
|
|
fee.add(
|
|
format!("{}x Bootsplatz", amount_boats),
|
|
amount_boats * BOAT_STORAGE,
|
|
);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
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_role(db, "Unterstützend").await {
|
|
fee.add("Unterstützendes Mitglied".into(), UNTERSTUETZEND);
|
|
} else if self.has_role(db, "Förderndes Mitglied").await {
|
|
fee.add("Förderndes Mitglied".into(), FOERDERND);
|
|
} else if Family::find_by_opt_id(db, self.family_id).await.is_none() {
|
|
if self.has_role(db, "Student").await || self.has_role(db, "Schüler").await {
|
|
if halfprice {
|
|
fee.add("Schüler/Student (Halbpreis)".into(), STUDENT_OR_PUPIL / 2);
|
|
} else {
|
|
fee.add("Schüler/Student".into(), STUDENT_OR_PUPIL);
|
|
}
|
|
} else if self.has_role(db, "Ehrenmitglied").await {
|
|
fee.add("Ehrenmitglied".into(), 0);
|
|
} else if halfprice {
|
|
fee.add("Mitgliedsbeitrag (Halbpreis)".into(), REGULAR / 2);
|
|
} else {
|
|
fee.add("Mitgliedsbeitrag".into(), REGULAR);
|
|
}
|
|
}
|
|
|
|
fee
|
|
}
|
|
}
|