diff --git a/lnvps_api/src/api/model.rs b/lnvps_api/src/api/model.rs index e24a600..47f9205 100644 --- a/lnvps_api/src/api/model.rs +++ b/lnvps_api/src/api/model.rs @@ -403,10 +403,26 @@ pub struct VMPatchRequest { #[derive(Serialize, Deserialize, JsonSchema)] pub struct AccountPatchRequest { + #[serde(skip_serializing_if = "Option::is_none")] pub email: Option, pub contact_nip17: bool, pub contact_email: bool, + #[serde(skip_serializing_if = "Option::is_none")] pub country_code: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub address_1: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub address_2: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub city: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub postcode: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub tax_id: Option, } #[derive(Serialize, Deserialize, JsonSchema)] diff --git a/lnvps_api/src/api/routes.rs b/lnvps_api/src/api/routes.rs index 5f3243b..d68e512 100644 --- a/lnvps_api/src/api/routes.rs +++ b/lnvps_api/src/api/routes.rs @@ -133,6 +133,13 @@ async fn v1_patch_account( .as_ref() .and_then(|c| CountryCode::for_alpha3(c).ok()) .map(|c| c.alpha3().to_string()); + user.billing_name = req.name.clone(); + user.billing_address_1 = req.address_1.clone(); + user.billing_address_2 = req.address_2.clone(); + user.billing_city = req.city.clone(); + user.billing_state = req.state.clone(); + user.billing_postcode = req.postcode.clone(); + user.billing_tax_id = req.tax_id.clone(); db.update_user(&user).await?; ApiData::ok(()) @@ -154,6 +161,13 @@ async fn v1_get_account( contact_nip17: user.contact_nip17, contact_email: user.contact_email, country_code: user.country_code, + name: user.billing_name, + address_1: user.billing_address_1, + address_2: user.billing_address_2, + state: user.billing_state, + city: user.billing_city, + postcode: user.billing_postcode, + tax_id: user.billing_tax_id, }) } diff --git a/lnvps_api/src/mocks.rs b/lnvps_api/src/mocks.rs index 846c437..7c27406 100644 --- a/lnvps_api/src/mocks.rs +++ b/lnvps_api/src/mocks.rs @@ -275,10 +275,8 @@ impl LNVpsDb for MockDb { id: max + 1, pubkey: pubkey.to_vec(), created: Utc::now(), - email: None, - contact_nip17: false, - contact_email: false, country_code: Some("USA".to_string()), + ..Default::default() }, ); Ok(max + 1) diff --git a/lnvps_api/src/provisioner/pricing.rs b/lnvps_api/src/provisioner/pricing.rs index 51316d3..e037add 100644 --- a/lnvps_api/src/provisioner/pricing.rs +++ b/lnvps_api/src/provisioner/pricing.rs @@ -394,11 +394,8 @@ mod tests { User { id: 1, pubkey: vec![], - created: Default::default(), - email: None, - contact_nip17: false, - contact_email: false, country_code: Some("USA".to_string()), + ..Default::default() }, ); u.insert( @@ -406,11 +403,8 @@ mod tests { User { id: 2, pubkey: vec![], - created: Default::default(), - email: None, - contact_nip17: false, - contact_email: false, country_code: Some("IRL".to_string()), + ..Default::default() }, ); } diff --git a/lnvps_db/migrations/20250501132143_billing_info.sql b/lnvps_db/migrations/20250501132143_billing_info.sql new file mode 100644 index 0000000..aeb29bf --- /dev/null +++ b/lnvps_db/migrations/20250501132143_billing_info.sql @@ -0,0 +1,9 @@ +-- Add migration script here +alter table users + add column billing_name varchar(200), + add column billing_address_1 varchar(200), + add column billing_address_2 varchar(200), + add column billing_city varchar(100), + add column billing_state varchar(100), + add column billing_postcode varchar(50), + add column billing_tax_id varchar(50); \ No newline at end of file diff --git a/lnvps_db/src/model.rs b/lnvps_db/src/model.rs index 4937943..8187362 100644 --- a/lnvps_db/src/model.rs +++ b/lnvps_db/src/model.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; use std::str::FromStr; use url::Url; -#[derive(FromRow, Clone, Debug)] +#[derive(FromRow, Clone, Debug, Default)] /// Users who buy VM's pub struct User { /// Unique ID of this user (database generated) @@ -23,6 +23,20 @@ pub struct User { pub contact_email: bool, /// Users country pub country_code: Option, + /// Name to show on invoices + pub billing_name: Option, + /// Billing address line 1 + pub billing_address_1: Option, + /// Billing address line 2 + pub billing_address_2: Option, + /// Billing city + pub billing_city: Option, + /// Billing state/county + pub billing_state: Option, + /// Billing postcode/zip + pub billing_postcode: Option, + /// Billing tax id + pub billing_tax_id: Option, } #[derive(FromRow, Clone, Debug, Default)] diff --git a/lnvps_db/src/mysql.rs b/lnvps_db/src/mysql.rs index c15b6b1..e443e13 100644 --- a/lnvps_db/src/mysql.rs +++ b/lnvps_db/src/mysql.rs @@ -60,12 +60,19 @@ impl LNVpsDb for LNVpsDbMysql { async fn update_user(&self, user: &User) -> Result<()> { sqlx::query( - "update users set email=?, contact_nip17=?, contact_email=?, country_code=? where id = ?", + "update users set email=?, contact_nip17=?, contact_email=?, country_code=?, billing_name=?, billing_address_1=?, billing_address_2=?, billing_city=?, billing_state=?, billing_postcode=?, billing_tax_id=? where id = ?", ) .bind(&user.email) .bind(user.contact_nip17) .bind(user.contact_email) .bind(&user.country_code) + .bind(&user.billing_name) + .bind(&user.billing_address_1) + .bind(&user.billing_address_2) + .bind(&user.billing_city) + .bind(&user.billing_state) + .bind(&user.billing_postcode) + .bind(&user.billing_tax_id) .bind(user.id) .execute(&self.db) .await?;