update
@ -94,9 +94,9 @@ urlpatterns = [
|
||||
),
|
||||
path("crm/leads/<int:pk>/delete/", views.LeadDeleteView, name="lead_delete"),
|
||||
path("crm/leads/<int:pk>/lead-convert/", views.lead_convert, name="lead_convert"),
|
||||
path("crm/leads/<int:pk>/add-note/", views.add_note_to_lead, name="add_note"),
|
||||
path('crm/leads/<int:pk>/update-note/', views.update_note, name='update_note'),
|
||||
path("crm/leads/<int:pk>/delete-note/", views.delete_note, name="delete_note"),
|
||||
path("crm/leads/<int:pk>/add-note/", views.add_note_to_lead, name="add_note_to_lead"),
|
||||
path('crm/leads/<int:pk>/update-note/', views.update_note, name='update_note_to_lead'),
|
||||
path("crm/leads/<int:pk>/delete-note/", views.delete_note, name="delete_note_to_lead"),
|
||||
path(
|
||||
"crm/leads/<int:pk>/add-activity/",
|
||||
views.add_activity_to_lead,
|
||||
|
||||
@ -652,9 +652,7 @@ class CarInventory(LoginRequiredMixin, ListView):
|
||||
id_car_trim=trim_id,
|
||||
).order_by("receiving_date")
|
||||
|
||||
if query:
|
||||
cars = cars.filter(Q(vin__icontains=query))
|
||||
return cars
|
||||
return apply_search_filters(cars, query)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
@ -1234,13 +1232,7 @@ class CustomerListView(LoginRequiredMixin, ListView):
|
||||
|
||||
customers = dealer.entity.get_customers().filter(additional_info__type="customer")
|
||||
|
||||
if query:
|
||||
customers = customers.filter(
|
||||
Q(first_name__icontains=query)
|
||||
| Q(last_name__icontains=query)
|
||||
| Q(additional_info__info__icontains=query)
|
||||
)
|
||||
return customers
|
||||
return apply_search_filters(customers, query)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
@ -1287,7 +1279,7 @@ def add_note_to_customer(request, pk):
|
||||
return redirect("customer_detail", pk=pk)
|
||||
else:
|
||||
form = forms.NoteForm()
|
||||
return render(request, "crm/add_note.html", {"form": form, "customer": customer})
|
||||
return render(request, "crm/note_form.html", {"form": form, "customer": customer})
|
||||
|
||||
|
||||
def add_activity_to_customer(request, pk):
|
||||
@ -1421,10 +1413,11 @@ class VendorListView(LoginRequiredMixin, ListView):
|
||||
ordering = ["-created"]
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
# vendors = models.Vendor.objects.filter(dealer=dealer)
|
||||
return dealer.entity.get_vendors().filter(active=True)
|
||||
# return vendors
|
||||
vendors = dealer.entity.get_vendors().filter(active=True)
|
||||
return apply_search_filters(vendors, query)
|
||||
|
||||
|
||||
|
||||
# class VendorDetailView(LoginRequiredMixin, DetailView):
|
||||
@ -1861,8 +1854,10 @@ class UserListView(LoginRequiredMixin, ListView):
|
||||
template_name = "users/user_list.html"
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
return models.Staff.objects.filter(dealer=dealer).all()
|
||||
staff = models.Staff.objects.filter(dealer=dealer).all()
|
||||
return apply_search_filters(staff, query)
|
||||
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
@ -1944,12 +1939,13 @@ class OrganizationListView(LoginRequiredMixin, ListView):
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
return (
|
||||
dealer.entity.get_customers()
|
||||
.filter(additional_info__type="organization", active=True)
|
||||
.all()
|
||||
)
|
||||
organization = dealer.entity.get_customers().filter(additional_info__type="organization", active=True)
|
||||
|
||||
return apply_search_filters(organization, query)
|
||||
|
||||
|
||||
|
||||
|
||||
class OrganizationDetailView(DetailView):
|
||||
@ -2040,8 +2036,10 @@ class RepresentativeListView(LoginRequiredMixin, ListView):
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
return models.Representative.objects.filter(dealer=dealer).all()
|
||||
representative = models.Representative.objects.filter(dealer=dealer)
|
||||
return apply_search_filters(representative, query)
|
||||
|
||||
|
||||
class RepresentativeDetailView(DetailView):
|
||||
@ -2266,8 +2264,10 @@ class BankAccountListView(LoginRequiredMixin, ListView):
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
return BankAccountModel.objects.filter(entity_model=dealer.entity)
|
||||
bank_accounts = BankAccountModel.objects.filter(entity_model=dealer.entity)
|
||||
return apply_search_filters(bank_accounts, query)
|
||||
|
||||
|
||||
class BankAccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
@ -2337,9 +2337,10 @@ class AccountListView(LoginRequiredMixin, ListView):
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
entity = dealer.entity
|
||||
return entity.get_all_accounts()
|
||||
accounts = dealer.entity.get_all_accounts()
|
||||
return apply_search_filters(accounts, query)
|
||||
|
||||
|
||||
class AccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
@ -2436,7 +2437,7 @@ def sales_list_view(request):
|
||||
entity = dealer.entity
|
||||
|
||||
transactions = ItemTransactionModel.objects.for_entity(entity_slug=entity.slug, user_model=dealer.user)
|
||||
paginator = Paginator(transactions, 20)
|
||||
paginator = Paginator(transactions, 10)
|
||||
page_number = request.GET.get('page')
|
||||
page_obj = paginator.get_page(page_number)
|
||||
txs = get_item_transactions(page_obj)
|
||||
@ -2803,9 +2804,10 @@ class InvoiceListView(LoginRequiredMixin, ListView):
|
||||
paginate_by = 20
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
entity = dealer.entity
|
||||
return entity.get_invoices()
|
||||
invoices = dealer.entity.get_invoices()
|
||||
return apply_search_filters(invoices, query)
|
||||
|
||||
|
||||
class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
||||
@ -4356,8 +4358,24 @@ class EmployeeCalendarView(ListView):
|
||||
context_object_name = 'appointments'
|
||||
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get('q')
|
||||
dealer = get_user_type(self.request)
|
||||
staff = self.request.user.staff
|
||||
return Appointment.objects.filter(appointment_request__staff_member=staff).all()
|
||||
staff = getattr(self.request, 'staff', None)
|
||||
if staff:
|
||||
appointments = Appointment.objects.filter(appointment_request__staff_member=staff, ppointment_request__date__gt=timezone.now())
|
||||
appointments = Appointment.objects.filter(appointment_request__date__gt=timezone.now())
|
||||
return apply_search_filters(appointments, query)
|
||||
|
||||
|
||||
|
||||
def apply_search_filters(queryset, query):
|
||||
if not query:
|
||||
return queryset
|
||||
|
||||
search_filters = Q()
|
||||
model = queryset.model
|
||||
|
||||
for field in model._meta.get_fields():
|
||||
if hasattr(field, 'attname') and field.get_internal_type() in ["CharField", "TextField", "EmailField"]:
|
||||
search_filters |= Q(**{f"{field.name}__icontains": query})
|
||||
return queryset.filter(search_filters).distinct()
|
||||
BIN
static/images/car_make/Abarth_WQexAcP.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
static/images/car_make/Alfa-Romeo-2_jj41jXd.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
static/images/car_make/Aston-Martin_UVYOY98.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/images/car_make/Dodge.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
static/images/car_make/FAW.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
static/images/car_make/Ford.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
static/images/car_make/Jeep.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
static/images/car_make/KIA.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
static/images/car_make/KIA_RcrUDZf.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
static/images/car_make/Maserati.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
static/images/car_make/Nissan.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
static/images/car_make/Peugeot.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
static/images/car_make/Toyota.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
@ -1,22 +1,38 @@
|
||||
<!-- crm/employee_calendar.html -->
|
||||
<h1>Upcoming Test Drives</h1>
|
||||
<table>
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="table-responsive border-translucent">
|
||||
<table class="table table-sm fs-9">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Customer</th>
|
||||
<th>Vehicle</th>
|
||||
<th>Date/Time</th>
|
||||
<th>Service</th>
|
||||
<th>Date</th>
|
||||
<th>Start Time</th>
|
||||
<th>End Time</th>
|
||||
<th>Staff</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for appointment in appointments %}
|
||||
<tr>
|
||||
<td>{{ appointment.client.name }}</td>
|
||||
<td>{{ appointment.service.name }}</td>
|
||||
<td>{{ appointment.start_time|date:"M j, Y H:i" }}</td>
|
||||
<td>{{ appointment.staff.user.get_full_name }}</td>
|
||||
<td>{{ appointment.get_client_name }}</td>
|
||||
<td>{{ appointment.get_service }}</td>
|
||||
<td>{{ appointment.appointment_request.date|date:"Y-m-d" }}</td>
|
||||
<td>{{ appointment.appointment_request.start_time }}</td>
|
||||
<td>{{ appointment.appointment_request.end_time }}</td>
|
||||
<td>{{ appointment.get_staff_member_name }}</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<a href="{% url 'appointment:display_appointment' appointment.id %}">view</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -181,7 +181,7 @@
|
||||
<h3 class="mb-4" id="scrollspyNotes">{{ _("Notes") }}</h3>
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-start">
|
||||
<a id="addBtn" href="#" class="btn btn-sm btn-phoenix-primary mb-3" data-url="{% url 'add_note' lead.pk %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Add") }}<i class='fa fa-plus-circle text-success ms-2'></i>">
|
||||
<a id="addBtn" href="#" class="btn btn-sm btn-phoenix-primary mb-3" data-url="{% url 'add_note_to_lead' lead.pk %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Add") }}<i class='fa fa-plus-circle text-success ms-2'></i>">
|
||||
<span class="fas fa-plus me-1"></span>
|
||||
{% trans 'Add Note' %}
|
||||
</a>
|
||||
@ -197,7 +197,7 @@
|
||||
<th class="align-middle pe-0 text-end" scope="col" style="width:10%;"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list" id="lead-details-table-body">
|
||||
<tbody >
|
||||
{% for note in notes %}
|
||||
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
@ -205,17 +205,17 @@
|
||||
{% if note.created_by.staff %}
|
||||
<td class="align-middle white-space-nowrap text-start white-space-nowrap">{{ note.created_by.staff.name }}</td>
|
||||
{% else %}
|
||||
<td class="align-middle white-space-nowrap text-start white-space-nowrap">{{ note.created_by.dealer.get_local_name }}</td>
|
||||
<td class="align-middle white-space-nowrap text-start white-space-nowrap">{{ note.created_by.dealer.get_local_name|default:note.created_by.dealer.name }}</td>
|
||||
{% endif %}
|
||||
<td class="align-middle text-body-tertiary text-start white-space-nowrap">{{ note.created }}</td>
|
||||
<td class="align-middle text-end white-space-nowrap pe-0 action py-2">
|
||||
{% if note.created_by == request.user %}
|
||||
<a id="updateBtn" href="#" class="btn btn-sm btn-phoenix-primary me-2" data-url="{% url 'update_note' note.pk %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Update") }}<i class='fas fa-pen-square text-primary ms-2'></i>">
|
||||
<a id="updateBtn" href="#" class="btn btn-sm btn-phoenix-primary me-2" data-url="{% url 'update_note_to_lead' note.pk %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Update") }}<i class='fas fa-pen-square text-primary ms-2'></i>">
|
||||
<i class="fas fa-pen"></i>
|
||||
</a>
|
||||
|
||||
<button class="btn btn-phoenix-danger btn-sm delete-btn"
|
||||
data-url="{% url 'delete_note' note.pk %}"
|
||||
data-url="{% url 'delete_note_to_lead' note.pk %}"
|
||||
data-message="Are you sure you want to delete this note?"
|
||||
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
<i class="fas fa-trash"></i>
|
||||
|
||||
@ -121,8 +121,7 @@
|
||||
</div>
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="name align-middle white-space-nowrap ps-0">
|
||||
<div class="d-flex align-items-center"><a href="#!">
|
||||
</a>
|
||||
<div class="d-flex align-items-center">
|
||||
<div><a class="fs-8 fw-bold" href="{% url 'lead_detail' lead.pk %}">{{lead.full_name}}</a>
|
||||
<div class="d-flex align-items-center">
|
||||
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2"></p>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{% load i18n static crispy_forms_filters %}
|
||||
|
||||
{% if form.instance.pk %}
|
||||
<form method="post" action="{% url 'update_note' note.pk %}" enctype="multipart/form-data">
|
||||
<form method="post" action="{% url 'update_note_to_lead' note.pk %}" enctype="multipart/form-data">
|
||||
{% else %}
|
||||
<form method="post" action="{% url 'add_note' lead.pk %}" enctype="multipart/form-data">
|
||||
<form method="post" action="{% url 'add_note_to_lead' lead.pk %}" enctype="multipart/form-data">
|
||||
{% endif %}
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
|
||||
<h4 class="mb-4">{{ _("Customers")|capfirst }}</h4>
|
||||
<div class="row g-3 justify-content-between mb-4">
|
||||
<div class="col-auto">
|
||||
<div class="d-md-flex justify-content-between">
|
||||
@ -17,25 +17,15 @@
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="d-flex">
|
||||
<div class="search-box me-2">
|
||||
<form method="get" class="d-inline-block position-relative">
|
||||
<div class="input-group">
|
||||
<button type="submit" class="btn btn-phoenix-primary"><span class="fas fa-search search-box-icon"></span></button>
|
||||
<input name="q" class="form-control search-input search" type="search" placeholder="{{ _('Enter customer name') }}" value="{{ request.GET.q }}"/>
|
||||
{% if request.GET.q %}
|
||||
<a href="{% url request.resolver_match.view_name %}" class="btn btn-close"></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
{% include 'partials/search_box.html' %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if page_obj.object_list %}
|
||||
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||
<div class="table-responsive scrollbar transition">
|
||||
|
||||
<table class="table fs-9 mb-0 border-top border-translucent">
|
||||
<table class="table table-sm fs-9 mb-0 border-translucent">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
@ -104,11 +94,9 @@
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
<div class="row align-items-center justify-content-end py-4 pe-0 fs-9">
|
||||
{% if is_paginated %}
|
||||
|
||||
{% include 'partials/pagination.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% include 'modal/delete_modal.html' %}
|
||||
|
||||
|
||||
@ -106,7 +106,10 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-end">
|
||||
<a class="fw-bold fs-9 mb-0 text-end" href="{% url 'add_note_to_customer' customer.pk %}"><span class="fas fa-plus me-1"></span>{{ _("Add Note")}}</a>
|
||||
<a id="addBtn" href="#" class="btn btn-sm btn-phoenix-primary mb-3" data-url="{% url 'add_note_to_customer' customer.pk %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Add") }}<i class='fa fa-plus-circle text-success ms-2'></i>">
|
||||
<span class="fas fa-plus me-1"></span>
|
||||
{% trans 'Add Note' %}
|
||||
</a>
|
||||
</div>
|
||||
<table class="table fs-9 mb-0 table-responsive">
|
||||
<thead>
|
||||
@ -214,21 +217,13 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row align-items-center justify-content-between py-2 pe-0 fs-9">
|
||||
<div class="col-auto d-flex">
|
||||
<p class="mb-0 d-none d-sm-block me-3 fw-semibold text-body" data-list-info="data-list-info"></p><a class="fw-semibold" href="#!" data-list-view="*">View all<span class="fas fa-angle-right ms-1" data-fa-transform="down-1"></span></a><a class="fw-semibold d-none" href="#!" data-list-view="less">View Less<span class="fas fa-angle-right ms-1" data-fa-transform="down-1"></span></a>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button class="page-link" data-list-pagination="prev"><span class="fas fa-chevron-left"></span></button>
|
||||
<ul class="mb-0 pagination"></ul>
|
||||
<button class="page-link pe-0" data-list-pagination="next"><span class="fas fa-chevron-right"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'partials/pagination.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'partials/notes.html' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -436,15 +436,17 @@
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3 d-block" href="{% url 'user_detail' user.staff.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||
<a class="nav-link px-3 d-block" href="{% url 'appointment:user_profile' request.user.id %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user.dealer %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff") }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activity") }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link px-3 d-block" href=""> <span class="me-2 text-body align-bottom" data-feather="settings"></span>Settings & Privacy </a>
|
||||
</li>
|
||||
|
||||
@ -38,20 +38,20 @@
|
||||
<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-primary px-2 py-1"><span>{{ _("Filter") }}</span><span class="fas fa-caret-down fs-9 ms-1 filter-icon"></span></button></li>
|
||||
<li class="nav-item"><button hx-on:click="toggle_filter()" class="btn btn-sm btn-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">
|
||||
<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"
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -94,8 +94,6 @@
|
||||
<div class="row">
|
||||
<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">
|
||||
</div>
|
||||
<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()">
|
||||
@ -164,17 +162,13 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<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" hx-indicator=".htmx-indicator"
|
||||
hx-on::before-request="on_before_request()"
|
||||
hx-on::after-request="on_after_request()">
|
||||
</div>
|
||||
</div>
|
||||
{% include 'partials/pagination.html' %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if is_paginated %}
|
||||
{% include 'partials/pagination.html' %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="row">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card bg-body">
|
||||
<div class="card-header">
|
||||
{% if service.pk %}
|
||||
{{ _("Update Service") }}
|
||||
@ -19,7 +19,7 @@
|
||||
<form method="post" action="">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<button type="submit" class="btn btn-primary">{% trans 'Save' %}</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary">{% trans 'Save' %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,16 +4,16 @@
|
||||
{% block title %}{{ _("Expenses") }}{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row mt-4 mx-4">
|
||||
<div class="d-flex justify-content-between mb-2 p-6">
|
||||
<span></span>
|
||||
<h3 class="text-center">{% trans "Services" %}</h3>
|
||||
<a href="{% url 'item_service_create' %}" class="btn btn-sm btn-success ">{% trans "Add Service" %}</a>
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-between">
|
||||
|
||||
<h3 class="mb-2">{% trans "Services" %}</h3>
|
||||
<a href="{% url 'item_service_create' %}" class="btn btn-sm btn-phoenix-primary ">{% trans "Add Service" %}</a>
|
||||
</div>
|
||||
<div class="mx-n4 px-4 mx-lg-n6 px-lg-6 bg-body-emphasis pt-7 border-y">
|
||||
|
||||
|
||||
<div class="table-responsive mx-n1 px-1 scrollbar">
|
||||
<table class="table fs-9 mb-0 border-top border-translucent">
|
||||
<div class="table-responsive scrollbar transition">
|
||||
<table class="table table-sm fs-9 mb-0 border-translucent">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Item Number" %}</th>
|
||||
@ -56,5 +56,4 @@
|
||||
<div class="d-flex justify-content-center">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
15
templates/partials/search_box.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="search-box me-2">
|
||||
<form class="position-relative justify-content-between">
|
||||
|
||||
<input name="q" class="form-control form-control-sm search-input search" type="search" aria-label="Search" placeholder="{{ _('Search') }}" value="{{ request.GET.q }}"/>
|
||||
<span class="fa fa-magnifying-glass search-box-icon"></span>
|
||||
|
||||
</form>
|
||||
<div class="position-absolute top-50 start-50 translate-middle ">
|
||||
{% if request.GET.q %}
|
||||
<a href="{% url request.resolver_match.view_name %}" class="btn p-0"><span class="fas fa-times text-danger "></span></a>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -52,24 +52,7 @@
|
||||
/>
|
||||
<span class="fas fa-search search-box-icon"></span>
|
||||
</form>
|
||||
</div><a class="btn btn-phoenix-primary px-3 me-1 border-0 text-body" href="#" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="List view"><span class="fa-solid fa-list fs-10"></span></a><a class="btn btn-phoenix-primary px-3 me-1" href="#" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Board view">
|
||||
<svg width="9" height="9" viewbox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0.5C0 0.223857 0.223858 0 0.5 0H1.83333C2.10948 0 2.33333 0.223858 2.33333 0.5V1.83333C2.33333 2.10948 2.10948 2.33333 1.83333 2.33333H0.5C0.223857 2.33333 0 2.10948 0 1.83333V0.5Z" fill="currentColor"></path>
|
||||
<path d="M3.33333 0.5C3.33333 0.223857 3.55719 0 3.83333 0H5.16667C5.44281 0 5.66667 0.223858 5.66667 0.5V1.83333C5.66667 2.10948 5.44281 2.33333 5.16667 2.33333H3.83333C3.55719 2.33333 3.33333 2.10948 3.33333 1.83333V0.5Z" fill="currentColor"></path>
|
||||
<path d="M6.66667 0.5C6.66667 0.223857 6.89052 0 7.16667 0H8.5C8.77614 0 9 0.223858 9 0.5V1.83333C9 2.10948 8.77614 2.33333 8.5 2.33333H7.16667C6.89052 2.33333 6.66667 2.10948 6.66667 1.83333V0.5Z" fill="currentColor"></path>
|
||||
<path d="M0 3.83333C0 3.55719 0.223858 3.33333 0.5 3.33333H1.83333C2.10948 3.33333 2.33333 3.55719 2.33333 3.83333V5.16667C2.33333 5.44281 2.10948 5.66667 1.83333 5.66667H0.5C0.223857 5.66667 0 5.44281 0 5.16667V3.83333Z" fill="currentColor"></path>
|
||||
<path d="M3.33333 3.83333C3.33333 3.55719 3.55719 3.33333 3.83333 3.33333H5.16667C5.44281 3.33333 5.66667 3.55719 5.66667 3.83333V5.16667C5.66667 5.44281 5.44281 5.66667 5.16667 5.66667H3.83333C3.55719 5.66667 3.33333 5.44281 3.33333 5.16667V3.83333Z" fill="currentColor"></path>
|
||||
<path d="M6.66667 3.83333C6.66667 3.55719 6.89052 3.33333 7.16667 3.33333H8.5C8.77614 3.33333 9 3.55719 9 3.83333V5.16667C9 5.44281 8.77614 5.66667 8.5 5.66667H7.16667C6.89052 5.66667 6.66667 5.44281 6.66667 5.16667V3.83333Z" fill="currentColor"></path>
|
||||
<path d="M0 7.16667C0 6.89052 0.223858 6.66667 0.5 6.66667H1.83333C2.10948 6.66667 2.33333 6.89052 2.33333 7.16667V8.5C2.33333 8.77614 2.10948 9 1.83333 9H0.5C0.223857 9 0 8.77614 0 8.5V7.16667Z" fill="currentColor"></path>
|
||||
<path d="M3.33333 7.16667C3.33333 6.89052 3.55719 6.66667 3.83333 6.66667H5.16667C5.44281 6.66667 5.66667 6.89052 5.66667 7.16667V8.5C5.66667 8.77614 5.44281 9 5.16667 9H3.83333C3.55719 9 3.33333 8.77614 3.33333 8.5V7.16667Z" fill="currentColor"></path>
|
||||
<path d="M6.66667 7.16667C6.66667 6.89052 6.89052 6.66667 7.16667 6.66667H8.5C8.77614 6.66667 9 6.89052 9 7.16667V8.5C9 8.77614 8.77614 9 8.5 9H7.16667C6.89052 9 6.66667 8.77614 6.66667 8.5V7.16667Z" fill="currentColor"></path>
|
||||
</svg></a><a class="btn btn-phoenix-primary px-3" href="#" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Card view">
|
||||
<svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0.5C0 0.223858 0.223858 0 0.5 0H3.5C3.77614 0 4 0.223858 4 0.5V3.5C4 3.77614 3.77614 4 3.5 4H0.5C0.223858 4 0 3.77614 0 3.5V0.5Z" fill="currentColor"></path>
|
||||
<path d="M0 5.5C0 5.22386 0.223858 5 0.5 5H3.5C3.77614 5 4 5.22386 4 5.5V8.5C4 8.77614 3.77614 9 3.5 9H0.5C0.223858 9 0 8.77614 0 8.5V5.5Z" fill="currentColor"></path>
|
||||
<path d="M5 0.5C5 0.223858 5.22386 0 5.5 0H8.5C8.77614 0 9 0.223858 9 0.5V3.5C9 3.77614 8.77614 4 8.5 4H5.5C5.22386 4 5 3.77614 5 3.5V0.5Z" fill="currentColor"></path>
|
||||
<path d="M5 5.5C5 5.22386 5.22386 5 5.5 5H8.5C8.77614 5 9 5.22386 9 5.5V8.5C9 8.77614 8.77614 9 8.5 9H5.5C5.22386 9 5 8.77614 5 8.5V5.5Z" fill="currentColor"></path>
|
||||
</svg></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -109,24 +92,16 @@
|
||||
hx-on::before-request="filter_before_request()"
|
||||
hx-on::after-request="filter_after_request()">Search</button>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="table-responsive scrollbar transition">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9 border-bottom border-translucent">
|
||||
<div class="d-flex">
|
||||
</div>
|
||||
<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()">
|
||||
{% if page_obj.has_previous %}
|
||||
<a href="{% url 'sales_list' %}?page={{page_obj.previous_page_number}}" class="page-link" data-list-pagination="prev"><span class="fas fa-chevron-left"></span></a>
|
||||
{% endif %}
|
||||
<ul class="mb-0 pagination">Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</ul>
|
||||
{% if page_obj.has_next %}
|
||||
<a href="{% url 'sales_list' %}?page={{page_obj.next_page_number}}" class="page-link pe-0" data-list-pagination="next"><span class="fas fa-chevron-right"></span></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<table class="table fs-9 mb-0 border-top border-translucent">
|
||||
|
||||
<table class="table table-sm fs-9 mb-0 border-translucent">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort white-space-nowrap align-middle ps-0" scope="col" data-sort="projectName" style="width:10%;">
|
||||
@ -147,29 +122,29 @@
|
||||
<tbody class="list" id="project-list-table-body">
|
||||
{% for tx in txs %}
|
||||
<tr class="position-static">
|
||||
<td class="align-middle white-space-nowrap deadline ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap deadline">
|
||||
<p class="mb-0 fs-9 text-body">{{tx.customer.customer_name}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap deadline ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap deadline">
|
||||
<p class="mb-0 fs-9 text-body">{{tx.customer.address_1}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap deadline ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap deadline">
|
||||
<p class="mb-0 fs-9 text-body">{{tx.customer.phone}}</p>
|
||||
</td>
|
||||
<td class="align-middle time white-space-nowrap ps-0 projectName py-4">{{tx.info.make}}</td>
|
||||
<td class="align-middle white-space-nowrap start ps-3 py-4">
|
||||
<td class="align-middle time white-space-nowrap projectName">{{tx.info.make}}</td>
|
||||
<td class="align-middle white-space-nowrap start">
|
||||
<p class="mb-0 fs-9 text-body">{{tx.info.model}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap deadline ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap deadline">
|
||||
<p class="mb-0 fs-9 text-body">{{tx.info.vin}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap task ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap task">
|
||||
<p class="fw-bo text-body fs-9 mb-0">{{tx.info.trim}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap task ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap task">
|
||||
<p class="fw-bo text-body fs-9 mb-0">{{tx.finance.total}}</p>
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap task ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap task">
|
||||
{% if tx.has_estimate %}
|
||||
<p class="fw-bo text-body fs-9 mb-0">
|
||||
<a href="{% url 'estimate_detail' tx.estimate.uuid %}">
|
||||
@ -187,7 +162,7 @@
|
||||
</p>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="align-middle white-space-nowrap task ps-3 py-4">
|
||||
<td class="align-middle white-space-nowrap task">
|
||||
{% if tx.has_invoice %}
|
||||
<p class="fw-bo text-body fs-9 mb-0">
|
||||
<a href="{% url 'invoice_detail' tx.invoice.uuid %}">
|
||||
@ -235,18 +210,15 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9 border-bottom border-translucent">
|
||||
<div class="d-flex">
|
||||
{% if is_paginated %}
|
||||
{% include 'partials/pagination.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block customJS %}
|
||||
|
||||