new chnages to the sale and purchase report and chnages to the charts label colors #220

Merged
ismail merged 1 commits from frontend into main 2025-09-02 14:09:13 +03:00
9 changed files with 324 additions and 157 deletions

View File

@ -1308,6 +1308,7 @@ urlpatterns = [
views.car_sale_report_view,
name="car-sale-report",
),
path('<slug:dealer_slug>/car-sale-report/get_filtered_choices/',views.get_filtered_choices,name='get_filtered_choices'),
path('car-sale-report/<slug:dealer_slug>/csv/', views.car_sale_report_csv_export, name='car-sale-report-csv-export'),
path('feature/recall/', views.RecallListView.as_view(), name='recall_list'),

View File

@ -11030,55 +11030,76 @@ class InventoryListView(InventoryListViewBase):
permission_required = ["django_ledger.view_purchaseordermodel"]
@login_required
def purchase_report_view(request,dealer_slug):
def purchase_report_view(request, dealer_slug):
start_date_str = request.GET.get('start_date')
end_date_str = request.GET.get('end_date')
pos = request.entity.get_purchase_orders()
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
pos = pos.filter(created__date__gte=start_date)
except (ValueError, TypeError):
pass
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
pos = pos.filter(created__date__lte=end_date)
except (ValueError, TypeError):
pass
data = []
total_po_amount=0
total_po_cars=0
total_po_amount = 0
total_po_cars = 0
for po in pos:
items = [{"total":x.total_amount,"q":x.quantity} for x in po.get_itemtxs_data()[0].all()]
items = [{"total": x.total_amount, "q": x.quantity} for x in po.get_itemtxs_data()[0].all()]
po_amount=0
po_quantity=0
for item in items:
po_amount+=item["total"]
po_quantity+=item["q"]
po_amount = sum(item["total"] for item in items)
po_quantity = sum(item["q"] for item in items)
total_po_amount+=po_amount
total_po_cars+=po_quantity
bills=po.get_po_bill_queryset()
vendors=set([bill.vendor.vendor_name for bill in bills])
total_po_amount += po_amount
total_po_cars += po_quantity
bills = po.get_po_bill_queryset()
vendors = set([bill.vendor.vendor_name for bill in bills])
vendors_str = ", ".join(sorted(list(vendors))) if vendors else "N/A"
data.append({"po_number":po.po_number,"po_created":po.created,"po_status":po.po_status,"po_fulfilled_date":po.date_fulfilled,"po_amount":po_amount,
"po_quantity":po_quantity,"vendors_str":vendors_str})
data.append({
"po_number": po.po_number,
"po_created": po.created,
"po_status": po.po_status,
"po_fulfilled_date": po.date_fulfilled,
"po_amount": po_amount,
"po_quantity": po_quantity,
"vendors_str": vendors_str
})
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
context={
"dealer":request.entity.name,
"time":current_time,
"data":data,
"total_po_amount":total_po_amount,
"total_po_cars":total_po_cars,
"current_time":current_time
context = {
"dealer": request.entity.name,
"time": current_time,
"data": data,
"total_po_amount": total_po_amount,
"total_po_cars": total_po_cars,
"current_time": current_time,
"start_date": start_date_str,
"end_date": end_date_str,
}
return render(request, 'ledger/reports/purchase_report.html', context)
return render(request,'ledger/reports/purchase_report.html',context)
def purchase_report_csv_export(request,dealer_slug):
def purchase_report_csv_export(request, dealer_slug):
response = HttpResponse(content_type='text/csv')
current_time = timezone.now().strftime("%Y-%m-%d_%H%M%S")
filename = f"purchase_report_{dealer_slug}_{current_time}.csv"
response['Content-Disposition'] = f'attachment; filename="{filename}"'
writer = csv.writer(response)
header = [
'PO Number',
'Created Date',
@ -11089,22 +11110,38 @@ def purchase_report_csv_export(request,dealer_slug):
'Vendors'
]
writer.writerow(header)
pos = request.entity.get_purchase_orders()
start_date_str = request.GET.get('start_date')
end_date_str = request.GET.get('end_date')
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
pos = pos.filter(created__date__gte=start_date)
except (ValueError, TypeError):
pass
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
pos = pos.filter(created__date__lte=end_date)
except (ValueError, TypeError):
pass
for po in pos:
po_amount = 0
po_quantity = 0
items = [{"total":x.total_amount,"q":x.quantity} for x in po.get_itemtxs_data()[0].all()]
items = [{"total": x.total_amount, "q": x.quantity} for x in po.get_itemtxs_data()[0].all()]
for item in items:
po_amount += item["total"]
po_quantity += item["q"]
bills = po.get_po_bill_queryset()
vendors = set([bill.vendor.vendor_name for bill in bills ])
vendors = set([bill.vendor.vendor_name for bill in bills])
vendors_str = ", ".join(sorted(list(vendors))) if vendors else "N/A"
writer.writerow([
po.po_number,
po.created.strftime("%Y-%m-%d %H:%M:%S") if po.created else '',
@ -11117,22 +11154,22 @@ def purchase_report_csv_export(request,dealer_slug):
return response
@login_required
def car_sale_report_view(request, dealer_slug):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
vat = models.VatRate.objects.filter(dealer=dealer,is_active=True).first()
VAT_RATE=vat.rate
vat = models.VatRate.objects.filter(dealer=dealer, is_active=True).first()
VAT_RATE = vat.rate if vat else 0
cars_sold = models.Car.objects.filter(dealer=dealer, status='sold')
# Get filter parameters from the request
selected_make = request.GET.get('make')
selected_model = request.GET.get('model')
selected_serie = request.GET.get('serie')
selected_year = request.GET.get('year')
selected_stock_type=request.GET.get('stock_type')
selected_stock_type = request.GET.get('stock_type')
start_date_str = request.GET.get('start_date')
end_date_str = request.GET.get('end_date')
# Apply filters to the queryset
if selected_make:
@ -11145,62 +11182,122 @@ def car_sale_report_view(request, dealer_slug):
cars_sold = cars_sold.filter(year=selected_year)
if selected_stock_type:
cars_sold = cars_sold.filter(stock_type=selected_stock_type)
# Corrected: Apply date filters using the 'sold_date' field
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
cars_sold = cars_sold.filter(sold_date__gte=start_date)
except (ValueError, TypeError):
pass
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
cars_sold = cars_sold.filter(sold_date__lte=end_date)
except (ValueError, TypeError):
pass
# # Calculate summary data for the filtered results
total_cars_sold=cars_sold.count()
# Calculate summary data for the filtered results
total_cars_sold = cars_sold.count()
total_revenue_from_cars = cars_sold.aggregate(
total=Sum(F('marked_price') - F('discount_amount'))
)['total'] or 0
total_vat_on_cars=cars_sold.annotate(
total_vat_on_cars = cars_sold.annotate(
final_price=F('marked_price') - F('discount_amount')).aggregate(
total=Sum(F('final_price') * VAT_RATE))['total'] or 0
total_revenue_from_additonals=sum([car.get_additional_services()['total'] for car in cars_sold])
total_vat_from_additonals=sum([car.get_additional_services()['services_vat'] for car in cars_sold])
total_vat_collected = total_vat_on_cars+total_vat_from_additonals
total_revenue_collected=total_revenue_from_cars+total_revenue_from_additonals
total_discount = sum([car.discount for car in cars_sold])
total_revenue_from_additonals = sum([car.get_additional_services()['total'] for car in cars_sold])
total_vat_from_additonals = sum([car.get_additional_services()['services_vat'] for car in cars_sold])
total_vat_collected = total_vat_on_cars + total_vat_from_additonals
total_revenue_collected = total_revenue_from_cars + total_revenue_from_additonals
total_discount = cars_sold.aggregate(total=Sum('discount_amount'))['total'] or 0
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
# Get distinct values for filter dropdowns
# Get distinct makes for the initial dropdown, other dropdowns will be populated via AJAX
base_sold_cars_queryset = models.Car.objects.filter(dealer=dealer, status='sold')
makes =base_sold_cars_queryset.values_list('id_car_make__name', flat=True).distinct()
models_qs =base_sold_cars_queryset.values_list('id_car_model__name', flat=True).distinct()
series =base_sold_cars_queryset.values_list('id_car_serie__name', flat=True).distinct()
stock_types=base_sold_cars_queryset.values_list('stock_type', flat=True).distinct()
years = base_sold_cars_queryset.values_list('year', flat=True).distinct().order_by('-year')
makes = base_sold_cars_queryset.values_list('id_car_make__name', flat=True).distinct().order_by('id_car_make__name')
context = {
'cars_sold': cars_sold,
'total_cars_sold':total_cars_sold,
'total_cars_sold': total_cars_sold,
'current_time': current_time,
'dealer': dealer,
'total_revenue_from_cars': total_revenue_from_cars,
'total_revenue_from_additonals':total_revenue_from_additonals,
'total_revenue_from_additonals': total_revenue_from_additonals,
'total_revenue_collected': total_revenue_collected,
'total_vat_on_cars':total_vat_on_cars,
'total_vat_from_additonals':total_vat_from_additonals,
'total_vat_collected':total_vat_collected,
'total_vat_on_cars': total_vat_on_cars,
'total_vat_from_additonals': total_vat_from_additonals,
'total_vat_collected': total_vat_collected,
'total_discount': total_discount,
'makes': makes,
'models': models_qs,
'series': series,
'years': years,
'stock_types':stock_types,
'selected_make': selected_make,
'selected_model': selected_model,
'selected_serie': selected_serie,
'selected_year': selected_year,
'selected_stock_type':selected_stock_type,
'selected_stock_type': selected_stock_type,
'start_date': start_date_str,
'end_date': end_date_str,
}
return render(request, 'ledger/reports/car_sale_report.html', context)
### 2. Updated `get_filtered_choices`
@login_required
def get_filtered_choices(request, dealer_slug):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
# Get all filter parameters from the request
selected_make = request.GET.get('make')
selected_model = request.GET.get('model')
selected_serie = request.GET.get('serie')
start_date_str = request.GET.get('start_date')
end_date_str = request.GET.get('end_date')
# Start with the base queryset
queryset = models.Car.objects.filter(dealer=dealer, status='sold')
# Apply filters based on what is selected
if selected_make:
queryset = queryset.filter(id_car_make__name=selected_make)
if selected_model:
queryset = queryset.filter(id_car_model__name=selected_model)
if selected_serie:
queryset = queryset.filter(id_car_serie__name=selected_serie)
# Corrected: Apply date filters to the AJAX queryset
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
queryset = queryset.filter(sold_date__gte=start_date)
except (ValueError, TypeError):
pass
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
queryset = queryset.filter(sold_date__lte=end_date)
except (ValueError, TypeError):
pass
data = {
'models': list(queryset.values_list('id_car_model__name', flat=True).distinct().order_by('id_car_model__name')),
'series': list(queryset.values_list('id_car_serie__name', flat=True).distinct().order_by('id_car_serie__name')),
'years': list(queryset.values_list('year', flat=True).distinct().order_by('-year')),
'stock_types': list(queryset.values_list('stock_type', flat=True).distinct().order_by('stock_type'))
}
return JsonResponse(data)
### 3. Updated `car_sale_report_csv_export`
@login_required
def car_sale_report_csv_export(request, dealer_slug):
response = HttpResponse(content_type='text/csv')
@ -11229,6 +11326,8 @@ def car_sale_report_csv_export(request, dealer_slug):
selected_serie = request.GET.get('serie')
selected_year = request.GET.get('year')
selected_stock_type = request.GET.get('stock_type')
start_date_str = request.GET.get('start_date')
end_date_str = request.GET.get('end_date')
if selected_make:
cars_sold = cars_sold.filter(id_car_make__name=selected_make)
@ -11240,15 +11339,28 @@ def car_sale_report_csv_export(request, dealer_slug):
cars_sold = cars_sold.filter(year=selected_year)
if selected_stock_type:
cars_sold = cars_sold.filter(stock_type=selected_stock_type)
# Corrected: Apply date filters for CSV export
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
cars_sold = cars_sold.filter(sold_date__gte=start_date)
except (ValueError, TypeError):
pass
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
cars_sold = cars_sold.filter(sold_date__lte=end_date)
except (ValueError, TypeError):
pass
# Write the data for the filtered cars
for car in cars_sold:
# Fetching data for the additional services
additional_services = car.get_additional_services()
services_total_price = additional_services['total']
services_vat_amount = additional_services['services_vat']
# Checking for the invoice number to avoid errors on cars without one
invoice_number = None
sold_date = None
if car.invoice:
@ -11268,18 +11380,17 @@ def car_sale_report_csv_export(request, dealer_slug):
sold_date.strftime("%Y-%m-%d %H:%M:%S") if sold_date else '',
car.cost_price,
car.marked_price,
car.discount, # Ensure this property returns a number
car.final_price, # Selling Price without VAT
car.vat_amount, # VAT on the car
services_total_price, # Total services without VAT
services_vat_amount, # VAT on services
car.discount_amount,
car.final_price,
car.vat_amount,
services_total_price,
services_vat_amount,
car.final_price_plus_services_plus_vat,
invoice_number,
])
return response
@login_required
# @permission_required('inventory.view_staff')
def staff_password_reset_view(request, dealer_slug, user_pk):

Binary file not shown.

View File

@ -13191,20 +13191,14 @@ msgid "Total cars"
msgstr "إجمالي السيارات"
#: templates/dealers/dealer_detail.html:113
#, fuzzy
#| msgid "Subscriptions"
msgid "Plan & Subscription"
msgstr "الاشتراكات"
#: templates/dealers/dealer_detail.html:125
#, fuzzy
#| msgid "Car Details"
msgid "Company Details"
msgstr "تفاصيل السيارة"
#: templates/dealers/dealer_detail.html:137
#, fuzzy
#| msgid "Car Transfer"
msgid "Car Brands"
msgstr "نقل السيارة"
@ -13252,8 +13246,6 @@ msgid "Upgrade Plan"
msgstr "ترقية الخطة"
#: templates/dealers/dealer_detail.html:212
#, fuzzy
#| msgid "Manage Groups & Permissions"
msgid "Manage Users & Cars"
msgstr "إدارة المجموعات والأذونات"
@ -13269,20 +13261,14 @@ msgid "Contact support to increase your limits"
msgstr ""
#: templates/dealers/dealer_detail.html:258
#, fuzzy
#| msgid "Client Information"
msgid "Contact Information"
msgstr "معلومات العميل"
#: templates/dealers/dealer_detail.html:286
#, fuzzy
#| msgid "User Information"
msgid "VAT Information"
msgstr "معلومات المستخدم"
#: templates/dealers/dealer_detail.html:292
#, fuzzy
#| msgid "Updated At"
msgid "Update VAT"
msgstr "تم التحديث"
@ -13291,8 +13277,6 @@ msgid "Makes you are selling"
msgstr "الماركات التي تبيعها"
#: templates/dealers/dealer_detail.html:321
#, fuzzy
#| msgid "No staff member selected."
msgid "No car makes selected."
msgstr "لم يتم اختيار أي عضو من الفريق."

View File

@ -122,7 +122,7 @@
data: {{ monthly_cars_sold_json|safe }},
backgroundColor: primaryColor,
borderColor: primaryColor,
borderWidth: 1
borderWidth: 1,
}]
},
options: {
@ -193,7 +193,7 @@
plugins: {
legend: {
display: true,
labels: { color: '#495057', boxWidth: 20 }
labels: { boxWidth: 20 }
},
tooltip: {
backgroundColor: 'rgba(33, 37, 41, 0.9)',
@ -250,7 +250,7 @@
plugins: {
legend: {
position: 'right',
labels: { color: '#343a40', font: { size: 14 } }
labels: { font: { size: 14 } }
},
tooltip: {
backgroundColor: 'rgba(33, 37, 41, 0.9)',
@ -349,7 +349,7 @@
plugins: {
legend: {
position: 'right',
labels: { color: '#343a40', font: { size: 14 } }
labels: { font: { size: 14 } }
},
tooltip: {
backgroundColor: 'rgba(33, 37, 41, 0.9)',

View File

@ -3,7 +3,7 @@
{% load static %}
{% load tenhal_tag %}
{% block title %}
{{ _("Car Sale Report") |capfirst }}
{{ _("Car Sale Report")|capfirst }}
{% endblock title %}
{% block content %}
<style>
@ -15,7 +15,7 @@
}
.summary-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0,0,0,0.1);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
.summary-card .card-body {
display: flex;
@ -32,9 +32,7 @@
.summary-card .card-text {
font-size: 2.25rem;
font-weight: 700;
}
</style>
<div class="container-fluid report-container">
<header class="report-header text-center">
@ -47,11 +45,19 @@
<p class="text-muted">{% trans 'Report Date' %}: {{ current_time }}</p>
</header>
<main>
<section id="filters" class="mb-5 p-4 rounded border border-primary">
<section id="filters" class="mb-5 p-4 rounded border border-primary">
<h2 class="section-heading mb-4">
{% trans 'Filters' %} <i class="fas fa-sliders-h ms-2"></i>
</h2>
<form method="GET" class="row g-3 align-items-end">
<form method="GET" class="row g-3 align-items-end" data-filter-url="{% url 'get_filtered_choices' dealer_slug=dealer.slug %}">
<div class="col-md-6">
<label for="start_date" class="form-label">{% trans 'Start Date' %}</label>
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ start_date }}">
</div>
<div class="col-md-6">
<label for="end_date" class="form-label">{% trans 'End Date' %}</label>
<input type="date" class="form-control" id="end_date" name="end_date" value="{{ end_date }}">
</div>
<div class="col-md-2">
<label for="make-select" class="form-label">{% trans 'Make' %}</label>
<select id="make-select" name="make" class="form-select">
@ -65,44 +71,36 @@
<label for="model-select" class="form-label">{% trans 'Model' %}</label>
<select id="model-select" name="model" class="form-select">
<option value="">{% trans 'All Models' %}</option>
{% for model in models %}
<option value="{{ model }}"
{% if model == selected_model %}selected{% endif %}>{{ model }}</option>
{% endfor %}
{% if selected_model %}
<option value="{{ selected_model }}" selected>{{ selected_model }}</option>
{% endif %}
</select>
</div>
<div class="col-md-2">
<label for="serie-select" class="form-label">{% trans 'Serie' %}</label>
<select id="serie-select" name="serie" class="form-select">
<option value="">{% trans 'All Series' %}</option>
{% for serie in series %}
<option value="{{ serie }}"
{% if serie == selected_serie %}selected{% endif %}>{{ serie }}</option>
{% endfor %}
{% if selected_serie %}
<option value="{{ selected_serie }}" selected>{{ selected_serie }}</option>
{% endif %}
</select>
</div>
<div class="col-md-2">
<label for="year-select" class="form-label">{% trans 'Year' %}</label>
<select id="year-select" name="year" class="form-select">
<option value="">{% trans 'All Years' %}</option>
{% for year in years %}
<option value="{{ year }}"
{% if year|stringformat:"s" == selected_year %}selected{% endif %}>
{{ year }}
</option>
{% endfor %}
{% if selected_year %}
<option value="{{ selected_year }}" selected>{{ selected_year }}</option>
{% endif %}
</select>
</div>
<div class="col-md-2">
<label for="stock_type-select" class="form-label">{% trans 'Stock Types' %}</label>
<select id="stock_type-select" name="stock_type" class="form-select">
<option value="">{% trans 'Stock Types' %}</option>
{% for stock_type in stock_types %}
<option value="{{ stock_type }}"
{% if stock_type == selected_stock_type %}selected{% endif %}>
{{ stock_type }}
</option>
{% endfor %}
<option value="">{% trans 'All Stock Types' %}</option>
{% if selected_stock_type %}
<option value="{{ selected_stock_type }}" selected>{{ selected_stock_type }}</option>
{% endif %}
</select>
</div>
<div class="col-md-2">
@ -111,27 +109,8 @@
</button>
</div>
</form>
</section>
<!---->
{% comment %} 'cars_sold': cars_sold,
'current_time': current_time,
'dealer': dealer,
'total_revenue_from_cars': total_revenue_from_cars,
'total_revenue_from_additonals':total_revenue_from_additonals,
'total_revenue_collected': total_revenue_collected,
'total_vat_on_cars':total_vat_on_cars,
'total_vat_from_additonals':total_vat_from_additonals,
'total_vat_collected':total_vat_collected,
'total_discount': total_discount,
'makes': makes,
'models': models_qs,
'series': series,
'years': years,
'selected_make': selected_make,
'selected_model': selected_model,
'selected_serie': selected_serie,
'selected_year': selected_year, {% endcomment %}
<!---->
</section>
<section id="summary" class="mb-5">
<h2 class="section-heading mb-4 border-start border-5 border-primary p-2">{% trans 'Report Summary' %}</h2>
<div class="row g-4">
@ -166,7 +145,7 @@
<span>{% trans 'Total Revenue' %}<span class="icon-saudi_riyal"></span></span>
</h5>
<p class="card-text">
<span>{{ total_revenue_collected |floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
<span>{{ total_revenue_collected|floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
</p>
</div>
</div>
@ -302,14 +281,82 @@
<span>{{ car.final_price_plus_services_plus_vat|floatformat:2 }}<span class="icon-saudi_riyal"></span></span>
</td>
<td class="fs-9">
<span>{{ car.invoice.invoice_number }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
</main>
</div>
{% endblock %}
<span>{{ car.invoice.invoice_number }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
</main>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const makeSelect = document.getElementById('make-select');
const modelSelect = document.getElementById('model-select');
const serieSelect = document.getElementById('serie-select');
const yearSelect = document.getElementById('year-select');
const stockTypeSelect = document.getElementById('stock_type-select');
const startDateInput = document.getElementById('start_date');
const endDateInput = document.getElementById('end_date');
const form = document.querySelector('form');
const baseUrl = form.dataset.filterUrl;
function updateOptions(selectElement, options, currentValue) {
const name = selectElement.name.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
selectElement.innerHTML = `<option value="">All ${name}s</option>`;
options.forEach(option => {
const newOption = document.createElement('option');
newOption.value = option;
newOption.textContent = option;
if (String(option) === String(currentValue)) {
newOption.selected = true;
}
selectElement.appendChild(newOption);
});
}
function fetchAndUpdateDropdowns() {
const make = makeSelect.value;
const model = modelSelect.value;
const serie = serieSelect.value;
const start_date = startDateInput.value;
const end_date = endDateInput.value;
// Corrected: Include start_date and end_date in the AJAX URL
const url = `${baseUrl}?make=${make}&model=${model}&serie=${serie}&start_date=${start_date}&end_date=${end_date}`;
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
updateOptions(modelSelect, data.models, model);
updateOptions(serieSelect, data.series, serie);
updateOptions(yearSelect, data.years, yearSelect.value);
updateOptions(stockTypeSelect, data.stock_types, stockTypeSelect.value);
})
.catch(error => console.error('Error fetching filtered choices:', error));
}
// Event listeners for all filter elements
makeSelect.addEventListener('change', fetchAndUpdateDropdowns);
modelSelect.addEventListener('change', fetchAndUpdateDropdowns);
serieSelect.addEventListener('change', fetchAndUpdateDropdowns);
yearSelect.addEventListener('change', fetchAndUpdateDropdowns);
stockTypeSelect.addEventListener('change', fetchAndUpdateDropdowns);
startDateInput.addEventListener('change', fetchAndUpdateDropdowns);
endDateInput.addEventListener('change', fetchAndUpdateDropdowns);
// Initial call to populate other dropdowns on page load
fetchAndUpdateDropdowns();
});
</script>
{% endblock %}

View File

@ -2,7 +2,7 @@
{% load i18n %}
{% load static %}
{% block title %}
{{ _("Car Purchase Report") |capfirst }}
{{ _("Car Purchase Report")|capfirst }}
{% endblock title %}
{% block content %}
<style>
@ -45,6 +45,26 @@
</p>
<p class="text-muted">{% trans "Report Date" %}: {{ current_time }}</p>
</header>
<section id="filters" class="mb-5 p-4 rounded border border-primary">
<h2 class="section-heading mb-4">
{% trans 'Filters' %} <i class="fas fa-sliders-h ms-2"></i>
</h2>
<form method="GET" class="row g-3 align-items-end">
<div class="col-md-3">
<label for="start_date" class="form-label">{% trans 'Start Date' %}</label>
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ start_date|default_if_none:'' }}">
</div>
<div class="col-md-3">
<label for="end_date" class="form-label">{% trans 'End Date' %}</label>
<input type="date" class="form-control" id="end_date" name="end_date" value="{{ end_date|default_if_none:'' }}">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">
<i class="fas fa-filter me-2"></i>{% trans 'Filter' %}
</button>
</div>
</form>
</section>
<main>
<section id="summary" class="mb-5">
<h2 class="section-heading mb-4 border-start border-3 border-primary p-2">{% trans 'Report Summary' %}</h2>
@ -84,7 +104,7 @@
<section id="purchase-details" class="mb-3">
<h2 class="section-heading border-start border-3 border-primary p-2">{% trans 'Detailed Purchase List' %}</h2>
<div class="d-flex justify-content-end mb-3 d-print-none">
<a href="{% url 'purchase-report-csv-export' request.dealer.slug %}"
<a href="{% url 'purchase-report-csv-export' request.dealer.slug %}?start_date={{ start_date|default_if_none:'' }}&end_date={{ end_date|default_if_none:'' }}"
class="btn btn-phoenix-primary">
<i class="bi bi-download me-2"></i>{% trans 'Download as CSV' %}
</a>
@ -126,4 +146,4 @@
</section>
</main>
</div>
{% endblock %}
{% endblock %}

View File

@ -122,7 +122,7 @@
<div class="row d-flex justify-content-center align-items-center mt-5 mb-3 ms-6 ps-3">
<div class="row">
<div class="col">
{% if not items.car %}
{% if not items %}
{% url "car_add" request.dealer.slug as create_car_url %}
{% include "message-illustration.html" with value1="Please add at least one car or complete the car info before creating a quotation." value2="Add car" message_image="images/logos/no-content-new.jpg" url=create_car_url %}
{% endif %}

View File

@ -128,7 +128,9 @@
<h2 class="mb-7">{{ _("Pricing") }}</h2>
<div class="row g-3 mb-7 mb-lg-11">
{% for plan in plan_list %}
<div class="col-lg-3">
<div class="col-lg-4" onclick="window.location='{% url "account_signup" %}';">
<input type="radio"
class="btn-check"
name="selected_plan"
@ -156,7 +158,9 @@
</div>
</div>
</label>
</div>
{% endfor %}
</div>
</div>