From a7a0a46fb1c4d20b27a39bea79f1469891f2f9d7 Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 09:33:48 +0000 Subject: [PATCH 1/8] fix: changed unwrap to standard error handling in post attachment --- src/entities/invoice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entities/invoice.rs b/src/entities/invoice.rs index c65f58b..6b851ba 100644 --- a/src/entities/invoice.rs +++ b/src/entities/invoice.rs @@ -249,5 +249,5 @@ pub async fn post_attachment( info!("Failed to upload attachment. Status: {}", response.status()); } - Ok(response.json::().await.unwrap()) + Ok(response.json::().await?) } From dcb81213602706de5b749a90f5d2ef2a37d05cd8 Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 09:36:03 +0000 Subject: [PATCH 2/8] fix: changed line item behaviour to provide wider support across other endpoints. --- src/entities/line_item.rs | 69 ++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/src/entities/line_item.rs b/src/entities/line_item.rs index 41c53b2..7438d0a 100644 --- a/src/entities/line_item.rs +++ b/src/entities/line_item.rs @@ -5,6 +5,8 @@ use uuid::Uuid; #[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub enum LineAmountType { + #[serde(alias = "NONE")] + None, #[serde(alias = "EXCLUSIVE")] Exclusive, #[serde(alias = "INCLUSIVE")] @@ -13,32 +15,62 @@ pub enum LineAmountType { NoTax, } +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ItemSummary { + #[serde(rename = "ItemID")] + pub item_id: Uuid, + pub name: String, + pub code: String, +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct TrackingSummary { + pub name: String, + pub option: String, + #[serde(rename = "TrackingCategoryID")] + pub tracking_category_id: Uuid, + #[serde(rename = "TrackingOptionID")] + pub tracking_option_id: Option, +} + #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LineItem { + #[serde(rename = "LineItemID")] + pub line_item_id: Uuid, pub description: String, - pub quantity: Decimal, - pub unit_amount: Decimal, + pub quantity: Option, + pub unit_amount: Option, pub item_code: Option, pub account_code: Option, - #[serde(rename = "LineItemID")] - pub line_item_id: Uuid, - pub tax_type: String, + #[serde(rename = "AccountID")] + pub account_id: Option, + pub item: Option, + pub tracking: Vec, + pub tax_type: Option, pub tax_amount: Decimal, - pub line_amount: Decimal, + pub line_amount: Option, pub discount_rate: Option, - // tracking + pub discount_amount: Option } impl LineItem { #[must_use] pub fn into_builder(self) -> Builder { - let mut builder = Builder::new(self.description, self.quantity, self.unit_amount); + let mut builder = Builder::new(); + builder.description = Some(self.description); + builder.quantity = self.quantity; + builder.unit_amount = self.unit_amount; builder.item_code = self.item_code; builder.account_code = self.account_code; + builder.line_item_id = Some(self.line_item_id); builder.tax_type = self.tax_type; + builder.line_amount = self.line_amount; builder.discount_rate = self.discount_rate; - builder.line_item_id = Some(self.line_item_id); + builder.discount_amount = self.discount_amount; + builder.tracking = Some(self.tracking); builder } @@ -47,25 +79,24 @@ impl LineItem { #[derive(Default, Debug, Serialize, Clone)] #[serde(rename_all = "PascalCase")] pub struct Builder { - pub description: String, - pub quantity: Decimal, - pub unit_amount: Decimal, + pub description: Option, + pub quantity: Option, + pub unit_amount: Option, pub item_code: Option, pub account_code: Option, - pub tax_type: String, - pub discount_rate: Option, - // tracking #[serde(rename = "LineItemID")] pub line_item_id: Option, + pub tax_type: Option, + pub line_amount: Option, + pub discount_rate: Option, + pub discount_amount: Option, + pub tracking: Option>, } impl Builder { #[must_use] - pub fn new(description: String, quantity: Decimal, unit_amount: Decimal) -> Self { + pub fn new() -> Self { Builder { - description, - quantity, - unit_amount, ..Self::default() } } From 818277eb35931794d26ab0af0465d3586abb7d48 Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:04:37 +0000 Subject: [PATCH 3/8] fix: aligned test invoice.rs to use ListParameters --- tests/invoice.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/invoice.rs b/tests/invoice.rs index 2bbc14d..bf117a9 100644 --- a/tests/invoice.rs +++ b/tests/invoice.rs @@ -2,6 +2,7 @@ extern crate tracing; use anyhow::Result; +use xero_rs::invoice::ListParameters; use xero_rs::KeyPair; #[tokio::test] @@ -12,7 +13,7 @@ async fn get_invoices() -> Result<()> { .init(); let client = xero_rs::Client::from_client_credentials(KeyPair::from_env(), None).await?; - let invoices = xero_rs::invoice::list(&client, vec![]).await?; + let invoices = xero_rs::invoice::list(&client, ListParameters::default()).await?; debug!("found {:?} invoices", invoices.len()); let invoice_from_list = invoices.first().unwrap(); From f25203058b62873b0f339088e9172f832c6a45c1 Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:07:28 +0000 Subject: [PATCH 4/8] fix: aligned test purchase_order.rs to use new builder for line_items --- tests/purchase_order.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/purchase_order.rs b/tests/purchase_order.rs index b5fde45..be3bec6 100644 --- a/tests/purchase_order.rs +++ b/tests/purchase_order.rs @@ -32,7 +32,7 @@ async fn get_purchase_orders() -> Result<()> { let purchase_order_from_list = purchase_orders.first().unwrap(); let purchase_order = - xero_rs::purchase_order::get(&client, purchase_order_from_list.purchase_order_id).await?; + purchase_order::get(&client, purchase_order_from_list.purchase_order_id).await?; assert_eq!( purchase_order_from_list.purchase_order_id, purchase_order.purchase_order_id @@ -55,17 +55,19 @@ async fn create_purchase_order() -> Result<()> { let description = "test description"; let quantity = dec!(3.00); let unit_amount = dec!(2.00); - let line_items: Vec = vec![line_item::Builder::new( - description.to_string(), - quantity, - unit_amount, - )]; + let mut line_item = line_item::Builder::new(); + + line_item.description = Some(description.into()); + line_item.quantity = Some(quantity.into()); + line_item.unit_amount = Some(unit_amount.into()); + + let line_items = vec![line_item]; let po_builder = purchase_order::Builder::new(ContactIdentifier::ID(contact.contact_id), line_items); let created_po = purchase_order::create(&client, &po_builder).await?; - let po = xero_rs::purchase_order::get(&client, created_po.purchase_order_id).await?; + let po = purchase_order::get(&client, created_po.purchase_order_id).await?; assert_eq!(created_po.purchase_order_id, po.purchase_order_id); Ok(()) From 7b8abd7291827c2e64fd4d879b7919f840af167f Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:09:09 +0000 Subject: [PATCH 5/8] fix: Changed title to Optional field --- src/entities/quote.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entities/quote.rs b/src/entities/quote.rs index f96ff63..fe53fa1 100644 --- a/src/entities/quote.rs +++ b/src/entities/quote.rs @@ -47,7 +47,7 @@ pub struct Quote { pub quote_number: String, pub reference: Option, pub branding_theme_id: Option, - pub title: String, + pub title: Option, pub summary: Option, pub terms: Option, } From e8501df1c1fa2b94d201053f727341a00f151732 Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:11:53 +0000 Subject: [PATCH 6/8] fix: examples use ListParameters on invoices --- examples/accounting.rs | 3 ++- examples/code_flow_authorization.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/accounting.rs b/examples/accounting.rs index 8c77d8b..a19f28b 100644 --- a/examples/accounting.rs +++ b/examples/accounting.rs @@ -3,6 +3,7 @@ extern crate tracing; use anyhow::Result; use xero_rs::KeyPair; +use xero_rs::invoice::ListParameters; #[tokio::main] async fn main() -> Result<()> { @@ -14,7 +15,7 @@ async fn main() -> Result<()> { let connections = xero_rs::connection::list(&client).await?; info!("found client connections: {:#?}", connections); - let invoices = xero_rs::invoice::list(&client).await?; + let invoices = xero_rs::invoice::list(&client, ListParameters::default()).await?; info!("found invoices: {:#?}", invoices); Ok(()) diff --git a/examples/code_flow_authorization.rs b/examples/code_flow_authorization.rs index d448026..ee03ba5 100644 --- a/examples/code_flow_authorization.rs +++ b/examples/code_flow_authorization.rs @@ -9,6 +9,7 @@ use serde::Deserialize; use tokio::sync::Mutex; use url::Url; use warp::Filter; +use xero_rs::invoice::ListParameters; use xero_rs::KeyPair; lazy_static::lazy_static! { @@ -69,7 +70,7 @@ async fn main() -> Result<()> { connections.first().expect("no connections found").tenant_id, )); - let invoices = xero_rs::invoice::list(&client).await?; + let invoices = xero_rs::invoice::list(&client, ListParameters::default()).await?; info!("found invoices: {:#?}", invoices); Ok(()) From 05c0d17f18343f0bfff021361d542a46273648be Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:12:46 +0000 Subject: [PATCH 7/8] added: added feature "env-filter" to dev dependency tracing-subscriber --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8cdf1dd..f692b59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,4 +47,4 @@ tokio = { version = "1", default-features = false, features = [ "rt-multi-thread", ] } anyhow = "1" -tracing-subscriber = "0.2" +tracing-subscriber = { version = "0.3", features = ["env-filter"]} From 2021937f0f0a58f8fe1530c95a8bc9e77fc7008f Mon Sep 17 00:00:00 2001 From: Dale Stephenson Date: Wed, 5 Feb 2025 10:17:47 +0000 Subject: [PATCH 8/8] chore: version bump - breaking changes --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f692b59..15c923b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xero-rs" -version = "0.0.4-alpha.2" +version = "0.0.5-alpha.1" edition = "2018" description = "A Xero API client library for Rust" license-file = "LICENSE"