You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.8 KiB
178 lines
4.8 KiB
<!doctype html> |
|
<html> |
|
<head> |
|
<title>New Invoice</title> |
|
<link rel="icon" type="image/png" href="/static/favicon.png"> |
|
</head> |
|
|
|
<body> |
|
|
|
<h1>Create Invoice</h1> |
|
<p> |
|
<strong>Invoice Number</strong><br> |
|
This invoice number will be generated automatically when the invoice is created. |
|
</p> |
|
|
|
{% if errors %} |
|
<div style="border:1px solid red; padding:10px; margin-bottom:15px;"> |
|
<strong>Please fix the following:</strong> |
|
<ul> |
|
{% for error in errors %} |
|
<li>{{ error }}</li> |
|
{% endfor %} |
|
</ul> |
|
</div> |
|
{% endif %} |
|
|
|
<form method="post"> |
|
|
|
<p> |
|
Client *<br> |
|
<select name="client_id" required> |
|
<option value="">Select client</option> |
|
{% for c in clients %} |
|
<option value="{{ c.id }}" {% if form_data.get('client_id') == (c.id|string) %}selected{% endif %}> |
|
{{ c.client_code }} - {{ c.company_name }} |
|
</option> |
|
{% endfor %} |
|
</select> |
|
</p> |
|
|
|
<p> |
|
Service *<br> |
|
<select name="service_id" required> |
|
<option value="">Select service</option> |
|
{% for s in services %} |
|
<option value="{{ s.id }}" {% if form_data.get('service_id') == (s.id|string) %}selected{% endif %}> |
|
{{ s.service_code }} - {{ s.service_name }} |
|
</option> |
|
{% endfor %} |
|
</select> |
|
</p> |
|
|
|
<p> |
|
Currency *<br> |
|
<select name="currency_code" id="currency_code" required> |
|
<option value="CAD" {% if form_data.get('currency_code', 'CAD') == 'CAD' %}selected{% endif %}>CAD</option> |
|
<option value="ETHO" {% if form_data.get('currency_code') == 'ETHO' %}selected{% endif %}>ETHO</option> |
|
<option value="EGAZ" {% if form_data.get('currency_code') == 'EGAZ' %}selected{% endif %}>EGAZ</option> |
|
<option value="ALT" {% if form_data.get('currency_code') == 'ALT' %}selected{% endif %}>ALT</option> |
|
</select> |
|
</p> |
|
|
|
<p> |
|
Description *<br> |
|
<textarea name="description" rows="5" cols="80" required>{{ form_data.get('description', '') }}</textarea> |
|
</p> |
|
|
|
<p> |
|
Qty *<br> |
|
<input |
|
type="number" |
|
step="0.0001" |
|
min="0.0001" |
|
name="quantity" |
|
id="quantity" |
|
value="{{ form_data.get('quantity', '1') }}" |
|
required |
|
> |
|
</p> |
|
|
|
<p> |
|
Unit Cost *<br> |
|
<input |
|
type="number" |
|
step="0.00000001" |
|
min="0.00000001" |
|
name="unit_amount" |
|
id="unit_amount" |
|
value="{{ form_data.get('unit_amount', '') }}" |
|
required |
|
> |
|
</p> |
|
|
|
<p> |
|
<label> |
|
<input |
|
type="checkbox" |
|
name="apply_tax" |
|
id="apply_tax" |
|
value="1" |
|
{% if form_data.get('apply_tax') == '1' %}checked{% endif %} |
|
> |
|
Apply 13% HST |
|
</label> |
|
</p> |
|
|
|
<div style="border:1px solid #ccc; padding:10px; max-width:420px; margin:15px 0;"> |
|
<strong>Invoice Summary</strong><br><br> |
|
<table> |
|
<tr> |
|
<th style="text-align:left; padding-right:20px;">Subtotal</th> |
|
<td id="summary_subtotal">0.00 CAD</td> |
|
</tr> |
|
<tr id="summary_tax_row" style="display:none;"> |
|
<th style="text-align:left; padding-right:20px;">HST 13%</th> |
|
<td id="summary_tax">0.00 CAD</td> |
|
</tr> |
|
<tr> |
|
<th style="text-align:left; padding-right:20px;">Total Amount</th> |
|
<td><strong id="summary_total">0.00 CAD</strong></td> |
|
</tr> |
|
</table> |
|
</div> |
|
|
|
<p> |
|
Due Date *<br> |
|
<input type="date" name="due_at" value="{{ form_data.get('due_at', '') }}" required> |
|
</p> |
|
|
|
<p> |
|
<button type="submit">Create Invoice</button> |
|
</p> |
|
|
|
</form> |
|
|
|
<script> |
|
(function () { |
|
const qtyInput = document.getElementById("quantity"); |
|
const unitInput = document.getElementById("unit_amount"); |
|
const taxBox = document.getElementById("apply_tax"); |
|
const currencySelect = document.getElementById("currency_code"); |
|
const subtotalEl = document.getElementById("summary_subtotal"); |
|
const taxRow = document.getElementById("summary_tax_row"); |
|
const taxEl = document.getElementById("summary_tax"); |
|
const totalEl = document.getElementById("summary_total"); |
|
|
|
function money(value) { |
|
const currency = currencySelect.value || "CAD"; |
|
const decimals = currency === "CAD" ? 2 : 8; |
|
const n = Number(value || 0); |
|
return n.toFixed(decimals) + " " + currency; |
|
} |
|
|
|
function updateSummary() { |
|
const qty = Number(qtyInput.value || 0); |
|
const unit = Number(unitInput.value || 0); |
|
const subtotal = qty * unit; |
|
const applyTax = taxBox.checked; |
|
const tax = applyTax ? subtotal * 0.13 : 0; |
|
const total = subtotal + tax; |
|
|
|
subtotalEl.textContent = money(subtotal); |
|
taxEl.textContent = money(tax); |
|
totalEl.textContent = money(total); |
|
taxRow.style.display = applyTax ? "table-row" : "none"; |
|
} |
|
|
|
qtyInput.addEventListener("input", updateSummary); |
|
unitInput.addEventListener("input", updateSummary); |
|
taxBox.addEventListener("change", updateSummary); |
|
currencySelect.addEventListener("change", updateSummary); |
|
updateSummary(); |
|
})(); |
|
</script> |
|
|
|
</body> |
|
</html> |
|
{% include "footer.html" %}
|
|
|