Merge remote-tracking branch 'origin/main'

# Conflicts:
#	inventory/templatetags/custom_filters.py
#	templates/inventory/car_list_view.html
This commit is contained in:
Marwan Alwali 2025-06-17 20:56:51 +03:00
commit 5f970e9dd8
5 changed files with 303 additions and 288 deletions

View File

@ -1,10 +1,13 @@
from typing import Union
from random import randint from random import randint
from django import template from django import template
from calendar import month_abbr
from django.urls import reverse from django.urls import reverse
from calendar import month_abbr
from django.conf import settings
from django.forms import ValidationError
from django.utils.formats import number_format from django.utils.formats import number_format
from django_ledger.io.io_core import get_localdate,validate_activity from django_ledger.io.io_core import get_localdate,validate_activity
from django.conf import settings from django_ledger.models import InvoiceModel, JournalEntryModel, BillModel
register = template.Library() register = template.Library()
@ -391,6 +394,31 @@ def bill_item_formset_table(context, item_formset):
'item_formset': item_formset, 'item_formset': item_formset,
} }
@register.inclusion_tag('bill/transactions/tags/txs_table.html')
def transactions_table(object_type: Union[JournalEntryModel, BillModel, InvoiceModel], style='detail'):
if isinstance(object_type, JournalEntryModel):
transaction_model_qs = object_type.transactionmodel_set.all().with_annotated_details().order_by(
'-timestamp')
elif isinstance(object_type, BillModel):
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
elif isinstance(object_type, InvoiceModel):
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
else:
raise ValidationError(
'Cannot handle object of type {} to get transaction model queryset'.format(type(object_type))
)
total_credits = sum(tx.amount for tx in transaction_model_qs if tx.is_credit())
total_debits = sum(tx.amount for tx in transaction_model_qs if tx.is_debit())
return {
'style': style,
'transaction_model_qs': transaction_model_qs,
'total_debits': total_debits,
'total_credits': total_credits,
'object': object_type
}
@register.filter @register.filter
def get_vehicle_image(car_serie): def get_vehicle_image(car_serie):

View File

@ -2,6 +2,7 @@
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load django_ledger %} {% load django_ledger %}
{% load custom_filters %}
{% block title %}Bill Details - {{ block.super }}{% endblock %} {% block title %}Bill Details - {{ block.super }}{% endblock %}
@ -64,7 +65,7 @@
<div class="border rounded p-3"> <div class="border rounded p-3">
<h6 class="text-uppercase text-xs text-muted mb-2"> <h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Cash Account' %}: {% trans 'Cash Account' %}:
<a href="{% url 'django_ledger:account-detail' account_pk=bill.cash_account.uuid coa_slug=bill.cash_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}" <a href="{% url 'account_detail' bill.cash_account.uuid %}"
class="text-decoration-none ms-1"> class="text-decoration-none ms-1">
{{ bill.cash_account.code }} {{ bill.cash_account.code }}
</a> </a>
@ -79,7 +80,7 @@
<div class="border rounded p-3"> <div class="border rounded p-3">
<h6 class="text-uppercase text-xs text-muted mb-2"> <h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Prepaid Account' %}: {% trans 'Prepaid Account' %}:
<a href="{% url 'django_ledger:account-detail' account_pk=bill.prepaid_account.uuid coa_slug=bill.prepaid_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}" <a href="{% url 'account_detail' bill.prepaid_account.uuid %}"
class="text-decoration-none ms-1"> class="text-decoration-none ms-1">
{{ bill.prepaid_account.code }} {{ bill.prepaid_account.code }}
</a> </a>
@ -93,7 +94,7 @@
<div class="border rounded p-3"> <div class="border rounded p-3">
<h6 class="text-uppercase text-xs text-muted mb-2"> <h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Accounts Payable' %}: {% trans 'Accounts Payable' %}:
<a href="{% url 'django_ledger:account-detail' account_pk=bill.unearned_account.uuid coa_slug=bill.unearned_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}" <a href="{% url 'account_detail' bill.unearned_account.uuid %}"
class="text-decoration-none ms-1"> class="text-decoration-none ms-1">
{{ bill.unearned_account.code }} {{ bill.unearned_account.code }}
</a> </a>

