0 ) { // Load invoice, scoped to API key permissions $invoice_sql = mysqli_query( $mysqli, "SELECT * FROM invoices WHERE invoice_id = $invoice_id AND invoice_status != 'Paid' AND 1=1 " . apiClientScopeSql('invoice_client_id') . " LIMIT 1" ); $invoice_row = $invoice_sql ? mysqli_fetch_assoc($invoice_sql) : null; // Ensure supplied client matches invoice client if ($invoice_row && $client_id != 0 && intval($invoice_row['invoice_client_id']) !== $client_id) { $invoice_row = null; } if ($invoice_row) { $client_id = intval($invoice_row['invoice_client_id']); $invoice_prefix = escapeSql($invoice_row['invoice_prefix']); $invoice_number = intval($invoice_row['invoice_number']); $invoice_discount = floatval($invoice_row['invoice_discount_amount']); $subtotal = $price * $qty; $take_stock = false; // Product inventory if ($product_id) { // Only products whose stock is tracked move stock if (intval(getFieldById('products', $product_id, 'product_track_stock')) === 1) { $stock_sql = mysqli_query( $mysqli, "SELECT COALESCE(SUM(stock_qty),0) AS available_stock FROM product_stock WHERE stock_product_id = $product_id" ); $stock_row = mysqli_fetch_assoc($stock_sql); $available_stock = floatval($stock_row['available_stock']); if ($available_stock >= $qty) { // Taken off the shelf once the line is in $take_stock = true; } else { logAudit( "API", "Failure", "Failed adding item $name to invoice $invoice_prefix$invoice_number via API ($api_key_name) due to insufficient stock", $client_id ); require_once '../create_output.php'; exit; } } } // Tax - at the rate's parts, each to the cent; a rate that doesn't exist is none if ($tax_id_posted === 'default') { $tax_id = $product_id ? taxDefaultFor($client_id, 'product', intval(getFieldById('products', $product_id, 'product_tax_id'))) : taxDefaultFor($client_id); } if ($tax_id > 0 && !taxRow($tax_id)) { $tax_id = 0; } [$subtotal, $tax_amount, $total] = billingLineTax($qty, $price, $tax_id); $insert_sql = mysqli_query( $mysqli, "INSERT INTO invoice_items SET item_name = '$name', item_description = '$description', item_quantity = $qty, item_price = $price, item_subtotal = $subtotal, item_tax = $tax_amount, item_total = $total, item_order = $item_order, item_tax_id = $tax_id, item_product_id = $product_id, item_invoice_id = $invoice_id" ); if ($insert_sql) { $insert_id = mysqli_insert_id($mysqli); if ($take_stock) { productStockMove($product_id, -$qty, 'sold', ['invoice_id' => $invoice_id, 'item_id' => $insert_id, 'note' => stripslashes($invoice_prefix) . "$invoice_number - API"]); } // The invoice's total - and each line's tax after any discount (functions/billing.php) billingRecalc('invoice', $invoice_id); logAudit( "Invoice", "Edit", "Added item $name to invoice $invoice_prefix$invoice_number via API ($api_key_name)", $client_id, $invoice_id ); logAudit( "API", "Success", "Added item $name to invoice $invoice_prefix$invoice_number via API ($api_key_name)", $client_id ); } } } // Output require_once '../create_output.php';