Compare commits
16 Commits
429f0c1ddc
...
main
Author | SHA1 | Date | |
---|---|---|---|
7be9339645 | |||
837d0febdf | |||
51c7cf28f8 | |||
80eca1a3b2 | |||
d1341006f7 | |||
a534568a39 | |||
b4c04cbdd8 | |||
1f0bfb04e4 | |||
86b8d3a30d | |||
da7a303efb | |||
0a31410ca5 | |||
f793cb4a9a | |||
d3b2d78f9f | |||
155adce2e9 | |||
9548cb4f0b | |||
c42713b86e |
@@ -31,7 +31,7 @@ jobs:
|
||||
- Run `cargo upgrade` to update version requirements in Cargo.toml
|
||||
- Run `cargo update` to update Cargo.lock
|
||||
branch: update-cargo-dependencies
|
||||
delete-branch: true
|
||||
delete-branch: false
|
||||
|
||||
- name: Create Pull Request Main
|
||||
uses: https://git.hofer.link/philipp/create-pull-request@18ef1fdad70eec569ab10292c1fa79c1b5296370
|
||||
|
287
LICENSE
Normal file
287
LICENSE
Normal file
@@ -0,0 +1,287 @@
|
||||
EUROPEAN UNION PUBLIC LICENCE v. 1.2
|
||||
EUPL © the European Union 2007, 2016
|
||||
|
||||
This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined
|
||||
below) which is provided under the terms of this Licence. Any use of the Work,
|
||||
other than as authorised under this Licence is prohibited (to the extent such
|
||||
use is covered by a right of the copyright holder of the Work).
|
||||
|
||||
The Work is provided under the terms of this Licence when the Licensor (as
|
||||
defined below) has placed the following notice immediately following the
|
||||
copyright notice for the Work:
|
||||
|
||||
Licensed under the EUPL
|
||||
|
||||
or has expressed by any other means his willingness to license under the EUPL.
|
||||
|
||||
1. Definitions
|
||||
|
||||
In this Licence, the following terms have the following meaning:
|
||||
|
||||
- ‘The Licence’: this Licence.
|
||||
|
||||
- ‘The Original Work’: the work or software distributed or communicated by the
|
||||
Licensor under this Licence, available as Source Code and also as Executable
|
||||
Code as the case may be.
|
||||
|
||||
- ‘Derivative Works’: the works or software that could be created by the
|
||||
Licensee, based upon the Original Work or modifications thereof. This Licence
|
||||
does not define the extent of modification or dependence on the Original Work
|
||||
required in order to classify a work as a Derivative Work; this extent is
|
||||
determined by copyright law applicable in the country mentioned in Article 15.
|
||||
|
||||
- ‘The Work’: the Original Work or its Derivative Works.
|
||||
|
||||
- ‘The Source Code’: the human-readable form of the Work which is the most
|
||||
convenient for people to study and modify.
|
||||
|
||||
- ‘The Executable Code’: any code which has generally been compiled and which is
|
||||
meant to be interpreted by a computer as a program.
|
||||
|
||||
- ‘The Licensor’: the natural or legal person that distributes or communicates
|
||||
the Work under the Licence.
|
||||
|
||||
- ‘Contributor(s)’: any natural or legal person who modifies the Work under the
|
||||
Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||
|
||||
- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of
|
||||
the Work under the terms of the Licence.
|
||||
|
||||
- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending,
|
||||
renting, distributing, communicating, transmitting, or otherwise making
|
||||
available, online or offline, copies of the Work or providing access to its
|
||||
essential functionalities at the disposal of any other natural or legal
|
||||
person.
|
||||
|
||||
2. Scope of the rights granted by the Licence
|
||||
|
||||
The Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
sublicensable licence to do the following, for the duration of copyright vested
|
||||
in the Original Work:
|
||||
|
||||
- use the Work in any circumstance and for all usage,
|
||||
- reproduce the Work,
|
||||
- modify the Work, and make Derivative Works based upon the Work,
|
||||
- communicate to the public, including the right to make available or display
|
||||
the Work or copies thereof to the public and perform publicly, as the case may
|
||||
be, the Work,
|
||||
- distribute the Work or copies thereof,
|
||||
- lend and rent the Work or copies thereof,
|
||||
- sublicense rights in the Work or copies thereof.
|
||||
|
||||
Those rights can be exercised on any media, supports and formats, whether now
|
||||
known or later invented, as far as the applicable law permits so.
|
||||
|
||||
In the countries where moral rights apply, the Licensor waives his right to
|
||||
exercise his moral right to the extent allowed by law in order to make effective
|
||||
the licence of the economic rights here above listed.
|
||||
|
||||
The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to
|
||||
any patents held by the Licensor, to the extent necessary to make use of the
|
||||
rights granted on the Work under this Licence.
|
||||
|
||||
3. Communication of the Source Code
|
||||
|
||||
The Licensor may provide the Work either in its Source Code form, or as
|
||||
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||
provides in addition a machine-readable copy of the Source Code of the Work
|
||||
along with each copy of the Work that the Licensor distributes or indicates, in
|
||||
a notice following the copyright notice attached to the Work, a repository where
|
||||
the Source Code is easily and freely accessible for as long as the Licensor
|
||||
continues to distribute or communicate the Work.
|
||||
|
||||
4. Limitations on copyright
|
||||
|
||||
Nothing in this Licence is intended to deprive the Licensee of the benefits from
|
||||
any exception or limitation to the exclusive rights of the rights owners in the
|
||||
Work, of the exhaustion of those rights or of other applicable limitations
|
||||
thereto.
|
||||
|
||||
5. Obligations of the Licensee
|
||||
|
||||
The grant of the rights mentioned above is subject to some restrictions and
|
||||
obligations imposed on the Licensee. Those obligations are the following:
|
||||
|
||||
Attribution right: The Licensee shall keep intact all copyright, patent or
|
||||
trademarks notices and all notices that refer to the Licence and to the
|
||||
disclaimer of warranties. The Licensee must include a copy of such notices and a
|
||||
copy of the Licence with every copy of the Work he/she distributes or
|
||||
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||
notices stating that the Work has been modified and the date of modification.
|
||||
|
||||
Copyleft clause: If the Licensee distributes or communicates copies of the
|
||||
Original Works or Derivative Works, this Distribution or Communication will be
|
||||
done under the terms of this Licence or of a later version of this Licence
|
||||
unless the Original Work is expressly distributed only under this version of the
|
||||
Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee
|
||||
(becoming Licensor) cannot offer or impose any additional terms or conditions on
|
||||
the Work or Derivative Work that alter or restrict the terms of the Licence.
|
||||
|
||||
Compatibility clause: If the Licensee Distributes or Communicates Derivative
|
||||
Works or copies thereof based upon both the Work and another work licensed under
|
||||
a Compatible Licence, this Distribution or Communication can be done under the
|
||||
terms of this Compatible Licence. For the sake of this clause, ‘Compatible
|
||||
Licence’ refers to the licences listed in the appendix attached to this Licence.
|
||||
Should the Licensee's obligations under the Compatible Licence conflict with
|
||||
his/her obligations under this Licence, the obligations of the Compatible
|
||||
Licence shall prevail.
|
||||
|
||||
Provision of Source Code: When distributing or communicating copies of the Work,
|
||||
the Licensee will provide a machine-readable copy of the Source Code or indicate
|
||||
a repository where this Source will be easily and freely available for as long
|
||||
as the Licensee continues to distribute or communicate the Work.
|
||||
|
||||
Legal Protection: This Licence does not grant permission to use the trade names,
|
||||
trademarks, service marks, or names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the copyright notice.
|
||||
|
||||
6. Chain of Authorship
|
||||
|
||||
The original Licensor warrants that the copyright in the Original Work granted
|
||||
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||
power and authority to grant the Licence.
|
||||
|
||||
Each Contributor warrants that the copyright in the modifications he/she brings
|
||||
to the Work are owned by him/her or licensed to him/her and that he/she has the
|
||||
power and authority to grant the Licence.
|
||||
|
||||
Each time You accept the Licence, the original Licensor and subsequent
|
||||
Contributors grant You a licence to their contributions to the Work, under the
|
||||
terms of this Licence.
|
||||
|
||||
7. Disclaimer of Warranty
|
||||
|
||||
The Work is a work in progress, which is continuously improved by numerous
|
||||
Contributors. It is not a finished work and may therefore contain defects or
|
||||
‘bugs’ inherent to this type of development.
|
||||
|
||||
For the above reason, the Work is provided under the Licence on an ‘as is’ basis
|
||||
and without warranties of any kind concerning the Work, including without
|
||||
limitation merchantability, fitness for a particular purpose, absence of defects
|
||||
or errors, accuracy, non-infringement of intellectual property rights other than
|
||||
copyright as stated in Article 6 of this Licence.
|
||||
|
||||
This disclaimer of warranty is an essential part of the Licence and a condition
|
||||
for the grant of any rights to the Work.
|
||||
|
||||
8. Disclaimer of Liability
|
||||
|
||||
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||
material or moral, damages of any kind, arising out of the Licence or of the use
|
||||
of the Work, including without limitation, damages for loss of goodwill, work
|
||||
stoppage, computer failure or malfunction, loss of data or any commercial
|
||||
damage, even if the Licensor has been advised of the possibility of such damage.
|
||||
However, the Licensor will be liable under statutory product liability laws as
|
||||
far such laws apply to the Work.
|
||||
|
||||
9. Additional agreements
|
||||
|
||||
While distributing the Work, You may choose to conclude an additional agreement,
|
||||
defining obligations or services consistent with this Licence. However, if
|
||||
accepting obligations, You may act only on your own behalf and on your sole
|
||||
responsibility, not on behalf of the original Licensor or any other Contributor,
|
||||
and only if You agree to indemnify, defend, and hold each Contributor harmless
|
||||
for any liability incurred by, or claims asserted against such Contributor by
|
||||
the fact You have accepted any warranty or additional liability.
|
||||
|
||||
10. Acceptance of the Licence
|
||||
|
||||
The provisions of this Licence can be accepted by clicking on an icon ‘I agree’
|
||||
placed under the bottom of a window displaying the text of this Licence or by
|
||||
affirming consent in any other similar way, in accordance with the rules of
|
||||
applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||
acceptance of this Licence and all of its terms and conditions.
|
||||
|
||||
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||
conditions by exercising any rights granted to You by Article 2 of this Licence,
|
||||
such as the use of the Work, the creation by You of a Derivative Work or the
|
||||
Distribution or Communication by You of the Work or copies thereof.
|
||||
|
||||
11. Information to the public
|
||||
|
||||
In case of any Distribution or Communication of the Work by means of electronic
|
||||
communication by You (for example, by offering to download the Work from a
|
||||
remote location) the distribution channel or media (for example, a website) must
|
||||
at least provide to the public the information requested by the applicable law
|
||||
regarding the Licensor, the Licence and the way it may be accessible, concluded,
|
||||
stored and reproduced by the Licensee.
|
||||
|
||||
12. Termination of the Licence
|
||||
|
||||
The Licence and the rights granted hereunder will terminate automatically upon
|
||||
any breach by the Licensee of the terms of the Licence.
|
||||
|
||||
Such a termination will not terminate the licences of any person who has
|
||||
received the Work from the Licensee under the Licence, provided such persons
|
||||
remain in full compliance with the Licence.
|
||||
|
||||
13. Miscellaneous
|
||||
|
||||
Without prejudice of Article 9 above, the Licence represents the complete
|
||||
agreement between the Parties as to the Work.
|
||||
|
||||
If any provision of the Licence is invalid or unenforceable under applicable
|
||||
law, this will not affect the validity or enforceability of the Licence as a
|
||||
whole. Such provision will be construed or reformed so as necessary to make it
|
||||
valid and enforceable.
|
||||
|
||||
The European Commission may publish other linguistic versions or new versions of
|
||||
this Licence or updated versions of the Appendix, so far this is required and
|
||||
reasonable, without reducing the scope of the rights granted by the Licence. New
|
||||
versions of the Licence will be published with a unique version number.
|
||||
|
||||
All linguistic versions of this Licence, approved by the European Commission,
|
||||
have identical value. Parties can take advantage of the linguistic version of
|
||||
their choice.
|
||||
|
||||
14. Jurisdiction
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- any litigation resulting from the interpretation of this License, arising
|
||||
between the European Union institutions, bodies, offices or agencies, as a
|
||||
Licensor, and any Licensee, will be subject to the jurisdiction of the Court
|
||||
of Justice of the European Union, as laid down in article 272 of the Treaty on
|
||||
the Functioning of the European Union,
|
||||
|
||||
- any litigation arising between other parties and resulting from the
|
||||
interpretation of this License, will be subject to the exclusive jurisdiction
|
||||
of the competent court where the Licensor resides or conducts its primary
|
||||
business.
|
||||
|
||||
15. Applicable Law
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- this Licence shall be governed by the law of the European Union Member State
|
||||
where the Licensor has his seat, resides or has his registered office,
|
||||
|
||||
- this licence shall be governed by Belgian law if the Licensor has no seat,
|
||||
residence or registered office inside a European Union Member State.
|
||||
|
||||
Appendix
|
||||
|
||||
‘Compatible Licences’ according to Article 5 EUPL are:
|
||||
|
||||
- GNU General Public License (GPL) v. 2, v. 3
|
||||
- GNU Affero General Public License (AGPL) v. 3
|
||||
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||
- Eclipse Public License (EPL) v. 1.0
|
||||
- CeCILL v. 2.0, v. 2.1
|
||||
- Mozilla Public Licence (MPL) v. 2
|
||||
- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
|
||||
- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for
|
||||
works other than software
|
||||
- European Union Public Licence (EUPL) v. 1.1, v. 1.2
|
||||
- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong
|
||||
Reciprocity (LiLiQ-R+).
|
||||
|
||||
The European Commission may update this Appendix to later versions of the above
|
||||
licences without producing a new version of the EUPL, as long as they provide
|
||||
the rights granted in Article 2 of this Licence and protect the covered Source
|
||||
Code from exclusive appropriation.
|
||||
|
||||
All other changes or additions to this Appendix require the production of a new
|
||||
EUPL version.
|
@@ -1,8 +1,8 @@
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use chrono::NaiveDateTime;
|
||||
use rocket::FromForm;
|
||||
use rocket::serde::{Deserialize, Serialize};
|
||||
use rocket::FromForm;
|
||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||
|
||||
use crate::model::boathouse::Boathouse;
|
||||
|
@@ -1,7 +1,10 @@
|
||||
use rocket::serde::{Deserialize, Serialize};
|
||||
use sqlx::{FromRow, SqlitePool};
|
||||
|
||||
use crate::tera::board::boathouse::FormBoathouseToAdd;
|
||||
use crate::{
|
||||
model::{log::Log, user::AllowedToUpdateBoathouse},
|
||||
tera::board::boathouse::FormBoathouseToAdd,
|
||||
};
|
||||
|
||||
use super::boat::Boat;
|
||||
|
||||
@@ -114,7 +117,11 @@ impl Boathouse {
|
||||
BoathouseAisles::from(db, boathouses).await
|
||||
}
|
||||
|
||||
pub async fn create(db: &SqlitePool, data: FormBoathouseToAdd) -> Result<(), String> {
|
||||
pub async fn create(
|
||||
db: &SqlitePool,
|
||||
changed_by: &AllowedToUpdateBoathouse,
|
||||
data: FormBoathouseToAdd,
|
||||
) -> Result<(), String> {
|
||||
sqlx::query!(
|
||||
"INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)",
|
||||
data.boat_id,
|
||||
@@ -125,6 +132,17 @@ impl Boathouse {
|
||||
.execute(db)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let boat = Boat::find_by_id(db, data.boat_id).await.unwrap();
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
"{changed_by} hat das Boot {boat} auf den Gang {}, Seite {}, und Höhe {} 'gelegt'.",
|
||||
data.aisle, data.side, data.level
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -135,10 +153,20 @@ impl Boathouse {
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub async fn delete(&self, db: &SqlitePool) {
|
||||
pub async fn delete(&self, db: &SqlitePool, changed_by: &AllowedToUpdateBoathouse) {
|
||||
sqlx::query!("DELETE FROM boathouse WHERE id=?", self.id)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a Boat of a valid id
|
||||
|
||||
let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap();
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
"{changed_by} hat das Boot {boat} von Gang {}, Seite {}, und Höhe {} gelöscht.",
|
||||
self.aisle, self.side, self.level
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
use super::Trip;
|
||||
use crate::model::{
|
||||
log::Log,
|
||||
notification::Notification,
|
||||
planned::{tripdetails::TripDetails, triptype::TripType},
|
||||
user::{ErgoUser, SteeringUser, User},
|
||||
@@ -34,6 +35,8 @@ impl Trip {
|
||||
.execute(db)
|
||||
.await;
|
||||
|
||||
Log::create(db, format!("{user} created a new trip: {trip_details}")).await;
|
||||
|
||||
Self::notify_trips_same_datetime(db, trip_details, user).await;
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@ use super::{
|
||||
trip::{Trip, TripWithDetails},
|
||||
triptype::TripType,
|
||||
};
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||
pub struct TripDetails {
|
||||
@@ -22,6 +23,20 @@ pub struct TripDetails {
|
||||
pub is_locked: bool,
|
||||
}
|
||||
|
||||
impl Display for TripDetails {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&format!(
|
||||
"Ausfahrt am {} um {} mit {} Personen",
|
||||
self.day, self.planned_starting_time, self.max_people
|
||||
))?;
|
||||
if let Some(notes) = &self.notes {
|
||||
f.write_str(&format!(" Notizen: {notes}"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromForm, Serialize)]
|
||||
pub struct TripDetailsToAdd<'r> {
|
||||
//TODO: properly parse `planned_starting_time`
|
||||
|
@@ -342,12 +342,33 @@ impl User {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zum normalen Mitglied gemacht (keine Steuerperson/Schiffsführer mehr)"))
|
||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zum normalen Mitglied gemacht (keine Steuerperson/Bootsführer mehr)"))
|
||||
.user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
(old, new) if old == Some(bootsfuehrer.clone()) && new == Some(cox.clone()) => {
|
||||
self.remove_role(db, updated_by, &bootsfuehrer).await?;
|
||||
self.add_role(db, updated_by, &cox).await?;
|
||||
Notification::create_for_role(
|
||||
db,
|
||||
&member,
|
||||
&format!(
|
||||
"Lieber Vorstand, {self} ist ab sofort kein Bootsführer:in mehr, sondern 'nur' mehr eine Steuerperson."
|
||||
),
|
||||
"Bootsführer--",
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat {self} zur Steuerperson gemacht (kein Bootsführer mehr)"
|
||||
))
|
||||
.user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
(old, new) => return Err(format!("Not allowed to change from {old:?} to {new:?}")),
|
||||
};
|
||||
|
||||
@@ -508,6 +529,13 @@ impl User {
|
||||
}
|
||||
|
||||
pub(crate) async fn remove_membership_pdf(&self, db: &SqlitePool, updated_by: &ManageUserUser) {
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Beitrittserklärung vom Beutzer gelöscht."
|
||||
))
|
||||
.user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE user SET membership_pdf = null where id = ?",
|
||||
self.id
|
||||
|
@@ -102,6 +102,13 @@ impl UserWithDetails {
|
||||
user,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allowed_to_row(&self) -> bool {
|
||||
self.roles.contains(&"Donau Linz".into())
|
||||
|| self.roles.contains(&"Förderndes Mitglied".into())
|
||||
|| self.roles.contains(&"scheckbuch".into())
|
||||
|| self.user.name == "Externe Steuerperson"
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -859,6 +866,7 @@ special_user!(AllowedToEditPaymentStatusUser, +"kassier", +"admin");
|
||||
special_user!(ManageUserUser, +"admin", +"schriftfuehrer");
|
||||
special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier");
|
||||
special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin");
|
||||
special_user!(AllowedToUpdateBoathouse, +"admin", +"Vorstand", +"tech");
|
||||
|
||||
#[derive(FromRow, Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct UserWithRolesAndMembershipPdf {
|
||||
|
@@ -7,11 +7,11 @@ use crate::{
|
||||
mail::valid_mails,
|
||||
role::Role,
|
||||
user::{
|
||||
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
||||
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
||||
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
||||
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
||||
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
||||
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
||||
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
||||
},
|
||||
},
|
||||
tera::Config,
|
||||
@@ -19,7 +19,6 @@ use crate::{
|
||||
use chrono::NaiveDate;
|
||||
use futures::future::join_all;
|
||||
use rocket::{
|
||||
FromForm, Request, Route, State,
|
||||
form::Form,
|
||||
fs::TempFile,
|
||||
get,
|
||||
@@ -27,9 +26,9 @@ use rocket::{
|
||||
post,
|
||||
request::{FlashMessage, FromRequest, Outcome},
|
||||
response::{Flash, Redirect},
|
||||
routes,
|
||||
routes, FromForm, Request, Route, State,
|
||||
};
|
||||
use rocket_dyn_templates::{Template, tera::Context};
|
||||
use rocket_dyn_templates::{tera::Context, Template};
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
// Custom request guard to extract the Referer header
|
||||
@@ -357,7 +356,7 @@ async fn add_note(
|
||||
match user.add_note(db, &admin, &data.note).await {
|
||||
Ok(_) => Flash::success(
|
||||
Redirect::to(format!("/admin/user/{}", user.id)),
|
||||
"Notiz hinzugefügt",
|
||||
"Notiz hinzugefügt. Du findest sie ab sofort unter 'Aktivitäten'.",
|
||||
),
|
||||
Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", user.id)), e),
|
||||
}
|
||||
|
@@ -1,17 +1,16 @@
|
||||
use crate::model::{
|
||||
boat::Boat,
|
||||
boathouse::Boathouse,
|
||||
user::{AdminUser, UserWithDetails, VorstandUser},
|
||||
user::{AllowedToUpdateBoathouse, UserWithDetails, VorstandUser},
|
||||
};
|
||||
use rocket::{
|
||||
FromForm, Route, State,
|
||||
form::Form,
|
||||
get, post,
|
||||
request::FlashMessage,
|
||||
response::{Flash, Redirect},
|
||||
routes,
|
||||
routes, FromForm, Route, State,
|
||||
};
|
||||
use rocket_dyn_templates::{Template, tera::Context};
|
||||
use rocket_dyn_templates::{tera::Context, Template};
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
#[get("/boathouse")]
|
||||
@@ -38,6 +37,11 @@ async fn index(
|
||||
let boathouse = Boathouse::get(db).await;
|
||||
context.insert("boathouse", &boathouse);
|
||||
|
||||
let allowed_to_edit = AllowedToUpdateBoathouse::new(db, &admin.user)
|
||||
.await
|
||||
.is_some();
|
||||
context.insert("allowed_to_edit", &allowed_to_edit);
|
||||
|
||||
context.insert(
|
||||
"loggedin_user",
|
||||
&UserWithDetails::from_user(admin.into_inner(), db).await,
|
||||
@@ -57,36 +61,29 @@ pub struct FormBoathouseToAdd {
|
||||
async fn new<'r>(
|
||||
db: &State<SqlitePool>,
|
||||
data: Form<FormBoathouseToAdd>,
|
||||
_admin: AdminUser,
|
||||
user: AllowedToUpdateBoathouse,
|
||||
) -> Flash<Redirect> {
|
||||
match Boathouse::create(db, data.into_inner()).await {
|
||||
match Boathouse::create(db, &user, data.into_inner()).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"),
|
||||
Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/boathouse/<boathouse_id>/delete")]
|
||||
async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boathouse_id: i32) -> Flash<Redirect> {
|
||||
async fn delete(
|
||||
db: &State<SqlitePool>,
|
||||
user: AllowedToUpdateBoathouse,
|
||||
boathouse_id: i32,
|
||||
) -> Flash<Redirect> {
|
||||
let boat = Boathouse::find_by_id(db, boathouse_id).await;
|
||||
match boat {
|
||||
Some(boat) => {
|
||||
boat.delete(db).await;
|
||||
boat.delete(db, &user).await;
|
||||
Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
|
||||
}
|
||||
None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"),
|
||||
}
|
||||
}
|
||||
//#[post("/boat/new", data = "<data>")]
|
||||
//async fn create(
|
||||
// db: &State<SqlitePool>,
|
||||
// data: Form<BoatToAdd<'_>>,
|
||||
// _admin: AdminUser,
|
||||
//) -> Flash<Redirect> {
|
||||
// match Boat::create(db, data.into_inner()).await {
|
||||
// Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"),
|
||||
// Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
|
||||
// }
|
||||
//}
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
routes![index, new, delete]
|
||||
|
117
src/tera/log.rs
117
src/tera/log.rs
@@ -47,12 +47,44 @@ impl<'r> FromRequest<'r> for KioskCookie {
|
||||
}
|
||||
|
||||
#[get("/", rank = 2)]
|
||||
async fn index(
|
||||
async fn index_loggedin(
|
||||
db: &State<SqlitePool>,
|
||||
flash: Option<FlashMessage<'_>>,
|
||||
user: DonauLinzUser,
|
||||
) -> Template {
|
||||
let mut context = Context::new();
|
||||
|
||||
let boats = Boat::for_user(db, &user).await;
|
||||
context.insert("boats", &boats);
|
||||
|
||||
context.insert(
|
||||
"loggedin_user",
|
||||
&UserWithDetails::from_user(user.into_inner(), db).await,
|
||||
);
|
||||
|
||||
index(db, flash, context).await
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn index_kiosk(
|
||||
db: &State<SqlitePool>,
|
||||
flash: Option<FlashMessage<'_>>,
|
||||
_kiosk: KioskCookie,
|
||||
) -> Template {
|
||||
let mut context = Context::new();
|
||||
|
||||
let boats = Boat::all(db).await;
|
||||
context.insert("boats", &boats);
|
||||
|
||||
context.insert("show_kiosk_header", &true);
|
||||
|
||||
index(db, flash, context).await
|
||||
}
|
||||
|
||||
async fn index(db: &SqlitePool, flash: Option<FlashMessage<'_>>, mut context: Context) -> Template {
|
||||
if let Some(msg) = flash {
|
||||
context.insert("flash", &msg.into_inner());
|
||||
}
|
||||
|
||||
let mut coxes: Vec<UserWithDetails> = futures::future::join_all(
|
||||
User::cox(db)
|
||||
@@ -61,9 +93,7 @@ async fn index(
|
||||
.map(|user| UserWithDetails::from_user(user, db)),
|
||||
)
|
||||
.await;
|
||||
coxes.retain(|u| {
|
||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
||||
});
|
||||
coxes.retain(|u| u.roles.contains(&"Donau Linz".into()));
|
||||
|
||||
let mut users: Vec<UserWithDetails> = futures::future::join_all(
|
||||
User::all(db)
|
||||
@@ -72,23 +102,13 @@ async fn index(
|
||||
.map(|user| UserWithDetails::from_user(user, db)),
|
||||
)
|
||||
.await;
|
||||
users.retain(|u| {
|
||||
u.roles.contains(&"Donau Linz".into())
|
||||
|| u.roles.contains(&"scheckbuch".into())
|
||||
|| u.user.name == "Externe Steuerperson"
|
||||
});
|
||||
users.retain(|u| u.allowed_to_row());
|
||||
|
||||
let logtypes = LogType::all(db).await;
|
||||
let distances = Distance::all(db).await;
|
||||
|
||||
let on_water = Logbook::on_water(db).await;
|
||||
|
||||
let mut context = Context::new();
|
||||
if let Some(msg) = flash {
|
||||
context.insert("flash", &msg.into_inner());
|
||||
}
|
||||
|
||||
context.insert("boats", &boats);
|
||||
context.insert("planned_trips", &Trip::get_for_today(db).await);
|
||||
context.insert(
|
||||
"reservations",
|
||||
@@ -97,14 +117,10 @@ async fn index(
|
||||
context.insert("coxes", &coxes);
|
||||
context.insert("users", &users);
|
||||
context.insert("logtypes", &logtypes);
|
||||
context.insert(
|
||||
"loggedin_user",
|
||||
&UserWithDetails::from_user(user.into_inner(), db).await,
|
||||
);
|
||||
context.insert("on_water", &on_water);
|
||||
context.insert("distances", &distances);
|
||||
|
||||
Template::render("log", context.into_json())
|
||||
Template::render("kiosk", context.into_json())
|
||||
}
|
||||
|
||||
#[get("/show", rank = 3)]
|
||||
@@ -179,63 +195,6 @@ async fn new_kiosk(
|
||||
Redirect::to("/log")
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn kiosk(
|
||||
db: &State<SqlitePool>,
|
||||
flash: Option<FlashMessage<'_>>,
|
||||
_kiosk: KioskCookie,
|
||||
) -> Template {
|
||||
let boats = Boat::all(db).await;
|
||||
let mut coxes: Vec<UserWithDetails> = futures::future::join_all(
|
||||
User::cox(db)
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|user| UserWithDetails::from_user(user, db)),
|
||||
)
|
||||
.await;
|
||||
|
||||
coxes.retain(|u| {
|
||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
||||
});
|
||||
|
||||
let mut users: Vec<UserWithDetails> = futures::future::join_all(
|
||||
User::all(db)
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|user| UserWithDetails::from_user(user, db)),
|
||||
)
|
||||
.await;
|
||||
|
||||
users.retain(|u| {
|
||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
||||
});
|
||||
|
||||
let logtypes = LogType::all(db).await;
|
||||
let distances = Distance::all(db).await;
|
||||
|
||||
let on_water = Logbook::on_water(db).await;
|
||||
|
||||
let mut context = Context::new();
|
||||
if let Some(msg) = flash {
|
||||
context.insert("flash", &msg.into_inner());
|
||||
}
|
||||
|
||||
context.insert("planned_trips", &Trip::get_for_today(db).await);
|
||||
context.insert("boats", &boats);
|
||||
context.insert(
|
||||
"reservations",
|
||||
&BoatReservation::all_future_with_groups(db).await,
|
||||
);
|
||||
context.insert("coxes", &coxes);
|
||||
context.insert("users", &users);
|
||||
context.insert("logtypes", &logtypes);
|
||||
context.insert("on_water", &on_water);
|
||||
context.insert("distances", &distances);
|
||||
context.insert("show_kiosk_header", &true);
|
||||
|
||||
Template::render("kiosk", context.into_json())
|
||||
}
|
||||
|
||||
async fn create_logbook(
|
||||
db: &SqlitePool,
|
||||
data: Form<LogToAdd>,
|
||||
@@ -568,11 +527,11 @@ async fn delete_kiosk(
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
routes![
|
||||
index,
|
||||
index_loggedin,
|
||||
index_kiosk,
|
||||
create,
|
||||
create_kiosk,
|
||||
home,
|
||||
kiosk,
|
||||
home_kiosk,
|
||||
new_kiosk,
|
||||
show,
|
||||
|
@@ -7,12 +7,12 @@
|
||||
{% set place = boathouse[aisle_name][side_name].boats %}
|
||||
{% if place[level] %}
|
||||
{{ place[level].boat.name }}
|
||||
{% if "admin" in loggedin_user.roles %}
|
||||
{% if allowed_to_edit %}
|
||||
<a class="btn btn-primary absolute end-0"
|
||||
href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a>
|
||||
{% endif %}
|
||||
{% elif boats | length > 0 %}
|
||||
{% if "admin" in loggedin_user.roles %}
|
||||
{% if allowed_to_edit %}
|
||||
<details>
|
||||
<summary>Kein Boot</summary>
|
||||
<form action="/board/boathouse" method="post" class="grid gap-3">
|
||||
|
Reference in New Issue
Block a user