dodacia adresa

This commit is contained in:
Priec
2026-06-27 14:01:30 +02:00
parent 5001e46866
commit e8d8aafd97
13 changed files with 195 additions and 40 deletions

View File

@@ -35,10 +35,15 @@ struct CheckoutForm {
company_id: Option<String>,
tax_id: Option<String>,
vat_id: Option<String>,
address: String,
city: String,
zip: String,
country: String,
residence_address: String,
residence_city: String,
residence_zip: String,
residence_country: String,
delivery_same_as_residence: Option<String>,
address: Option<String>,
city: Option<String>,
zip: Option<String>,
country: Option<String>,
note: Option<String>,
payment_method: String,
carrier_code: String,
@@ -110,7 +115,7 @@ async fn checkout_page(
let p = |get: fn(&customer_profiles::Model) -> Option<String>| {
profile.as_ref().and_then(get)
};
// Whether the customer already has a shipping address on file. When they do,
// Whether the customer already has a residence address on file. When they do,
// the "save this address to my profile" opt-in is pointless (the profile was
// filled in advance), so it's hidden and the existing profile is left alone.
let profile_filled = profile
@@ -147,10 +152,10 @@ async fn checkout_page(
"prefill_vat_id": p(|x| x.vat_id.clone()),
"prefill_phone_prefix": p(|x| x.phone_prefix.clone()),
"prefill_phone": p(|x| x.phone.clone()),
"prefill_address": p(|x| x.address.clone()),
"prefill_city": p(|x| x.city.clone()),
"prefill_zip": p(|x| x.zip.clone()),
"prefill_country": p(|x| x.country.clone()),
"prefill_residence_address": p(|x| x.address.clone()),
"prefill_residence_city": p(|x| x.city.clone()),
"prefill_residence_zip": p(|x| x.zip.clone()),
"prefill_residence_country": p(|x| x.country.clone()),
"lang": current_lang(&jar),
}),
)
@@ -177,16 +182,37 @@ async fn place_order(
None => number.clone(),
};
// Contact and shipping-address fields are mandatory (also enforced in the
// Contact and residence-address fields are mandatory (also enforced in the
// browser via `required`).
let require = |value: &str, field: &str| -> Result<String> {
trimmed(value).ok_or_else(|| Error::BadRequest(format!("{field} is required")))
};
let require_opt = |value: Option<&str>, field: &str| -> Result<String> {
value
.and_then(trimmed)
.ok_or_else(|| Error::BadRequest(format!("{field} is required")))
};
let customer_name = require(&form.customer_name, "name")?;
let address = require(&form.address, "address")?;
let city = require(&form.city, "city")?;
let zip = require(&form.zip, "zip")?;
let country = require(&form.country, "country")?;
let residence_address = require(&form.residence_address, "residence address")?;
let residence_city = require(&form.residence_city, "residence city")?;
let residence_zip = require(&form.residence_zip, "residence zip")?;
let residence_country = require(&form.residence_country, "residence country")?;
let same_address = form.delivery_same_as_residence.is_some();
let (address, city, zip, country) = if same_address {
(
residence_address.clone(),
residence_city.clone(),
residence_zip.clone(),
residence_country.clone(),
)
} else {
(
require_opt(form.address.as_deref(), "delivery address")?,
require_opt(form.city.as_deref(), "delivery city")?,
require_opt(form.zip.as_deref(), "delivery zip")?,
require_opt(form.country.as_deref(), "delivery country")?,
)
};
// The account type is fixed for a logged-in customer (taken from their
// account, never the form); a guest picks it on the form. Admins are treated
@@ -246,10 +272,10 @@ async fn place_order(
vat_id: vat_id.clone(),
phone_prefix: trimmed(&form.phone_prefix),
phone: Some(number.clone()),
address: Some(address.clone()),
city: Some(city.clone()),
zip: Some(zip.clone()),
country: Some(country.clone()),
address: Some(residence_address.clone()),
city: Some(residence_city.clone()),
zip: Some(residence_zip.clone()),
country: Some(residence_country.clone()),
};
// Resolve the account that will own this order. A logged-in customer always
@@ -318,6 +344,10 @@ async fn place_order(
company_id,
tax_id,
vat_id,
residence_address: Some(residence_address),
residence_city: Some(residence_city),
residence_zip: Some(residence_zip),
residence_country: Some(residence_country),
address: Some(address),
city: Some(city),
zip: Some(zip),

View File

@@ -38,6 +38,10 @@ pub struct Model {
pub tax_id: Option<String>,
pub vat_id: Option<String>,
pub user_id: Option<i32>,
pub residence_address: Option<String>,
pub residence_city: Option<String>,
pub residence_zip: Option<String>,
pub residence_country: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@@ -24,6 +24,10 @@ pub struct Checkout {
pub company_id: Option<String>,
pub tax_id: Option<String>,
pub vat_id: Option<String>,
pub residence_address: Option<String>,
pub residence_city: Option<String>,
pub residence_zip: Option<String>,
pub residence_country: Option<String>,
pub address: Option<String>,
pub city: Option<String>,
pub zip: Option<String>,
@@ -102,6 +106,10 @@ pub async fn place(
company_id: Set(details.company_id),
tax_id: Set(details.tax_id),
vat_id: Set(details.vat_id),
residence_address: Set(details.residence_address),
residence_city: Set(details.residence_city),
residence_zip: Set(details.residence_zip),
residence_country: Set(details.residence_country),
address: Set(details.address),
city: Set(details.city),
zip: Set(details.zip),

View File

@@ -40,6 +40,10 @@ pub fn detail(order: &orders::Model, bank_iban: &str, bank_account_name: &str) -
"subtotal": format_price(order.total_cents - order.shipping_cents),
"shipping": format_price(order.shipping_cents),
"total": format_price(order.total_cents),
"residence_address": order.residence_address,
"residence_city": order.residence_city,
"residence_zip": order.residence_zip,
"residence_country": order.residence_country,
"address": order.address,
"city": order.city,
"zip": order.zip,