Compare commits

...

7 Commits

Author SHA1 Message Date
04122cda2c update 2025-06-22 13:21:46 +03:00
39ed2620cd Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-22 13:21:11 +03:00
366df0135a update 2025-06-22 13:20:46 +03:00
Marwan Alwali
ebd2f06eb6 update car list cards 2025-06-20 21:11:51 +03:00
Marwan Alwali
190efbe72e update car list with images 2025-06-19 20:56:51 +03:00
8f5472ec52 ordered the txns based on debit listed first 2025-06-19 17:15:18 +03:00
9d6bd24937 chnage the custome filter logic for the Transaction bills 2025-06-18 20:41:15 +03:00
46 changed files with 447 additions and 402 deletions

BIN
.DS_Store vendored

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,7 @@ from django.forms import ValidationError
from django.utils.formats import number_format
from django_ledger.io.io_core import get_localdate,validate_activity
from django_ledger.models import InvoiceModel, JournalEntryModel, BillModel
from django.db.models import Case, Value, When, IntegerField
register = template.Library()
@ -398,9 +399,23 @@ def bill_item_formset_table(context, item_formset):
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')
'-timestamp',
)
elif isinstance(object_type, BillModel):
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
# Specific ordering for BillModel (timestamp ascending, then debit before credit)
qs = object_type.get_transaction_queryset(annotated=True)
transaction_model_qs = qs.annotate(
debit_credit_sort_order=Case(
When(tx_type='debit', then=Value(0)), # Debits will get sort order 0
When(tx_type='credit', then=Value(1)), # Credits will get sort order 1
default=Value(2), # Fallback for any other tx_type, if applicable
output_field=IntegerField()
)
).order_by(
'-timestamp', # Primary sort: chronological (oldest first)
'-debit_credit_sort_order', # Secondary sort: Debits (0) before Credits (1)
'pk' # Optional: Tie-breaker for consistent order
)
elif isinstance(object_type, InvoiceModel):
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
else:
@ -514,4 +529,5 @@ def get_vehicle_type_name(car_serie):
elif 'liftback' in serie_lower:
return 'liftback'
else:
return 'sedan'
return 'sedan'

View File

