required
Some checks failed
CI / Check Style (push) Has been cancelled
CI / Run Clippy (push) Has been cancelled
CI / Run Tests (push) Has been cancelled

This commit is contained in:
Priec
2026-06-18 21:38:32 +02:00
parent 996358be87
commit 46cc2459bd
7 changed files with 84 additions and 34 deletions

View File

@@ -64,16 +64,49 @@ impl From<ProfileForm> for ProfileFields {
}
}
/// Render the profile form for `profile` (which may be `None` for a customer
/// who hasn't saved anything yet). `saved` shows the success banner after a
/// POST.
/// The profile fields held by a saved profile, for re-prefilling the form.
fn fields_of(profile: Option<&customer_profiles::Model>) -> ProfileFields {
match profile {
Some(p) => ProfileFields {
account_type: p.account_type.clone(),
company_name: p.company_name.clone(),
company_id: p.company_id.clone(),
tax_id: p.tax_id.clone(),
vat_id: p.vat_id.clone(),
phone_prefix: p.phone_prefix.clone(),
phone: p.phone.clone(),
address: p.address.clone(),
city: p.city.clone(),
zip: p.zip.clone(),
country: p.country.clone(),
},
None => ProfileFields {
account_type: "personal".to_string(),
..Default::default()
},
}
}
/// A company profile must carry its invoicing identity (company name + IČO +
/// DIČ; IČ DPH stays optional). Personal profiles have no such requirement.
fn company_fields_missing(fields: &ProfileFields) -> bool {
fields.account_type == "company"
&& (fields.company_name.is_none()
|| fields.company_id.is_none()
|| fields.tax_id.is_none())
}
/// Render the profile form prefilled from `fields`. `saved` shows the success
/// banner; `error` shows a validation message and is set when a company profile
/// is missing required identifiers.
fn profile_view(
v: &TeraView,
jar: &CookieJar,
name: &str,
email: &str,
profile: Option<&customer_profiles::Model>,
fields: &ProfileFields,
saved: bool,
error: bool,
) -> Result<Response> {
format::view(
v,
@@ -82,19 +115,20 @@ fn profile_view(
"logged_in_admin": false,
"logged_in_customer": true,
"saved": saved,
"error": error,
"name": name,
"email": email,
"account_type": profile.map_or("personal", |p| p.account_type.as_str()),
"company_name": profile.and_then(|p| p.company_name.clone()),
"company_id": profile.and_then(|p| p.company_id.clone()),
"tax_id": profile.and_then(|p| p.tax_id.clone()),
"vat_id": profile.and_then(|p| p.vat_id.clone()),
"phone_prefix": profile.and_then(|p| p.phone_prefix.clone()),
"phone": profile.and_then(|p| p.phone.clone()),
"address": profile.and_then(|p| p.address.clone()),
"city": profile.and_then(|p| p.city.clone()),
"zip": profile.and_then(|p| p.zip.clone()),
"country": profile.and_then(|p| p.country.clone()),
"account_type": fields.account_type,
"company_name": fields.company_name,
"company_id": fields.company_id,
"tax_id": fields.tax_id,
"vat_id": fields.vat_id,
"phone_prefix": fields.phone_prefix,
"phone": fields.phone,
"address": fields.address,
"city": fields.city,
"zip": fields.zip,
"country": fields.country,
"lang": current_lang(jar),
}),
)
@@ -113,7 +147,7 @@ async fn profile_page(
return format::redirect("/admin/dashboard");
}
let profile = customer_profiles::Model::find_for_user(&ctx.db, user.id).await?;
profile_view(&v, &jar, &user.name, &user.email, profile.as_ref(), false)
profile_view(&v, &jar, &user.name, &user.email, &fields_of(profile.as_ref()), false, false)
}
#[debug_handler]
@@ -129,8 +163,14 @@ async fn save_profile(
if guard::is_admin(&ctx, &user) {
return format::redirect("/admin/dashboard");
}
let profile = customer_profiles::Model::upsert(&ctx.db, user.id, form.into()).await?;
profile_view(&v, &jar, &user.name, &user.email, Some(&profile), true)
let fields: ProfileFields = form.into();
// A company profile is rejected (and the form re-shown with the entered
// values) until it carries its required identifiers.
if company_fields_missing(&fields) {
return profile_view(&v, &jar, &user.name, &user.email, &fields, false, true);
}
customer_profiles::Model::upsert(&ctx.db, user.id, fields.clone()).await?;
profile_view(&v, &jar, &user.name, &user.email, &fields, true, false)
}
pub fn routes() -> Routes {