From 27d6cce9f308ce94d60f0bf43df05f3c1a9d6576 Mon Sep 17 00:00:00 2001 From: Faheedkhan Date: Mon, 14 Jul 2025 17:34:21 +0300 Subject: [PATCH] changed the most of the forms and pricing_page --- .vscode/launch.json | 4 +- car_inventory/urls.py | 4 +- inventory/views.py | 264 ++---------------- static/css/custom.css | 2 +- templates/bill/bill_create.html | 62 +++- templates/crm/leads/lead_form.html | 80 ++++-- templates/crm/leads/lead_list.html | 2 +- templates/crm/leads/lead_tracking.html | 2 +- .../crm/opportunities/opportunity_list.html | 2 +- templates/customers/customer_form.html | 44 +-- templates/customers/customer_list.html | 2 +- templates/inventory/car_form.html | 58 ++-- templates/inventory/car_list_view.html | 2 +- templates/items/expenses/expense_create.html | 45 ++- templates/items/expenses/expense_update.html | 38 ++- templates/items/service/service_create.html | 43 ++- .../bank_accounts/bank_account_form.html | 48 +++- .../ledger/coa_accounts/account_form.html | 44 ++- .../journal_entry/journal_entry_form.html | 39 ++- templates/ledger/ledger/ledger_form.html | 47 +++- .../organizations/organization_form.html | 50 ++-- .../organizations/organization_list.html | 2 +- templates/partials/search_box.html | 2 +- templates/pricing_page.html | 256 ++++++++++------- templates/purchase_orders/po_form.html | 68 +++-- templates/purchase_orders/po_list.html | 27 +- templates/sales/estimates/estimate_form.html | 85 +++++- templates/sales/invoices/invoice_create.html | 40 ++- templates/vendors/vendor_form.html | 41 ++- 29 files changed, 884 insertions(+), 519 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8e4ea5ba..adc68ca8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,13 +8,13 @@ "name": "Python Debugger: Django", "type": "debugpy", "request": "launch", - "args": [ + "args": [ "runserver", "0.0.0.0:8000" ], "django": true, "autoStartBrowser": false, - "program": "${workspaceFolder}/manage.py" + "program": "C:\\Users\\user\\Desktop\\haikal_projects\\venv\\bin\\activate & ${workspaceFolder}/manage.py" } ] } \ No newline at end of file diff --git a/car_inventory/urls.py b/car_inventory/urls.py index 55d3bc26..74198b9d 100644 --- a/car_inventory/urls.py +++ b/car_inventory/urls.py @@ -4,7 +4,7 @@ from django.conf.urls.static import static from django.conf import settings from django.conf.urls.i18n import i18n_patterns from inventory import views -from debug_toolbar.toolbar import debug_toolbar_urls +# from debug_toolbar.toolbar import debug_toolbar_urls # import debug_toolbar @@ -17,7 +17,7 @@ urlpatterns = [ path("api-auth/", include("rest_framework.urls")), path("api/", include("api.urls")), # path('dj-rest-auth/', include('dj_rest_auth.urls')), -] + debug_toolbar_urls() +]# + debug_toolbar_urls() urlpatterns += i18n_patterns( path("admin/", admin.site.urls), path("switch_language/", views.switch_language, name="switch_language"), diff --git a/inventory/views.py b/inventory/views.py index 427c366d..e493ff3b 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -206,7 +206,7 @@ from .tasks import create_accounts_for_make, create_user_dealer, send_email # djago easy audit log from easyaudit.models import RequestEvent, CRUDEvent, LoginEvent from django_q.tasks import async_task -from django.db.models import Prefetch + logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -1150,7 +1150,7 @@ class CarListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): def get_queryset(self): dealer = get_user_type(self.request) - qs = super().get_queryset().prefetch_related("id_car_make", "id_car_model", "id_car_trim","finances","colors") + qs = super().get_queryset() qs = qs.filter(dealer=dealer) status = self.request.GET.get("status") search = self.request.GET.get("search") @@ -1202,193 +1202,8 @@ def inventory_stats_view(request, dealer_slug): "inventory/inventory_stats.html" template. :rtype: HttpResponse """ - # cars = ( - # models.Car.objects - # .filter(dealer=request.dealer) - # .select_related( - # "id_car_make", - # "id_car_model", - # "id_car_trim__id_car_serie__id_car_model__id_car_make" - # ) - # .only( - # "id", - # "id_car_make__id_car_make", - # "id_car_make__slug", - # "id_car_make__name", - # "id_car_make__arabic_name", - # "id_car_model__id_car_model", - # "id_car_model__slug", - # "id_car_model__name", - # "id_car_model__arabic_name", - # "id_car_trim__id_car_trim", - # "id_car_trim__slug", - # "id_car_trim__name", - # "id_car_trim__id_car_serie__id_car_model__id_car_make", - # "id_car_trim__id_car_serie__id_car_model__id_car_model", - # ) - # .order_by('id_car_make', 'id_car_model', 'id_car_trim') - # ) - # # Get counts in optimized queries - # total_cars = cars.count() - # reserved_cars = models.CarReservation.objects.filter( - # car__dealer=request.dealer - # ).count() - - # # Prefetch related data if needed for additional fields - # cars = cars.prefetch_related( - # Prefetch('colors', queryset=models.CarColors.objects.select_related('exterior', 'interior')) - # ) - - # # Get distinct makes, models, trims in database-compatible way - # makes = ( - # cars.order_by('id_car_make') - # .values_list('id_car_make', flat=True) - # .distinct() - # ) - - # _models = ( - # cars.order_by('id_car_model') - # .values_list('id_car_model', flat=True) - # .distinct() - # ) - - # trims = ( - # cars.order_by('id_car_trim') - # .values_list('id_car_trim', flat=True) - # .distinct() - # ) - - # # Get counts by make/model/trim - # make_counts = dict( - # cars.values_list('id_car_make') - # .annotate(count=Count('id')) - # .order_by('id_car_make') - # ) - - # model_counts = dict( - # cars.values_list('id_car_model') - # .annotate(count=Count('id')) - # .order_by('id_car_model') - # ) - - # trim_counts = dict( - # cars.values_list('id_car_trim') - # .annotate(count=Count('id')) - # .order_by('id_car_trim') - # ) - - # # Build inventory structure - # inventory = {} - - # # Process makes - # make_objects = { - # m.id_car_make: m for m in - # models.CarMake.objects.filter(id_car_make__in=makes) - # .only('id_car_make', 'slug', 'name', 'arabic_name') - # } - - # for make_id in makes: - # if not make_id: - # continue - - # make_obj = make_objects.get(make_id) - # if not make_obj: - # continue - - # inventory[make_id] = { - # "make_id": make_id, - # "slug": make_obj.slug, - # "make_name": make_obj.get_local_name(), - # "total_cars": make_counts.get(make_id, 0), - # "models": {}, - # } - - # # Process models - # model_objects = { - # m.id_car_model: m for m in - # models.CarModel.objects.filter(id_car_model__in=_models) - # .select_related('id_car_make') - # .only('id_car_model', 'slug', 'name', 'arabic_name', 'id_car_make') - # } - - # for model_id in _models: - # if not model_id: - # continue - - # model_obj = model_objects.get(model_id) - # if not model_obj: - # continue - - # make_id = model_obj.id_car_make.id_car_make - # if make_id not in inventory: - # continue - - # inventory[make_id]["models"][model_id] = { - # "model_id": model_id, - # "slug": model_obj.slug, - # "model_name": model_obj.get_local_name(), - # "total_cars": model_counts.get(model_id, 0), - # "trims": {}, - # } - - # # Process trims - # trim_objects = { - # t.id_car_trim: t for t in - # models.CarTrim.objects.filter(id_car_trim__in=trims) - # .select_related('id_car_serie__id_car_model__id_car_make') - # .only('id_car_trim', 'slug', 'name', 'id_car_serie__id_car_model__id_car_make') - # } - - # for trim_id in trims: - # if not trim_id: - # continue - - # trim_obj = trim_objects.get(trim_id) - # if not trim_obj: - # continue - - # make_id = trim_obj.id_car_serie.id_car_model.id_car_make.id_car_make - # model_id = trim_obj.id_car_serie.id_car_model.id_car_model - - # if make_id not in inventory or model_id not in inventory[make_id]["models"]: - # continue - - # inventory[make_id]["models"][model_id]["trims"][trim_id] = { - # "trim_id": trim_id, - # "slug": trim_obj.slug, - # "trim_name": trim_obj.name, - # "total_cars": trim_counts.get(trim_id, 0), - # } - - # # Convert to final structure - # result = { - # "total_cars": total_cars, - # "reserved_cars": reserved_cars, - # "makes": [ - # { - # "make_id": make_data["make_id"], - # "slug": make_data["slug"], - # "make_name": make_data["make_name"], - # "total_cars": make_data["total_cars"], - # "models": [ - # { - # "model_id": model_data["model_id"], - # "slug": model_data["slug"], - # "model_name": model_data["model_name"], - # "total_cars": model_data["total_cars"], - # "trims": list(model_data["trims"].values()), - # } - # for model_data in make_data["models"].values() - # if model_data["model_id"] # Skip empty models - # ], - # } - # for make_data in inventory.values() - # if make_data["make_id"] # Skip empty makes - # ], - # } - ############################################### - # # Base queryset for cars belonging to the dealer + # Base queryset for cars belonging to the dealer cars = models.Car.objects.filter(dealer=request.dealer) # Count for total, reserved, showroom, and unreserved cars @@ -1628,18 +1443,6 @@ class CarDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView): context_object_name = "car" permission_required = ["inventory.view_car"] - def get_queryset(self): - qs = super().get_queryset() - qs = qs.select_related( - "id_car_make", - "id_car_model", - "id_car_trim", - "colors", - "finances", - "vendor", - "registrations" - ) - return qs class CarFinanceCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): """ @@ -2718,11 +2521,6 @@ def vendorDetailView(request, dealer_slug,slug): :rtype: HttpResponse """ vendor = get_object_or_404(models.Vendor, slug=slug) - dealer=vendor.dealer - cars=Car.objects.filter(dealer=dealer,vendor=vendor) - print(cars) - - return render( request, template_name="vendors/view_vendor.html", context={"vendor": vendor} ) @@ -4074,7 +3872,7 @@ 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') @@ -5543,6 +5341,7 @@ def PaymentCreateView(request, dealer_slug, pk): model = invoice if invoice else bill entity = dealer.entity form = forms.PaymentForm() + breakpoint() if request.method == "POST": form = forms.PaymentForm(request.POST) @@ -5799,25 +5598,25 @@ class LeadListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): def get_queryset(self): dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) query = self.request.GET.get("q") - qs = models.Lead.objects.select_related("staff","id_car_make","id_car_model","customer").filter(dealer=dealer).exclude(status="converted") - + qs = models.Lead.objects.filter(dealer=dealer).exclude(status="converted") if 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)) - + | 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 if self.request.user.is_staff: staff = getattr(self.request.user.staffmember, "staff", None) return qs.filter(staff=staff) return models.Lead.objects.none() - + + class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView): """ @@ -6886,9 +6685,9 @@ class OpportunityListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): 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") @@ -7307,7 +7106,7 @@ class ItemExpenseListView(LoginRequiredMixin, PermissionRequiredMixin, ListView) # 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) query=self.request.GET.get('q') @@ -10183,9 +9982,9 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie if query: qs=apply_search_filters(qs,query) return qs - - - + + + # def get_queryset(self): # dealer = get_user_type(self.request) # entity = dealer.entity @@ -10319,28 +10118,11 @@ class BillModelActionMarkAsInReviewView(BaseBillActionView): class BillModelActionMarkAsApprovedView(BaseBillActionView): action_name = "mark_as_approved" - def get_redirect_url(self, dealer_slug, entity_slug, bill_pk, *args, **kwargs): - if self.request.is_manager: - messages.add_message( - self.request, - message="Bill updated successfully.", - level=messages.SUCCESS, - ) - return reverse("home",kwargs={"dealer_slug": dealer_slug}) - - return reverse( - "bill-update", - kwargs={ - "dealer_slug": dealer_slug, - "entity_slug": entity_slug, - "bill_pk": bill_pk, - }, - ) - class BillModelActionMarkAsPaidView(BaseBillActionView): action_name = "mark_as_paid" + class BillModelActionDeleteView(BaseBillActionView): action_name = "mark_as_delete" diff --git a/static/css/custom.css b/static/css/custom.css index b61b11af..424f319d 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -45,7 +45,7 @@ } .form-control, .form-select { - text-align: center; + /* text-align: center; */ display: flex; align-items: center; justify-content: center; diff --git a/templates/bill/bill_create.html b/templates/bill/bill_create.html index 0aeabe45..4e0a8ae7 100644 --- a/templates/bill/bill_create.html +++ b/templates/bill/bill_create.html @@ -5,7 +5,7 @@ {% load crispy_forms_filters %} {% block content %} -
+ {% comment %}
@@ -46,5 +46,63 @@
-
+
{% endcomment %} + + + + +
+ +
+
+
+

