more updates

This commit is contained in:
ismail 2025-07-24 18:42:38 +03:00
parent 6c2b6b1588
commit 1fd00af6ac
6 changed files with 87 additions and 76 deletions

View File

@ -2293,8 +2293,10 @@ class CustomerDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
dealer = get_user_type(self.request)
entity = dealer.entity
context = super().get_context_data(**kwargs)
context["customer_notes"] = models.Notes.objects.filter(
object_id=self.object.pk
context["notes"] = models.Notes.objects.filter(
dealer=dealer,
content_type__model="customer", object_id=self.object.id
)
estimates = entity.get_estimates().filter(customer=self.object.customer_model)
invoices = entity.get_invoices().filter(customer=self.object.customer_model)
@ -2304,6 +2306,7 @@ class CustomerDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
context["estimates"] = estimates
context["invoices"] = invoices
context["total"] = total
context["note_form"] = forms.NoteForm()
return context
@ -4337,16 +4340,12 @@ def sales_list_view(request, dealer_slug):
except Exception as e:
print(e)
# query = request.GET.get('q')
# # if query:
# # qs = qs.filter(
# # Q(order_number__icontains=query) |
# # Q(customer__name__icontains=query) |
# # Q(item_details__icontains=query)
# # ).distinct()
# for so in qs:
# if query in so.customer_customer
search_query = request.GET.get('q', None)
if search_query:
qs = qs.filter(
Q(order_number__icontains=search_query)|
Q(customer__customer_name__icontains=search_query)
).distinct()
paginator = Paginator(qs, 30)
page_number = request.GET.get("page")
@ -4446,22 +4445,32 @@ class EstimateListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
related_content_type=ContentType.objects.get_for_model(models.Staff),
related_object_id=self.request.staff.pk,
)
context["staff_estimates"] = EstimateModel.objects.filter(pk__in=[x.content_object.pk for x in qs])
qs = EstimateModel.objects.filter(pk__in=[x.content_object.pk for x in qs])
search_query = self.request.GET.get('q', None)
if search_query:
qs = qs.filter(
Q(estimate_number__icontains=search_query)|
Q(customer__customer_name__icontains=search_query)
).distinct()
context["staff_estimates"] = qs
return context
def get_queryset(self):
dealer = get_user_type(self.request)
entity = dealer.entity
status = self.request.GET.get("status")
queryset = entity.get_estimates()
if status:
queryset = queryset.filter(status=status)
search_query = self.request.GET.get('q', None)
if search_query:
queryset = queryset.filter(
Q(estimate_number__icontains=search_query)
Q(estimate_number__icontains=search_query)|
Q(customer__customer_name__icontains=search_query)
).distinct()
return queryset

View File

@ -249,3 +249,46 @@ const getDataTableInit = () => {
};
/*
// Register delete modal initializer
htmxInitializer.register(function initDeleteModals() {
const deleteModal = document.getElementById("deleteModal");
const confirmDeleteBtn = document.getElementById("deleteModalConfirm");
const deleteModalMessage = document.getElementById("deleteModalText");
// Clean up old listeners
document.querySelectorAll(".delete-btn").forEach(btn => {
btn.removeEventListener("click", handleDeleteClick);
});
// Add new listeners
document.querySelectorAll(".delete-btn").forEach(button => {
button.addEventListener("click", handleDeleteClick);
});
function handleDeleteClick() {
if (!deleteModal || !confirmDeleteBtn || !deleteModalMessage) return;
const deleteUrl = this.getAttribute("data-url");
const deleteMessage = this.getAttribute("data-message") || "Are you sure?";
confirmDeleteBtn.setAttribute("href", deleteUrl);
deleteModalMessage.textContent = deleteMessage;
if (typeof htmx !== 'undefined') htmx.process(confirmDeleteBtn);
if (typeof bootstrap !== 'undefined') new bootstrap.Modal(deleteModal).show();
}
}, "delete_modals");
// Register custom selects initializer
htmxInitializer.register(function initCustomSelects() {
// Your custom select initialization code
}, "custom_selects");
// Register form submission initializer
htmxInitializer.register(function initForms() {
// Your form handling code
}, "forms");
*/

View File

@ -811,9 +811,6 @@
<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="nav-link px-3 d-block"
href="{% url 'appointment:get_user_appointments' %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("View in Calendar") }}
<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">

View File

@ -3,7 +3,7 @@
<div class="content">
<h2 class="mb-5">{{ _("Notifications") }}</h2>
<div class="d-flex justify-content-end mb-3">
<a href="{% url 'mark_all_notifications_as_read' %}" class="btn btn-phoenix-primary"><i class="far fa-envelope fs-8 me-2"></i>{{ _("Mark all as read") }}</a>
<a href="{% url 'mark_all_notifications_as_read' %}" hx-select-oob="#notification-counter:outerHTML" class="btn btn-phoenix-primary"><i class="far fa-envelope fs-8 me-2"></i>{{ _("Mark all as read") }}</a>
</div>
{% if notifications %}
<div class="mx-n4 mx-lg-n6 mb-5 border-bottom">

View File

@ -88,16 +88,15 @@
<div class="card-body">
{% if perms.inventory.change_customer %}
<div class="d-flex align-items-center justify-content-end">
<a id="addBtn"
href="#"
class="btn btn-sm btn-phoenix-primary mb-3"
data-url="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}"
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>
{% if perms.inventory.change_lead %}
<button class="btn btn-phoenix-primary btn-sm"
type="button"
onclick=""
data-bs-toggle="modal"
data-bs-target="#noteModal">
<span class="fas fa-plus me-1"></span>{{ _("Add Note") }}
</button>
{% endif %}
</div>
{% endif %}
<table class="table fs-9 mb-0 table-responsive">
@ -105,8 +104,8 @@
<th class="align-middle pe-6 text-start" scope="col">{{ _("Note") }}</th>
<th class="align-middle pe-6 text-start" scope="col">{{ _("Date") }}</th>
</tr>
<tbody>
{% for note in customer_notes %}
<tbody id="notesTable">
{% for note in notes %}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="align-middle text-start fw-bold text-body-tertiary ps-1">{{ note.note }}</td>
<td class="align-middle text-body-tertiary text-start white-space-nowrap">{{ note.created }}</td>
@ -223,28 +222,9 @@
</div>
</div>
</div>
<div class="modal fade"
id="noteModal"
tabindex="-1"
aria-labelledby="noteModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header justify-content-between align-items-start gap-5 px-4 pt-4 pb-3 border-0">
<h4 class="modal-title" id="noteModalLabel">{% trans 'Notes' %}</h4>
<button class="btn p-0 text-body-quaternary fs-6"
data-bs-dismiss="modal"
aria-label="Close">
<span class="fas fa-times"></span>
</button>
</div>
<div class="modal-body">
<!-- Content will be loaded here via AJAX -->
</div>
</div>
</div>
</div>
</div>
{% include "components/note_modal.html" with content_type="customer" slug=customer.slug %}
<script>
document.addEventListener("DOMContentLoaded", function () {
const noteModal = document.getElementById("noteModal");
@ -269,5 +249,6 @@
});
});
});
</script>
{% endblock %}

View File

@ -1,35 +1,16 @@
<div class="search-box me-2">
<form class="position-relative show" id="search-form">
<input name="q"
hx-get=""
hx-boost="true"
hx-trigger="keyup delay:500ms"
id="search-input"
class="form-control form-control-sm search-input search"
type="search"
aria-label="Search"
placeholder="{{ _("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>
<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>