Add issue/cancel lifecycle, GST derivation and integer-paise totals
issue_invoice allocates the number, freezes vendor and bank details and stores server-computed totals in one transaction. Issued invoices are cancelled, not deleted. Tax heads derive from supplier state and place of supply (a disagreeing choice is rejected); unregistered suppliers issue a plain Invoice. Adds GSTIN checksum validation, canonical India Compliance state list, server-side drafts, series validation, relative and magic-byte-checked asset paths, and GST settings. PDF re-exports use the frozen vendor snapshot.
This commit is contained in:
+26
-13
@@ -96,6 +96,8 @@ pub struct InvoiceItem {
|
||||
pub amount: f64,
|
||||
#[serde(default)]
|
||||
pub sort_order: i64,
|
||||
#[serde(default)]
|
||||
pub hsn_sac: String,
|
||||
}
|
||||
|
||||
fn default_mode() -> String {
|
||||
@@ -106,6 +108,8 @@ fn default_unit() -> String {
|
||||
"unit".to_string()
|
||||
}
|
||||
|
||||
/// What the webview may send when issuing an invoice. Money totals, tax amounts,
|
||||
/// the amount in words and the vendor/bank snapshots are derived on the Rust side.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InvoiceInput {
|
||||
@@ -125,34 +129,25 @@ pub struct InvoiceInput {
|
||||
#[serde(default)]
|
||||
pub place_of_supply_state_code: String,
|
||||
#[serde(default)]
|
||||
pub subtotal: f64,
|
||||
#[serde(default)]
|
||||
pub discount: f64,
|
||||
/// The tax treatment the user chose; it must match the derived one.
|
||||
#[serde(default = "default_tax_type")]
|
||||
pub tax_type: String,
|
||||
#[serde(default)]
|
||||
pub tax_rate: f64,
|
||||
#[serde(default)]
|
||||
pub cgst_amount: f64,
|
||||
#[serde(default)]
|
||||
pub sgst_amount: f64,
|
||||
#[serde(default)]
|
||||
pub igst_amount: f64,
|
||||
#[serde(default)]
|
||||
pub total: f64,
|
||||
#[serde(default)]
|
||||
pub amount_in_words: String,
|
||||
pub reverse_charge: bool,
|
||||
#[serde(default)]
|
||||
pub bank_account_id: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub bank_snapshot: String,
|
||||
#[serde(default)]
|
||||
pub signature_path: Option<String>,
|
||||
#[serde(default)]
|
||||
pub notes: String,
|
||||
#[serde(default)]
|
||||
pub save_client: bool,
|
||||
#[serde(default)]
|
||||
pub draft_id: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub items: Vec<InvoiceItem>,
|
||||
}
|
||||
|
||||
@@ -187,9 +182,18 @@ pub struct Invoice {
|
||||
pub bank_snapshot: String,
|
||||
pub signature_path: Option<String>,
|
||||
pub notes: String,
|
||||
/// draft | issued | cancelled
|
||||
pub status: String,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
pub doc_type: String,
|
||||
pub reverse_charge: bool,
|
||||
/// JSON of the supplier details as they were when the invoice was issued; empty if unknown.
|
||||
pub vendor_snapshot: String,
|
||||
pub snapshot_origin: String,
|
||||
pub cancelled_at: Option<String>,
|
||||
pub cancel_reason: String,
|
||||
pub archived_pdf_sha256: Option<String>,
|
||||
pub items: Vec<InvoiceItem>,
|
||||
}
|
||||
|
||||
@@ -205,3 +209,12 @@ pub struct InvoiceSummary {
|
||||
pub status: String,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DraftSummary {
|
||||
pub id: i64,
|
||||
pub updated_at: String,
|
||||
pub client_name: Option<String>,
|
||||
pub total: Option<f64>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user