+ {% trans 'Create Bill' %} +

+
+
+ +
+
+ + {% csrf_token %} + {% if po_model %} +
+

{% trans 'Bill for' %} {{ po_model.po_number }}

+

{% trans 'Bill for' %} {{ po_model.po_title }}

+
+ {% for itemtxs in po_itemtxs_qs %} + {{ itemtxs }} + {% endfor %} +
+
+ {% endif %} + +
+ {{ form|crispy }} +
+
+ + +
+ + + +
+
+ +
+ +
+ {% endblock %} \ No newline at end of file diff --git a/templates/crm/leads/lead_form.html b/templates/crm/leads/lead_form.html index 2beec219..f68575ee 100644 --- a/templates/crm/leads/lead_form.html +++ b/templates/crm/leads/lead_form.html @@ -1,13 +1,14 @@ {% extends 'base.html' %} {% load i18n static crispy_forms_filters %} + {% block title %} - {# Check if an 'object' exists in the context #} {% if object %} - {% trans 'Update Lead'%} + {% trans 'Update Lead' %} {% else %} - {% trans 'Add New Lead'%} + {% trans 'Add New Lead' %} {% endif %} {% endblock %} + {% block customcss %} {% endblock customcss %} {% block content %} -
-

{% if object %}{{ _("Update Lead") }}{% else %}{{ _("Create New Lead") }}{% endif %}

-
-
+
+
+
+
+

+ {% if object %} + {{ _("Update Lead") }} + {% else %} + {{ _("Create New Lead") }} + {% endif %} +

+ +
+
+
+ {% csrf_token %} + {{ form|crispy }} - - {% csrf_token %} - {{ form|crispy }} -
- - {% trans "Cancel" %} -
-
+
+ +
+ + + + + {% trans "Cancel" %} + +
+ +
+
-
+ diff --git a/templates/crm/leads/lead_list.html b/templates/crm/leads/lead_list.html index 42792e05..8595f4f8 100644 --- a/templates/crm/leads/lead_list.html +++ b/templates/crm/leads/lead_list.html @@ -4,7 +4,7 @@ {% block content %}
-

{{ _("Leads")|capfirst }}

+

{{ _("Leads")|capfirst }}
  • {% include "crm/leads/partials/update_action.html" %} diff --git a/templates/crm/leads/lead_tracking.html b/templates/crm/leads/lead_tracking.html index 65b992c7..0056673b 100644 --- a/templates/crm/leads/lead_tracking.html +++ b/templates/crm/leads/lead_tracking.html @@ -68,7 +68,7 @@
    -

    {{ _("Lead Tracking")}}

    +

    {{ _("Lead Tracking")}}
  • diff --git a/templates/crm/opportunities/opportunity_list.html b/templates/crm/opportunities/opportunity_list.html index 2412faa1..0c04b653 100644 --- a/templates/crm/opportunities/opportunity_list.html +++ b/templates/crm/opportunities/opportunity_list.html @@ -5,7 +5,7 @@ {% block content %}
    -

    {{ _("Opportunities") }}

    +

    {{ _("Opportunities") }}
  • diff --git a/templates/customers/customer_form.html b/templates/customers/customer_form.html index 22cb7ebb..fb30d470 100644 --- a/templates/customers/customer_form.html +++ b/templates/customers/customer_form.html @@ -9,38 +9,38 @@ {% trans 'Add New Customer'%} {% endif %} {% endblock %} + + {% block content %} - -
    -
    -
    -
    -

    +
    + +
    +
    +
    +

    {% if customer.created %} {{ _("Edit Customer") }} {% else %} {{ _("Add Customer") }} {% endif %}

    -
    -
    -
    -
    +
    {% csrf_token %} {{ form|crispy }} -
    - - {% trans "Cancel" %} -
    -
    -
    -
    -
    -{% endblock %} +
    +
    + + {% trans "Cancel" %} +
    + + +
    + +

    + +
    +{%endblock %} diff --git a/templates/customers/customer_list.html b/templates/customers/customer_list.html index db1ce14f..bae02f70 100644 --- a/templates/customers/customer_list.html +++ b/templates/customers/customer_list.html @@ -6,7 +6,7 @@ {% block content %}
    -

    {{ _("Customers")|capfirst }}

    +

    {{ _("Customers")|capfirst }}
  • diff --git a/templates/inventory/car_form.html b/templates/inventory/car_form.html index 67b851e3..7119c628 100644 --- a/templates/inventory/car_form.html +++ b/templates/inventory/car_form.html @@ -28,16 +28,27 @@ aria-label="Close">
    {% endif %} -
    -
    - {% csrf_token %} - {% include 'partials/form_errors.html' %} + + +
    + +
    +
    +
    +

    +

    {% trans 'Add Car' %}
  • + +
    +
    + + {% csrf_token %} + {% include 'partials/form_errors.html' %}
    -

    {% trans 'Add Car' %}

    + -
    +
    @@ -144,7 +155,7 @@
    -
    +
    @@ -202,28 +213,39 @@
    - -
    - -
    + +
    - + + + - + + +
    +
    +
    -
    +
    + +
    + +