@ -67,6 +67,7 @@ from django.views.generic import (
ArchiveIndexView,
)
from django.db.models import Case, Value, IntegerField, When
# Django Ledger
from django_ledger.io import roles
@ -8123,6 +8124,7 @@ class JournalEntryListView(LoginRequiredMixin, ListView):
model = JournalEntryModel
context_object_name = "journal_entries"
template_name = "ledger/journal_entry/journal_entry_list.html"
ordering=['-timestamp']
def get_queryset(self):
qs = super().get_queryset()
@ -8229,11 +8231,17 @@ def JournalEntryTransactionsView(request, pk):
:rtype: django.http.HttpResponse
"""
journal = JournalEntryModel.objects.filter(pk=pk).first()
transactions = (
TransactionModel.objects.filter(journal_entry=journal)
.order_by("account__code")
.all()
)
# transactions = (
# TransactionModel.objects.filter(journal_entry=journal)
# .order_by("account__code")
# .all()
# )
qs=TransactionModel.objects.filter(journal_entry=journal).all()
transactions=qs.annotate(
debit_credit_sort_order=Case(When(tx_type='debit',then=Value(0)),
When(tx_type='credit',then=Value(1)),
output_field=IntegerField())
).order_by('debit_credit_sort_order')
return render(
request,
"ledger/journal_entry/journal_entry_transactions.html",

BIN
static/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -9,9 +9,9 @@
<form action="" method="post">
{% csrf_token %}
<div class="col-12 col-xl-8">
<div class="border-bottom mb-4">
<div class=" mb-4">
<div class="row gx-3 mb-6 gy-6 gy-sm-3">
<div class="row gx-3 mb-4 gy-6 gy-sm-3">
<div class="col-12 col-sm-8">
<h4 class="mb-4">Default Invoice Accounts</h4>
<div class="form-icon-container mb-3">
@ -25,7 +25,7 @@
</div>
</div>
</div>
<div class="row gx-3 mb-6 gy-6 gy-sm-3">
<div class="row gx-3 mb-4 gy-6 gy-sm-3">
<div class="col-12 col-sm-8">
<h4 class="mb-4">Default Bill Accounts</h4>
<div class="form-icon-container mb-3">

View File

@ -71,6 +71,7 @@
{% include 'header.html' %}
<div class="content">
{% include "plans/expiration_messages.html" %}
{% block period_navigation %}
@ -140,5 +141,6 @@
</script>
{% block customJS %}
{% endblock %}
</body>
</html>

View File

@ -17,7 +17,9 @@
</tr>
</thead>
<tbody class="fs-9">
{% for transaction_model in transaction_model_qs %}
<tr>
<td class=" white-space-nowrap align-middle ps-2" scope="col" >{{ transaction_model.timestamp }}</td>
<td class=" white-space-nowrap align-middle" scope="col">{{ transaction_model.account_code }}</td>

View File

@ -3,8 +3,8 @@
{% block title %}{{ _('Leads')|capfirst }}{% endblock title %}
{% block content %}
<div class="row g-3">
<h2 class="mb-4">{{ _("Leads")|capfirst }}</h2>
<div class="row g-3 mt-4">
<h2 class="mb-2">{{ _("Leads")|capfirst }}</h2>
<!-- Action Tracking Modal -->
{% include "crm/leads/partials/update_action.html" %}
@ -231,19 +231,24 @@
</tr>
{% endfor %}
</tbody>
{% endif %}
</table>
</div>
</div>
</div>
<div class="d-flex justify-content-end mt-3">
<div class="d-flex">
<div class="d-flex justify-content-end mt-3">
<div class="d-flex">
{% if is_paginated %}
{% include 'partials/pagination.html' %}
{% endif %}
</div>
</div>
{% else %}
<tr>
<td colspan="6" class="text-center">{% trans "No Lead Yet" %}</td>
</tr>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -2,7 +2,7 @@
{% load i18n static humanize %}
{% block title %}{{ _("Opportunity Detail") }}{% endblock title %}
{% block content %}
<div class="row align-items-center justify-content-between g-3 mb-4">
<div class="row align-items-center justify-content-between g-3 mb-4 mt-4">
<div class="col-12 col-md-auto">
<h2 class="mb-0">{{ _("Opportunity details")}}</h2>
</div>

View File

@ -3,7 +3,7 @@
{% load custom_filters %}
{% block title %}{{ _("Opportunities") }}{% endblock title %}
{% block content %}
<div class="row g-3">
<div class="row g-3 mt-4">
<div class="col-12">
<h2 class="mb-3">{{ _("Opportunities") }}</h2>
</div>

View File

@ -5,8 +5,8 @@
{% block vendors %}<a class="nav-link active">{{ _("Customers")|capfirst }}</a>{% endblock %}
{% block content %}
<div class="row">
<h4 class="mb-4">{{ _("Customers")|capfirst }}</h4>
<div class="row g-3 mt-4">
<h2 class="mb-2">{{ _("Customers")|capfirst }}</h2>
<div class="row g-3 justify-content-between mb-4">
<div class="col-auto">
<div class="d-md-flex justify-content-between">

View File

@ -9,14 +9,14 @@
<div class="col-md-8">
<!-- Form Header -->
<h4 class="mb-3">{{ _("Update Dealer Information") }}</h4>
<h3 class="mb-3">{{ _("Update Dealer Information") }}</h3>
<form method="post" enctype="multipart/form-data" class="needs-validation" novalidate>
{% csrf_token %}
{{ form|crispy }}
<div class="gap-2 mt-3">
<button type="submit" class="btn btn-phoenix-success btn-sm">
<i class="fa fa-save"></i> {{ _("Save") }}
<button type="submit" class="btn btn-phoenix-success btn-sm me-2">
<i class="fa fa-save me-1"></i> {{ _("Save") }}
</button>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-phoenix-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>

View File

@ -1,349 +1,361 @@
{% extends "base.html" %}
{% load i18n custom_filters humanize %}
{% load static i18n custom_filters humanize %}
{%block title%} {%trans 'Stocks'%} {%endblock%}
{% block customCSS %}
<style>
.htmx-indicator{
opacity:0;
transition: opacity 500ms ease-in;
}
.htmx-request .htmx-indicator{
opacity:1;
}
.htmx-request.htmx-indicator{
opacity:1;
}
.on-before-request{
opacity: 0.5;
pointer-events: none;
}
.transition {
transition: all ease-in 1s ;
}
</style>
<style>
.htmx-indicator {
opacity: 0;
transition: opacity 500ms ease-in;
}
.htmx-request .htmx-indicator {
opacity: 1;
}
.htmx-request.htmx-indicator {
opacity: 1;
}
.on-before-request {
opacity: 0.5;
pointer-events: none;
}
.transition {
transition: all ease-in 1s;
}
</style>
{% endblock customCSS %}
{% block content %}
<div class="mb-9">
<div id="projectSummary">
<div class="row g-3 justify-content-between align-items-end mb-4">
<div class="col-12 col-sm-auto">
<ul class="nav nav-links mx-n2"
hx-boost="true"
hx-push-url='false'
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()">
<li class="nav-item">
<a class="nav-link px-2 py-1 active"
aria-current="page"
href="{% url 'car_list' %}"><span>{{ _("All") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.all }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=available"><span>{{ _("Available") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.available }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=reserved"><span>{{ _("Reserved") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1"
href="{% url 'car_list' %}?status=transfer"><span>{{ _("Transfer") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span></a>
</li>
<li class="nav-item">
<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>
</li>
<li class="nav-item">
<button hx-on:click="toggle_filter()"
class="btn btn-sm btn-phoenix-primary px-2 py-1">
<span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span><span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
</button>
</li>
</ul>
</div>
<div class="col-12 col-sm-auto">
<div class="d-flex align-items-center">
<div class="spinner-border mx-3 htmx-indicator" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div class="search-box me-3">
<form class="position-relative">
<input class="form-control search-input search"
name='search'
type="search"
placeholder="Search"
aria-label="Search"
hx-get="{% url 'car_list' %}"
hx-trigger='keyup changed delay:500ms'
hx-target='.table-responsive'
hx-select='.table-responsive'
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()" />
<span class="fas fa-search search-box-icon"></span>
</form>
</div>
</div>
</div>
</div>
<div class="d-flex align-items-center d-none filter">
<select hx-get="{% url 'car_list' %}"
name="make"
hx-target='.model-select'
hx-select='.model-select'
hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 make"
aria-label="Default select example"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Make") }}</option>
{% for m in make %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
</select>
<select hx-get="{% url 'car_list' %}"
hx-include=".make"
name="model"
hx-target='.year'
hx-select='.year'
hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 model-select"
aria-label="Default select example"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Model") }}</option>
{% for m in model %}<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>{% endfor %}
</select>
<select class="form-select form-control-sm me-1 year"
name="year"
aria-label="Default select example">
<option selected="" value="" disabled>{{ _("Year") }}</option>
{% for y in year %}<option value="{{ y.0 }}">{{ y.0 }}</option>{% endfor %}
</select>
<select class="form-select form-control-sm me-1 car_status"
name="car_status"
aria-label="Default select example">
<option selected="" value="">{{ _("All") }}</option>
<option value="available">{{ _("Available") }}</option>
<option value="reserved">{{ _("Reserved") }}</option>
<option value="sold">{{ _("Sold") }}</option>
<option value="transfer">{{ _("Transfer") }}</option>
</select>
<button id="search"
hx-get="{% url 'car_list' %}"
hx-include=".make,.model,.year,.car_status"
hx-indicator=".htmx-indicator"
hx-target='.table-responsive'
hx-select='.table-responsive'
hx-swap="outerHTML show:window:top"
class="btn btn-sm btn-phoenix-primary ms-1"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
</div>
<div class="row">
<form hx-boost='true' action="{% url 'bulk_update_car_price' %}" method="post"
hx-include=".car-checkbox"
class="update-price-form d-flex flex-row align-items-center ms-auto w-25 d-none" style="float:right;">
{% csrf_token %}
<div class="form-floating me-2">
<input class="form-control" type="number" placeholder='{{ _("Search") }}' name="price" aria-label="Price" id="price">
<label for="price">{{ _("Price") }}</label>
</div>
<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"
hx-boost="true"
hx-push-url='false'
hx-include=".make,.model,.year,.car_status"
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()"></div>
<table class="table align-items-center table-flush">
<thead class="text-body">
<tr class="bg-body-highlight">
<th class="sort white-space-nowrap align-middle" scope="col">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="select-all" />
</div>
</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("VIN") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Make") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Model") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Year") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Trim") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Color") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Date Received") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Status") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col">{{ _("Inventory Ready") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col"></th>
</tr>
</thead>
<tbody class="list" id="project-list-table-body">
{% for car in cars %}
<tr class="position-static">
<td class="align-middle white-space-nowrap">
<div class="form-check">
<input class="form-check-input car-checkbox" type="checkbox" name="car" value="{{ car.pk }}" id="car-{{car.pk}}">
</div>
</td>
<td class="align-middle white-space-nowrap ps-1">
<a class="fw-bold" href="{% url 'car_detail' car.slug %}">{{ car.vin }}</a>
</td>
<td class="align-middle white-space-nowrap">
{% if car.id_car_make %}
<p class="text-body mb-0">{{ car.id_car_make.get_local_name|default:car.id_car_make.name }}</p>
{% endif %}
</td>
<td class="align-middle white-space-nowrap">
{% if car.id_car_model %}
<p class="text-body mb-0">{{ car.id_car_model.get_local_name|default:car.id_car_model.name }}</p>
{% endif %}
</td>
<td class="align-middle white-space-nowrap">
<p class="text-body mb-0">{{ car.year }}</p>
</td>
<td class="align-middle white-space-nowrap">
<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 %}
</td>
<td class="align-middle product white-space-nowrap">
{% if not car.ready %}
<span class="text-danger"> {{ _("NO") }} </span>
{%else%}
<span class="text-success"> {{ _("YES") }} </span>
{%endif%}
</td>
<td class="align-middle text-end white-space-nowrap pe-0 action">
<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 %}">{{ _("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 class="mb-9">
<div id="projectSummary">
<div class="row g-3 justify-content-between align-items-end mb-4">
<div class="col-12 col-sm-auto">
<ul
class="nav nav-links mx-n2"
hx-boost="true"
hx-push-url="false"
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()">
<li class="nav-item">
<a class="nav-link px-2 py-1 active" aria-current="page" href="{% url 'car_list' %}"><span>{{ _("All") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.all }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1" href="{% url 'car_list' %}?status=available"><span>{{ _("Available") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.available }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1" href="{% url 'car_list' %}?status=reserved"><span>{{ _("Reserved") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.reserved }})</span></a>
</li>
<li class="nav-item">
<a class="nav-link px-2 py-1" href="{% url 'car_list' %}?status=transfer"><span>{{ _("Transfer") }}</span><span class="text-body-tertiary fw-semibold">({{ stats.transfer }})</span></a>
</li>
<li class="nav-item">
<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>
</li>
<li class="nav-item">
<button hx-on:click="toggle_filter()" class="btn btn-sm btn-phoenix-primary px-2 py-1">
<span><span class="fa fa-filter me-1"></span>{{ _("Filter") }}</span><span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span>
</button>
</li>
</ul>
</div>
<div class="col-12 col-sm-auto">
<div class="d-flex align-items-center">
<div class="spinner-border mx-3 htmx-indicator" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div class="search-box me-3">
<form class="position-relative">
<input
class="form-control search-input search"
name="search"
type="search"
placeholder="Search"
aria-label="Search"
hx-get="{% url 'car_list' %}"
hx-trigger="keyup changed delay:500ms"
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()"
/>
<span class="fas fa-search search-box-icon"></span>
</form>
</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')
}
</div>
</div>
<div class="d-flex align-items-center d-none filter">
<select
hx-get="{% url 'car_list' %}"
name="make"
hx-target=".model-select"
hx-select=".model-select"
hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 make"
aria-label="Default select example"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Make") }}</option>
{% for m in make %}
<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>
{% endfor %}
</select>
<select
hx-get="{% url 'car_list' %}"
hx-include=".make"
name="model"
hx-target=".year"
hx-select=".year"
hx-swap="outerHTML show:window:top"
hx-indicator=".htmx-indicator"
class="form-select form-control-sm me-1 model-select"
aria-label="Default select example"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">
<option selected="" value="" disabled>{{ _("Model") }}</option>
{% for m in model %}
<option value="{{ m.pk }}">{{ m.get_local_name|default:m.name }}</option>
{% endfor %}
</select>
<select class="form-select form-control-sm me-1 year" name="year" aria-label="Default select example">
<option selected="" value="" disabled>{{ _("Year") }}</option>
{% for y in year %}
<option value="{{ y.0 }}">{{ y.0 }}</option>
{% endfor %}
</select>
<select class="form-select form-control-sm me-1 car_status" name="car_status" aria-label="Default select example">
<option selected="" value="">{{ _("All") }}</option>
<option value="available">{{ _("Available") }}</option>
<option value="reserved">{{ _("Reserved") }}</option>
<option value="sold">{{ _("Sold") }}</option>
<option value="transfer">{{ _("Transfer") }}</option>
</select>
<button
id="search"
hx-get="{% url 'car_list' %}"
hx-include=".make,.model,.year,.car_status"
hx-indicator=".htmx-indicator"
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="outerHTML show:window:top"
class="btn btn-sm btn-phoenix-primary ms-1"
hx-on::before-request="filter_before_request()"
hx-on::after-request="filter_after_request()">
{{ _("Search") }}
</button>
</div>
<div class="row">
<form hx-boost="true" action="{% url 'bulk_update_car_price' %}" method="post" hx-include=".car-checkbox" class="update-price-form d-flex flex-row align-items-center ms-auto w-25 d-none" style="float: right;">
{% csrf_token %}
<div class="form-floating me-2">
<input class="form-control" type="number" placeholder='{{ _("Search") }}' name="price" aria-label="Price" id="price" />
<label for="price">{{ _("Price") }}</label>
</div>
<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"
hx-boost="true"
hx-push-url="false"
hx-include=".make,.model,.year,.car_status"
hx-target=".table-responsive"
hx-select=".table-responsive"
hx-swap="innerHTML show:window:top"
hx-indicator=".htmx-indicator"
hx-on::before-request="on_before_request()"
hx-on::after-request="on_after_request()"></div>
<div class="w-100 list table-responsive" >
<div class="form-check">
<input class="form-check-input ms-4" type="checkbox" id="select-all" /> <span class="ms-1 text-body-tertiary">{{ _("Select All") }}</span>
</div>
{% for car in cars %}
<div class="card border mb-3 py-0 px-0" id="project-list-table-body">
<div class="card-body">
<div class="row align-items-center">
<div class="col-auto">
<div class="form-check">
<input class="form-check-input car-checkbox" type="checkbox" name="car" value="{{ car.pk }}" id="car-{{car.pk}}" />
</div>
</div>
<!-- Vehicle Image/Icon -->
<div class="col-auto">
<div class="avatar avatar-3xl">
<img class="rounded-soft shadow shadow-lg" src="{% static 'images/cars/' %}{{ car.vin }}.png" alt="{{ car.vin }}" />
</div>
</div>
<!-- Vehicle Details -->
<div class="col">
<div class="row">
<!-- Make/Model/Specs -->
<div class="col-md-4">
<h5 class="text-body-emphasis fw-bold">{{ car.year }}</h5>
<p class="text-body-emphasis fw-bold">
<a href="{% url 'car_detail' car.slug %}" class="text-decoration-none text-body-emphasis">
{{ car.id_car_make.get_local_name }}
</a>
<small>{{ car.id_car_model.get_local_name }}</small>
</p>
<small class="text-body-secondary" dir="ltr">
{{ car.id_car_trim }}
</small>
</div>
document.getElementById('select-all').addEventListener('change', function() {
const checkboxes = document.querySelectorAll('#project-list-table-body input[type="checkbox"]');
if (this.checked) {
checkboxes.forEach(checkbox => checkbox.checked = true);
} else {
checkboxes.forEach(checkbox => checkbox.checked = false);
}
updateFormVisibility();
<!-- Color and Date -->
<div class="col-md-3">
<p class="text-body mb-1">
{{ car.colors.exterior.get_local_name }}
</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-10 badge-phoenix-success text-uppercase px-3 py-2">{{ _("Available") }}</span>
{% elif car.status == "reserved" %}
<span class="badge badge-phoenix fs-10 badge-phoenix-warning text-uppercase px-3 py-2">{{ _("Reserved") }}</span>
{% elif car.status == "sold" %}
<span class="badge badge-phoenix fs-10 badge-phoenix-danger text-uppercase px-3 py-2">{{ _("Sold") }}</span>
{% elif car.status == "transfer" %}
<span class="badge badge-phoenix fs-10 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">
<span class="fs-10 fw-light me-2">{{ _("Inventory Ready") }}</span>
{% 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-bold">{{ _("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-bold">{{ _("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>
{% empty %}
<div class="text-center py-5">
<div class="text-body-secondary">
<span class="fas fa-car fa-4x mb-3 opacity-50"></span>
<h4 class="text-body-secondary">{{ _("No vehicles found") }}</h4>
<p class="text-body-tertiary">{{ _("Try adjusting your search criteria or filters") }}</p>
</div>
</div>
{% endfor %}
</div>
</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>
{% 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");
}
const cbox = document.querySelectorAll('.car-checkbox');
cbox.forEach(checkbox => {
checkbox.addEventListener('change', function() {
updateFormVisibility();
});
});
document.getElementById("select-all").addEventListener("change", function () {
const checkboxes = document.querySelectorAll('#project-list-table-body input[type="checkbox"]');
if (this.checked) {
checkboxes.forEach((checkbox) => (checkbox.checked = true));
} else {
checkboxes.forEach((checkbox) => (checkbox.checked = false));
}
updateFormVisibility();
});
function updateFormVisibility() {
const form = document.querySelector('.update-price-form');
const checkedCount = document.querySelectorAll('.car-checkbox:checked').length;
const submitButton = form.querySelector('button[type="submit"]');
if (checkedCount > 0) {
form.classList.remove('d-none');
submitButton.textContent = `Update Cost Price (${checkedCount})`;
} else {
form.classList.add('d-none');
}
}
</script>
{% endblock customJS %}
const cbox = document.querySelectorAll(".car-checkbox");
cbox.forEach((checkbox) => {
checkbox.addEventListener("change", function () {
updateFormVisibility();
});
});
function updateFormVisibility() {
const form = document.querySelector(".update-price-form");
const checkedCount = document.querySelectorAll(".car-checkbox:checked").length;
const submitButton = form.querySelector('button[type="submit"]');
if (checkedCount > 0) {
form.classList.remove("d-none");
submitButton.textContent = `Update Cost Price (${checkedCount})`;
} else {
form.classList.add("d-none");
}
}
</script>
{% endblock customJS %}
</div>

View File

@ -41,7 +41,7 @@
<div class="table-responsive px-1 scrollbar">
<div class="table-responsive px-1 scrollbar fs-9">
<table class="table align-items-center table-flush">
<thead>
<tr class="bg-body-highlight">

View File

@ -7,16 +7,17 @@
<div class="col-sm-6">
<form action="{% url 'billing_info' %}{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}" method="post" class="form">
<legend>{% trans "Provide billing data"|upper %}</legend>
{% comment %} <legend>{% trans "Provide billing data"|upper %}</legend> {% endcomment %}
<h3>{% trans "Provide billing data"|upper %}</h3>
{% csrf_token %}
{{ form|crispy }}
{% if object %}
<a class="btn btn-sm btn-phoenix-danger" href="{% url 'billing_info_delete' %}"><i class="fa-solid fa-trash me-1"></i> {{ _("Delete") }}</a>
{% endif %}
<button type="submit" class="btn btn-sm btn-phoenix-success">
<button type="submit" class="btn btn-sm btn-phoenix-success me-2">
<i class="fa fa-save me-1"></i>{{ _("Save") }}
</button>
{% if object %}
<a class="btn btn-sm btn-phoenix-danger " href="{% url 'billing_info_delete' %}"><i class="fa-solid fa-trash me-1"></i> {{ _("Delete") }}</a>
{% endif %}
</form>
</div>

View File

@ -107,7 +107,7 @@
</select>
</div>
<div class="row g-4 mt-4">
<div class="col">
<div class="col ms-6">
<p class="fs-5 mb-2">{% trans 'Exterior Colors' %}</p>
<div class="color-options-container">
{% for color in form.fields.exterior.queryset %}

View File

@ -31,7 +31,7 @@
{% if not create_po %}
{% if style == 'po-detail' %}
<div class="card shadow-sm border-0 mb-4">
<div class="card shadow-sm border-0 mb-2">
<div class="card-header bg-light">
<div class="d-flex align-items-center">
<span class="me-3 text-primary">
@ -120,7 +120,7 @@
<div class="card border-light h-100">
<div class="card-body">
<h5 class="h6 text-muted mb-2">{% trans 'PO Amount' %}</h5>
<p class="h5">{% currency_symbol %}{{ po_model.po_amount|currency_format }}</p>
<p class="h5">{{ po_model.po_amount|currency_format }}{% currency_symbol %}</p>
</div>
</div>
</div>
@ -128,7 +128,7 @@
<div class="card border-light h-100">
<div class="card-body">
<h5 class="h6 text-muted mb-2">{% trans 'Received Amount' %}</h5>
<p class="h5 text-success">{% currency_symbol %}{{ po_model.po_amount_received|currency_format }}</p>
<p class="h5 text-success">{{ po_model.po_amount_received|currency_format }}{% currency_symbol %}</p>
</div>
</div>
</div>

View File

@ -6,9 +6,9 @@
{% block content %}
<div class="container-fluid mt-4">
<div class="row g-4">
<!-- Left Sidebar -->
<div class="col-lg-4">
<div class="row g-1">
<div class="col-lg-12">
<div class="d-flex flex-column gap-3">
<!-- PO Card -->
<div class="card">
@ -17,22 +17,13 @@
</div>
</div>
<!-- PO List Button -->
<a class="btn btn-phoenix-primary w-100 py-2"
href="{% url 'purchase_order_list' %}">
<i class="fas fa-list me-2"></i>{% trans 'PO List' %}
</a>
</div>
</div>
<!-- Main Content -->
<div class="col-lg-8">
<!-- Stats Cards -->
<div class="card mb-4">
<!-- PO Stats Card-->
<div class="card mb-4">
<div class="card-body">
<div class="row text-center">
<div class="col-md-6 border-end">
<div class="p-3">
<div class="p-2">
<h6 class="text-muted mb-2">{% trans 'PO Amount' %}</h6>
<h3 class="fw-light mb-0">
{% currency_symbol %}{{ po_model.po_amount | absolute | currency_format }}
@ -40,7 +31,7 @@
</div>
</div>
<div class="col-md-6">
<div class="p-3">
<div class="p-2">
<h6 class="text-muted mb-2">{% trans 'Amount Received' %}</h6>
<h3 class="fw-light mb-0 text-success">
{% currency_symbol %}{{ po_model.po_amount_received | currency_format }}
@ -50,11 +41,14 @@
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<!-- PO Details -->
<div class="card">
<div class="card-body">
<h3 class="h4 fw-light mb-4">{{ po_model.po_title }}</h3>
<h3 class="h4 fw-light mb-2">{{ po_model.po_title }}</h3>
<!-- PO Items Table -->
<div class="table-responsive">
@ -62,6 +56,11 @@
</div>
</div>
</div>
<!--POS list-->
<a class="btn btn-phoenix-primary w-100 py-2 mt-2"
href="{% url 'purchase_order_list' %}">
<i class="fas fa-list me-2"></i>{% trans 'PO List' %}
</a>
</div>
</div>
</div>

View File

@ -42,7 +42,7 @@
{% if purchase_orders %}
{% for po in purchase_orders %}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="align-middle product white-space-nowrap">{{ po.po_number }}</td>
<td class="align-middle product white-space-nowrap ps-1">{{ po.po_number }}</td>
<td class="align-middle product white-space-nowrap">{{ po.po_title }}</td>
<td class="align-middle product white-space-nowrap">
<span class="">

View File

@ -10,9 +10,9 @@
{% if po.po_status == 'draft' %}
<h4 class="ms-2 text-warning mb-0">{{ po.po_status|capfirst }}</h4>
{% elif po.po_status == 'in_review' %}
<h4 class="ms-2 text-primary mb-0">{{ po.po_status|capfirst }}</h4>
<h4 class="ms-2 text-secondary mb-0">{{ po.po_status|capfirst }}</h4>
{% elif po.po_status == 'approved' %}
<h4 class="ms-2 text-info mb-0">{{ po.po_status|capfirst }}</h4>
<h4 class="ms-2 text-success mb-0">{{ po.po_status|capfirst }}</h4>
{% elif po.po_status == 'fulfilled' %}
<h4 class="ms-2 text-success mb-0">{{ po.po_status|capfirst }}</h4>
{% elif po.po_status == 'void' %}

View File

@ -53,7 +53,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center">{% trans "No Quotations Found" %}</td>
<td colspan="6" class="text-center">{% trans "No Quotation Found" %}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -37,7 +37,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center">{% trans "No Quotations Found" %}</td>
<td colspan="6" class="text-center">{% trans "No journal entry Found" %}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -46,7 +46,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center">{% trans "No Quotations Found" %}</td>
<td colspan="6" class="text-center">{% trans "No Order Found" %}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -15,7 +15,7 @@
<a href="{% url 'user_create' %}" class="btn btn-sm btn-phoenix-primary me-4"><i class="fa-solid fa-user-tie me-1"></i> {% trans "Add New Staff" %}</a>
<a href="{% url 'group_list' %}" class="btn btn-sm btn-phoenix-success"><i class="fa-solid fa-user-group me-1"></i> {% trans "Manage Groups & Permissions" %}</a>
{% else %}
<div class="alert alert-outline-info d-flex align-items-center" role="alert">
<div class="alert alert-outline-warning d-flex align-items-center" role="alert">
<i class="fa-solid fa-circle-info fs-6"></i>
<p class="mb-0 flex-1">{{ _("No Active Subscription,please activate your subscription.") }}<a href="{% url 'pricing_page' %}" class="ms-3 text-body-primary fs-9">Manage Subscription</a></p>
<button class="btn-close" type="button" data-bs-dismiss="alert" aria-label="Close"></button>

View File

@ -72,7 +72,7 @@
<th class="sort white-space-nowrap align-middle"
scope="col"
data-sort="date"
style="width:15%">{{ _("Create date") }}</th>
style="width:15%">{{ _("Created date") }}</th>
<th class="sort white-space-nowrap align-middle" scope="col"></th>
</tr>
</thead>