added search

This commit is contained in:
Faheedkhan 2025-07-10 13:17:15 +03:00
parent 8398dcd5de
commit 51b2833e54
4 changed files with 104 additions and 51 deletions

View File

@ -3864,6 +3864,15 @@ class BankAccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
template_name = "ledger/bank_accounts/bank_account_detail.html"
context_object_name = "bank_account"
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(
@ -5584,14 +5593,23 @@ class LeadListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
query = self.request.GET.get("q")
qs = models.Lead.objects.filter(dealer=dealer).exclude(status="converted")
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:
return qs
staffmember = getattr(self.request.user, "staffmember", None)
if staff := getattr(staffmember, "staff", None):
return qs.filter(staff=staff)
return models.Lead.objects.none()
class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
"""
@ -6654,12 +6672,15 @@ class OpportunityListView(LoginRequiredMixin,PermissionRequiredMixin, ListView):
queryset = models.Opportunity.objects.filter(dealer=dealer, lead__staff=staff)
# Search filter
search = self.request.GET.get("search")
search = self.request.GET.get("q")
if search:
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)
)
)
# Stage filter
stage = self.request.GET.get("stage")
@ -6947,10 +6968,17 @@ class ItemServiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
paginate_by = 30
permission_required = ["inventory.view_additionalservices"]
def get_queryset(self):
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):
@ -7068,9 +7096,18 @@ class ItemExpenseListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
paginate_by = 30
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):
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):
@ -7100,6 +7137,9 @@ class BillListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
def get_queryset(self):
dealer = get_user_type(self.request)
qs = dealer.entity.get_bills()
query=self.request.GET.get('q')
if query:
qs=qs.filter(vendor__vendor_name__icontains=query)
return qs
def get_context_data(self, **kwargs):
@ -9917,12 +9957,23 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie
template_name = "purchase_orders/po_list.html"
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):
# 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
# queryset = self.model.objects.filter(entity=entity)

View File

@ -12,25 +12,22 @@
<!-- 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">
<!-- 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>
<input
class="form-control ps-6"
type="text"
placeholder="{% trans 'Search opportunities...' %}"
name="search"
hx-get="{% url 'opportunity_list' request.dealer.slug %}"
hx-trigger="keyup changed delay:500ms"
hx-target="#opportunities-grid"
hx-select="#opportunities-grid"
hx-include="#filter-container select"
hx-swap="outerHTML"
style="width: 100%;"
>
</div>
<div class="search-box position-relative flex-grow-1 me-2" style="min-width: 200px;">
<form class="position-relative show" id="search-form">
<input name="q" id="search-input" 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>
{% if request.GET.q %}
<button type="button" class="btn-close position-absolute end-0 top-50 translate-middle cursor-pointer shadow-none"
id="clear-search" aria-label="Close"></button>
{% endif %}
</form>
</div>
<!-- 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 -->
<div class="flex-grow-1">
<select
@ -78,7 +75,7 @@
</div>
</div>
{% 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 %}">
<span class="fas fa-plus me-2"></span>{{ _("Add Opportunity") }}
</a>
@ -101,4 +98,24 @@
</div>
{% 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 %}

View File

@ -48,7 +48,7 @@
</th>
<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-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>
</th>
<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>
</th>
<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>
</tr>
</thead>

View File

@ -19,25 +19,10 @@
{% endif %}
</div>
<div class="col-12">
<form method="get" class=" mb-4">
<div class="input-group input-group-sm">
<button class="btn btn-sm btn-phoenix-secondary rounded-start" type="submit">
{% 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 class="col-auto">
<div class="d-flex">
{% include 'partials/search_box.html' %}
</div>
</div>