Feature: Added Qualifications

This commit is contained in:
Keanu D?lle 2020-09-08 02:57:41 +02:00
parent 6fb8358ec8
commit eeb3cc6a81
13 changed files with 188 additions and 63 deletions

View File

@ -4,7 +4,7 @@ create table qualification_categories
id uuid default uuid_generate_v1() not null
constraint qualification_categories_pk
primary key,
name text,
name text not null,
description text
);

View File

@ -133,8 +133,9 @@
<div class="card bg-light mb-3">
<div class="card-header">Qualifikationen</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
{{#each qualification_categories}}
<b>{{name}}: </b>{{#each qualifications}}<span class="badge badge-secondary">{{name}}</span> {{/each}}<br>
{{/each}}
</div>
</div>
</div>

View File

@ -3,4 +3,5 @@ pub mod connector;
pub mod groups;
pub mod member_licenses;
pub mod members;
pub mod qualifications;
pub mod users;

View File

@ -0,0 +1,77 @@
use crate::database::controller::connector::establish_connection;
use crate::database::model::qualifications::RawQualificationCategory;
use crate::helper::settings::Settings;
use crate::modules::member_management::model::qualifications::{
Qualification, QualificationCategory,
};
use diesel::{ExpressionMethods, JoinOnDsl, QueryDsl, RunQueryDsl};
use rocket::State;
pub fn get_raw_qualification_categories(
settings: &State<Settings>,
) -> Vec<RawQualificationCategory> {
use crate::schema::qualification_categories::dsl::*;
let connection = establish_connection(settings);
let data: Result<Vec<RawQualificationCategory>, diesel::result::Error> =
qualification_categories.load(&connection);
match data {
Ok(data) => data,
Err(e) => {
error!("Couldn't read Qualification categories: {}", e);
vec![]
}
}
}
pub fn get_qualifcation_categories(
settings: &State<Settings>,
member_entity_id: uuid::Uuid,
) -> Vec<QualificationCategory> {
let raw_categories = get_raw_qualification_categories(settings);
let mut categories: Vec<QualificationCategory> = vec![];
for category in raw_categories {
let qualifications =
get_qualifications_for_member_for_category(settings, member_entity_id, category.id);
categories.push(QualificationCategory {
id: category.id,
name: category.name,
description: category.description,
qualifications,
})
}
categories
}
pub fn get_qualifications_for_member_for_category(
settings: &State<Settings>,
member_entity_id: uuid::Uuid,
category_id: uuid::Uuid,
) -> Vec<Qualification> {
use crate::schema::qualifications::dsl::*;
use crate::schema::qualifications_members::dsl::*;
let connection = establish_connection(settings);
let data: Result<Vec<Qualification>, diesel::result::Error> = qualifications
.left_join(qualifications_members.on(qualification_id.eq(id)))
.filter(member_id.eq(member_entity_id))
.filter(category.eq(category_id))
.select((id, name, description))
.load(&connection);
match data {
Ok(data) => data,
Err(e) => {
error!(
"Couldn't read Qualifications for category {} for member {}: {}",
category_id, member_entity_id, e
);
vec![]
}
}
}

View File

@ -3,4 +3,5 @@ pub mod entities;
pub mod groups;
pub mod member_licenses;
pub mod members;
pub mod qualifications;
pub mod users;

View File

@ -0,0 +1,6 @@
#[derive(Serialize, Queryable, Clone)]
pub struct RawQualificationCategory {
pub(crate) id: uuid::Uuid,
pub(crate) name: String,
pub(crate) description: Option<String>,
}

View File

@ -0,0 +1,75 @@
use crate::database::controller::addresses::get_addresses_for_entity_only_one_allowed;
use crate::database::controller::member_licenses::get_member_licenses;
use crate::database::controller::members::get_raw_member_by_uuid;
use crate::database::controller::qualifications::get_qualifcation_categories;
use crate::helper::age_calculator::calculate_age;
use crate::helper::settings::Settings;
use crate::helper::sitebuilder::model::general::{Footer, Header, Stylesheet};
use crate::helper::sitebuilder::model::sidebar::Sidebar;
use crate::modules::member_management::model::member::Member;
use crate::modules::member_management::model::member_module::MemberModuleProfile;
use rocket::http::Status;
use rocket::State;
use rocket_contrib::templates::Template;
use std::str::FromStr;
pub fn handle_view(
settings: &State<Settings>,
id: String,
member: Member,
) -> Result<Template, Status> {
let uuid = match uuid::Uuid::from_str(&id) {
Ok(uuid) => uuid,
Err(e) => {
warn!("Tried to view member with invalid uuid: {}", e);
return Err(Status::NotFound);
}
};
let raw_member = match get_raw_member_by_uuid(uuid, settings) {
Some(member) => member,
None => return Err(Status::NotFound),
};
let header = Header {
html_language: "de".to_string(),
site_title: "Member Profile".to_string(),
stylesheets: vec![Stylesheet {
path: "/css/errms.css".to_string(),
}],
};
let footer = Footer { scripts: vec![] };
let mut sidebar = Sidebar::new(member.clone());
sidebar.member_management.active = true;
let age = match raw_member.date_of_birth {
Some(date) => Some(calculate_age(date)),
None => None,
};
let address = get_addresses_for_entity_only_one_allowed(settings, raw_member.entity_id);
let licenses = get_member_licenses(settings, raw_member.entity_id);
let qualification_categories = get_qualifcation_categories(settings, raw_member.entity_id);
return Ok(Template::render(
"module_member_management_profile",
MemberModuleProfile {
header,
footer,
member: raw_member,
member_age: age,
address,
licenses,
qualification_categories,
readonly: true,
sidebar,
},
));
}
pub fn handle_edit() -> Result<Template, Status> {
return Err(Status::NotImplemented);
}
pub fn handle_delete() -> Result<Template, Status> {
return Err(Status::NotImplemented);
}

View File

@ -1,5 +1,6 @@
pub mod filter_form_from_form_trait;
pub mod licenses_trait;
pub mod member_check_permission;
pub mod member_profile;
pub mod member_trait;
pub mod render;

View File

@ -5,6 +5,9 @@ use crate::helper::sitebuilder::model::sidebar::Sidebar;
use crate::modules::member_management::model::group::Group;
use crate::modules::member_management::model::licenses::MemberLicense;
use crate::modules::member_management::model::member::MemberWithAccess;
use crate::modules::member_management::model::qualifications::{
Qualification, QualificationCategory,
};
use std::collections::HashMap;
#[derive(Serialize)]
@ -24,6 +27,7 @@ pub struct MemberModuleProfile {
pub member_age: Option<i32>,
pub address: Option<Address>,
pub licenses: Vec<MemberLicense>,
pub qualification_categories: Vec<QualificationCategory>,
pub readonly: bool,
pub sidebar: Sidebar,
}

View File

@ -3,3 +3,4 @@ pub mod group;
pub mod licenses;
pub mod member;
pub mod member_module;
pub mod qualifications;

View File

@ -0,0 +1,14 @@
#[derive(Serialize, Deserialize, Queryable, Clone)]
pub struct QualificationCategory {
pub(crate) id: uuid::Uuid,
pub(crate) name: String,
pub(crate) description: Option<String>,
pub(crate) qualifications: Vec<Qualification>,
}
#[derive(Serialize, Deserialize, Queryable, Clone)]
pub struct Qualification {
pub(crate) id: uuid::Uuid,
pub(crate) name: String,
pub(crate) description: Option<String>,
}

View File

@ -6,6 +6,9 @@ use crate::helper::session_cookies::model::SessionCookie;
use crate::helper::settings::Settings;
use crate::helper::sitebuilder::model::general::{Footer, Header, Stylesheet};
use crate::helper::sitebuilder::model::sidebar::Sidebar;
use crate::modules::member_management::controller::member_profile::{
handle_delete, handle_edit, handle_view,
};
use crate::modules::member_management::model::member::Member;
use crate::modules::member_management::model::member_module::MemberModuleProfile;
use rocket::http::Status;
@ -35,62 +38,3 @@ pub fn member_management_core_data_get(
_ => return Err(Status::NotFound),
}
}
pub fn handle_view(
settings: &State<Settings>,
id: String,
member: Member,
) -> Result<Template, Status> {
let uuid = match uuid::Uuid::from_str(&id) {
Ok(uuid) => uuid,
Err(e) => {
warn!("Tried to view member with invalid uuid: {}", e);
return Err(Status::NotFound);
}
};
let raw_member = match get_raw_member_by_uuid(uuid, settings) {
Some(member) => member,
None => return Err(Status::NotFound),
};
let header = Header {
html_language: "de".to_string(),
site_title: "Member Profile".to_string(),
stylesheets: vec![Stylesheet {
path: "/css/errms.css".to_string(),
}],
};
let footer = Footer { scripts: vec![] };
let mut sidebar = Sidebar::new(member.clone());
sidebar.member_management.active = true;
let age = match raw_member.date_of_birth {
Some(date) => Some(calculate_age(date)),
None => None,
};
let address = get_addresses_for_entity_only_one_allowed(settings, raw_member.entity_id);
let licenses = get_member_licenses(settings, raw_member.entity_id);
return Ok(Template::render(
"module_member_management_profile",
MemberModuleProfile {
header,
footer,
member: raw_member,
member_age: age,
address,
licenses,
readonly: true,
sidebar,
},
));
}
pub fn handle_edit() -> Result<Template, Status> {
return Err(Status::NotImplemented);
}
pub fn handle_delete() -> Result<Template, Status> {
return Err(Status::NotImplemented);
}

View File

@ -159,7 +159,7 @@ table! {
qualification_categories (id) {
id -> Uuid,
name -> Nullable<Text>,
name -> Text,
description -> Nullable<Text>,
}
}