324 lines
18 KiB
HTML
324 lines
18 KiB
HTML
{% extends "base.html" %}
|
|
{% load i18n %}
|
|
{% load tenhal_tag %}
|
|
|
|
{% block title %}{{ _("View Invoice") }}{% endblock title %}
|
|
{% block customCSS %}
|
|
<style>
|
|
.disabled{
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
}
|
|
</style>
|
|
{% endblock customCSS %}
|
|
{% block content %}
|
|
<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-primary">
|
|
<h5 class="modal-title text-light" id="confirmModalLabel">{% trans 'Confirm' %}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
{% trans 'Are you sure ?' %}
|
|
<div class="modal-footer">
|
|
<button type="button"
|
|
class="btn btn-sm btn-danger"
|
|
data-bs-dismiss="modal"><i class="fa-solid fa-ban"></i> {% trans 'No' %}
|
|
</button>
|
|
<form id="confirmForm" method="POST" action="{% url 'invoice_mark_as' invoice.pk %}?mark=accept" class="d-inline">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-success btn-sm"><i class="fa-solid fa-circle-check"></i> {% trans "Yes" %}</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- ============================================-->
|
|
<div class="modal fade" id="mark_as_paid_Modal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-primary">
|
|
<h5 class="modal-title text-light" id="confirmModalLabel">{% trans 'Confirm' %}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
{% trans 'Are you sure ?' %}
|
|
<div class="modal-footer">
|
|
<button type="button"
|
|
class="btn btn-sm btn-danger"
|
|
data-bs-dismiss="modal">
|
|
<i class="fa-solid fa-ban"></i> {% trans 'No' %}
|
|
</button>
|
|
<form id="confirmForm" method="POST" action="{% url 'payment_mark_as_paid' invoice.pk %}" class="d-inline">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-success btn-sm"><i class="fa-solid fa-circle-check"></i> {% trans "Yes" %}</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- ============================================-->
|
|
<!-- <section> begin ============================-->
|
|
<section class="pt-5 pb-9 bg-body-emphasis dark__bg-gray-1200 border-top">
|
|
<div class="row-small mt-3 mx-3">
|
|
<div class="d-flex justify-content-between align-items-end mb-4 mx-3">
|
|
<div class="d-flex flex-row align-items-center gap-2">
|
|
<h2 class="mb-0"><i class="fa-solid fa-receipt"></i> {% trans 'Invoice' %}</h2>
|
|
<div class="fs-9 text-body-secondary fw-semibold mt-2">
|
|
{% if invoice.invoice_status == 'draft' %}
|
|
<span class="badge text-bg-warning">{% trans "Draft" %}</span>
|
|
{% elif invoice.invoice_status == 'in_review' %}
|
|
<span class="badge text-bg-info">{% trans "In Review" %}</span>
|
|
{% elif invoice.invoice_status == 'approved' %}
|
|
<span class="badge text-bg-info">{% trans "Approved" %}</span>
|
|
{% elif invoice.invoice_status == 'declined' %}
|
|
<span class="badge text-bg-danger">{% trans "Declined" %}</span>
|
|
{% elif invoice.invoice_status == 'paid' %}
|
|
<span class="badge text-bg-success">{% trans "Paid" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2">
|
|
{% if invoice.invoice_status == 'in_review' %}
|
|
<button id="accept_invoice" class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#confirmModal"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-check-double"></i> {% trans 'Accept' %}</span></button>
|
|
{% endif %}
|
|
{% if invoice.invoice_status == 'approved' %}
|
|
<a href="{% url 'payment_create' invoice.pk %}" class="btn btn-phoenix-success"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-money-bill"></i> {% trans 'Record Payment' %}</span></a>
|
|
{% endif %}
|
|
{% if not invoice.is_paid %}
|
|
<button {% if invoice.is_review or invoice.amount_paid|to_int < invoice.amount_due|to_int %}disabled{% endif %} id="mark_invoice_as_paid" class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#mark_as_paid_Modal"><span class="d-none d-sm-inline-block"><span class="icon-saudi_riyal"></span> {% trans 'Mark as Paid' %}</span></button>
|
|
{% endif %}
|
|
<a href="{% url 'invoice_preview' invoice.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block"><i class="fa-regular fa-eye"></i> {% trans 'Preview' %}</span></a>
|
|
</div>
|
|
</div>
|
|
{{invoice.amount_owned}}
|
|
|
|
<!-- ============================================-->
|
|
<div class="card mb-5 {% if invoice.is_review %}disabled{% endif %}">
|
|
<div class="card-body">
|
|
<div class="row g-4 g-xl-1 g-xxl-3 justify-content-between">
|
|
<div class="col-sm-auto">
|
|
<div class="d-sm-block d-inline-flex d-md-flex flex-xl-column flex-xxl-row align-items-center align-items-xl-start align-items-xxl-center">
|
|
<div class="d-flex bg-success-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-success-dark" data-feather="dollar-sign" style="width:24px; height:24px"></span></div>
|
|
<div>
|
|
<p class="fw-bold mb-1">{% trans 'Paid Amount' %}</p>
|
|
<h4 class="fw-bolder text-nowrap {% if invoice.is_paid %}text-success{% endif %}">{{invoice.amount_paid}} <span class="icon-saudi_riyal"></span></h4>
|
|
<h6 class="fw-bolder text-nowrap">{{ _("Owned") }} <span class="fw-semibold text-nowrap text-success">{{invoice.get_amount_open|floatformat}} <span class="icon-saudi_riyal"></span></span></h6>
|
|
<div class="progress" style="height:17px">
|
|
<div class="progress-bar fw-semibold bg-{% if invoice.get_progress_percent < 100 %}secondary{% else %}success{% endif %} rounded-2" role="progressbar" style="width: {{invoice.get_progress_percent}}%" aria-valuenow="{{invoice.get_progress_percent}}" aria-valuemin="0" aria-valuemax="100">{{invoice.get_progress_percent}}%</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% if 'net' in invoice.terms %}
|
|
<div class="col-sm-auto">
|
|
<div class="d-sm-block d-inline-flex d-md-flex flex-xl-column flex-xxl-row align-items-center align-items-xl-start align-items-xxl-center border-start-sm ps-sm-5 border-translucent">
|
|
<div class="d-flex bg-primary-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-primary-dark" data-feather="layout" style="width:24px; height:24px"></span></div>
|
|
<div>
|
|
<p class="fw-bold mb-1"></p>
|
|
<div class="fs-9 text-body-secondary fw-semibold mb-0 d-sm-block d-inline-flex d-md-flex flex-xl-column ">
|
|
<table>
|
|
<tr>
|
|
<td>{% trans 'Terms' %}:</td>
|
|
<td><span class="badge rounded bg-success">{{invoice.terms}}</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td>{% trans 'Date Due' %}:</td>
|
|
<td><span class="badge rounded bg-success">{{invoice.date_due}}</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td>{% trans 'Due in Days' %}:</td>
|
|
<td>
|
|
<span class="badge rounded bg-success">{{invoice.due_in_days}}</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>{% trans 'Is Past Due' %}:</td>
|
|
<td>
|
|
{% if invoice.is_past_due %}
|
|
<span class="badge rounded bg-danger">{% trans 'Yes' %}</span>
|
|
{% else %}
|
|
<span class="badge rounded bg-success">{% trans 'No' %}</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
<div class="col-sm-auto">
|
|
<div class="d-sm-block d-inline-flex d-md-flex flex-xl-column flex-xxl-row align-items-center align-items-xl-start align-items-xxl-center border-start-sm ps-sm-5 border-translucent">
|
|
<div class="d-flex bg-primary-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-primary-dark" data-feather="layout" style="width:24px; height:24px"></span></div>
|
|
<div>
|
|
<p class="fw-bold mb-1">{% trans 'Due Amount' %}</p>
|
|
{% if invoice.is_paid %}
|
|
<s><h4 class="fw-bolder text-nowrap">{{invoice.amount_due|floatformat}} <span class="icon-saudi_riyal"></span></h4></s>
|
|
{% else %}
|
|
<h4 class="fw-bolder text-nowrap">{{invoice.amount_due|floatformat}} <span class="icon-saudi_riyal"></span></h4>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- <section> begin ============================-->
|
|
<div class="bg-body dark__bg-gray-1100 p-4 mb-4 rounded-2 text-body-tertiary {% if invoice.is_review %}disabled{% endif %}">
|
|
<div class="row g-4">
|
|
<div class="col-12 col-lg-3">
|
|
<div class="row g-4 g-lg-2">
|
|
<div class="col-12 col-sm-6 col-lg-12">
|
|
<div class="row align-items-center g-0">
|
|
<div class="col-auto col-lg-6 col-xl-5">
|
|
<h6 class="mb-0 me-3"><i class="fa-solid fa-hashtag"></i> {% trans "Invoice Number" %} :</h6>
|
|
</div>
|
|
<div class="col-auto col-lg-6 col-xl-7">
|
|
<p class="fs-9 text-body-secondary fw-semibold mb-0">{{invoice.invoice_number}}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6 col-lg-12">
|
|
<div class="row align-items-center g-0">
|
|
<div class="col-auto col-lg-6 col-xl-5">
|
|
<h6 class="me-3"><i class="fa-solid fa-calendar-days"></i> {% trans "Invoice Date" %} :</h6>
|
|
</div>
|
|
<div class="col-auto col-lg-6 col-xl-7">
|
|
<p class="fs-9 text-body-secondary fw-semibold mb-0">{{invoice.created}}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6 col-lg-5">
|
|
<div class="row align-items-center g-0">
|
|
<div class="col-auto col-lg-6 col-xl-5">
|
|
<h6 class="mb-2 me-3"><i class="fa-solid fa-user"></i> {% trans "Customer Name" %} :</h6>
|
|
<p class="fs-9 text-body-secondary fw-semibold mb-0">{{invoice.customer.customer_name}}</p>
|
|
</div>
|
|
<div class="col-12 col-lg-4">
|
|
<h6 class="mb-2"><i class="fa-solid fa-envelope"></i> {% trans "Customer Email" %} :</h6>
|
|
<p class="fs-9 text-body-secondary fw-semibold mb-0">{{invoice.customer.email}}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<div class="row g-4">
|
|
<div class="col-12 col-lg-6">
|
|
<h6 class="mb-2"><i class="fa-solid fa-list"></i> {% trans "Invoice Status" %} :</h6>
|
|
<div class="fs-9 text-body-secondary fw-semibold mb-0">
|
|
{% if invoice.invoice_status == 'draft' %}
|
|
<span class="badge text-bg-warning">{% trans "Draft" %}</span>
|
|
{% elif invoice.invoice_status == 'in_review' %}
|
|
<span class="badge text-bg-info">{% trans "In Review" %}</span>
|
|
{% elif invoice.invoice_status == 'approved' %}
|
|
<span class="badge text-bg-info">{% trans "Approved" %}</span>
|
|
{% elif invoice.invoice_status == 'declined' %}
|
|
<span class="badge text-bg-danger">{% trans "Declined" %}</span>
|
|
{% elif invoice.invoice_status == 'paid' %}
|
|
<span class="badge text-bg-success">{% trans "Paid" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="px-0 {% if invoice.is_review %}disabled{% endif %}">
|
|
<div class="table-responsive scrollbar">
|
|
<table id="invoice-table" class="table fs-9 text-body mb-0">
|
|
<thead class="bg-body-secondary">
|
|
<tr>
|
|
<th scope="col" style="width: 24px;"><i class="fa-solid fa-hashtag"></i> </th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Make" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Model" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Year" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "VIN" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Quantity" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Unit Price" %}</th>
|
|
<th scope="col" style="min-width: 100px;">{% trans "Total" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in data.cars %}
|
|
<tr>
|
|
<td class="align-middle"></td>
|
|
<td class="align-middle">{{item.make}}</td>
|
|
<td class="align-middle">{{item.model}}</td>
|
|
<td class="align-middle">{{item.year}}</td>
|
|
<td class="align-middle">{{item.vin}}</td>
|
|
<td class="align-middle">{{item.quantity|floatformat:-1}}</td>
|
|
<td class="align-middle ps-5">{{item.total}}</td>
|
|
<td class="align-middle text-body-tertiary fw-semibold">{{item.total}}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
<tr class="bg-body-secondary total-sum">
|
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="7">{% trans "Discount Amount" %}</td>
|
|
<td class="align-middle text-start fw-semibold">
|
|
<span id="grand-total">- {{data.total_discount|floatformat}}<span class="icon-saudi_riyal"></span></span>
|
|
</td>
|
|
</tr>
|
|
<tr class="bg-body-secondary total-sum">
|
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="7">{% trans "VAT" %} ({{data.vat}}%)</td>
|
|
<td class="align-middle text-start fw-semibold">
|
|
<span id="grand-total">+ {{data.total_vat_amount|floatformat}}<span class="icon-saudi_riyal"></span></span>
|
|
</td>
|
|
</tr>
|
|
<tr class="bg-body-secondary total-sum">
|
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="7">{% trans "Additional Services" %}</td>
|
|
<td class="align-middle text-start fw-bold">
|
|
{% for service in data.additionals %}
|
|
<small><span class="fw-bold">+ {{service.name}} - {{service.price_|floatformat}}<span class="icon-saudi_riyal"></span></span></small><br>
|
|
{% endfor %}
|
|
</td>
|
|
</tr>
|
|
<tr class="bg-body-secondary total-sum">
|
|
<td class="align-middle ps-4 fw-bolder text-body-highlight" colspan="7">{% trans "Grand Total" %}</td>
|
|
<td class="align-middle text-start fw-bolder">
|
|
<span id="grand-total">{{data.grand_total|floatformat}}<span class="icon-saudi_riyal"></span></span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
function calculateTotals() {
|
|
const table = document.getElementById('estimate-table');
|
|
const rows = table.getElementsByTagName('tbody')[0].rows;
|
|
let grandTotal = 0;
|
|
|
|
for (let row of rows) {
|
|
// Ensure the row has the expected number of cells
|
|
if (row.cells.length >= 5) {
|
|
const quantity = parseFloat(row.cells[2].textContent); // Quantity column
|
|
const unitPrice = parseFloat(row.cells[3].textContent); // Unit Price column
|
|
|
|
if (!isNaN(quantity) && !isNaN(unitPrice)) {
|
|
const total = quantity * unitPrice;
|
|
row.cells[4].textContent = total.toFixed(2); // Populate Total column
|
|
grandTotal += total; // Add to grand total
|
|
}
|
|
}
|
|
}
|
|
|
|
// Display the grand total
|
|
document.getElementById('grand-total').textContent = grandTotal.toFixed(2);
|
|
}
|
|
|
|
|
|
// Run the function on page load
|
|
window.onload = calculateTotals;
|
|
</script>
|
|
|
|
{% endblock %} |