Files
itflow/client/quotes.php
johnnyq 2fcdd6006b Invoices, quotes and recurring invoices makeover stage 4: quote lines billed one time or each month, quarter or year with a Billed choice on the add-a-line row and in Edit Line, quotes grouped into One-time, Each month, Each quarter and Each year with a total for each on the page, PDF and client view, lines dragged within their own group, Start Billing on accepted quotes putting one-time lines on a draft invoice due on the client's terms and each recurring part on a new recurring invoice from a chosen date, emailed or left as drafts, or added to one of the client's recurring invoices of the same frequency, with an option to bill the first period on the invoice, an Invoiced as card on the quote linking every invoice and recurring invoice it became including ones it added lines to, From links back on invoices and recurring invoices, monthly amounts in the quotes list and its totals, search, client portal, quote email, Send and Copy windows, quotes export and client export, and Quotes Pipeline valuing quotes at up front plus a year of recurring lines. Fixes Make Invoice invoicing a quote twice or one never accepted, and its audit entry using the current quote prefix instead of the quote's own. Adds DB 2.9.3 with item_frequency, quote_monthly_amount, invoice_quote_id and recurring_invoice_quote_id, linking invoices to their quotes from history, quoteConvert() as the one invoicing path claiming the quote in a transaction, quoteLineGroups(), quoteAmountText() and quoteMadeFrom(), reportCsv() totals written as given, and updates the 26.11 changelog
2026-10-16 14:14:53 -04:00

99 lines
3.6 KiB
PHP

<?php
/*
* Client Portal
* Quotes for PTC / billing contacts
*/
header("Content-Security-Policy: default-src 'self'");
require_once "includes/inc_all.php";
enforceContactCan('accounting');
$quotes_sql = mysqli_query($mysqli, "SELECT quote_amount, quote_monthly_amount, quote_date, quote_id, quote_number, quote_prefix, quote_scope, quote_status,
quote_url_key FROM quotes WHERE quote_client_id = $session_client_id AND quote_status != 'Draft' ORDER BY quote_date DESC");
?>
<h3>Quotes</h3>
<div class="row">
<div class="col-md-10">
<?php if (mysqli_num_rows($quotes_sql) == 0) { ?>
<?= portalEmptyState('There are no quotes on this account yet.') ?>
<?php } else { ?>
<table class="table table-bordered border border-dark">
<thead class="table-dark">
<tr>
<th>#</th>
<th>Scope</th>
<th>Amount</th>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_assoc($quotes_sql)) {
$quote_id = intval($row['quote_id']);
$quote_prefix = escapeHtml($row['quote_prefix']);
$quote_number = intval($row['quote_number']);
$quote_scope = escapeHtml($row['quote_scope']);
$quote_status = escapeHtml($row['quote_status']);
$quote_date = escapeHtml($row['quote_date']);
$quote_amount = floatval($row['quote_amount']);
$quote_url_key = escapeHtml($row['quote_url_key']);
if (empty($quote_scope)) {
$quote_scope_display = "-";
} else {
$quote_scope_display = $quote_scope;
}
if ($quote_status == "Sent") {
$quote_badge_color = "warning";
} elseif ($quote_status == "Viewed") {
$quote_badge_color = "primary";
} elseif ($quote_status == "Accepted") {
$quote_badge_color = "success";
} elseif ($quote_status == "Declined") {
$quote_badge_color = "danger";
} elseif ($quote_status == "Invoiced") {
$quote_badge_color = "info";
} else {
$quote_badge_color = "secondary";
}
?>
<tr>
<td><a target="_blank" href="//<?= $config_base_url ?>/guest/guest_view_quote.php?quote_id=<?= "$quote_id&url_key=$quote_url_key" ?>"> <?= "$quote_prefix$quote_number" ?></a></td>
<td><?= $quote_scope_display ?></td>
<td>
<?= numfmt_format_currency($currency_format, $quote_amount, $session_company_currency) ?>
<?php if (floatval($row['quote_monthly_amount']) != 0) { ?>
<div class="small text-body-secondary">+ <?= numfmt_format_currency($currency_format, floatval($row['quote_monthly_amount']), $session_company_currency) ?> a month</div>
<?php } ?>
</td>
<td><?= $quote_date ?></td>
<td>
<span class="p-2 badge text-bg-<?= $quote_badge_color ?>">
<?= $quote_status ?>
</span>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } ?>
</div>
</div>
<?php
require_once "includes/footer.php";