'That invoice no longer exists.'])); } $invoice_id = intval($invoice['invoice_id']); $client_id = intval($invoice['client_id']); enforceClientAccess(); $number = billingNumber('invoice', $invoice); $invoice_date = substr((string) $invoice['invoice_date'], 0, 10); if ($invoice['invoice_status'] === 'Cancelled') { exit(json_encode(['error' => escapeHtml($number) . ' is cancelled - nothing on it was sold.'])); } $lines = array_values(array_filter(productInvoiceHardware($invoice_id), function ($line) { return $line['to_add'] > 0; })); if (!$lines) { exit(json_encode(['error' => 'Every unit of hardware on ' . escapeHtml($number) . ' is on ' . escapeHtml($invoice['client_name']) . "'s assets."])); } $statuses = []; foreach (categoryPicker('asset_status') as $status_name => $status_row) { $statuses[$status_name] = assetStatusColor($status_name, $status_row['category_color'] ?? ''); } $status_default = isset($statuses['Deployed']) ? 'Deployed' : (isset($statuses['Ready to Deploy']) ? 'Ready to Deploy' : (string) array_key_first($statuses)); $locations = []; $location_default = 0; $sql = mysqli_query($mysqli, "SELECT location_id, location_name, location_primary FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_primary DESC, location_name ASC"); while ($row = mysqli_fetch_assoc($sql)) { $locations[intval($row['location_id'])] = $row['location_name']; if (intval($row['location_primary']) && !$location_default) { $location_default = intval($row['location_id']); } } $contacts = []; $sql = mysqli_query($mysqli, "SELECT contact_id, contact_name FROM contacts WHERE contact_client_id = $client_id AND contact_archived_at IS NULL ORDER BY contact_name ASC"); while ($row = mysqli_fetch_assoc($sql)) { $contacts[intval($row['contact_id'])] = $row['contact_name']; } $form_id = "invoiceAssets$invoice_id"; $total = array_sum(array_column($lines, 'to_add')); ob_start(); ?>