added search
This commit is contained in:
parent
8398dcd5de
commit
51b2833e54
@ -3865,6 +3865,15 @@ class BankAccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
|
|||||||
context_object_name = "bank_account"
|
context_object_name = "bank_account"
|
||||||
permission_required = ["django_ledger.view_bankaccountmodel"]
|
permission_required = ["django_ledger.view_bankaccountmodel"]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
|
query=self.request.GET.get('q')
|
||||||
|
qs=self.model.objects.filter(entity=dealer.entity)
|
||||||
|
if query:
|
||||||
|
qs=apply_search_filters(qs,query)
|
||||||
|
return qs
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class BankAccountUpdateView(
|
class BankAccountUpdateView(
|
||||||
LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView
|
LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView
|
||||||
@ -5584,7 +5593,15 @@ class LeadListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
qs = models.Lead.objects.filter(dealer=dealer).exclude(status="converted")
|
qs = models.Lead.objects.filter(dealer=dealer).exclude(status="converted")
|
||||||
if query:
|
if query:
|
||||||
qs = apply_search_filters(qs, query)
|
qs = qs.filter(Q(first_name__icontains=query)
|
||||||
|
| Q(last_name__icontains=query)
|
||||||
|
| Q(id_car_make__name__icontains=query)
|
||||||
|
| Q(id_car_model__name__icontains=query)
|
||||||
|
| Q(email__icontains=query)
|
||||||
|
| Q(phone_number__icontains=query)
|
||||||
|
| Q(next_action__icontains=query)
|
||||||
|
| Q(staff__name__icontains=query))
|
||||||
|
|
||||||
if self.request.is_dealer:
|
if self.request.is_dealer:
|
||||||
return qs
|
return qs
|
||||||
staffmember = getattr(self.request.user, "staffmember", None)
|
staffmember = getattr(self.request.user, "staffmember", None)
|
||||||
@ -5593,6 +5610,7 @@ class LeadListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
return models.Lead.objects.none()
|
return models.Lead.objects.none()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||||
"""
|
"""
|
||||||
View that provides detailed information about a specific lead.
|
View that provides detailed information about a specific lead.
|
||||||
@ -6654,12 +6672,15 @@ class OpportunityListView(LoginRequiredMixin,PermissionRequiredMixin, ListView):
|
|||||||
queryset = models.Opportunity.objects.filter(dealer=dealer, lead__staff=staff)
|
queryset = models.Opportunity.objects.filter(dealer=dealer, lead__staff=staff)
|
||||||
|
|
||||||
# Search filter
|
# Search filter
|
||||||
search = self.request.GET.get("search")
|
search = self.request.GET.get("q")
|
||||||
if search:
|
if search:
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
Q(customer__customer_name__icontains=search)
|
Q(customer__first_name__icontains=search)
|
||||||
|
| Q(customer__last_name__icontains=search)
|
||||||
| Q(customer__email__icontains=search)
|
| Q(customer__email__icontains=search)
|
||||||
)
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Stage filter
|
# Stage filter
|
||||||
stage = self.request.GET.get("stage")
|
stage = self.request.GET.get("stage")
|
||||||
@ -6947,10 +6968,17 @@ class ItemServiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
|
|||||||
paginate_by = 30
|
paginate_by = 30
|
||||||
permission_required = ["inventory.view_additionalservices"]
|
permission_required = ["inventory.view_additionalservices"]
|
||||||
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
return models.AdditionalServices.objects.filter(dealer=dealer).all()
|
query=self.request.GET.get('q')
|
||||||
|
qs= models.AdditionalServices.objects.filter(dealer=dealer).all()
|
||||||
|
if query:
|
||||||
|
qs=apply_search_filters(qs,query)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
# def get_queryset(self):
|
||||||
|
# dealer = get_user_type(self.request)
|
||||||
|
# return models.AdditionalServices.objects.filter(dealer=dealer).all()
|
||||||
|
|
||||||
|
|
||||||
class ItemExpenseCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
class ItemExpenseCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||||
@ -7068,9 +7096,18 @@ class ItemExpenseListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
|
|||||||
paginate_by = 30
|
paginate_by = 30
|
||||||
permission_required = ["django_ledger.view_itemmodel"]
|
permission_required = ["django_ledger.view_itemmodel"]
|
||||||
|
|
||||||
|
# def get_queryset(self):
|
||||||
|
# dealer = get_user_type(self.request)
|
||||||
|
# return dealer.entity.get_items_expenses()
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
return dealer.entity.get_items_expenses()
|
query=self.request.GET.get('q')
|
||||||
|
qs= dealer.entity.get_items_expenses()
|
||||||
|
if query:
|
||||||
|
qs=apply_search_filters(qs,query)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BillListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
class BillListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||||
@ -7100,6 +7137,9 @@ class BillListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
qs = dealer.entity.get_bills()
|
qs = dealer.entity.get_bills()
|
||||||
|
query=self.request.GET.get('q')
|
||||||
|
if query:
|
||||||
|
qs=qs.filter(vendor__vendor_name__icontains=query)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@ -9917,12 +9957,23 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie
|
|||||||
template_name = "purchase_orders/po_list.html"
|
template_name = "purchase_orders/po_list.html"
|
||||||
permission_required = ["django_ledger.view_purchaseordermodel"]
|
permission_required = ["django_ledger.view_purchaseordermodel"]
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
|
||||||
return self.model.objects.filter(entity=dealer.entity)
|
|
||||||
|
|
||||||
# def get_queryset(self):
|
# def get_queryset(self):
|
||||||
# dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
# dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
|
# return self.model.objects.filter(entity=dealer.entity)
|
||||||
|
def get_queryset(self):
|
||||||
|
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
|
query=self.request.GET.get("q")
|
||||||
|
qs=self.model.objects.filter(entity=dealer.entity)
|
||||||
|
if query:
|
||||||
|
qs=apply_search_filters(qs,query)
|
||||||
|
if self.request.is_dealer:
|
||||||
|
return qs
|
||||||
|
staffmember= staffmember = getattr(self.request.user, "staffmember", None)
|
||||||
|
if staff := getattr(staffmember, "staff", None):
|
||||||
|
return qs.filter(staff=staff)
|
||||||
|
return self.model.objects.none()
|
||||||
|
# def get_queryset(self):
|
||||||
|
# dealer = get_user_type(self.request)
|
||||||
# entity = dealer.entity
|
# entity = dealer.entity
|
||||||
# queryset = self.model.objects.filter(entity=entity)
|
# queryset = self.model.objects.filter(entity=entity)
|
||||||
|
|
||||||
|
|||||||
@ -12,25 +12,22 @@
|
|||||||
<!-- Filter Controls -->
|
<!-- Filter Controls -->
|
||||||
<div class="d-flex flex-column flex-lg-row align-items-start align-items-lg-center gap-3 w-100" id="filter-container">
|
<div class="d-flex flex-column flex-lg-row align-items-start align-items-lg-center gap-3 w-100" id="filter-container">
|
||||||
<!-- Search Input - Wider and properly aligned -->
|
<!-- Search Input - Wider and properly aligned -->
|
||||||
<div class="position-relative flex-grow-1" style="min-width: 300px;">
|
|
||||||
<span class="fas fa-search position-absolute top-50 translate-middle-y ms-3 text-body-tertiary"></span>
|
<div class="search-box position-relative flex-grow-1 me-2" style="min-width: 200px;">
|
||||||
<input
|
<form class="position-relative show" id="search-form">
|
||||||
class="form-control ps-6"
|
<input name="q" id="search-input" class="form-control form-control-sm search-input search" type="search"
|
||||||
type="text"
|
aria-label="Search" placeholder="{{ _('Search') }}" value="{{ request.GET.q }}" />
|
||||||
placeholder="{% trans 'Search opportunities...' %}"
|
<span class="fa fa-magnifying-glass search-box-icon"></span>
|
||||||
name="search"
|
{% if request.GET.q %}
|
||||||
hx-get="{% url 'opportunity_list' request.dealer.slug %}"
|
<button type="button" class="btn-close position-absolute end-0 top-50 translate-middle cursor-pointer shadow-none"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
id="clear-search" aria-label="Close"></button>
|
||||||
hx-target="#opportunities-grid"
|
{% endif %}
|
||||||
hx-select="#opportunities-grid"
|
</form>
|
||||||
hx-include="#filter-container select"
|
</div>
|
||||||
hx-swap="outerHTML"
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Filter Dropdowns - Aligned in a row -->
|
<!-- Filter Dropdowns - Aligned in a row -->
|
||||||
<div class="d-flex flex-column flex-sm-row gap-3 w-100" style="max-width: 500px;">
|
<div class="d-flex flex-column flex-sm-row gap-3 w-100" style="max-width: 400px;">
|
||||||
<!-- Stage Filter -->
|
<!-- Stage Filter -->
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<select
|
<select
|
||||||
@ -78,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if perms.inventory.add_opportunity %}
|
{% if perms.inventory.add_opportunity %}
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-between">
|
||||||
<a class="btn btn-phoenix-primary btn-sm" href="{% url 'opportunity_create' request.dealer.slug %}">
|
<a class="btn btn-phoenix-primary btn-sm" href="{% url 'opportunity_create' request.dealer.slug %}">
|
||||||
<span class="fas fa-plus me-2"></span>{{ _("Add Opportunity") }}
|
<span class="fas fa-plus me-2"></span>{{ _("Add Opportunity") }}
|
||||||
</a>
|
</a>
|
||||||
@ -101,4 +98,24 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% block customJS %}
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
const searchInput = document.getElementById("search-input");
|
||||||
|
const clearButton = document.getElementById("clear-search");
|
||||||
|
|
||||||
|
if (clearButton) {
|
||||||
|
clearButton.addEventListener("click", function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
searchInput.value = ""; // Clear input field
|
||||||
|
// Remove query parameter without reloading the page
|
||||||
|
const newUrl = window.location.pathname;
|
||||||
|
history.replaceState(null, "", newUrl);
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -48,7 +48,7 @@
|
|||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
||||||
<div class="d-inline-flex flex-center">
|
<div class="d-inline-flex flex-center">
|
||||||
<div class="d-flex align-items-center px-1 py-1 bg-warning-subtle rounded me-2"><span class="text-warning-dark" data-feather="grid"></span></div><span>{{ _("Address")|capfirst }}</span>
|
<div class="d-flex align-items-center px-1 py-1 bg-warning-subtle rounded me-2"><span class="text-warning-dark" data-feather="home"></span></div><span>{{ _("Address")|capfirst }}</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
||||||
@ -57,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" data-sort="date" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" data-sort="date" style="width:15%;">
|
||||||
{{ _("Create date") }}</th>
|
{{ _("Create date") }} <span class="text-warning-dark" data-feather="clock"></span></th>
|
||||||
<th class="sort text-end align-middle pe-0 ps-4" scope="col"></th>
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
@ -19,25 +19,10 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-auto">
|
||||||
<form method="get" class=" mb-4">
|
<div class="d-flex">
|
||||||
<div class="input-group input-group-sm">
|
{% include 'partials/search_box.html' %}
|
||||||
<button class="btn btn-sm btn-phoenix-secondary rounded-start" type="submit">
|
</div>
|
||||||
{% trans "search" %}
|
|
||||||
</button>
|
|
||||||
<input type="text"
|
|
||||||
name="q"
|
|
||||||
class="form-control form-control-sm rounded-end"
|
|
||||||
value="{{ request.GET.q }}"
|
|
||||||
placeholder="{% trans 'Search bills...' %}" />
|
|
||||||
{% if request.GET.q %}
|
|
||||||
<a href="{% url request.resolver_match.view_name %}"
|
|
||||||
class="btn btn-sm btn-phoenix-danger ms-1 rounded">
|
|
||||||
<i class="bi bi-x-lg"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user