'That quote no longer exists.'])); } $client_id = intval($doc['client_id']); enforceClientAccess(); $doc_number = billingNumber('quote', $doc); if ($doc['quote_status'] !== 'Accepted') { exit(json_encode(['error' => $doc['quote_status'] === 'Invoiced' ? "$doc_number is already invoiced." : "$doc_number has to be accepted before it is invoiced."])); } $quote_id = intval($doc['quote_id']); $currency = (string) $doc['quote_currency_code']; $money = function ($amount) use ($currency) { return escapeHtml(billingMoney($amount, $currency)); }; $groups = quoteGroups($doc); $recurring = quoteHasRecurring($groups); $one_time = $groups[''] ?? null; // 0 is On Receipt - a contract in force's net terms, else the default [$terms, $terms_from] = contractNetTermsWhose($client_id, date('Y-m-d')); $frequencies = recurringInvoiceFrequencies(); // The client's recurring invoices each part could go on $existing = []; $sql = mysqli_query($mysqli, "SELECT recurring_invoice_id, recurring_invoice_prefix, recurring_invoice_number, recurring_invoice_scope, recurring_invoice_frequency, recurring_invoice_amount FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id AND recurring_invoice_archived_at IS NULL ORDER BY recurring_invoice_number DESC"); while ($row = mysqli_fetch_assoc($sql)) { $existing[$row['recurring_invoice_frequency']][intval($row['recurring_invoice_id'])] = $row; } ob_start(); ?>