From 150eea38df44644126efe5772a7c019f2d24eb8a Mon Sep 17 00:00:00 2001 From: Faheedkhan Date: Mon, 4 Aug 2025 15:22:21 +0300 Subject: [PATCH 1/6] email modifiied --- inventory/views.py | 178 ++++++-- templates/admin_management/management.html | 1 + templates/base.html | 2 +- templates/crm/notifications_history.html | 18 +- .../crm/opportunities/opportunity_list.html | 102 +++-- templates/customers/view_customer.html | 407 +++++++++--------- templates/dealers/assign_car_makes.html | 6 +- templates/groups/group_permission_form.html | 4 +- templates/items/expenses/expenses_list.html | 12 +- templates/items/service/service_list.html | 10 +- templates/ledger/reports/car_sale_report.html | 229 ++++++---- templates/ledger/reports/purchase_report.html | 113 +++-- templates/mail/change_plan_body.txt | 26 +- templates/mail/change_plan_title.txt | 4 +- templates/mail/expired_account_body.txt | 27 +- templates/mail/expired_account_title.txt | 6 +- templates/mail/extend_account_body.txt | 23 +- templates/mail/extend_account_title.txt | 15 +- templates/mail/invoice_created_body.txt | 25 +- templates/mail/invoice_created_title.txt | 4 +- templates/mail/remind_expire_body.txt | 26 +- templates/mail/remind_expire_title.txt | 4 +- templates/users/user_list.html | 2 +- 23 files changed, 765 insertions(+), 479 deletions(-) diff --git a/inventory/views.py b/inventory/views.py index 434a540b..03f16f99 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -6762,27 +6762,37 @@ def send_lead_email(request, dealer_slug, slug, email_pk=None): # return response # return redirect("lead_list", dealer_slug=dealer_slug) msg = f""" - السلام عليكم - Dear {lead.full_name}, +السلام عليكم {lead.full_name}, - أود أن أشارككم تقدير المشروع الذي ناقشناه. يرجى العثور على الوثيقة التفصيلية للمقترح المرفقة. +شكراً لزيارتك لـ {lead.dealer.name}! لقد كان من دواعي سرورنا مساعدتك اليوم. - I hope this email finds you well. I wanted to share with you the estimate for the project we discussed. Please find the detailed estimate document attached. +لقد أنشأنا ملفاً شخصياً لك في نظامنا لتتبع تفضيلاتك والسيارات التي تهتم بها. سنتواصل معك قريباً للمتابعة والإجابة على أي أسئلة أخرى قد تكون لديك. - يرجى مراجعة المقترح وإعلامي إذا كانت لديك أي أسئلة أو مخاوف. إذا كانت كل شيء يبدو جيدًا، يمكننا المضي قدمًا في المشروع. +في هذه الأثناء، لا تتردد في الاتصال بنا مباشرة على {lead.dealer.phone_number} أو زيارتنا مرة أخرى في أي وقت يناسبك. - Please review the estimate and let me know if you have any questions or concerns. If everything looks good, we can proceed with the project. +نتطلع إلى مساعدتك في العثور على سيارتك القادمة! - شكراً لاهتمامكم بهذا الأمر. - Thank you for your attention to this matter. +تحياتي، +{lead.dealer.arabic_name} +{lead.dealer.address} +{lead.dealer.phone_number} +----- +Dear {lead.full_name}, - تحياتي, - Best regards, - [Your Name] - [Your Position] - [Your Company] - [Your Contact Information] - """ +Thank you for visiting {lead.dealer.name}! It was a pleasure to assist you today. + +We've created a profile for you in our system to keep track of your preferences and the vehicles you're interested in. We'll be in touch shortly to follow up and answer any further questions you may have. + +In the meantime, feel free to contact us directly at {lead.dealer.phone_number} or visit us again at your convenience. + +We look forward to helping you find your next car! + +Best regards, +{lead.dealer.name} +{lead.dealer.address} +{lead.dealer.phone_number} + +""" subject = "" if email_pk: email = get_object_or_404(models.Email, pk=email_pk) @@ -7034,17 +7044,11 @@ class OpportunityListView(LoginRequiredMixin, PermissionRequiredMixin, ListView) staff = self.request.staff queryset = models.Opportunity.objects.filter(dealer=dealer, lead__staff=staff) - # Search filter - search = self.request.GET.get("q") - if search: - queryset = queryset.filter( - 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") + print(stage) if stage: queryset = queryset.filter(stage=stage) @@ -7055,7 +7059,16 @@ class OpportunityListView(LoginRequiredMixin, PermissionRequiredMixin, ListView) elif sort == "highest": queryset = queryset.order_by("-expected_revenue") elif sort == "closing": - queryset = queryset.order_by("closing_date") + queryset = queryset.order_by("expected_close_date") + + # Search filter + search = self.request.GET.get("q") + if search: + queryset = queryset.filter( + Q(customer__first_name__icontains=search) + | Q(customer__last_name__icontains=search) + | Q(customer__email__icontains=search) + ) return queryset @@ -7799,27 +7812,44 @@ def send_email_view(request, dealer_slug, pk): ) msg = f""" - السلام عليكم - Dear {estimate.customer.customer_name}, +السلام عليكم، - أود أن أشارككم عرض السعر. +عزيزي {estimate.customer.customer_name}، - I wanted to share with you the quotation. +يسعدني أن أشارككم عرض السعر الذي طلبتموه. يرجى الاطلاع على التفاصيل الكاملة والأسعار من خلال الرابط أدناه. - يرجى مراجعة عرض السعر وإعلامي إذا كانت لديك أي استفسارات أو ملاحظات. إذا كان كل شيء على ما يرام، يمكننا المتابعة في الإجراءات. +حرصنا على أن يكون عرضنا مناسباً وشفافاً. إذا كانت لديكم أي استفسارات أو ملاحظات، فلا تترددوا في التواصل معنا. - Please review the quotation and let me know if you have any questions or concerns. If everything looks good, we can proceed with the process. +رابط عرض السعر: +{link} - رابط عرض السعر: - {link} +نأمل أن ينال العرض إعجابكم ونتطلع إلى بدء العمل قريباً! +تحياتي، - تحياتي, - Best regards, - {dealer.get_local_name} - {dealer.phone_number} - هيكل | Haikal - """ +{dealer.get_local_name} +{dealer.phone_number} +Haikal | هيكل +----- +Dear {estimate.customer.customer_name}, + +I hope this email finds you well. + +Following up on our conversation, I'm excited to share the quotation for your review. Please find the detailed pricing and information by clicking on the link below. + +We've done our best to provide you with a fair and competitive offer. If you have any questions or would like to discuss it further, please don't hesitate to reach out. + +Quotation Link: +{link} + +We look forward to hearing from you and hopefully moving forward with your project! + +Best regards, + +{dealer.get_local_name} +{dealer.phone_number} +Haikal +""" # subject = _("Quotation") send_email( @@ -10687,13 +10717,69 @@ def purchase_report_csv_export(request,dealer_slug): ]) return response +# @login_required +# def car_sale_report_view(request,dealer_slug): +# dealer = get_object_or_404(models.Dealer, slug=dealer_slug) +# cars_sold = models.Car.objects.filter(dealer=dealer,status='sold') +# current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S") +# context={'cars_sold':cars_sold,'current_time':current_time } +# return render(request,'ledger/reports/car_sale_report.html',context) + + @login_required -def car_sale_report_view(request,dealer_slug): - dealer = get_object_or_404(models.Dealer, slug=dealer_slug) - cars_sold = models.Car.objects.filter(dealer=dealer,status='sold') - current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S") - context={'cars_sold':cars_sold,'current_time':current_time } - return render(request,'ledger/reports/car_sale_report.html',context) +def car_sale_report_view(request, dealer_slug): + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) + cars_sold = models.Car.objects.filter(dealer=dealer, status='sold') + + # Get filter parameters from the request + selected_make = request.GET.get('make') + selected_model = request.GET.get('model') + selected_serie = request.GET.get('serie') + selected_year = request.GET.get('year') + + # Apply filters to the queryset + if selected_make: + cars_sold = cars_sold.filter(id_car_make__name=selected_make) + if selected_model: + cars_sold = cars_sold.filter(id_car_model__name=selected_model) + if selected_serie: + cars_sold = cars_sold.filter(id_car_serie__name=selected_serie) + if selected_year: + cars_sold = cars_sold.filter(year=selected_year) + + # Get distinct values for filter dropdowns + makes = models.Car.objects.filter(dealer=dealer, status='sold').values_list('id_car_make__name', flat=True).distinct() + models_qs = models.Car.objects.filter(dealer=dealer, status='sold').values_list('id_car_model__name', flat=True).distinct() + series = models.Car.objects.filter(dealer=dealer, status='sold').values_list('id_car_serie__name', flat=True).distinct() + years = models.Car.objects.filter(dealer=dealer, status='sold').values_list('year', flat=True).distinct().order_by('-year') + + # # Calculate summary data for the filtered results + + total_revenue = cars_sold.aggregate(total_revenue=Sum('finances__marked_price'))['total_revenue'] or 0 + # total_vat = cars_sold.aggregate(total_vat=Sum('finances__vat_amount'))['total_vat'] or 0 + total_discount = cars_sold.aggregate(total_discount=Sum('finances__discount_amount'))['total_discount'] or 0 + + current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S") + + context = { + 'cars_sold': cars_sold, + 'current_time': current_time, + 'dealer': dealer, + 'total_revenue': total_revenue, + # 'total_vat': total_vat, + 'total_discount': total_discount, + 'makes': makes, + 'models': models_qs, + 'series': series, + 'years': years, + 'selected_make': selected_make, + 'selected_model': selected_model, + 'selected_serie': selected_serie, + 'selected_year': selected_year, + } + + return render(request, 'ledger/reports/car_sale_report.html', context) + def car_sale_report_csv_export(request,dealer_slug): @@ -10737,10 +10823,10 @@ def car_sale_report_csv_export(request,dealer_slug): car.year, car.id_car_serie.name, car.id_car_trim.name, - car.mileage, + car.mileage if car.mileage else '0', car.stock_type, car.created_at.strftime("%Y-%m-%d %H:%M:%S") if car.created_at else '', - car.sold_date.strftime("%Y-%m-%d %H:%M:%S") if car.created_at else '', + car.sold_date.strftime("%Y-%m-%d %H:%M:%S") if car.sold_date else '', car.finances.cost_price, car.finances.marked_price, car.finances.discount_amount, diff --git a/templates/admin_management/management.html b/templates/admin_management/management.html index d79103e3..efd75f84 100644 --- a/templates/admin_management/management.html +++ b/templates/admin_management/management.html @@ -3,6 +3,7 @@ {% block title %} {% trans 'Admin Management' %} {% endblock %} {% block content %} +