View File

@ -0,0 +1,73 @@
{% load i18n %}
{% load django_ledger %}
{% if style == 'detail' %}
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<thead class="table-light">
<tr>
<th>{% trans 'Timestamp' %}</th>
<th>{% trans 'Account' %}</th>
<th>{% trans 'Account Name' %}</th>
<th>{% trans 'Unit' %}</th>
<th>{% trans 'Credit' %}</th>
<th>{% trans 'Debit' %}</th>
<th>{% trans 'Description' %}</th>
</tr>
</thead>
<tbody>
{% for transaction_model in transaction_model_qs %}
<tr>
<td>{{ transaction_model.timestamp }}</td>
<td>{{ transaction_model.account_code }}</td>
<td>{{ transaction_model.account_name }}</td>
<td>{% if transaction_model.entity_unit_name %}{{ transaction_model.entity_unit_name }}{% endif %}</td>
<td>{% if transaction_model.is_credit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
<td>{% if transaction_model.is_debit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
<td>{% if transaction_model.description %}{{ transaction_model.description }}{% endif %}</td>
</tr>
{% endfor %}
<tr class="fw-bold">
<td colspan="3"></td>
<td class="text-end">{% trans 'Total' %}</td>
<td>{% currency_symbol %}{{ total_credits | currency_format }}</td>
<td>{% currency_symbol %}{{ total_debits | currency_format }}</td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% elif style == 'compact' %}
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<thead class="table-light">
<tr>
<th>{% trans 'Account' %}</th>
<th>{% trans 'Account Name' %}</th>
<th>{% trans 'Credit' %}</th>
<th>{% trans 'Debit' %}</th>
<th>{% trans 'Description' %}</th>
</tr>
</thead>
<tbody>
{% for transaction_model in transaction_model_qs %}
<tr>
<td>{{ transaction_model.account_code }}</td>
<td>{{ transaction_model.account_name }}</td>
<td>{% if transaction_model.is_credit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
<td>{% if transaction_model.is_debit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
<td>{% if transaction_model.description %}{{ transaction_model.description }}{% endif %}</td>
</tr>
{% endfor %}
<tr class="fw-bold">
<td colspan="1"></td>
<td class="text-end">{% trans 'Total' %}</td>
<td>{% currency_symbol %}{{ total_credits | currency_format }}</td>
<td>{% currency_symbol %}{{ total_debits | currency_format }}</td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% endif %}

View File

@ -38,7 +38,14 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'purchase_order_list' %}"> <a class="nav-link" href="{% url 'purchase_order_list' %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "purchase Orders"|capfirst %}</span> <span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "purchase Orders"|capfirst %}</span>
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'upload_cars' %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-file-invoice"></span></span><span class="nav-link-text">{% trans "Upload Cars"|capfirst %}</span>
</div> </div>
</a> </a>
</li> </li>

