From 65843ef6a307b0c7c0ab70622c3c6d5dd8981f3a Mon Sep 17 00:00:00 2001 From: Faheed Date: Mon, 15 Sep 2025 18:01:57 +0300 Subject: [PATCH 1/6] add default image back --- car_inventory/urls.py | 4 ++-- inventory/models.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/car_inventory/urls.py b/car_inventory/urls.py index 5c18bae8..0f1085b0 100644 --- a/car_inventory/urls.py +++ b/car_inventory/urls.py @@ -33,5 +33,5 @@ urlpatterns += i18n_patterns( # path('', include(tf_urls)), ) -if not settings.DEBUG: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +# if not settings.DEBUG: +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/inventory/models.py b/inventory/models.py index e3d70112..0a9feba5 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -1374,7 +1374,7 @@ class Dealer(models.Model, LocalizedNameMixin): blank=True, null=True, verbose_name=_("Logo"), - default="", + default="default-image/user.jpg", ) thumbnail = ImageSpecField( source="logo", @@ -1516,7 +1516,7 @@ class Staff(models.Model): blank=True, null=True, verbose_name=_("Image"), - default="", + default="default-image/user.jpg", ) thumbnail = ImageSpecField( source="logo", @@ -1744,7 +1744,7 @@ class Customer(models.Model): blank=True, null=True, verbose_name=_("Image"), - default="", + default="default-image/user.jpg", ) thumbnail = ImageSpecField( source="image", @@ -1898,7 +1898,7 @@ class Organization(models.Model, LocalizedNameMixin): blank=True, null=True, verbose_name=_("Logo"), - default="", + default="default-image/user.jpg", ) thumbnail = ImageSpecField( source="logo", @@ -2716,7 +2716,7 @@ class Vendor(models.Model, LocalizedNameMixin): blank=True, null=True, verbose_name=_("Logo"), - default="", + default="default-image/user.jpg", ) thumbnail = ImageSpecField( source="logo", -- 2.39.5 From f19627f6b35e48db9234a230c9a52b27a85a1538 Mon Sep 17 00:00:00 2001 From: Faheed Date: Mon, 15 Sep 2025 19:44:00 +0300 Subject: [PATCH 2/6] update --- inventory/models.py | 15 +++++++++++++++ inventory/views.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/inventory/models.py b/inventory/models.py index 0a9feba5..6b4e3619 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -2742,6 +2742,21 @@ class Vendor(models.Model, LocalizedNameMixin): models.Index(fields=["crn"], name="vendor_crn_idx"), models.Index(fields=["vrn"], name="vendor_vrn_idx"), ] + constraints = [ + models.UniqueConstraint( + fields=["dealer", "crn"], name="unique_crn_per_dealer" + ), + models.UniqueConstraint( + fields=["dealer", "vrn"], name="unique_vrn_per_dealer" + ), + models.UniqueConstraint( + fields=["dealer", "email"], name="unique_email_per_dealer" + ), + models.UniqueConstraint( + fields=["dealer", "phone_number"], name="unique_phone_number_per_dealer" + ), + ] + def __str__(self): return self.name diff --git a/inventory/views.py b/inventory/views.py index f9be7e6c..79b7aaf3 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -3654,7 +3654,7 @@ class UserCreateView( # return self.form_invalid(form) email = form.cleaned_data["email"] - if models.Staff.objects.filter(dealer=dealer,user__email=email).exists() or models.Dealer.objects.filter(user__email=email).exists(): + if models.Staff.objects.filter(user__email=email).exists() or models.Dealer.objects.filter(user__email=email).exists(): messages.error( self.request, _( -- 2.39.5 From 543b896db2d5ccc58609e4926b6190245e18e631 Mon Sep 17 00:00:00 2001 From: Faheed Date: Mon, 15 Sep 2025 20:05:04 +0300 Subject: [PATCH 3/6] slugify fix --- inventory/models.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/inventory/models.py b/inventory/models.py index 6b4e3619..7e65f17d 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -61,7 +61,7 @@ from encrypted_model_fields.fields import ( # from simple_history.models import HistoricalRecords from plans.models import Invoice -from django_extensions.db.fields import RandomCharField +from django_extensions.db.fields import RandomCharField,AutoSlugField logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -74,15 +74,7 @@ class Base(models.Model): primary_key=True, verbose_name=_("Primary Key"), ) - slug = models.SlugField( - null=True, - blank=True, - unique=True, - verbose_name=_("Slug"), - help_text=_( - "Slug for the object. If not provided, it will be generated automatically." - ), - ) + slug = RandomCharField(length=8, unique=True) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At")) updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At")) @@ -744,7 +736,7 @@ class Car(Base): ) def save(self, *args, **kwargs): - self.slug = slugify(self.vin) + # self.slug = slugify(self.vin) self.hash = self.get_hash super(Car, self).save(*args, **kwargs) -- 2.39.5 From f5856d6fb79ced5b5cbca6aa128afaa8b6f4e808 Mon Sep 17 00:00:00 2001 From: Faheed Date: Tue, 16 Sep 2025 17:05:29 +0300 Subject: [PATCH 4/6] po download added --- inventory/views.py | 22 +++ templates/crm/notifications_history.html | 4 +- templates/groups/group_list.html | 17 +- templates/partials/task.html | 5 +- .../purchase_orders/includes/card_po.html | 6 +- templates/purchase_orders/po_detail.html | 4 + templates/purchase_orders/po_detail_pdf.html | 178 ++++++++++++++++++ templates/users/user_list.html | 2 +- 8 files changed, 221 insertions(+), 17 deletions(-) create mode 100644 templates/purchase_orders/po_detail_pdf.html diff --git a/inventory/views.py b/inventory/views.py index 0aeac725..baf08370 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -12,6 +12,8 @@ import tempfile import numpy as np from time import sleep +from weasyprint import HTML + # from rich import print from random import randint from decimal import Decimal @@ -10971,7 +10973,27 @@ class PurchaseOrderDetailView(LoginRequiredMixin, PermissionRequiredMixin, Detai if i["po_item_status"] != "cancelled" ) return context + def get(self, request, *args, **kwargs): + self.object = self.get_object() + context = self.get_context_data(object=self.object) + + # Check if PDF format is requested + if request.GET.get('format') == 'pdf': + # Use a separate, print-friendly template for the PDF + html_string = render_to_string( + "purchase_orders/po_detail_pdf.html", + context + ) + + # Use WeasyPrint to generate the PDF + pdf = HTML(string=html_string).write_pdf() + + response = HttpResponse(pdf, content_type="application/pdf") + response["Content-Disposition"] = f'attachment; filename="PO_{self.object.po_number}.pdf"' + return response + # If not a PDF request, return the standard HTML response + return self.render_to_response(context) class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): model = PurchaseOrderModel diff --git a/templates/crm/notifications_history.html b/templates/crm/notifications_history.html index 2e7a9853..9405399a 100644 --- a/templates/crm/notifications_history.html +++ b/templates/crm/notifications_history.html @@ -73,7 +73,7 @@ body { {% endif %}
-
+
{{ notification.message|safe }}

@@ -100,7 +100,7 @@ body {

-
+

{% trans "Status" %}