quickbooks_types/models/
item.rs

1use chrono::NaiveDate;
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4
5use super::common::{MetaData, NtRef};
6#[cfg(feature = "builder")]
7use crate::error::QBTypeError;
8use crate::{QBCreatable, QBFullUpdatable, QBItem};
9
10#[skip_serializing_none]
11#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Default)]
12#[serde(rename_all = "PascalCase", default)]
13#[cfg_attr(
14    feature = "builder",
15    derive(Builder),
16    builder(default, build_fn(error = "QBTypeError"), setter(into, strip_option))
17)]
18/// Item
19///
20/// Represents a product or service that can be purchased or sold. Items determine posting accounts (income, expense, inventory) and pricing.
21///
22/// API reference:
23/// <https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/item>
24pub struct Item {
25    pub id: Option<String>,
26    pub sync_token: Option<String>,
27    #[serde(skip_serializing)]
28    pub meta_data: Option<MetaData>,
29
30    /// If true, the object is currently enabled for use by `QuickBooks`.
31    pub active: Option<bool>,
32
33    /// Reference to the Inventory Asset account that tracks the current value of the inventory.
34    /// If the same account is used for all inventory items, the current balance of this account will represent the current total value of the inventory.
35    /// Query the Account name list resource to determine the appropriate Account object for this reference.
36    /// Use `Account.id` and `Account.name` from that object for `AssetAccountRef.value` and `AssetAccountRef.name`, respectively.
37    ///
38    /// Required for Inventory item types.
39    pub asset_account_ref: Option<NtRef>,
40
41    /// Description of the item.
42    ///
43    /// * max character: maximum of 4000 chars
44    pub description: Option<String>,
45
46    /// Documentation unavailable.
47    #[serde(rename = "domain")]
48    pub domain: Option<String>,
49
50    /// Reference to the expense account used to pay the vendor for this item.
51    /// Must be an account with account type of Cost of Goods Sold.
52    /// Query the Account name list resource to determine the appropriate Account object for this reference.
53    /// Use `Account.id` and `Account.name` from that object for `ExpenseAccountRef.value` and `ExpenseAccountRef.name`, respectively.
54    ///
55    /// For France locales:
56    /// * This is an optional field.
57    /// * This is the purchase account id, If not provided it defaults to the default purchase account: 605100 and 601100 are the default expense accounts used for Service and Product type of item, respectively.
58    ///
59    /// Required for Inventory, `NonInventory`, and Service item types
60    pub expense_account_ref: Option<NtRef>,
61
62    /// Fully qualified name of the entity.
63    /// The fully qualified name prepends the topmost parent, followed by each sub element separated by colons.
64    /// Takes the form of Item:SubItem.
65    /// Returned from an existing object and not input on a new object.
66    /// Limited to 5 levels.
67    ///
68    /// * filterable
69    /// * read only
70    /// * system defined
71    pub fully_qualified_name: Option<String>,
72    pub income_account_ref: Option<NtRef>,
73    pub inv_start_date: Option<NaiveDate>,
74    pub sales_tax_included: Option<bool>,
75    pub sales_tax_code_ref: Option<NtRef>,
76    pub class_ref: Option<NtRef>,
77    pub source: Option<String>,
78    pub purchase_tax_included: Option<bool>,
79    pub reorder_point: Option<f64>,
80    pub purchase_dec: Option<String>,
81    pub pref_vendor_ref: Option<NtRef>,
82    pub purchase_tax_code_ref: Option<NtRef>,
83    pub purchase_cost: Option<f64>,
84    pub parent_ref: Option<NtRef>,
85    pub tax_classification_ref: Option<NtRef>,
86
87    /// Classification that specifies the use of this item.
88    /// Available when endpoint is evoked with the minorversion=3 query parameter.
89    /// Read-only after object is created.
90    /// Valid values include: Product and Service.
91    ///
92    /// Applicable for France companies only.
93    pub item_category_type: Option<String>,
94    #[serde(rename = "Type")]
95    pub item_type: Option<ItemType>,
96    pub level: Option<i64>,
97    pub name: Option<String>,
98    pub purchase_desc: Option<String>,
99    pub qty_on_hand: Option<i64>,
100    pub sku: Option<String>,
101    #[serde(rename = "sparse")]
102    pub sparse: Option<bool>,
103    pub sub_item: Option<bool>,
104    pub taxable: Option<bool>,
105    pub track_qty_on_hand: Option<bool>,
106    pub unit_price: Option<f64>,
107}
108
109/// Item Type
110///
111/// Classification that specifies whether the item is an inventory item, a service item, or a non-inventory item.
112#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Default)]
113pub enum ItemType {
114    Inventory,
115    Service,
116    #[default]
117    NonInventory,
118}
119
120impl QBCreatable for Item {
121    fn can_create(&self) -> bool {
122        self.name.is_some()
123            && self.expense_account_ref.is_some()
124            && match self.item_type.as_ref() {
125                Some(typ) => match *typ {
126                    ItemType::Inventory => {
127                        self.income_account_ref.is_some()
128                            && self.asset_account_ref.is_some()
129                            && self.inv_start_date.is_some()
130                            && self.qty_on_hand.is_some()
131                    }
132                    ItemType::Service => self.income_account_ref.is_some(),
133                    ItemType::NonInventory => true,
134                },
135                None => self.asset_account_ref.is_some(),
136            }
137    }
138}
139
140impl QBFullUpdatable for Item {
141    fn can_full_update(&self) -> bool {
142        self.has_read() && self.name.is_some()
143    }
144}