add scheckbook functionality, Fixes #184 #235
@ -226,6 +226,38 @@ ORDER BY departure DESC
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn completed_with_user(
|
||||||
|
db: &SqlitePool,
|
||||||
|
user: &User,
|
||||||
|
) -> Vec<LogbookWithBoatAndRowers> {
|
||||||
|
let logs = sqlx::query_as(
|
||||||
|
&format!("
|
||||||
|
SELECT id, boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype
|
||||||
|
FROM logbook
|
||||||
|
JOIN rower ON logbook.id = rower.logbook_id
|
||||||
|
WHERE arrival is not null AND rower_id = {}
|
||||||
|
ORDER BY departure DESC
|
||||||
|
", user.id)
|
||||||
|
)
|
||||||
|
.fetch_all(db)
|
||||||
|
.await
|
||||||
|
.unwrap(); //TODO: fixme
|
||||||
|
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for log in logs {
|
||||||
|
ret.push(LogbookWithBoatAndRowers {
|
||||||
|
rowers: Rower::for_log(db, &log).await,
|
||||||
|
boat: Boat::find_by_id(db, log.boat_id as i32).await.unwrap(),
|
||||||
|
shipmaster_user: User::find_by_id(db, log.shipmaster as i32).await.unwrap(),
|
||||||
|
steering_user: User::find_by_id(db, log.steering_person as i32)
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
logbook: log,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
|
pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
|
||||||
let year = chrono::Utc::now().year();
|
let year = chrono::Utc::now().year();
|
||||||
let logs = sqlx::query_as(
|
let logs = sqlx::query_as(
|
||||||
|
@ -225,28 +225,6 @@ impl User {
|
|||||||
.count
|
.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn rowed_km(&self, db: &SqlitePool) -> i32 {
|
|
||||||
sqlx::query!(
|
|
||||||
"SELECT COALESCE(SUM(distance_in_km),0) as rowed_km
|
|
||||||
FROM (
|
|
||||||
SELECT distance_in_km
|
|
||||||
FROM logbook
|
|
||||||
WHERE shipmaster = ?1
|
|
||||||
UNION
|
|
||||||
SELECT l.distance_in_km
|
|
||||||
FROM logbook l
|
|
||||||
INNER JOIN rower r ON r.logbook_id = l.id
|
|
||||||
WHERE r.rower_id = ?1
|
|
||||||
|
|
||||||
);",
|
|
||||||
self.id,
|
|
||||||
)
|
|
||||||
.fetch_one(db)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.rowed_km
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn has_role(&self, db: &SqlitePool, role: &str) -> bool {
|
pub async fn has_role(&self, db: &SqlitePool, role: &str) -> bool {
|
||||||
if sqlx::query!(
|
if sqlx::query!(
|
||||||
"SELECT * FROM user_role WHERE user_id=? AND role_id = (SELECT id FROM role WHERE name = ?)",
|
"SELECT * FROM user_role WHERE user_id=? AND role_id = (SELECT id FROM role WHERE name = ?)",
|
||||||
|
@ -10,6 +10,7 @@ use tera::Context;
|
|||||||
|
|
||||||
use crate::model::{
|
use crate::model::{
|
||||||
log::Log,
|
log::Log,
|
||||||
|
logbook::Logbook,
|
||||||
tripdetails::TripDetails,
|
tripdetails::TripDetails,
|
||||||
triptype::TripType,
|
triptype::TripType,
|
||||||
user::{AllowedForPlannedTripsUser, User, UserWithRoles},
|
user::{AllowedForPlannedTripsUser, User, UserWithRoles},
|
||||||
@ -31,6 +32,11 @@ async fn index(
|
|||||||
context.insert("trip_types", &triptypes);
|
context.insert("trip_types", &triptypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.has_role(db, "scheckbuch").await {
|
||||||
|
let last_trips = Logbook::completed_with_user(db, &user).await;
|
||||||
|
context.insert("last_trips", &last_trips);
|
||||||
|
}
|
||||||
|
|
||||||
let days = user.get_days(db).await;
|
let days = user.get_days(db).await;
|
||||||
|
|
||||||
if let Some(msg) = flash {
|
if let Some(msg) = flash {
|
||||||
|
@ -1,8 +1,27 @@
|
|||||||
{% import "includes/macros" as macros %}
|
{% import "includes/macros" as macros %}
|
||||||
|
{% import "includes/forms/log" as log %}
|
||||||
{% extends "base" %}
|
{% extends "base" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="max-w-screen-xl w-full grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div class="max-w-screen-xl w-full grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{% if flash %}{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}{% endif %}
|
{% if flash %}{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}{% endif %}
|
||||||
|
{% if "scheckbuch" in loggedin_user.roles %}
|
||||||
|
<div class="grid gap-3 sm:col-span-2 lg:col-span-3">
|
||||||
|
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||||
|
role="alert">
|
||||||
|
<h2 class="h2">Scheckbuch</h2>
|
||||||
|
<div class="text-sm p-3">
|
||||||
|
<h3>Du hast bisher {{ last_trips | length }} deiner 5 Scheckbuch-Ausfahrten gemacht:</h3>
|
||||||
|
<ol>
|
||||||
|
{% for last_trip in last_trips %}
|
||||||
|
<li>
|
||||||
|
{{ log::show_old(log=last_trip, state="completed", only_ones=false, index=1) }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% if "paid" not in loggedin_user.roles and "Donau Linz" in loggedin_user.roles %}
|
{% if "paid" not in loggedin_user.roles and "Donau Linz" in loggedin_user.roles %}
|
||||||
<div class="grid gap-3 sm:col-span-2 lg:col-span-3">
|
<div class="grid gap-3 sm:col-span-2 lg:col-span-3">
|
||||||
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||||
|
Loading…
Reference in New Issue
Block a user