adding customers receive
This commit is contained in:
parent
34d6321e11
commit
82334fa523
Binary file not shown.
Binary file not shown.
@ -53,11 +53,11 @@
|
|||||||
|
|
||||||
<!-- Sales Group -->
|
<!-- Sales Group -->
|
||||||
<li class="sidebar-group-header mt-2">
|
<li class="sidebar-group-header mt-2">
|
||||||
<a href="#salesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
|
<a href="#salesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path or url_name == 'customer_payments' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
|
||||||
<span>{% trans "Sales" %}</span>
|
<span>{% trans "Sales" %}</span>
|
||||||
<i class="bi bi-chevron-down chevron"></i>
|
<i class="bi bi-chevron-down chevron"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="collapse list-unstyled sub-menu {% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path %}show{% endif %}" id="salesSubmenu">
|
<ul class="collapse list-unstyled sub-menu {% if url_name == 'pos' or url_name == 'invoice_create' or url_name == 'invoices' or url_name == 'invoice_detail' or url_name == 'quotations' or url_name == 'quotation_create' or url_name == 'quotation_detail' or 'sales/returns' in path or url_name == 'customer_payments' %}show{% endif %}" id="salesSubmenu">
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'pos' %}" class="{% if url_name == 'pos' %}active{% endif %}">
|
<a href="{% url 'pos' %}" class="{% if url_name == 'pos' %}active{% endif %}">
|
||||||
<i class="bi bi-shop"></i> {% trans "POS System" %}
|
<i class="bi bi-shop"></i> {% trans "POS System" %}
|
||||||
@ -83,24 +83,34 @@
|
|||||||
<i class="bi bi-arrow-return-left"></i> {% trans "Sales Return" %}
|
<i class="bi bi-arrow-return-left"></i> {% trans "Sales Return" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'customer_payments' %}" class="{% if url_name == 'customer_payments' %}active{% endif %}">
|
||||||
|
<i class="bi bi-receipt-cutoff"></i> {% trans 'Customer Receipts' %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Inventory Group -->
|
<!-- Purchases Group -->
|
||||||
<li class="sidebar-group-header mt-2">
|
<li class="sidebar-group-header mt-2">
|
||||||
<a href="#inventorySubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'inventory' or url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or 'purchases/returns' in path or url_name == 'barcode_labels' or url_name == 'reports' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
|
<a href="#purchasesSubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or url_name == 'supplier_payments' or 'purchases/returns' in path %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
|
||||||
<span>{% trans "Inventory" %}</span>
|
<span>{% trans "Purchases" %}</span>
|
||||||
<i class="bi bi-chevron-down chevron"></i>
|
<i class="bi bi-chevron-down chevron"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="collapse list-unstyled sub-menu {% if url_name == 'inventory' or url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or 'purchases/returns' in path or url_name == 'barcode_labels' or url_name == 'reports' %}show{% endif %}" id="inventorySubmenu">
|
<ul class="collapse list-unstyled sub-menu {% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' or url_name == 'supplier_payments' or 'purchases/returns' in path %}show{% endif %}" id="purchasesSubmenu">
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'inventory' %}" class="{% if url_name == 'inventory' %}active{% endif %}">
|
<a href="{% url 'purchase_create' %}" class="{% if url_name == 'purchase_create' %}active{% endif %}">
|
||||||
<i class="bi bi-box-seam"></i> {% trans "Products" %}
|
<i class="bi bi-plus-circle"></i> {% trans "New Purchase" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' %}active{% endif %}">
|
<a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_detail' %}active{% endif %}">
|
||||||
<i class="bi bi-cart-check"></i> {% trans "Purchases" %}
|
<i class="bi bi-cart-check"></i> {% trans "Purchase List" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'supplier_payments' %}" class="{% if url_name == 'supplier_payments' %}active{% endif %}">
|
||||||
|
<i class="bi bi-cash-stack"></i> {% trans "Supplier Payments" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -108,6 +118,21 @@
|
|||||||
<i class="bi bi-arrow-return-right"></i> {% trans "Purchase Return" %}
|
<i class="bi bi-arrow-return-right"></i> {% trans "Purchase Return" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Inventory Group -->
|
||||||
|
<li class="sidebar-group-header mt-2">
|
||||||
|
<a href="#inventorySubmenu" data-bs-toggle="collapse" aria-expanded="{% if url_name == 'inventory' or url_name == 'barcode_labels' or url_name == 'reports' %}true{% else %}false{% endif %}" class="dropdown-toggle-custom">
|
||||||
|
<span>{% trans "Inventory" %}</span>
|
||||||
|
<i class="bi bi-chevron-down chevron"></i>
|
||||||
|
</a>
|
||||||
|
<ul class="collapse list-unstyled sub-menu {% if url_name == 'inventory' or url_name == 'barcode_labels' or url_name == 'reports' %}show{% endif %}" id="inventorySubmenu">
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'inventory' %}" class="{% if url_name == 'inventory' %}active{% endif %}">
|
||||||
|
<i class="bi bi-box-seam"></i> {% trans "Products" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'barcode_labels' %}" class="{% if url_name == 'barcode_labels' %}active{% endif %}">
|
<a href="{% url 'barcode_labels' %}" class="{% if url_name == 'barcode_labels' %}active{% endif %}">
|
||||||
<i class="bi bi-upc-scan"></i> {% trans "Barcode Printing" %}
|
<i class="bi bi-upc-scan"></i> {% trans "Barcode Printing" %}
|
||||||
@ -296,4 +321,4 @@
|
|||||||
</script>
|
</script>
|
||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
221
core/templates/core/customer_payment_receipt.html
Normal file
221
core/templates/core/customer_payment_receipt.html
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
{% load i18n static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ LANGUAGE_CODE }}" dir="{% if LANGUAGE_CODE == 'ar' %}rtl{% else %}ltr{% endif %}">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{% trans "Payment Receipt" %} #{{ payment.id }}</title>
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
.no-print { display: none; }
|
||||||
|
body { padding: 0; margin: 0; }
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 40px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
.receipt-container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
border-bottom: 2px solid #eee;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
.business-info h1 {
|
||||||
|
margin: 0;
|
||||||
|
color: #0d6efd;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
.business-info p {
|
||||||
|
margin: 5px 0;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.receipt-title {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.receipt-title h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #333;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
.receipt-meta {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.info-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.info-box h3 {
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
.info-box p {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.payment-details {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px dashed #eee;
|
||||||
|
}
|
||||||
|
.detail-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.amount-box {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
color: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.amount-box h4 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.amount-box .amount {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.btn-print {
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.btn-print:hover { background: #000; }
|
||||||
|
|
||||||
|
[dir="rtl"] .header, [dir="rtl"] .detail-row {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
[dir="rtl"] .receipt-title {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="no-print" style="text-align: center;">
|
||||||
|
<button class="btn-print" onclick="window.print()">{% trans "Print Receipt" %}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="receipt-container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="business-info">
|
||||||
|
{% if settings.logo %}
|
||||||
|
<img src="{{ settings.logo.url }}" alt="Logo" height="50" style="margin-bottom: 10px;">
|
||||||
|
{% endif %}
|
||||||
|
<h1>{{ settings.business_name }}</h1>
|
||||||
|
<p>{{ settings.address|linebreaksbr }}</p>
|
||||||
|
<p>{% trans "Phone" %}: {{ settings.phone }}</p>
|
||||||
|
{% if settings.vat_number %}
|
||||||
|
<p>{% trans "VAT No" %}: {{ settings.vat_number }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="receipt-title">
|
||||||
|
<h2>{% trans "Payment Receipt" %}</h2>
|
||||||
|
<div class="receipt-meta">
|
||||||
|
<p><strong>{% trans "Receipt #" %}:</strong> {{ payment.id }}</p>
|
||||||
|
<p><strong>{% trans "Date" %}:</strong> {{ payment.payment_date|date:"Y-m-d" }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-grid">
|
||||||
|
<div class="info-box">
|
||||||
|
<h3>{% trans "Received From" %}</h3>
|
||||||
|
<p>{{ payment.sale.customer.name|default:"Guest" }}</p>
|
||||||
|
{% if payment.sale.customer.phone %}
|
||||||
|
<p class="text-muted" style="font-weight: normal; font-size: 14px;">{{ payment.sale.customer.phone }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="info-box">
|
||||||
|
<h3>{% trans "In Reference To" %}</h3>
|
||||||
|
<p>{% trans "Invoice" %} #{{ payment.sale.invoice_number|default:payment.sale.id }}</p>
|
||||||
|
<p class="text-muted" style="font-weight: normal; font-size: 14px;">{% trans "Total Amount" %}: {{ settings.currency_symbol }}{{ payment.sale.total_amount|floatformat:3 }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="payment-details">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">{% trans "Payment Method" %}</span>
|
||||||
|
<span class="value">{{ payment.payment_method_name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">{% trans "Transaction Status" %}</span>
|
||||||
|
<span class="value" style="color: green;">{% trans "Completed" %}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">{% trans "Recorded By" %}</span>
|
||||||
|
<span class="value">{{ payment.created_by.get_full_name|default:payment.created_by.username }}</span>
|
||||||
|
</div>
|
||||||
|
{% if payment.notes %}
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">{% trans "Notes" %}</span>
|
||||||
|
<span class="value">{{ payment.notes }}</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="amount-box">
|
||||||
|
<h4>{% trans "Amount Received" %}</h4>
|
||||||
|
<div class="amount">{{ settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p>{% trans "Thank you for your business!" %}</p>
|
||||||
|
<p>{{ settings.business_name }} © {% now "Y" %}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
113
core/templates/core/customer_payments.html
Normal file
113
core/templates/core/customer_payments.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Customer Receipts" %} | {{ site_settings.business_name }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container-fluid px-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div>
|
||||||
|
<h2 class="fw-bold mb-0">{% trans "Customer Receipts" %}</h2>
|
||||||
|
<p class="text-muted small mb-0">{% trans "History of payments received from customers" %}</p>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<a href="{% url 'invoices' %}" class="btn btn-outline-primary rounded-3 px-4 shadow-sm">
|
||||||
|
<i class="bi bi-file-earmark-text me-2"></i>{% trans "Sales Invoices" %}
|
||||||
|
</a>
|
||||||
|
<a href="{% url 'pos' %}" class="btn btn-primary rounded-3 px-4 shadow-sm">
|
||||||
|
<i class="bi bi-shop me-2"></i>{% trans "POS System" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Filters -->
|
||||||
|
<div class="card border-0 shadow-sm rounded-4 mb-4">
|
||||||
|
<div class="card-body p-3">
|
||||||
|
<form method="get" class="row g-3">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label small fw-bold text-muted">{% trans "Customer" %}</label>
|
||||||
|
<select name="customer" class="form-select border-0 bg-light">
|
||||||
|
<option value="">{% trans "All Customers" %}</option>
|
||||||
|
{% for c in customers %}
|
||||||
|
<option value="{{ c.id }}" {% if customer_id == c.id|stringformat:"s" %}selected{% endif %}>{{ c.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label small fw-bold text-muted">{% trans "From" %}</label>
|
||||||
|
<input type="date" name="start_date" class="form-control border-0 bg-light" value="{{ start_date }}">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label small fw-bold text-muted">{% trans "To" %}</label>
|
||||||
|
<input type="date" name="end_date" class="form-control border-0 bg-light" value="{{ end_date }}">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 d-flex align-items-end gap-2">
|
||||||
|
<button type="submit" class="btn btn-dark w-100 rounded-3">{% trans "Filter" %}</button>
|
||||||
|
<a href="{% url 'customer_payments' %}" class="btn btn-light w-100 rounded-3 border">{% trans "Clear" %}</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card border-0 shadow-sm rounded-4">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle mb-0">
|
||||||
|
<thead class="bg-light">
|
||||||
|
<tr>
|
||||||
|
<th class="ps-4">{% trans "Date" %}</th>
|
||||||
|
<th>{% trans "Invoice #" %}</th>
|
||||||
|
<th>{% trans "Customer" %}</th>
|
||||||
|
<th>{% trans "Amount" %}</th>
|
||||||
|
<th>{% trans "Method" %}</th>
|
||||||
|
<th>{% trans "User" %}</th>
|
||||||
|
<th>{% trans "Receipt" %}</th>
|
||||||
|
<th class="pe-4">{% trans "Notes" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for payment in payments %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-4">{{ payment.payment_date|date:"Y-m-d" }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'invoice_detail' payment.sale.id %}" class="fw-bold text-decoration-none">
|
||||||
|
{{ payment.sale.invoice_number|default:payment.sale.id }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ payment.sale.customer.name|default:"Guest" }}</td>
|
||||||
|
<td class="fw-bold text-dark">{{ site_settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge bg-light text-dark border rounded-pill px-3">
|
||||||
|
{{ payment.payment_method_name }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="text-muted small">
|
||||||
|
<i class="bi bi-person me-1"></i>{{ payment.created_by.username|default:"System" }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'customer_payment_receipt' payment.id %}" target="_blank" class="btn btn-sm btn-outline-info rounded-pill">
|
||||||
|
<i class="bi bi-printer me-1"></i>{% trans "Print" %}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="pe-4">
|
||||||
|
<span class="small text-muted">{{ payment.notes|default:"-" }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="8" class="text-center py-5">
|
||||||
|
<img src="https://illustrations.popsy.co/gray/payments.svg" alt="Empty" style="width: 200px;" class="mb-3">
|
||||||
|
<p class="text-muted">{% trans "No customer receipts found." %}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% include "core/pagination.html" with page_obj=payments %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
73
core/templates/core/supplier_payments.html
Normal file
73
core/templates/core/supplier_payments.html
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Supplier Payments" %} | {{ site_settings.business_name }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container-fluid px-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div>
|
||||||
|
<h2 class="fw-bold mb-0">{% trans "Supplier Payments" %}</h2>
|
||||||
|
<p class="text-muted small mb-0">{% trans "History of payments made to suppliers" %}</p>
|
||||||
|
</div>
|
||||||
|
<a href="{% url 'purchases' %}" class="btn btn-primary rounded-3 px-4 shadow-sm">
|
||||||
|
<i class="bi bi-list-ul me-2"></i>{% trans "Purchase Invoices" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card border-0 shadow-sm rounded-4">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle mb-0">
|
||||||
|
<thead class="bg-light">
|
||||||
|
<tr>
|
||||||
|
<th class="ps-4">{% trans "Date" %}</th>
|
||||||
|
<th>{% trans "Purchase #" %}</th>
|
||||||
|
<th>{% trans "Supplier" %}</th>
|
||||||
|
<th>{% trans "Amount" %}</th>
|
||||||
|
<th>{% trans "Method" %}</th>
|
||||||
|
<th>{% trans "User" %}</th>
|
||||||
|
<th class="pe-4">{% trans "Notes" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for payment in payments %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-4">{{ payment.payment_date|date:"Y-m-d" }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'purchase_detail' payment.purchase.id %}" class="fw-bold text-decoration-none">
|
||||||
|
{{ payment.purchase.invoice_number|default:payment.purchase.id }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ payment.purchase.supplier.name|default:"-" }}</td>
|
||||||
|
<td class="fw-bold text-dark">{{ site_settings.currency_symbol }}{{ payment.amount|floatformat:3 }}</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge bg-light text-dark border rounded-pill px-3">
|
||||||
|
{{ payment.payment_method_name }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="text-muted small">
|
||||||
|
<i class="bi bi-person me-1"></i>{{ payment.created_by.username|default:"System" }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="pe-4">
|
||||||
|
<span class="small text-muted">{{ payment.notes|default:"-" }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="7" class="text-center py-5">
|
||||||
|
<img src="https://illustrations.popsy.co/gray/payments.svg" alt="Empty" style="width: 200px;" class="mb-3">
|
||||||
|
<p class="text-muted">{% trans "No purchase payments found." %}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% include "core/pagination.html" with page_obj=payments %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -20,6 +20,8 @@ urlpatterns = [
|
|||||||
path('invoices/<int:pk>/', views.invoice_detail, name='invoice_detail'),
|
path('invoices/<int:pk>/', views.invoice_detail, name='invoice_detail'),
|
||||||
path('invoices/payment/<int:pk>/', views.add_sale_payment, name='add_sale_payment'),
|
path('invoices/payment/<int:pk>/', views.add_sale_payment, name='add_sale_payment'),
|
||||||
path('invoices/delete/<int:pk>/', views.delete_sale, name='delete_sale'),
|
path('invoices/delete/<int:pk>/', views.delete_sale, name='delete_sale'),
|
||||||
|
path('invoices/payments/', views.customer_payments, name='customer_payments'),
|
||||||
|
path('invoices/receipt/<int:pk>/', views.customer_payment_receipt, name='customer_payment_receipt'),
|
||||||
path("invoices/edit/<int:pk>/", views.edit_invoice, name="edit_invoice"),
|
path("invoices/edit/<int:pk>/", views.edit_invoice, name="edit_invoice"),
|
||||||
|
|
||||||
# Quotations
|
# Quotations
|
||||||
@ -42,6 +44,7 @@ urlpatterns = [
|
|||||||
path('purchases/<int:pk>/', views.purchase_detail, name='purchase_detail'),
|
path('purchases/<int:pk>/', views.purchase_detail, name='purchase_detail'),
|
||||||
path('purchases/payment/<int:pk>/', views.add_purchase_payment, name='add_purchase_payment'),
|
path('purchases/payment/<int:pk>/', views.add_purchase_payment, name='add_purchase_payment'),
|
||||||
path('purchases/delete/<int:pk>/', views.delete_purchase, name='delete_purchase'),
|
path('purchases/delete/<int:pk>/', views.delete_purchase, name='delete_purchase'),
|
||||||
|
path('purchases/payments/', views.supplier_payments, name='supplier_payments'),
|
||||||
|
|
||||||
# Purchase Returns
|
# Purchase Returns
|
||||||
path('purchases/returns/', views.purchase_returns, name='purchase_returns'),
|
path('purchases/returns/', views.purchase_returns, name='purchase_returns'),
|
||||||
|
|||||||
@ -132,6 +132,13 @@ def suppliers(request):
|
|||||||
# --- Purchase Views ---
|
# --- Purchase Views ---
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
def supplier_payments(request):
|
||||||
|
payments_qs = PurchasePayment.objects.all().select_related("purchase", "purchase__supplier", "payment_method", "created_by").order_by("-payment_date", "-id")
|
||||||
|
paginator = Paginator(payments_qs, 25)
|
||||||
|
page_number = request.GET.get("page")
|
||||||
|
payments = paginator.get_page(page_number)
|
||||||
|
return render(request, "core/supplier_payments.html", {"payments": payments})
|
||||||
|
|
||||||
def purchases(request):
|
def purchases(request):
|
||||||
purchases_qs = Purchase.objects.all().select_related('supplier', 'created_by').order_by('-created_at')
|
purchases_qs = Purchase.objects.all().select_related('supplier', 'created_by').order_by('-created_at')
|
||||||
paginator = Paginator(purchases_qs, 25)
|
paginator = Paginator(purchases_qs, 25)
|
||||||
@ -1859,3 +1866,48 @@ def update_sale_api(request, pk):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return JsonResponse({'success': False, 'error': str(e)}, status=400)
|
return JsonResponse({'success': False, 'error': str(e)}, status=400)
|
||||||
return JsonResponse({'success': False, 'error': 'Invalid request'}, status=405)
|
return JsonResponse({'success': False, 'error': 'Invalid request'}, status=405)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def customer_payments(request):
|
||||||
|
"""
|
||||||
|
List of payments received from customers
|
||||||
|
"""
|
||||||
|
payments_qs = SalePayment.objects.all().select_related("sale", "sale__customer", "payment_method", "created_by").order_by("-payment_date", "-id")
|
||||||
|
|
||||||
|
# Filtering
|
||||||
|
start_date = request.GET.get("start_date")
|
||||||
|
end_date = request.GET.get("end_date")
|
||||||
|
customer_id = request.GET.get("customer")
|
||||||
|
|
||||||
|
if start_date:
|
||||||
|
payments_qs = payments_qs.filter(payment_date__gte=start_date)
|
||||||
|
if end_date:
|
||||||
|
payments_qs = payments_qs.filter(payment_date__lte=end_date)
|
||||||
|
if customer_id:
|
||||||
|
payments_qs = payments_qs.filter(sale__customer_id=customer_id)
|
||||||
|
|
||||||
|
paginator = Paginator(payments_qs, 25)
|
||||||
|
page_number = request.GET.get("page")
|
||||||
|
payments = paginator.get_page(page_number)
|
||||||
|
|
||||||
|
customers = Customer.objects.all().order_by("name")
|
||||||
|
|
||||||
|
return render(request, "core/customer_payments.html", {
|
||||||
|
"payments": payments,
|
||||||
|
"customers": customers,
|
||||||
|
"start_date": start_date,
|
||||||
|
"end_date": end_date,
|
||||||
|
"customer_id": customer_id,
|
||||||
|
})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def customer_payment_receipt(request, pk):
|
||||||
|
"""
|
||||||
|
Printable receipt for a customer payment
|
||||||
|
"""
|
||||||
|
payment = get_object_or_404(SalePayment, pk=pk)
|
||||||
|
settings = SystemSetting.objects.first()
|
||||||
|
return render(request, "core/customer_payment_receipt.html", {
|
||||||
|
"payment": payment,
|
||||||
|
"settings": settings
|
||||||
|
})
|
||||||
|
|||||||
@ -193,4 +193,117 @@ body {
|
|||||||
#content {
|
#content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enhanced Responsiveness */
|
||||||
|
|
||||||
|
/* Container & Spacing Adjustments */
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
main.p-4 {
|
||||||
|
padding: 1rem !important;
|
||||||
|
}
|
||||||
|
.hero-gradient {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
.top-navbar {
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
h1, .h1 { font-size: 1.5rem; }
|
||||||
|
h2, .h2 { font-size: 1.25rem; }
|
||||||
|
h3, .h3 { font-size: 1.1rem; }
|
||||||
|
h4, .h4 { font-size: 1rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar Overlay for Mobile */
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
#sidebar {
|
||||||
|
box-shadow: 0 0 20px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
#sidebar.active {
|
||||||
|
margin-inline-start: 0;
|
||||||
|
}
|
||||||
|
#sidebar:not(.active) {
|
||||||
|
margin-inline-start: calc(-1 * var(--sidebar-width));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overlay effect when sidebar is active */
|
||||||
|
#sidebar.active::after {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(0,0,0,0.2);
|
||||||
|
z-index: -1;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table Card Styling for Mobile */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.table-responsive {
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.btn-sm {
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* POS Specific Responsive Utilities */
|
||||||
|
.mobile-cart-toggle {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 1030;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding: 12px 24px;
|
||||||
|
box-shadow: 0 4px 15px rgba(46, 91, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .mobile-cart-toggle {
|
||||||
|
right: auto;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.mobile-cart-toggle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.cart-container {
|
||||||
|
position: fixed !important;
|
||||||
|
top: 0 !important;
|
||||||
|
right: -100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
z-index: 1040 !important;
|
||||||
|
transition: right 0.3s ease;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
[dir="rtl"] .cart-container {
|
||||||
|
right: auto !important;
|
||||||
|
left: -100% !important;
|
||||||
|
transition: left 0.3s ease;
|
||||||
|
}
|
||||||
|
.cart-container.show {
|
||||||
|
right: 0 !important;
|
||||||
|
}
|
||||||
|
[dir="rtl"] .cart-container.show {
|
||||||
|
left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure body doesn't scroll when cart is open */
|
||||||
|
body.cart-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grid adjustments */
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
#productGrid .col {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user