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 -->
|
||||
<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>
|
||||
<i class="bi bi-chevron-down chevron"></i>
|
||||
</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>
|
||||
<a href="{% url 'pos' %}" class="{% if url_name == 'pos' %}active{% endif %}">
|
||||
<i class="bi bi-shop"></i> {% trans "POS System" %}
|
||||
@ -83,24 +83,34 @@
|
||||
<i class="bi bi-arrow-return-left"></i> {% trans "Sales Return" %}
|
||||
</a>
|
||||
</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>
|
||||
</li>
|
||||
|
||||
<!-- Inventory Group -->
|
||||
<!-- Purchases Group -->
|
||||
<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">
|
||||
<span>{% trans "Inventory" %}</span>
|
||||
<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 "Purchases" %}</span>
|
||||
<i class="bi bi-chevron-down chevron"></i>
|
||||
</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>
|
||||
<a href="{% url 'inventory' %}" class="{% if url_name == 'inventory' %}active{% endif %}">
|
||||
<i class="bi bi-box-seam"></i> {% trans "Products" %}
|
||||
<a href="{% url 'purchase_create' %}" class="{% if url_name == 'purchase_create' %}active{% endif %}">
|
||||
<i class="bi bi-plus-circle"></i> {% trans "New Purchase" %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_create' or url_name == 'purchase_detail' %}active{% endif %}">
|
||||
<i class="bi bi-cart-check"></i> {% trans "Purchases" %}
|
||||
<a href="{% url 'purchases' %}" class="{% if url_name == 'purchases' or url_name == 'purchase_detail' %}active{% endif %}">
|
||||
<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>
|
||||
</li>
|
||||
<li>
|
||||
@ -108,6 +118,21 @@
|
||||
<i class="bi bi-arrow-return-right"></i> {% trans "Purchase Return" %}
|
||||
</a>
|
||||
</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>
|
||||
<a href="{% url 'barcode_labels' %}" class="{% if url_name == 'barcode_labels' %}active{% endif %}">
|
||||
<i class="bi bi-upc-scan"></i> {% trans "Barcode Printing" %}
|
||||
|
||||
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/payment/<int:pk>/', views.add_sale_payment, name='add_sale_payment'),
|
||||
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"),
|
||||
|
||||
# Quotations
|
||||
@ -42,6 +44,7 @@ urlpatterns = [
|
||||
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/delete/<int:pk>/', views.delete_purchase, name='delete_purchase'),
|
||||
path('purchases/payments/', views.supplier_payments, name='supplier_payments'),
|
||||
|
||||
# Purchase Returns
|
||||
path('purchases/returns/', views.purchase_returns, name='purchase_returns'),
|
||||
|
||||
@ -132,6 +132,13 @@ def suppliers(request):
|
||||
# --- Purchase Views ---
|
||||
|
||||
@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):
|
||||
purchases_qs = Purchase.objects.all().select_related('supplier', 'created_by').order_by('-created_at')
|
||||
paginator = Paginator(purchases_qs, 25)
|
||||
@ -1859,3 +1866,48 @@ def update_sale_api(request, pk):
|
||||
traceback.print_exc()
|
||||
return JsonResponse({'success': False, 'error': str(e)}, status=400)
|
||||
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
|
||||
})
|
||||
|
||||
@ -194,3 +194,116 @@ body {
|
||||
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