use chrono::NaiveDate;
use rust_decimal::Decimal;
use serde::Serialize;
use crate::enums::{CurrencyCode, InvoiceCreateStatus, InvoiceDiscountType, InvoiceSendMethod};
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceCreateInput {
pub business_id: String,
pub customer_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<InvoiceCreateStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub currency: Option<CurrencyCode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subhead: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invoice_number: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub po_number: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invoice_date: Option<NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub due_date: Option<NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exchange_rate: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Vec<InvoiceCreateItemInput>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub discounts: Option<Vec<InvoiceDiscountInput>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub footer: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disable_credit_card_payments: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disable_bank_payments: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disable_amex_payments: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub item_title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unit_title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub price_title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub amount_title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hide_name: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hide_description: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hide_unit: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hide_price: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hide_amount: Option<bool>,
}
impl InvoiceCreateInput {
pub fn new(
business_id: impl Into<String>,
customer_id: impl Into<String>,
) -> Self {
Self {
business_id: business_id.into(),
customer_id: customer_id.into(),
status: None,
currency: None,
title: None,
subhead: None,
invoice_number: None,
po_number: None,
invoice_date: None,
due_date: None,
exchange_rate: None,
items: None,
discounts: None,
memo: None,
footer: None,
disable_credit_card_payments: None,
disable_bank_payments: None,
disable_amex_payments: None,
item_title: None,
unit_title: None,
price_title: None,
amount_title: None,
hide_name: None,
hide_description: None,
hide_unit: None,
hide_price: None,
hide_amount: None,
}
}
pub fn status(mut self, v: InvoiceCreateStatus) -> Self {
self.status = Some(v);
self
}
pub fn items(mut self, v: Vec<InvoiceCreateItemInput>) -> Self {
self.items = Some(v);
self
}
pub fn invoice_date(mut self, v: NaiveDate) -> Self {
self.invoice_date = Some(v);
self
}
pub fn due_date(mut self, v: NaiveDate) -> Self {
self.due_date = Some(v);
self
}
pub fn memo(mut self, v: impl Into<String>) -> Self {
self.memo = Some(v.into());
self
}
pub fn footer(mut self, v: impl Into<String>) -> Self {
self.footer = Some(v.into());
self
}
pub fn discounts(mut self, v: Vec<InvoiceDiscountInput>) -> Self {
self.discounts = Some(v);
self
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceCreateItemInput {
pub product_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quantity: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unit_price: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub taxes: Option<Vec<InvoiceCreateItemTaxInput>>,
}
impl InvoiceCreateItemInput {
pub fn new(product_id: impl Into<String>) -> Self {
Self {
product_id: product_id.into(),
description: None,
quantity: None,
unit_price: None,
taxes: None,
}
}
pub fn quantity(mut self, v: Decimal) -> Self {
self.quantity = Some(v);
self
}
pub fn unit_price(mut self, v: Decimal) -> Self {
self.unit_price = Some(v);
self
}
pub fn description(mut self, v: impl Into<String>) -> Self {
self.description = Some(v.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceCreateItemTaxInput {
pub sales_tax_id: String,
}
impl InvoiceCreateItemTaxInput {
pub fn new(sales_tax_id: impl Into<String>) -> Self {
Self {
sales_tax_id: sales_tax_id.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceDiscountInput {
pub discount_type: InvoiceDiscountType,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub amount: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub percentage: Option<Decimal>,
}
impl InvoiceDiscountInput {
pub fn fixed(amount: Decimal) -> Self {
Self {
discount_type: InvoiceDiscountType::Fixed,
name: None,
amount: Some(amount),
percentage: None,
}
}
pub fn percentage(pct: Decimal) -> Self {
Self {
discount_type: InvoiceDiscountType::Percentage,
name: None,
amount: None,
percentage: Some(pct),
}
}
pub fn name(mut self, v: impl Into<String>) -> Self {
self.name = Some(v.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoicePatchInput {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub customer_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<InvoiceCreateStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invoice_date: Option<NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub due_date: Option<NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Vec<InvoiceCreateItemInput>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub footer: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub po_number: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invoice_number: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub discounts: Option<Vec<InvoiceDiscountInput>>,
}
impl InvoicePatchInput {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
customer_id: None,
status: None,
title: None,
invoice_date: None,
due_date: None,
items: None,
memo: None,
footer: None,
po_number: None,
invoice_number: None,
discounts: None,
}
}
pub fn memo(mut self, v: impl Into<String>) -> Self {
self.memo = Some(v.into());
self
}
pub fn items(mut self, v: Vec<InvoiceCreateItemInput>) -> Self {
self.items = Some(v);
self
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceDeleteInput {
pub invoice_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceCloneInput {
pub invoice_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceApproveInput {
pub invoice_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceMarkSentInput {
pub invoice_id: String,
pub send_method: InvoiceSendMethod,
#[serde(skip_serializing_if = "Option::is_none")]
pub sent_at: Option<chrono::DateTime<chrono::Utc>>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InvoiceSendInput {
pub invoice_id: String,
pub to: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
pub attach_pdf: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub from_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cc_myself: Option<bool>,
}
impl InvoiceSendInput {
pub fn new(invoice_id: impl Into<String>, to: Vec<String>) -> Self {
Self {
invoice_id: invoice_id.into(),
to,
subject: None,
message: None,
attach_pdf: true,
from_address: None,
cc_myself: None,
}
}
pub fn subject(mut self, v: impl Into<String>) -> Self {
self.subject = Some(v.into());
self
}
pub fn message(mut self, v: impl Into<String>) -> Self {
self.message = Some(v.into());
self
}
}