{% trans "Admin Management" %}
  • diff --git a/templates/base.html b/templates/base.html index 5c3cf542..3e1e03c5 100644 --- a/templates/base.html +++ b/templates/base.html @@ -84,7 +84,7 @@ {% include "plans/expiration_messages.html" %} {% block period_navigation %} {% endblock period_navigation %} -
    +
    diff --git a/templates/crm/notifications_history.html b/templates/crm/notifications_history.html index 764226ae..98649969 100644 --- a/templates/crm/notifications_history.html +++ b/templates/crm/notifications_history.html @@ -30,19 +30,11 @@ {% endfor %}
    -
    + {% if page_obj.paginator.num_pages > 1 %} +
    +
    {% include 'partials/pagination.html' %}
    +
    + {% endif %} {% else %}

    No notifications found.

    {% endif %} diff --git a/templates/crm/opportunities/opportunity_list.html b/templates/crm/opportunities/opportunity_list.html index c1f17a56..65c45ab2 100644 --- a/templates/crm/opportunities/opportunity_list.html +++ b/templates/crm/opportunities/opportunity_list.html @@ -5,13 +5,28 @@ {{ _("Opportunities") }} {% endblock title %} {% block content %} + {% if opportunities or request.GET.q%}
    -
    -

    - {{ _("Opportunities") }} -
  • -

    +
    +
    +
    +

    + {{ _("Opportunities") }} +
  • +

    +
    +
    +
    + {% if perms.inventory.add_opportunity %} + + {% endif %} +
    @@ -19,29 +34,38 @@
    - + + {% include 'modal/delete_modal.html' %} diff --git a/templates/header.html b/templates/header.html index 6732d11b..17ad6cef 100644 --- a/templates/header.html +++ b/templates/header.html @@ -352,7 +352,7 @@ {% endif %}
    - {% trans 'Car purchase Report'|capfirst %} + {% trans 'Car purchase Report'|capfirst %}
    @@ -363,9 +363,9 @@ {% endif %}
    - {% trans 'Car Sale Report'|capfirst %} + {% trans 'Car Sale Report'|capfirst %}
    -
    + diff --git a/templates/ledger/reports/car_sale_report.html b/templates/ledger/reports/car_sale_report.html index 9b65954b..f3eb846b 100644 --- a/templates/ledger/reports/car_sale_report.html +++ b/templates/ledger/reports/car_sale_report.html @@ -107,7 +107,7 @@
    {% trans 'Total VAT Amount' %}
    -

    {{ total_vat|floatformat:2 }}

    +

    {{ 10000|floatformat:2 }}

    diff --git a/templates/purchase_orders/po_list.html b/templates/purchase_orders/po_list.html index bb51e728..1d760d7b 100644 --- a/templates/purchase_orders/po_list.html +++ b/templates/purchase_orders/po_list.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}Purchase Orders - {{ block.super }}{% endblock %} +{% block title %}Purchase Orders{% endblock %} {% block content %} @@ -123,7 +123,15 @@ {% include 'modal/delete_modal.html' %} {% else %} - {% url "purchase_order_create" request.dealer.slug request.dealer.entity.slug as create_purchase_url %} - {% include "empty-illustration-page.html" with value="purchase order" url=create_purchase_url %} + {% if vendors %} + {% url "purchase_order_create" request.dealer.slug request.dealer.entity.slug as create_purchase_url %} + {% include "empty-illustration-page.html" with value="purchase order" url=create_purchase_url %} + {% else %} + + {% url "vendor_create" request.dealer.slug as vendor_create_url %} + {% include "message-illustration.html" with value1=_("You don't have a Vendor, Please add a Vendor before creating a Purchase Order.") value2=_("Create New Vendor") url=vendor_create_url %} + + {% endif %} + {% endif %} {% endblock %} diff --git a/templates/users/user_detail.html b/templates/users/user_detail.html index 9246bfc9..a1a980e8 100644 --- a/templates/users/user_detail.html +++ b/templates/users/user_detail.html @@ -79,12 +79,12 @@
    From f16c6b6a516dd535f5b040f6f7db57c429f05908 Mon Sep 17 00:00:00 2001 From: Faheedkhan Date: Tue, 5 Aug 2025 17:57:13 +0300 Subject: [PATCH 4/6] bug fixes --- inventory/urls.py | 1 + inventory/views.py | 10 +++++++++- templates/customers/view_customer.html | 8 ++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/inventory/urls.py b/inventory/urls.py index 5f5060c7..902e6690 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -933,6 +933,7 @@ urlpatterns = [ views.ItemServiceUpdateView.as_view(), name="item_service_update", ), + # Expanese path( "/items/expeneses/", diff --git a/inventory/views.py b/inventory/views.py index f0f19592..61e18314 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -7358,10 +7358,15 @@ class ItemServiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView) query = self.request.GET.get("q") qs = models.AdditionalServices.objects.filter(dealer=dealer).all() if query: - qs = apply_search_filters(qs, query) + qs = qs.filter(Q(name__icontains=query)| + Q(id__icontains=query)| + Q(uom__icontains=query) + ) return qs + + class ItemExpenseCreateView(LoginRequiredMixin, PermissionRequiredMixin,SuccessMessageMixin, CreateView): """ Represents a view for creating item expense entries. @@ -7453,6 +7458,9 @@ class ItemExpenseUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateV ) + + + class ItemExpenseListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): """ Handles the display of a list of item expenses. diff --git a/templates/customers/view_customer.html b/templates/customers/view_customer.html index be7a2ec6..6ed96dba 100644 --- a/templates/customers/view_customer.html +++ b/templates/customers/view_customer.html @@ -180,22 +180,22 @@ {% for estimate in estimates %}
    -
    +
    {{ estimate }}
    {{ estimate.created|date:"d M Y" }}
    -
      +
        {% for sale_order in estimate.sale_orders.all %} -
      • +
      • {{ sale_order }}
      • {% endfor %} {% for invoice in estimate.invoicemodel_set.all %} -
      • +
      • {{ invoice }} {% if invoice.is_paid %}{% trans "Paid" %}{% else %}{% trans "Unpaid" %}{% endif %} From 0ea27d0826d0334b69225bbf02a7e4756db428d6 Mon Sep 17 00:00:00 2001 From: Faheedkhan Date: Wed, 6 Aug 2025 13:14:49 +0300 Subject: [PATCH 5/6] email chnages reverted --- inventory/views.py | 20 ++++++++++++++-- templates/mail/change_plan_body.txt | 26 ++++++--------------- templates/mail/change_plan_title.txt | 4 +--- templates/mail/expired_account_body.txt | 27 ++++++---------------- templates/mail/expired_account_title.txt | 6 +---- templates/mail/extend_account_body.txt | 23 ++++++------------- templates/mail/extend_account_title.txt | 15 +----------- templates/mail/invoice_created_body.txt | 25 ++++++++------------ templates/mail/invoice_created_title.txt | 4 +--- templates/mail/remind_expire_body.txt | 29 ++++-------------------- templates/mail/remind_expire_title.txt | 4 +--- 11 files changed, 58 insertions(+), 125 deletions(-) diff --git a/inventory/views.py b/inventory/views.py index 94d9458e..c80ab853 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -9456,10 +9456,12 @@ def submit_plan(request, dealer_slug): tax=15, status=1, ) + logger.info(f"order created {order}") except Exception as e: - print(e) + logger.error(e) if not order: messages.error(request, _("Error creating order")) + logger.error("unable to create order") return redirect("pricing_page", dealer_slug=dealer_slug) transaction_url = handle_payment(request, order) return redirect(transaction_url) @@ -9473,9 +9475,13 @@ def payment_callback(request, dealer_slug): payment_id = request.GET.get("id") history = models.PaymentHistory.objects.filter(transaction_id=payment_id).first() payment_status = request.GET.get("status") + logger.info(f"Received payment callback for dealer_slug: {dealer_slug}, payment_id: {payment_id}, status: {payment_status}") order = Order.objects.filter(user=dealer.user, status=1).first() # Status 1 = NEW + print(order) if payment_status == "paid": + logger.info(f"Payment successful for transaction ID {payment_id}. Processing order completion.") + billing_info, created = BillingInfo.objects.get_or_create( user=dealer.user, defaults={ @@ -9487,12 +9493,20 @@ def payment_callback(request, dealer_slug): 'country': dealer.entity.country or " ", } ) + if created: + logger.info(f"Created new billing info for user {dealer.user}.") + else: + logger.debug(f"Billing info already exists for user {dealer.user}.") + if not hasattr(order.user, 'userplan'): UserPlan.objects.create( user=order.user, plan=order.plan, expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period) ) + logger.info(f"Created new UserPlan for user {order.user} with plan {order.plan}.") + else: + logger.info(f"UserPlan already exists for user {order.user}.") try: @@ -9510,7 +9524,7 @@ def payment_callback(request, dealer_slug): order.complete_order() history.status = "paid" history.save() - + logger.info(f"Order {order.id} for user {order.user} completed successfully. Payment history updated.") invoice = order.get_invoices().first() return render( request, @@ -9519,12 +9533,14 @@ def payment_callback(request, dealer_slug): ) except Exception as e: + logger.exception(f"Error completing order {order.id} for user {order.user}: {e}") logger.error(f"Plan activation failed: {str(e)}") history.status = "failed" history.save() return render(request, "payment_failed.html", {"message": "Plan activation error"}) elif payment_status == "failed": + logger.warning(f"Payment failed for transaction ID {payment_id}. Message: {message}") history.status = "failed" history.save() return render(request, "payment_failed.html", {"message": message}) diff --git a/templates/mail/change_plan_body.txt b/templates/mail/change_plan_body.txt index bcd93981..489b5100 100644 --- a/templates/mail/change_plan_body.txt +++ b/templates/mail/change_plan_body.txt @@ -1,25 +1,13 @@ {% load i18n %}{% autoescape off %} - -مرحباً {% firstof user.get_full_name user.username %}، +{% trans "Hi" %} {% firstof user.get_full_name user.username %}, {% if userplan.expire != None %} -خطتك الحالية هي {{ plan.name }} وستنتهي صلاحيتها في {{ userplan.expire }}. + {% blocktrans with plan_name=plan.name expire=userplan.expire %}Your current plan is {{ plan_name }} and it will expire on {{ expire }}. {% endblocktrans %} {% else %} -خطتك الحالية هي {{ plan.name }}. + {% blocktrans with plan_name=plan.name %}Your current plan is {{ plan_name }}. {% endblocktrans %} {% endif %} -شكراً لك، -فريق تنحل ---------------------- - -Hi {% firstof user.get_full_name user.username %}, - -{% if userplan.expire != None %} -Your current plan is {{ plan_name }} and it will expire on {{ expire }}. {% endblocktrans %} -{% else %} -Your current plan is {{ plan_name }}. {% endblocktrans %} -{% endif %} - -Thank you -The Team at Tenhal -{% endautoescape %} \ No newline at end of file +{% trans "Thank you" %} +-- +{% blocktrans %}The Team at {{ site_name }}{% endblocktrans %} +{% endautoescape %} diff --git a/templates/mail/change_plan_title.txt b/templates/mail/change_plan_title.txt index a4a303c2..bbec277e 100644 --- a/templates/mail/change_plan_title.txt +++ b/templates/mail/change_plan_title.txt @@ -1,3 +1 @@ -{% load i18n %} -Your account {{ user }} has new plan {{ plan }} -حسابك {{ user }} لديه خطة جديدة {{ plan }} \ No newline at end of file +{% load i18n %}{% blocktrans with user=user plan=plan.name %}Your account {{ user }} has new plan {{ plan }}{% endblocktrans %} \ No newline at end of file diff --git a/templates/mail/expired_account_body.txt b/templates/mail/expired_account_body.txt index 9355474a..701ad8f9 100644 --- a/templates/mail/expired_account_body.txt +++ b/templates/mail/expired_account_body.txt @@ -1,27 +1,14 @@ {% load i18n %}{% autoescape off %} -مرحباً {% firstof user.get_full_name user.username %}، +{% trans "Hi" %} {% firstof user.get_full_name user.username %}, -لقد انتهت صلاحية حسابك للتو. +{% blocktrans %}Your account has just expired.{% endblocktrans %} -يمكنك استعادة خطتك الحالية {{ userplan.plan.name }} من هنا: +{% blocktrans with plan_name=userplan.plan.name %}You can restore your current plan {{ plan_name }} here:{% endblocktrans %} http://{{ site_domain }}{% url 'current_plan' %} -أو يمكنك ترقية خطتك من هنا: +{% blocktrans %}or you can upgrade your plan here:{% endblocktrans %} http://{{ site_domain }}{% url 'upgrade_plan' %} -شكراً لك، +{% trans "Thank you" %} -- -فريق تنحل ---------------------- -Hi {% firstof user.get_full_name user.username %}, - -Your account has just expired. - -You can restore your current plan {{ userplan.plan.name }} here: -http://{{ site_domain }}{% url 'current_plan' %} -or you can upgrade your plan here: -http://{{ site_domain }}{% url 'upgrade_plan' %} - -Thank you, --- -The Team at TENHAL -{% endautoescape %} \ No newline at end of file +{% blocktrans %}The Team at {{ site_name }}{% endblocktrans %} +{% endautoescape %} diff --git a/templates/mail/expired_account_title.txt b/templates/mail/expired_account_title.txt index e4b758bc..54a3d3a7 100644 --- a/templates/mail/expired_account_title.txt +++ b/templates/mail/expired_account_title.txt @@ -1,5 +1 @@ -{% load i18n %}{% autoescape off %} -لقد انتهت صلاحية حسابك {{ user }} للتو. ---------------------- -Your account {{ user }} has just expired. -{% endautoescape %} \ No newline at end of file +{% load i18n %}{% blocktrans %}Your account {{ user }} has just expired{% endblocktrans %} \ No newline at end of file diff --git a/templates/mail/extend_account_body.txt b/templates/mail/extend_account_body.txt index ed64cb6a..f7e77e50 100644 --- a/templates/mail/extend_account_body.txt +++ b/templates/mail/extend_account_body.txt @@ -1,20 +1,11 @@ {% load i18n %}{% autoescape off %} -مرحباً {% firstof user.get_full_name user.username %}، +{% trans "Hi" %} {% firstof user.get_full_name user.username %}, -تم تمديد صلاحية حسابك للتو لمدة {{ pricing.period }} يوم. خطتك الحالية هي {{plan.name}} وستنتهي في {{userplan.expire}}. +{% blocktrans with days=pricing.period plan_name=plan.name expire=userplan.expire %}Your account has just been extended by {{ days }} days. Your current plan is {{ plan_name }} and it will expire on {{ expire }}. {% endblocktrans %} -سيتم إرسال فاتورة في رسالة بريد إلكتروني أخرى، في حال تم تقديم بيانات الفوترة. -شكراً لك +{% trans "An invoice will be sent with another e-mail, if billing data was provided." %} + +{% trans "Thank you" %} -- -فريق تنحل ---------------------- -Hi {% firstof user.get_full_name user.username %}, - -Your account has just been extended by {{ pricing.period }} days. Your current plan is {{plan.name}} and it will expire on {{userplan.expire}}. - -An invoice will be sent with another e-mail, if billing data was provided. - -Thank you --- -The Team at Tenhal -{% endautoescape %} \ No newline at end of file +{% blocktrans %}The Team at {{ site_name }}{% endblocktrans %} +{% endautoescape %} diff --git a/templates/mail/extend_account_title.txt b/templates/mail/extend_account_title.txt index 2f66c163..8a984a5e 100644 --- a/templates/mail/extend_account_title.txt +++ b/templates/mail/extend_account_title.txt @@ -1,14 +1 @@ -{% load i18n %} -{% autoescape off %} -مرحباً {% firstof user.get_full_name user.username %}، -تم تمديد حسابك {{ user }} لمدة {{ pricing.period }} يوم -شكراً لك --- -فريق تنحل --------- -Hi {% firstof user.get_full_name user.username %}, -Your account {{ user }} has been extended by {{ pricing.period }} days -Thank you --- -The Team at Tenhal -{% endautoescape %} \ No newline at end of file +{% load i18n %}{% blocktrans with user=user days=pricing.period %}Your account {{ user }} has been extended by {{ days }} days{% endblocktrans %} \ No newline at end of file diff --git a/templates/mail/invoice_created_body.txt b/templates/mail/invoice_created_body.txt index 7df530ad..4367230c 100644 --- a/templates/mail/invoice_created_body.txt +++ b/templates/mail/invoice_created_body.txt @@ -1,21 +1,14 @@ {% load i18n %}{% autoescape off %} -مرحباً {% firstof user.get_full_name user.username %}، -نكتب إليك لإعلامك، أنه قد تم إصدار {{ invoice_type }} رقم {{ invoice_number }}. يمكنك الاطلاع عليها وطباعتها عبر الرابط: +{% trans "Hi" %} {% firstof user.get_full_name user.username %}, + +{% blocktrans %}We are writing to inform you, that {{ invoice_type }} {{ invoice_number }} has been issued. You can view it and print it at: http://{{ site_domain }}{{ url }} -يمكنك الاطلاع على تفاصيل الطلب عبر الرابط: +{% endblocktrans %} + +{% trans "Details of the order can be see on:" %}: http://{{ site_domain }}{% url 'order' pk=order %} -شكراً لك +{% trans "Thank you" %} -- -فريق تنحل ---------------------- -Hi {% firstof user.get_full_name user.username %}, -We are writing to inform you, that {{ invoice_type }} {{ invoice_number }} has been issued. You can view it and print it at: -http://{{ site_domain }}{{ url }} -Details of the order can be see on: -http://{{ site_domain }}{% url 'order' pk=order %} - -Thank you --- -The Team at Tenhal -{% endautoescape %} \ No newline at end of file +{% blocktrans %}The Team at {{ site_name }}{% endblocktrans %} +{% endautoescape %} diff --git a/templates/mail/invoice_created_title.txt b/templates/mail/invoice_created_title.txt index eaec9b08..3304e800 100644 --- a/templates/mail/invoice_created_title.txt +++ b/templates/mail/invoice_created_title.txt @@ -1,3 +1 @@ -{% load i18n %} -Order {{ order }} - {{ invoice_type }} {{ invoice_number }} has been issued for {{ user }} -تم إصدار {{ invoice_type }} {{ invoice_number }} للأمر {{ order }} باسم {{ user }} +{% load i18n %}{% trans 'Order' %} {{ order }} - {% blocktrans with invoice_type=invoice_type invoice_number=invoice_number user=user %}{{ invoice_type }} {{ invoice_number }} has been issued for {{ user }}{% endblocktrans %} \ No newline at end of file diff --git a/templates/mail/remind_expire_body.txt b/templates/mail/remind_expire_body.txt index 3ec99320..040dd7d8 100644 --- a/templates/mail/remind_expire_body.txt +++ b/templates/mail/remind_expire_body.txt @@ -1,29 +1,10 @@ {% load i18n %}{% autoescape off %} -Hi {% firstof user.get_full_name user.username %}, +{% trans "Hi" %} {% firstof user.get_full_name user.username %}, -Your account will expire in {{ days }} days. +{% blocktrans %}Your account will expire in {{ days }} days.{% endblocktrans %} -You can extend your current plan {{ userplan.plan.name }} on page: +{% blocktrans with plan_name=userplan.plan.name %}You can extend your current plan {{ plan_name }} on page:{% endblocktrans %} http://{{ site_domain }}{% url 'current_plan' %} -or you can upgrade your plan here: -http://{{ site_domain }}{% url 'upgrade_plan' %} - -Thank you --- -The Team at Tenhal ----------------- -مرحباً {% firstof full_name username %}، - -سينتهي حسابك في غضون {{ days }} يوم. - -يمكنك تمديد خطتك الحالية {{ userplan.plan.name }} على الصفحة التالية: -http://{{ site_domain }}{% url 'current_plan' %} - -أو يمكنك ترقية خطتك هنا: -http://{{ site_domain }}{% url 'upgrade_plan' %} - -شكراً لك --- -فريق تنحل -{% endautoescape %} +{% blocktrans %}or you can upgrade your plan here:{% endblocktrans %} +http://{{ site_domain }}{% url 'upgrade_plan' %} \ No newline at end of file diff --git a/templates/mail/remind_expire_title.txt b/templates/mail/remind_expire_title.txt index 01885ad3..b6863e01 100644 --- a/templates/mail/remind_expire_title.txt +++ b/templates/mail/remind_expire_title.txt @@ -1,3 +1 @@ -{% load i18n %} -Your account {{ user }} will expire in {{ days }} day. -سينتهي حسابك {{ user }} في غضون {{ days }} يوم. \ No newline at end of file +{% load i18n %}{% blocktrans count days as days %}Your account {{ user }} will expire in {{ days }} day{% plural %}Your account {{ user }} will expire in {{ days }} days{% endblocktrans %} \ No newline at end of file From 095885c9b7d9cb63f50203f99e567ead0cf604eb Mon Sep 17 00:00:00 2001 From: Faheedkhan Date: Wed, 6 Aug 2025 15:29:05 +0300 Subject: [PATCH 6/6] staff profile page --- inventory/urls.py | 4 ++ inventory/views.py | 29 ++++++++ templates/header.html | 4 +- templates/staff/staff_detail.html | 107 ++++++++++++++++++++++++++++++ templates/users/user_detail.html | 2 +- 5 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 templates/staff/staff_detail.html diff --git a/inventory/urls.py b/inventory/urls.py index c83dc2ee..6a7b02a9 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -1290,6 +1290,10 @@ urlpatterns = [ path('/schedules/calendar/', views.schedule_calendar, name='schedule_calendar'), + # staff profile + path('/staff/detail/', views.StaffDetailView.as_view(), name='staff_detail'), + + ] handler404 = "inventory.views.custom_page_not_found_view" diff --git a/inventory/views.py b/inventory/views.py index 3335af8c..f87b5c89 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -2197,6 +2197,35 @@ class DealerUpdateView( def get_success_url(self): return reverse("dealer_detail", kwargs={"slug": self.object.slug}) + +class StaffDetailView(LoginRequiredMixin, DetailView): + """ + Represents a detailed view for a Dealer model. + + This class extends Django's `DetailView` to provide a detailed view of a dealer. + It includes additional context data such as the count of staff members, cars + associated with the dealer, available car makes, and dynamically fetched quotas. + The class also ensures that users must be logged in to access the detailed view. + + :ivar model: The model associated with this view (Dealer model). + :type model: django.db.models.Model + :ivar template_name: Path to the template used to render the view. + :type template_name: str + :ivar context_object_name: The name used to refer to the object in the template context. + :type context_object_name: str + """ + + model = models.Staff + template_name = "staff/staff_detail.html" + context_object_name = "staff" + + + +def dealer_vat_rate_update(request, slug): + dealer = get_object_or_404(models.Dealer, slug=slug) + models.VatRate.objects.filter(dealer=dealer).update(rate=request.POST.get("rate")) + messages.success(request, _("VAT rate updated successfully")) + return redirect("dealer_detail", slug=slug) class CustomerListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): diff --git a/templates/header.html b/templates/header.html index a79de5b6..941a4f44 100644 --- a/templates/header.html +++ b/templates/header.html @@ -504,7 +504,7 @@
      • {% else %} {% endif %} {% if request.is_dealer %} @@ -530,7 +530,7 @@ {% if request.is_staff %} {% endif %} diff --git a/templates/staff/staff_detail.html b/templates/staff/staff_detail.html new file mode 100644 index 00000000..c8cba830 --- /dev/null +++ b/templates/staff/staff_detail.html @@ -0,0 +1,107 @@ +{% extends 'base.html' %} +{% load i18n static custom_filters crispy_forms_filters %} +{% block title %} + {% trans 'Profile' %} {% endblock %} + {% block content %} +
        +
        +
        +

        {% trans 'Profile' %}

        + +
        + +
        +
        +
        +
        +
        +
        +
        +
        + + +
        + +
        +

        {{ staff.get_local_name }}

        +

        {{staff.user.groups.name}}

        +

        {% trans 'Joined' %} {{ staff.created|timesince }} {% trans 'ago' %}

        +
        +
        +
        +
        +
        +
        +
        {% trans 'last login'|capfirst %}
        +

        {{ staff.user.last_login|date:"D M d, Y H:i" }}

        +
        + +
        +
        +
        +
        +
        +
        +
        +
        +

        {% trans 'Default Address' %}

        +
        +
        +
        +
        +
        {% trans 'Address' %}
        +
        +
        +

        {{ staff.address }}

        +
        +
        +
        +
        +
        +
        +
        {% trans 'Email' %}
        +
        +
        {{ staff.user.email }}
        +
        +
        +
        +
        {% trans 'Phone' %}
        +
        +
        {{ staff.phone_number }}
        +
        +
        +
        +
        +
        +
        + +
        + {% endblock %} + + + \ No newline at end of file diff --git a/templates/users/user_detail.html b/templates/users/user_detail.html index a1a980e8..cd3da0bf 100644 --- a/templates/users/user_detail.html +++ b/templates/users/user_detail.html @@ -98,7 +98,7 @@ + href="{% url 'staff_password_reset' request.dealer.slug %}"> {{ _("Reset Password") }}