Compare commits
	
		
			3 Commits
		
	
	
		
			c4ca148b54
			...
			7ab6d95e23
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7ab6d95e23 | |||
| f38d506fe4 | |||
| 96dcf2c4ae | 
							
								
								
									
										12
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -10,6 +10,18 @@ pub mod rest; | ||||
|  | ||||
| pub mod scheduled; | ||||
|  | ||||
| pub(crate) const AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD: i64 = 10; | ||||
| pub(crate) const RENNRUDERBEITRAG: i32 = 11000; | ||||
| pub(crate) const BOAT_STORAGE: i32 = 4500; | ||||
| pub(crate) const FAMILY_TWO: i32 = 30000; | ||||
| pub(crate) const FAMILY_THREE_OR_MORE: i32 = 35000; | ||||
| pub(crate) const STUDENT_OR_PUPIL: i32 = 8000; | ||||
| pub(crate) const REGULAR: i32 = 22000; | ||||
| pub(crate) const UNTERSTUETZEND: i32 = 2500; | ||||
| pub(crate) const FOERDERND: i32 = 8500; | ||||
| pub(crate) const SCHECKBUCH: i32 = 3000; | ||||
| pub(crate) const EINSCHREIBGEBUEHR: i32 = 3000; | ||||
|  | ||||
| #[cfg(test)] | ||||
| #[macro_export] | ||||
| macro_rules! testdb { | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| use chrono::NaiveDate; | ||||
| use chrono::{Local, NaiveDate}; | ||||
| use serde::Serialize; | ||||
| use sqlx::SqlitePool; | ||||
| use waterlevel::WaterlevelDay; | ||||
|  | ||||
| use crate::AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD; | ||||
|  | ||||
| use self::{ | ||||
|     event::{Event, EventWithUserAndTriptype}, | ||||
|     trip::{Trip, TripWithUserAndType}, | ||||
| @@ -42,18 +44,23 @@ pub struct Day { | ||||
|     events: Vec<EventWithUserAndTriptype>, | ||||
|     trips: Vec<TripWithUserAndType>, | ||||
|     is_pinned: bool, | ||||
|     regular_sees_this_day: bool, | ||||
|     max_waterlevel: Option<WaterlevelDay>, | ||||
|     weather: Option<Weather>, | ||||
| } | ||||
|  | ||||
| impl Day { | ||||
|     pub async fn new(db: &SqlitePool, day: NaiveDate, is_pinned: bool) -> Self { | ||||
|         let today = Local::now().date_naive(); | ||||
|         let day_diff = (day - today).num_days() + 1; | ||||
|         let regular_sees_this_day = day_diff <= AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD; | ||||
|         if is_pinned { | ||||
|             Self { | ||||
|                 day, | ||||
|                 events: Event::get_pinned_for_day(db, day).await, | ||||
|                 trips: Trip::get_pinned_for_day(db, day).await, | ||||
|                 is_pinned, | ||||
|                 regular_sees_this_day, | ||||
|                 max_waterlevel: Waterlevel::max_waterlevel_for_day(db, day).await, | ||||
|                 weather: Weather::find_by_day(db, day).await, | ||||
|             } | ||||
| @@ -63,6 +70,7 @@ impl Day { | ||||
|                 events: Event::get_for_day(db, day).await, | ||||
|                 trips: Trip::get_for_day(db, day).await, | ||||
|                 is_pinned, | ||||
|                 regular_sees_this_day, | ||||
|                 max_waterlevel: Waterlevel::max_waterlevel_for_day(db, day).await, | ||||
|                 weather: Weather::find_by_day(db, day).await, | ||||
|             } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ use sqlx::SqlitePool; | ||||
|  | ||||
| use super::{ | ||||
|     event::{Event, Registration}, | ||||
|     log::Log, | ||||
|     notification::Notification, | ||||
|     tripdetails::TripDetails, | ||||
|     triptype::TripType, | ||||
| @@ -329,18 +330,16 @@ WHERE day=? | ||||
|             return Err(TripDeleteError::SomebodyAlreadyRegistered); | ||||
|         } | ||||
|  | ||||
|         if !self.is_trip_from_user(user.id) { | ||||
|         if !self.is_trip_from_user(user.id) && !user.has_role(db, "admin").await { | ||||
|             return Err(TripDeleteError::NotYourTrip); | ||||
|         } | ||||
|  | ||||
|         sqlx::query!( | ||||
|             "DELETE FROM trip WHERE cox_id = ? AND id = ?", | ||||
|             user.id, | ||||
|             self.id | ||||
|         ) | ||||
|         .execute(db) | ||||
|         .await | ||||
|         .unwrap(); //TODO: fixme | ||||
|         Log::create(db, format!("{} deleted trip: {:#?}", user.user.name, self)).await; | ||||
|  | ||||
|         sqlx::query!("DELETE FROM trip WHERE id = ?", self.id) | ||||
|             .execute(db) | ||||
|             .await | ||||
|             .unwrap(); //TODO: fixme | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|   | ||||
| @@ -18,18 +18,11 @@ use super::{ | ||||
|     family::Family, log::Log, mail::Mail, notification::Notification, role::Role, stat::Stat, | ||||
|     tripdetails::TripDetails, Day, | ||||
| }; | ||||
| use crate::tera::admin::user::UserEditForm; | ||||
|  | ||||
| const RENNRUDERBEITRAG: i32 = 11000; | ||||
| const BOAT_STORAGE: i32 = 4500; | ||||
| const FAMILY_TWO: i32 = 30000; | ||||
| const FAMILY_THREE_OR_MORE: i32 = 35000; | ||||
| const STUDENT_OR_PUPIL: i32 = 8000; | ||||
| const REGULAR: i32 = 22000; | ||||
| const UNTERSTUETZEND: i32 = 2500; | ||||
| const FOERDERND: i32 = 8500; | ||||
| pub const SCHECKBUCH: i32 = 3000; | ||||
| const EINSCHREIBGEBUEHR: i32 = 3000; | ||||
| use crate::{ | ||||
|     tera::admin::user::UserEditForm, AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD, BOAT_STORAGE, | ||||
|     EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO, FOERDERND, REGULAR, RENNRUDERBEITRAG, | ||||
|     SCHECKBUCH, STUDENT_OR_PUPIL, UNTERSTUETZEND, | ||||
| }; | ||||
|  | ||||
| #[derive(FromRow, Serialize, Deserialize, Clone, Debug, Eq, Hash, PartialEq)] | ||||
| pub struct User { | ||||
| @@ -910,7 +903,7 @@ ORDER BY last_access DESC | ||||
|                 days_left_in_year | ||||
|             } | ||||
|         } else { | ||||
|             10 | ||||
|             AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -20,11 +20,14 @@ use serde::Deserialize; | ||||
| use sqlx::SqlitePool; | ||||
| use tera::Context; | ||||
|  | ||||
| use crate::model::{ | ||||
|     logbook::Logbook, | ||||
|     notification::Notification, | ||||
|     role::Role, | ||||
|     user::{User, UserWithDetails, SCHECKBUCH}, | ||||
| use crate::{ | ||||
|     model::{ | ||||
|         logbook::Logbook, | ||||
|         notification::Notification, | ||||
|         role::Role, | ||||
|         user::{User, UserWithDetails}, | ||||
|     }, | ||||
|     SCHECKBUCH, | ||||
| }; | ||||
|  | ||||
| pub(crate) mod admin; | ||||
|   | ||||
| @@ -8,12 +8,15 @@ use rocket_dyn_templates::Template; | ||||
| use sqlx::SqlitePool; | ||||
| use tera::Context; | ||||
|  | ||||
| use crate::model::{ | ||||
|     log::Log, | ||||
|     tripdetails::TripDetails, | ||||
|     triptype::TripType, | ||||
|     user::{AllowedForPlannedTripsUser, User, UserWithDetails}, | ||||
|     usertrip::{UserTrip, UserTripDeleteError, UserTripError}, | ||||
| use crate::{ | ||||
|     model::{ | ||||
|         log::Log, | ||||
|         tripdetails::TripDetails, | ||||
|         triptype::TripType, | ||||
|         user::{AllowedForPlannedTripsUser, User, UserWithDetails}, | ||||
|         usertrip::{UserTrip, UserTripDeleteError, UserTripError}, | ||||
|     }, | ||||
|     AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD, | ||||
| }; | ||||
|  | ||||
| #[get("/")] | ||||
| @@ -42,6 +45,10 @@ async fn index( | ||||
|         &user.allowed_to_update_always_show_trip(db).await, | ||||
|     ); | ||||
|     context.insert("fee", &user.fee(db).await); | ||||
|     context.insert( | ||||
|         "amount_days_to_show_trips_ahead", | ||||
|         &AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD, | ||||
|     ); | ||||
|     context.insert("loggedin_user", &UserWithDetails::from_user(user, db).await); | ||||
|     context.insert("days", &days); | ||||
|     Template::render("planned", context.into_json()) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| {% macro show_boats() %} | ||||
|     {% for cat, grouped_boats in boats | group_by(attribute="cat") %} | ||||
|         <details> | ||||
|             <summary class="font-bold cursor-pointer text-primary-900 dark:text-white border-t p-3 hover:bg-gray-100 dark:hover:bg-primary-950"> | ||||
|             <summary class="font-bold cursor-pointer text-primary-900 dark:text-white {% if not loop.first %}border-t{% endif %} p-3 hover:bg-gray-100 dark:hover:bg-primary-950"> | ||||
|                 <span>{{ cat }}</span> | ||||
|                 <small class="text-gray-500 dark:text-gray-100">({{ grouped_boats | length }})</small> | ||||
|             </summary> | ||||
|   | ||||
| @@ -20,17 +20,18 @@ function setChoiceByLabel(choicesInstance, label) { | ||||
|         </script> | ||||
|         <div class="bg-white dark:bg-primary-900 rounded-md shadow pb-2 mt-3"> | ||||
|             <h2 class="h2">Heute geplante Ausfahrten</h2> | ||||
|             <div class="grid grid-cols-1 gap-3 mb-3 w-full"> | ||||
|             <div class="grid grid-cols-1 gap-3 w-full"> | ||||
|                 {% for planned_trip in planned_trips | sort(attribute='planned_starting_time') %} | ||||
|                     <div class="pt-2 px-3 border-t text-primary-900 dark:text-white"> | ||||
|                     <div class="pt-2 px-3 {% if not loop.first %}border-t{% endif %} text-primary-900 dark:text-white flex justify-between items-center"> | ||||
|                         <strong class="block"> | ||||
|                             {{ planned_trip.cox_name }} ({{ planned_trip.rower | length + 1 }} Personen) | ||||
|                             <small>{{ planned_trip.planned_starting_time }}</small> | ||||
|                             <button class="btn btn-primary" | ||||
|                                     onclick="choiceObjects['newrower'].removeActiveItems(-1);choiceObjects['newrower'].setChoiceByValue('{{ planned_trip.cox_id }}'); {% for rower in planned_trip.rower %}setChoiceByLabel(choiceObjects['newrower'], '{{ rower.name }}');{% endfor %}window.scrollTo(0,0); "> | ||||
|                 {% set amount_members = planned_trip.rower | length + 1 %} | ||||
|                             {{ planned_trip.cox_name }} ({{ amount_members }} Person{{ amount_members | pluralize(singular="", plural="en") }}) | ||||
|                             <small class="block">{{ planned_trip.planned_starting_time }}</small> | ||||
|                              | ||||
|                         </strong><button class="btn btn-primary ml-3" | ||||
| 					    onclick="choiceObjects['newrower'].removeActiveItems(-2);choiceObjects['newrower'].setChoiceByValue('{{ planned_trip.cox_id }}'); {% for rower in planned_trip.rower %}setChoiceByLabel(choiceObjects['newrower'], '{{ rower.name }}');{% endfor %}window.scrollTo(0,0); "> | ||||
|                                 👥 | ||||
|                             </button> | ||||
|                         </strong> | ||||
|                     </div> | ||||
|                 {% endfor %} | ||||
|             </div> | ||||
| @@ -43,7 +44,7 @@ function setChoiceByLabel(choicesInstance, label) { | ||||
|         <div class="grid grid-cols-1 gap-3 mb-3 w-full"> | ||||
|             {% for _, reservations_for_event in reservations %} | ||||
|                 {% set reservation = reservations_for_event[0] %} | ||||
|                 <div class="pt-2 px-3 border-t text-primary-900 dark:text-white"> | ||||
|                 <div class="pt-2 px-3 {% if not loop.first %}border-t{% endif %} text-primary-900 dark:text-white"> | ||||
|                     <strong class="block"> | ||||
|                         {{ reservation.start_date | date(format="%d.%m.%Y") }} | ||||
|                         {% if reservation.end_date != reservation.start_date %} | ||||
|   | ||||
| @@ -100,7 +100,8 @@ | ||||
|                                          style="order: {{ event.planned_starting_time | replace(from=":", to="") }}"> | ||||
|                                         <div class="flex justify-between items-center"> | ||||
|                                             <div class="mr-1"> | ||||
|                                                 {% if event.max_people == 0 %} | ||||
| 					    {% if event.always_show and not day.regular_sees_this_day %}<span title="Du siehst diese Ausfahrt schon, obwohl sie mehr als {{ amount_days_to_show_trips_ahead }} Tage in der Zukunft liegt. Du Magier!">🔮</span>{% endif -%} | ||||
|                                                 {%- if event.max_people == 0 %} | ||||
|                                                     <strong class="text-[#f43f5e]">⚠ Absage | ||||
|                                                         {{ event.planned_starting_time }} | ||||
|                                                         Uhr | ||||
| @@ -274,6 +275,7 @@ | ||||
|                                      data-coxneeded="false"> | ||||
|                                     <div class="flex justify-between items-center"> | ||||
|                                         <div class="mr-1"> | ||||
| 					    {% if trip.always_show and not day.regular_sees_this_day %}<span title="Du siehst diese Ausfahrt schon, obwohl sie mehr als {{ amount_days_to_show_trips_ahead }} Tage in der Zukunft liegt. Du Magier!">🔮</span>{% endif -%} | ||||
|                                             {% if trip.max_people == 0 %} | ||||
|                                                 <strong class="text-[#f43f5e]">⚠ | ||||
|                                                     {{ trip.planned_starting_time }} | ||||
| @@ -382,13 +384,25 @@ | ||||
|                                         {% if allowed_to_update_always_show_trip %} | ||||
|                                             <div class="bg-gray-100 dark:bg-primary-900 p-3 mt-4 rounded-md"> | ||||
|                                                 <h3 class="text-primary-950 dark:text-white font-bold uppercase tracking-wide mb-2">Admin-Modus</h3> | ||||
| 						{% if not day.regular_sees_this_day %} | ||||
|                                                 <form action="/cox/trip/{{ trip.id }}/toggle-always-show" | ||||
|                                                       method="get" | ||||
|                                                       class="grid gap-3"> | ||||
|                                                     <input value="{% if trip.always_show %}Normal anzeigen{% else %}Immer anzeigen{% endif %}" | ||||
|                                                     {% if not trip.always_show %} | ||||
|                                                         <small>Diese Ausfahrt sehen aktuell nur Steuerleute (und Admins). {{ amount_days_to_show_trips_ahead }} Tage vorher sehen sie dann alle.</small> | ||||
|                                                     {% else %} | ||||
|                                                         <small>Diese Ausfahrt sehen alle Mitglieder.</small> | ||||
|                                                     {% endif %} | ||||
|                                                     <input value="{% if trip.always_show %}Ausfahrt nur Steuerleute (und Admins) anzeigen{% else %}Ausfahrt allen anzeigen{% endif %}" | ||||
|                                                            class="btn btn-primary" | ||||
|                                                            type="submit" /> | ||||
|                                                 </form> | ||||
| 						{% endif %} | ||||
|                                                 <a href="/cox/remove/trip/{{ trip.id }}" | ||||
|                                                    class="inline-block btn btn-alert mt-5 w-full"> | ||||
|                                                     {% include "includes/delete-icon" %} | ||||
|                                                     Termin löschen | ||||
|                                                 </a> | ||||
|                                             </div> | ||||
|                                         {% endif %} | ||||
|                                         {# --- END Admin Form --- #} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user