View File

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static i18n custom_filters humanize %} {% load i18n custom_filters humanize %}
{%block title%} {%trans 'Inventory'%} {%endblock%} {%block title%} {%trans 'Stocks'%} {%endblock%}
{% block customCSS %} {% block customCSS %}
<style> <style>
.htmx-indicator{ .htmx-indicator{
@ -25,21 +25,13 @@
{% block content %} {% block content %}
<div class="mb-9"> <div class="mb-9">
<div id="projectSummary"> <div id="projectSummary">
<!-- Page Header -->
<div class="row g-3 justify-content-between align-items-end mb-4">
<div class="col-12 col-sm-auto">
<h1 class="text-body-emphasis fw-bold fs-2 mb-0">{{ _("Inventory") }}</h1>
</div>
</div>
<!-- Navigation Tabs -->
<div class="row g-3 justify-content-between align-items-end mb-4"> <div class="row g-3 justify-content-between align-items-end mb-4">
<div class="col-12 col-sm-auto"> <div class="col-12 col-sm-auto">
<ul class="nav nav-links mx-n2" <ul class="nav nav-links mx-n2"
hx-boost="true" hx-boost="true"
hx-push-url='false' hx-push-url='false'
hx-target=".vehicles-container" hx-target=".table-responsive"
hx-select=".vehicles-container" hx-select=".table-responsive"
hx-swap="innerHTML show:window:top" hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()" hx-on::before-request="on_before_request()"
@ -47,44 +39,27 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link px-2 py-1 active" <a class="nav-link px-2 py-1 active"
aria-current="page" aria-current="page"
href="{% url 'car_list' %}"> href="{% url 'car_list' %}"><span>{{ _("All") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.all }})</span></a>
<span>{{ _("All") }}</span>
<span class="text-body-tertiary fw-semibold">({{ stats.all }})</span>
</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link px-2 py-1" <a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=available"> href="{% url 'car_list' %}?status=available"><span>{{ _("Available") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.available }})</span></a>
<span>{{ _("Available") }}</span>
<span class="text-body-tertiary fw-semibold">({{ stats.available }})</span>
</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link px-2 py-1" <a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=reserved"> href="{% url 'car_list' %}?status=reserved"><span>{{ _("Reserved") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span></a>
<span>{{ _("Reserved") }}</span>
<span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span>
</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link px-2 py-1" <a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=transfer"> href="{% url 'car_list' %}?status=transfer"><span>{{ _("Transfer") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span></a>
<span>{{ _("Transfer") }}</span>
<span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span>
</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link px-2 py-1" <a class="nav-link px-2 py-1" href="{% url 'car_list' %}?status=sold"><span>{{ _("Sold") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.sold }})</span></a>
href="{% url 'car_list' %}?status=sold">
<span>{{ _("Sold") }}</span>
<span class="text-body-tertiary fw-semibold">({{ stats.sold }})</span>
</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<button hx-on:click="toggle_filter()" <button hx-on:click="toggle_filter()"
class="btn btn-sm btn-phoenix-primary px-2 py-1"> class="btn btn-sm btn-phoenix-primary px-2 py-1">
<span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span> <span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span><span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
<span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
</button> </button>
</li> </li>
</ul> </ul>
@ -99,12 +74,12 @@
<input class="form-control search-input search" <input class="form-control search-input search"
name='search' name='search'
type="search" type="search"
placeholder="Search vehicles..." placeholder="Search"
aria-label="Search" aria-label="Search"
hx-get="{% url 'car_list' %}" hx-get="{% url 'car_list' %}"
hx-trigger='keyup changed delay:500ms' hx-trigger='keyup changed delay:500ms'
hx-target='.vehicles-container' hx-target='.table-responsive'
hx-select='.vehicles-container' hx-select='.table-responsive'
hx-swap="innerHTML show:window:top" hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()" hx-on::before-request="on_before_request()"
@ -115,9 +90,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="d-flex align-items-center d-none filter">
<!-- Filter Section -->
<div class="d-flex align-items-center d-none filter mb-4">
<select hx-get="{% url 'car_list' %}" <select hx-get="{% url 'car_list' %}"
name="make" name="make"
hx-target='.model-select' hx-target='.model-select'
@ -125,7 +98,7 @@
hx-swap="outerHTML show:window:top" hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 make" class="form-select form-control-sm me-1 make"
aria-label="Select make" aria-label="Default select example"
hx-on::before-request="filter_before_request()" hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()"> hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Make") }}</option> <option selected="" value="" disabled>{{ _("Make") }}</option>
@ -139,7 +112,7 @@
hx-swap="outerHTML show:window:top" hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 model-select" class="form-select form-control-sm me-1 model-select"
aria-label="Select model" aria-label="Default select example"
hx-on::before-request="filter_before_request()" hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()"> hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Model") }}</option> <option selected="" value="" disabled>{{ _("Model") }}</option>
@ -147,14 +120,14 @@
</select> </select>
<select class="form-select form-control-sm me-1 year" <select class="form-select form-control-sm me-1 year"
name="year" name="year"
aria-label="Select year"> aria-label="Default select example">
<option selected="" value="" disabled>{{ _("Year") }}</option> <option selected="" value="" disabled>{{ _("Year") }}</option>
{% for y in year %}<option value="{{ y.0 }}">{{ y.0 }}</option>{% endfor %} {% for y in year %}<option value="{{ y.0 }}">{{ y.0 }}</option>{% endfor %}
</select> </select>
<select class="form-select form-control-sm me-1 car_status" <select class="form-select form-control-sm me-1 car_status"
name="car_status" name="car_status"
aria-label="Select status"> aria-label="Default select example">
<option selected="" value="">{{ _("All Status") }}</option> <option selected="" value="">{{ _("All") }}</option>
<option value="available">{{ _("Available") }}</option> <option value="available">{{ _("Available") }}</option>
<option value="reserved">{{ _("Reserved") }}</option> <option value="reserved">{{ _("Reserved") }}</option>
<option value="sold">{{ _("Sold") }}</option> <option value="sold">{{ _("Sold") }}</option>
@ -164,261 +137,194 @@
hx-get="{% url 'car_list' %}" hx-get="{% url 'car_list' %}"
hx-include=".make,.model,.year,.car_status" hx-include=".make,.model,.year,.car_status"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
hx-target='.vehicles-container' hx-target='.table-responsive'
hx-select='.vehicles-container' hx-select='.table-responsive'
hx-swap="outerHTML show:window:top" hx-swap="outerHTML show:window:top"
class="btn btn-sm btn-phoenix-primary ms-1" class="btn btn-sm btn-phoenix-primary ms-1"
hx-on::before-request="filter_before_request()" hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()"> hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
<span class="fas fa-search me-1"></span>{{ _("Search") }}
</button>
</div> </div>
<!-- Vehicles Container -->
<div class="row"> <div class="row">
<div class="vehicles-container transition"> <form class="update-price-form d-flex flex-row align-items-center ms-auto w-25 d-none" action="" method="post" style="float:right;">
<input class="form-control me-2" type="number" placeholder='{{ _("Search") }}' name="price" aria-label="Price">
<button class="btn btn-outline-primary" type="submit">{{ _("Search") }}</button>
</form>
<div class="table-responsive scrollbar transition">
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9"> <div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9">
<div class="d-flex" <div class="d-flex"
hx-boost="true" hx-boost="true"
hx-push-url='false' hx-push-url='false'
hx-include=".make,.model,.year,.car_status" hx-include=".make,.model,.year,.car_status"
hx-target=".vehicles-container" hx-target=".table-responsive"
hx-select=".vehicles-container" hx-select=".table-responsive"
hx-swap="innerHTML show:window:top" hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator" hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()" hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()"></div> hx-on::after-request="on_after_request()"></div>
<table class="table align-items-center table-flush">
<!-- Vehicle Cards Grid --> <thead class="text-body">
<div class="w-100"> <tr class="bg-body-highlight">
{% for car in cars %} <th class="sort white-space-nowrap align-middle" scope="col">
<div class="card border mb-3"> <div class="form-check">
<div class="card-body"> <input class="form-check-input" type="checkbox" id="select-all" />
<div class="row align-items-center">
<!-- Vehicle Image/Icon -->
<div class="col-auto">
{% if car.main_image %}
<img src="{{ car.main_image.url }}"
alt="{{ car.id_car_make.name }} {{ car.id_car_model.name }}"
class="rounded border car-image"
style="width: 120px; height: 80px; object-fit: cover;">
{% else %}
<!-- Dynamic Car Image with Color Styling -->
<div class="rounded border d-flex align-items-center justify-content-center position-relative overflow-hidden"
style="width: 120px; height: 80px;
{% if car.colors.exterior.rgb %}
background: linear-gradient(135deg, rgba({{ car.colors.exterior.rgb }}, 0.5) 0%, rgba({{ car.colors.exterior.rgb }}, 0.5) 100%);
{% endif %}">
<!-- Car Image -->
<img src="{% static 'images/cars/' %}{{ car.id_car_serie|get_vehicle_image }}"
alt="{{ car.id_car_serie|get_vehicle_type_name|title }}"
class="car-image"
style="width: 100%; height: 100%; object-fit: contain;
{% if car.colors.exterior.rgb %}
filter: sepia(0.3) saturate(1.5) brightness(1.1);
{% endif %}">
<!-- Vehicle Type Badge -->
<span class="badge bg-dark bg-opacity-75 text-white position-absolute bottom-0 start-0 m-1 fs-10">
{{ car.id_car_serie|get_vehicle_type_name|title }}
</span>
</div>
{% endif %}
</div>
<!-- Vehicle Details -->
<div class="col">
<div class="row">
<!-- Make/Model/Specs -->
<div class="col-md-4">
<h5 class="text-body-emphasis fw-bold mb-1">
<a href="{% url 'car_detail' car.slug %}"
class="text-decoration-none text-body-emphasis">
{% if car.id_car_make %}
{{ car.id_car_make.get_local_name|default:car.id_car_make.name }}
{% endif %}
</a>
</h5>
<p class="text-body mb-1 fw-semibold">
{% if car.id_car_model %}
{{ car.id_car_model.get_local_name|default:car.id_car_model.name }}
{% endif %}
</p>
<small class="text-body-secondary">
{% if car.id_car_trim %}{{ car.id_car_trim }}{% endif %}
{% if car.year %} ({{ car.year }}){% endif %}
</small>
</div>
<!-- Color and Date -->
<div class="col-md-3">
<p class="text-body mb-1">
{% if car.colors.exterior %}
{{ car.colors.exterior.get_local_name }}
{% endif %}
</p>
<small class="text-body-secondary">
{{ car.receiving_date|naturalday|capfirst }}
</small>
</div>
<!-- Status Badge -->
<div class="col-md-3">
{% if car.status == "available" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-success text-uppercase px-3 py-2">{{ _("Available") }}</span>
{% elif car.status == "reserved" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-warning text-uppercase px-3 py-2">{{ _("Reserved") }}</span>
{% elif car.status == "sold" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-danger text-uppercase px-3 py-2">{{ _("Sold") }}</span>
{% elif car.status == "transfer" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-info text-uppercase px-3 py-2">{{ _("Transfer") }}</span>
{% endif %}
</div>
<!-- Ready Status -->
<div class="col-md-2">
<div class="d-flex align-items-center">
{% if car.ready %}
<span class="badge bg-success rounded-circle p-1 me-2">
<span class="visually-hidden">Ready</span>
</span>
<span class="text-success fw-semibold">YES</span>
{% else %}
<span class="badge bg-danger rounded-circle p-1 me-2">
<span class="visually-hidden">Not Ready</span>
</span>
<span class="text-danger fw-semibold">NO</span>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Action Menu -->
<div class="col-auto">
<div class="btn-reveal-trigger position-static">
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10"
type="button"
data-bs-toggle="dropdown"
data-boundary="window"
aria-haspopup="true"
aria-expanded="false"
data-bs-reference="parent">
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a class="dropdown-item" href="{% url 'car_detail' car.slug %}">
<span class="fas fa-eye me-2"></span>{{ _("View") }}
</a>
<a class="dropdown-item" href="{% url 'car_update' car.slug %}">
<span class="fas fa-edit me-2"></span>{{ _("Edit") }}
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'car_delete' car.slug %}">
<span class="fas fa-trash me-2"></span>{{ _("Remove") }}
</a>
</div>
</div>
</div>
</div> </div>
</div> </th>
</div> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("VIN") }}</th>
{% empty %} <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Make") }}</th>
<div class="text-center py-5"> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Model") }}</th>
<div class="text-body-secondary"> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Year") }}</th>
<span class="fas fa-car fa-4x mb-3 opacity-50"></span> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Trim") }}</th>
<h4 class="text-body-secondary">{{ _("No vehicles found") }}</h4> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Color") }}</th>
<p class="text-body-tertiary">{{ _("Try adjusting your search criteria or filters") }}</p> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Date Received") }}</th>
</div> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Status") }}</th>
</div> <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Inventory Ready") }}</th>
{% endfor %} <th class="sort white-space-nowrap align-middle" scope="col"></th>
</div> </tr>
</thead>
<!-- Pagination --> <tbody class="list" id="project-list-table-body">
{% if is_paginated %} {% for car in cars %}
<div class="d-flex justify-content-between align-items-center mt-4 w-100"> <tr class="position-static">
<div class="text-body-secondary"> <td class="align-middle white-space-nowrap">
{{ _("Showing") }} {{ page_obj.start_index }} {{ _("to") }} {{ page_obj.end_index }} <div class="form-check">
{{ _("of") }} {{ page_obj.paginator.count }} {{ _("results") }} <input class="form-check-input car-checkbox" type="checkbox" name="car" id="car-{{car.pk}}">
</div> </div>
<nav aria-label="Page navigation"> </td>
<ul class="pagination pagination-sm mb-0"> <td class="align-middle white-space-nowrap ps-1">
{% if page_obj.has_previous %} <a class="fw-bold" href="{% url 'car_detail' car.slug %}">{{ car.vin }}</a>
<li class="page-item"> </td>
<a class="page-link" href="?page={{ page_obj.previous_page_number }}"> <td class="align-middle white-space-nowrap">
<span class="fas fa-chevron-left"></span> {% if car.id_car_make %}
</a> <p class="text-body mb-0">{{ car.id_car_make.get_local_name|default:car.id_car_make.name }}</p>
</li> {% endif %}
{% endif %} </td>
<td class="align-middle white-space-nowrap">
{% for num in page_obj.paginator.page_range %} {% if car.id_car_model %}
{% if page_obj.number == num %} <p class="text-body mb-0">{{ car.id_car_model.get_local_name|default:car.id_car_model.name }}</p>
<li class="page-item active"> {% endif %}
<span class="page-link">{{ num }}</span> </td>
</li> <td class="align-middle white-space-nowrap">
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %} <p class="text-body mb-0">{{ car.year }}</p>
<li class="page-item"> </td>
<a class="page-link" href="?page={{ num }}">{{ num }}</a> <td class="align-middle white-space-nowrap">
</li> <p class="fw-bold text-body mb-0">{{ car.id_car_trim }}</p>
</td>
<td class="align-middle white-space-nowrap">
<div class="d-flex flex-row align-items-center">
<div class="d-flex flex-column align-items-center">
<span class="color-div"
style="background: linear-gradient(90deg, rgba({{ car.colors.exterior.rgb }},1) 10%, rgba({{ car.colors.exterior.rgb }},0.10) 100%)"
title="{{ car.colors.exterior.get_local_name }}"></span><span>{{ car.colors.exterior.get_local_name }}</span>
</div>
<div class="d-flex flex-column align-items-center">
<span class="color-div"
style="background: linear-gradient(90deg, rgba({{ car.colors.interior.rgb }},1) 10%, rgba({{ car.colors.interior.rgb }},0.10) 100%)"
title="{{ car.colors.interior.get_local_name }}"></span><span>{{ car.colors.interior.get_local_name }}</span>
</div>
</div>
</td>
<td class="align-middle white-space-nowrap">
<p class="fw-bold text-body mb-0">{{ car.receiving_date|naturalday|capfirst }}</p>
</td>
<td class="align-middle white-space-nowrap statuses">
{% if car.status == "available" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-success">{{ _("Available") }}</span>
{% elif car.status == "reserved" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-danger">{{ _("Reserved") }}</span>
{% elif car.status == "sold" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-info">{{ _("Sold") }}</span>
{% elif car.status == "transfer" %}
<span class="badge badge-phoenix fs-11 badge-phoenix-warning">{{ _("Transfer") }}</span>
{% endif %} {% endif %}
{% endfor %} </td>
<td class="align-middle product white-space-nowrap">
{% if page_obj.has_next %} {% if not car.ready %}
<li class="page-item"> <span class="text-danger"> {{ _("NO") }} </span>
<a class="page-link" href="?page={{ page_obj.next_page_number }}"> {%else%}
<span class="fas fa-chevron-right"></span> <span class="text-success"> {{ _("YES") }} </span>
</a> {%endif%}
</li> </td>
{% endif %} <td class="align-middle text-end white-space-nowrap pe-0 action">
</ul> <div class="btn-reveal-trigger position-static">
</nav> <button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10"
</div> type="button"
{% endif %} data-bs-toggle="dropdown"
data-boundary="window"
aria-haspopup="true"
aria-expanded="false"
data-bs-reference="parent">
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a class="dropdown-item" href="{% url 'car_detail' car.slug %}">{{ _("View") }}</a>
<a class="dropdown-item" href="#!">{{ _("Export") }}</a>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="d-flex justify-content-end mt-3">
<div class="d-flex">
{% if is_paginated %}
{% include 'partials/pagination.html' %}
{% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> {% endblock %}
{% block customJS %}
<script>
links = document.querySelectorAll('.nav-link')
links.forEach(link => {
link.addEventListener('click', () => {
links.forEach(link => {
link.classList.remove('active')
})
link.classList.add('active')
})
})
function on_before_request() {
document.querySelector('.table').classList.toggle('on-before-request')
document.querySelector('.model-select').classList.add('on-after-request')
}
function on_after_request() {
document.querySelector('.table').classList.remove('on-before-request')
document.querySelector('.model-select').classList.remove('on-after-request')
}
function toggle_filter(){
document.querySelector('.filter').classList.toggle('d-none')
document.querySelector('.filter-icon').classList.toggle("fa-caret-down");
document.querySelector('.filter-icon').classList.toggle("fa-caret-up");
}
function filter_before_request(){
document.querySelector('.model-select').setAttribute('disabled', true)
document.querySelector('.year').setAttribute('disabled', true)
document.querySelector('.car_status').setAttribute('disabled', true)
}
function filter_after_request(){
document.querySelector('.model-select').removeAttribute('disabled')
document.querySelector('.year').removeAttribute('disabled')
document.querySelector('.car_status').removeAttribute('disabled')
}
<script> document.getElementById('select-all').addEventListener('change', function() {
function toggle_filter() { const checkboxes = document.querySelectorAll('#project-list-table-body input[type="checkbox"]');
const filter = document.querySelector('.filter'); checkboxes.forEach(checkbox => {
filter.classList.toggle('d-none'); checkbox.checked = this.checked;
});
const icon = document.querySelector('.filter-icon'); });
if (filter.classList.contains('d-none')) { document.getElementById('car-checkbox').addEventListener('change', function() {
icon.classList.remove('fa-caret-up'); const form = document.querySelector('.update-price-form');
icon.classList.add('fa-caret-down'); if (this.checked) {
} else { form.classList.remove('d-none');
icon.classList.remove('fa-caret-down'); } else {
icon.classList.add('fa-caret-up'); form.classList.add('d-none');
} }
} });
function on_before_request() {
const container = document.querySelector('.vehicles-container');
if (container) {
container.classList.add('on-before-request');
}
}
function on_after_request() {
const container = document.querySelector('.vehicles-container');
if (container) {
container.classList.remove('on-before-request');
}
}
function filter_before_request() {
on_before_request();
}
function filter_after_request() {
on_after_request();
}
</script>
{% endblock content %}
</script>
{% endblock customJS %}