Compare commits

...

4 Commits

13 changed files with 316 additions and 101 deletions

View File

@ -0,0 +1,134 @@
import logging
from datetime import timedelta
from django.urls import reverse
from django.conf import settings
from django.utils import timezone
from inventory.tasks import send_email
from django.core.management.base import BaseCommand
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django_ledger.models import InvoiceModel,EstimateModel
from inventory.models import ExtraInfo,Notification,CustomGroup
logger = logging.getLogger(__name__)
class Command(BaseCommand):
help = "Handles invoices due date reminders"
def handle(self, *args, **options):
self.stdout.write("Starting invoices due date reminders..")
# 1. Send expiration reminders
self.invocie_expiration_reminders()
# self.invoice_past_due()
# # 2. Deactivate expired plans
# self.deactivate_expired_plans()
# # 3. Clean up old incomplete orders
# self.cleanup_old_orders()
# self.stdout.write("Reminders completed!")
def invocie_expiration_reminders(self):
"""Queue email reminders for expiring plans"""
reminder_days = getattr(settings, 'INVOICE_PAST_DUE_REMIND', [3, 7, 14])
today = timezone.now().date()
for days in reminder_days:
target_date = today + timedelta(days=days)
expiring_plans = InvoiceModel.objects.filter(
date_due=target_date
).select_related('customer','ce_model')
for inv in expiring_plans:
# dealer = inv.customer.customer_set.first().dealer
subject = f"Your invoice is due in {days} days"
message = render_to_string('emails/invoice_past_due_reminder.txt', {
'customer_name': inv.customer.customer_name,
'invoice_number': inv.invoice_number,
'amount_due': inv.amount_due,
'days_past_due': inv.due_in_days(),
'SITE_NAME': settings.SITE_NAME
})
send_email(
'noreply@yourdomain.com',
inv.customer.email,
subject,
message,
)
self.stdout.write(f"Queuing {expiring_plans} reminders for {target_date}")
def invoice_past_due(self):
"""Queue email reminders for expiring plans"""
today = timezone.now().date()
expiring_plans = InvoiceModel.objects.filter(
date_due__lte = today
).select_related('customer','ce_model')
# Send email
for inv in expiring_plans:
dealer = inv.customer.customer_set.first().dealer
subject = f"Your invoice is past due"
message = render_to_string('emails/invoice_past_due.txt', {
'customer_name': inv.customer.customer_name,
'invoice_number': inv.invoice_number,
'amount_due': inv.amount_due,
'days_past_due': (today - inv.date_due).days,
'SITE_NAME': settings.SITE_NAME
})
# send notification to accountatnt
recipients = (
CustomGroup.objects.filter(dealer=dealer, name="Accountant")
.first()
.group.user_set.exclude(email=dealer.user.email)
.distinct()
)
for rec in recipients:
Notification.objects.create(
user=rec,
message=_(
"""
Invoice {invoice_number} is past due,please your
<a href="{url}" target="_blank">View</a>.
"""
).format(
invoice_number=inv.invoice_number,
url=reverse(
"invoice_detail",
kwargs={"dealer_slug": dealer.slug, "entity_slug": dealer.entity.slug, "pk": inv.pk},
),
),
)
# send email to customer
send_email(
'noreply@yourdomain.com',
inv.customer.email,
subject,
message,
)
self.stdout.write(f"Queuing {expiring_plans} reminders for {today}")
# def deactivate_expired_plans(self):
# """Deactivate plans that have expired (synchronous)"""
# expired_plans = UserPlan.objects.filter(
# active=True,
# expire__lt=timezone.now().date()
# )
# count = expired_plans.update(active=False)
# self.stdout.write(f"Deactivated {count} expired plans")
# def cleanup_old_orders(self):
# """Delete incomplete orders older than 30 days"""
# cutoff = timezone.now() - timedelta(days=30)
# count, _ = Order.objects.filter(
# created__lt=cutoff,
# status=Order.STATUS.NEW
# ).delete()
# self.stdout.write(f"Cleaned up {count} old incomplete orders")

View File

@ -2945,7 +2945,7 @@ class CustomGroup(models.Model):
"customgroup", "customgroup",
"saleorder", "saleorder",
"payment", "payment",
"staff", # "staff",
"schedule", "schedule",
"activity", "activity",
"opportunity", "opportunity",
@ -3028,7 +3028,7 @@ class CustomGroup(models.Model):
allowed_models=[ allowed_models=[
"saleorder", "saleorder",
# "payment", # "payment",
"staff", # "staff",
"schedule", "schedule",
"activity", "activity",
"lead", "lead",

View File

@ -2645,9 +2645,14 @@ def vendorDetailView(request, dealer_slug, slug):
:return: An HttpResponse object containing the rendered vendor detail page. :return: An HttpResponse object containing the rendered vendor detail page.
:rtype: HttpResponse :rtype: HttpResponse
""" """
vendor = get_object_or_404(models.Vendor, slug=slug) dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
vendor = get_object_or_404(models.Vendor, slug=slug,dealer=dealer)
vendor_bills=BillModel.objects.filter(vendor=vendor.vendor_model)
paginator=Paginator(vendor_bills,20)
page_number = request.GET.get("page")
page_obj=paginator.get_page(page_number)
return render( return render(
request, template_name="vendors/view_vendor.html", context={"vendor": vendor} request, template_name="vendors/view_vendor.html", context={"vendor": vendor,"vendor_bills":page_obj}
) )
@ -11007,11 +11012,9 @@ class RecallDetailView(DetailView):
return context return context
def RecallFilterView(request): def RecallFilterView(request):
context = {'make_data': models.CarMake.objects.all()} context = {'make_data': models.CarMake.objects.all()}
if request.method == "POST": if request.method == "POST":
print(request.POST)
make = request.POST.get('make') make = request.POST.get('make')
model = request.POST.get('model') model = request.POST.get('model')
serie = request.POST.get('serie') serie = request.POST.get('serie')

View File

@ -260,7 +260,7 @@
</button> </button>
{% modal_action_v2 bill bill.get_mark_as_canceled_url bill.get_mark_as_canceled_message bill.get_mark_as_canceled_html_id %} {% modal_action_v2 bill bill.get_mark_as_canceled_url bill.get_mark_as_canceled_message bill.get_mark_as_canceled_html_id %}
{% endif %} {% endif %}
{% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -0,0 +1,10 @@
Hello {{ customer_name }},
This is a friendly reminder that your invoice for {{ invoice_number }} is now {{ days_past_due }} days past due.
Please settle your outstanding balance of {{ amount_due }} .
If you have already paid, please disregard this notice.
Best regards,
{{ SITE_NAME }} Team

View File

@ -0,0 +1,11 @@
Hello {{ customer_name }},
This is a friendly reminder that your invoice for {{ invoice_number }} is due in {{ days_past_due }} days.
Please settle your outstanding balance of {{ amount_due }} before the due date to avoid any late fees.
If you have already paid, please disregard this notice.
Best regards,
{{ SITE_NAME }} Team

View File

@ -492,7 +492,7 @@
{% if request.is_dealer %} {% if request.is_dealer %}
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6> <h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
{% else %} {% else %}
<h6 class="mt-2 text-body-emphasis">{{ user.staffmember.staff.get_local_name }}</h6> <h6 class="mt-2 text-body-emphasis">{{ user.staff.get_local_name }}</h6>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load tenhal_tag %}
{% block title %} {% block title %}
{{ _("Car Sale Report") |capfirst }} {{ _("Car Sale Report") |capfirst }}
{% endblock title %} {% endblock title %}
@ -98,8 +99,8 @@
<div class="col-md-6 col-lg-3"> <div class="col-md-6 col-lg-3">
<div class="card summary-card"> <div class="card summary-card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{% trans 'Total Revenue' %}<i class="fas fa-dollar-sign ms-2"></i></h5> <h5 class="card-title">{% trans 'Total Revenue' %}<span class="icon-saudi_riyal"></span></h5>
<p class="card-text">{{ total_revenue|floatformat:2 }}</p> <p class="card-text">{{ total_revenue|floatformat:2 }} <span class="icon-saudi_riyal"></span></p>
</div> </div>
</div> </div>
</div> </div>
@ -107,7 +108,7 @@
<div class="card summary-card"> <div class="card summary-card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{% trans 'Total VAT Amount' %}<i class="fas fa-percent ms-2"></i></h5> <h5 class="card-title">{% trans 'Total VAT Amount' %}<i class="fas fa-percent ms-2"></i></h5>
<p class="card-text">{{ 10000|floatformat:2 }}</p> <p class="card-text">{{ 10000|floatformat:2 }} <span class="icon-saudi_riyal"></span></p>
</div> </div>
</div> </div>
</div> </div>
@ -115,7 +116,7 @@
<div class="card summary-card"> <div class="card summary-card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{% trans 'Total Discount Amount' %}<i class="fas fa-tag ms-2"></i></h5> <h5 class="card-title">{% trans 'Total Discount Amount' %}<i class="fas fa-tag ms-2"></i></h5>
<p class="card-text">{{ total_discount|floatformat:2 }}</p> <p class="card-text">{{ total_discount|floatformat:2 }} <span class="icon-saudi_riyal"></span></p>
</div> </div>
</div> </div>
</div> </div>
@ -174,14 +175,14 @@
<td class="fs-9">{{ car.id_car_serie.name }}</td> <td class="fs-9">{{ car.id_car_serie.name }}</td>
<td class="fs-9">{{ car.id_car_trim.name }}</td> <td class="fs-9">{{ car.id_car_trim.name }}</td>
<td class="fs-9">{{ car.mileage }}</td> <td class="fs-9">{{ car.mileage }}</td>
<td class="fs-9">{{ car.stock_type }}</td> <td class="fs-9">{{ car.stock_type|capfirst }}</td>
<td class="fs-9">{{ car.created_at|date }}</td> <td class="fs-9">{{ car.created_at|date }}</td>
<td class="fs-9">{{ car.invoice.date_paid|date|default_if_none:"-" }}</td> <td class="fs-9">{{ car.invoice.date_paid|date|default_if_none:"-" }}</td>
<td class="fs-9">{{ car.finances.cost_price }}</td> <td class="fs-9">{{ car.finances.cost_price }} <span class="icon-saudi_riyal"></span></td>
<td class="fs-9">{{ car.finances.marked_price }}</td> <td class="fs-9">{{ car.finances.marked_price }} <span class="icon-saudi_riyal"></span></td>
<td class="fs-9">{{ car.finances.discount_amount }}</td> <td class="fs-9">{{ car.finances.discount_amount }} <span class="icon-saudi_riyal"></span></td>
<td class="fs-9">{{ car.finances.selling_price }}</td> <td class="fs-9">{{ car.finances.selling_price }} <span class="icon-saudi_riyal"></span></td>
<td class="fs-9">{{ car.finances.vat_amount }}</td> <td class="fs-9">{{ car.finances.vat_amount }} <span class="icon-saudi_riyal"></span></td>
<td class="fs-9">{{ car.invoice.invoice_number }}</td> <td class="fs-9">{{ car.invoice.invoice_number }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -256,6 +256,7 @@
<tr class="bg-body-secondary total-sum"> <tr class="bg-body-secondary total-sum">
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="7">{% trans "Discount Amount" %}</td> <td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="7">{% trans "Discount Amount" %}</td>
<td class="align-middle text-start text-danger fw-semibold"> <td class="align-middle text-start text-danger fw-semibold">
{% if estimate.is_draft %}
<form action="{% url 'update_estimate_discount' request.dealer.slug estimate.pk %}" <form action="{% url 'update_estimate_discount' request.dealer.slug estimate.pk %}"
method="post"> method="post">
{% csrf_token %} {% csrf_token %}
@ -270,6 +271,9 @@
<button type="submit" class="btn btn-sm btn-phoenix-primary ms-n2">{% trans "Update" %}</button> <button type="submit" class="btn btn-sm btn-phoenix-primary ms-n2">{% trans "Update" %}</button>
</div> </div>
</form> </form>
{% else %}
{{ data.total_discount }} <span class="icon-saudi_riyal"></span>
{% endif %}
</td> </td>
</tr> </tr>
<tr class="bg-body-secondary total-sum"> <tr class="bg-body-secondary total-sum">
@ -285,12 +289,14 @@
<small><span class="fw-semibold">+ {{ service.name }} - {{ service.price_|floatformat }}<span class="icon-saudi_riyal"></span></span></small> <small><span class="fw-semibold">+ {{ service.name }} - {{ service.price_|floatformat }}<span class="icon-saudi_riyal"></span></span></small>
<br> <br>
{% endfor %} {% endfor %}
{% if estimate.is_draft %}
<button class="btn btn-phoenix-primary btn-xs ms-auto" <button class="btn btn-phoenix-primary btn-xs ms-auto"
type="button" type="button"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#additionalModal"> data-bs-target="#additionalModal">
<span class="fas fa-plus me-1"></span>{{ _("Add") }} <span class="fas fa-plus me-1"></span>{{ _("Add") }}
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
<tr class="bg-body-secondary total-sum"> <tr class="bg-body-secondary total-sum">

View File

@ -1,6 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load custom_filters %} {% load custom_filters %}
{% load tenhal_tag %}
{% block title %}{{ page_title }} - {{ sale_order.formatted_order_id }}{% endblock %} {% block title %}{{ page_title }} - {{ sale_order.formatted_order_id }}{% endblock %}
{% block content %} {% block content %}
<div class="container mt-4"> <div class="container mt-4">
@ -17,9 +18,9 @@
<!-- Basic Information --> <!-- Basic Information -->
<div class="row mb-4"> <div class="row mb-4">
<div class="col-md-4"> <div class="col-md-4">
<h4>{% trans "Customer Information" %}</h4> <h4 class="mb-3">{% trans "Customer Information" %}</h4>
<p> <p>
<strong>{% trans "Name" %}:</strong> {{ sale_order.full_name }} <strong>{% trans "Name" %}:</strong> {{ sale_order.full_name|title }}
<br> <br>
{% if sale_order.customer %} {% if sale_order.customer %}
<strong>{% trans "Contact" %}:</strong> {{ sale_order.customer.phone_number }} <strong>{% trans "Contact" %}:</strong> {{ sale_order.customer.phone_number }}
@ -29,7 +30,7 @@
</p> </p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h4>{% trans "Order Details" %}</h4> <h4 class="mb-3">{% trans "Order Details" %}</h4>
<p> <p>
<strong>{% trans "Order Date" %}:</strong> {{ sale_order.order_date|date }} <strong>{% trans "Order Date" %}:</strong> {{ sale_order.order_date|date }}
<br> <br>
@ -187,7 +188,7 @@
<strong>{% trans "Amount Paid" %}:</strong> <strong>{% trans "Amount Paid" %}:</strong>
</td> </td>
<td style="padding-left: 0.5rem;"> <td style="padding-left: 0.5rem;">
<span class="currency">{{ CURRENCY }}</span>{{ sale_order.invoice.amount_paid|floatformat:2 }} <span class="icon-saudi_riyal"></span>{{ sale_order.invoice.amount_paid|floatformat:2 }}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -195,7 +196,7 @@
<strong>{% trans "Balance Due" %}:</strong> <strong>{% trans "Balance Due" %}:</strong>
</td> </td>
<td style="padding-left: 0.5rem;"> <td style="padding-left: 0.5rem;">
<span class="currency">{{ CURRENCY }}</span>{{ sale_order.invoice.amount_due|floatformat:2 }} <span class="icon-saudi_riyal"></span>{{ sale_order.invoice.amount_due|floatformat:2 }}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -203,7 +204,7 @@
<strong>{% trans "Amount Unearned" %}:</strong> <strong>{% trans "Amount Unearned" %}:</strong>
</td> </td>
<td style="padding-left: 0.5rem;"> <td style="padding-left: 0.5rem;">
<span class="currency">{{ CURRENCY }}</span>{{ sale_order.invoice.amount_unearned|floatformat:2 }} <span class="icon-saudi_riyal"></span>{{ sale_order.invoice.amount_unearned|floatformat:2 }}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -211,7 +212,7 @@
<strong>{% trans "Amount Receivable" %}:</strong> <strong>{% trans "Amount Receivable" %}:</strong>
</td> </td>
<td style="padding-left: 0.5rem;"> <td style="padding-left: 0.5rem;">
<span class="currency">{{ CURRENCY }}</span>{{ sale_order.invoice.amount_receivable|floatformat:2 }} <span class="icon-saudi_riyal"></span>{{ sale_order.invoice.amount_receivable|floatformat:2 }}
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -12,11 +12,7 @@
<div class="col-auto"> <div class="col-auto">
<div class="row g-2 g-sm-3"> <div class="row g-2 g-sm-3">
<div class="col-auto"> <div class="col-auto">
<a class="btn btn-phoenix-primary" <a href="{% url 'staff_password_reset' request.dealer.slug staff.pk %}"
href="{% url 'user_update' request.dealer.slug request.staff.slug %}"><span class="fas fa-edit me-2 text-primary"></span>{{ _("Edit") }} </a>
</div>
<div class="col-auto">
<a href="{% url 'staff_password_reset' request.dealer.slug staff.user.pk %}" 'staff_password_reset' request.dealer.slug user_.pk
class="btn btn-phoenix-danger"><span class="fas fa-key me-2"></span>{{ _("Change Password") }}</a> class="btn btn-phoenix-danger"><span class="fas fa-key me-2"></span>{{ _("Change Password") }}</a>
</div> </div>
</div> </div>
@ -49,9 +45,14 @@
<div class="col-12 col-sm-auto flex-1"> <div class="col-12 col-sm-auto flex-1">
<h3>{{ staff.get_local_name }}</h3> <h3>{{ staff.get_local_name }}</h3>
<p class="text-body-secondary">{{staff.user.groups.name}}</p> <p>
{% trans 'Role' %}:
{% for group in staff.groups%}
<span class="text-body-secondary me-2">&nbsp;{{group}}</span>
{% endfor %}
</p>
<p class="text-body-secondary">{% trans 'Joined' %} {{ staff.created|timesince }} {% trans 'ago' %}</p> <p class="text-body-secondary">{% trans 'Joined' %} {{ staff.created|timesince }} {% trans 'ago' %}</p>
<div></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -98,7 +98,7 @@
<i class="fa-regular fa-circle-left"></i> <i class="fa-regular fa-circle-left"></i>
</a> </a>
<a class="btn btn-sm btn-phoenix-secondary" <a class="btn btn-sm btn-phoenix-secondary"
href="{% url 'staff_password_reset' request.dealer.slug %}"> href="{% url 'staff_password_reset' request.dealer.slug user_.pk %}">
{{ _("Reset Password") }} {{ _("Reset Password") }}
<i class="fa-solid fa-key"></i> <i class="fa-solid fa-key"></i>
</a> </a>

View File

@ -9,15 +9,38 @@
<div class="card shadow rounded"> <div class="card shadow rounded">
<p class="card-header mb-0 fs-5">{% trans "Vendor Details" %}</p> <p class="card-header mb-0 fs-5">{% trans "Vendor Details" %}</p>
<div class="card-body"> <div class="card-body">
<div class="col-12 col-sm-auto mb-sm-2"> <div class="row justify-content-start">
<div class="col-6 col-sm-auto mb-sm-2">
<div class="avatar avatar-5xl"> <div class="avatar avatar-5xl">
{% if vendor.logo%}<img class="rounded-circle" src="{{ vendor.logo.url }}" alt="" />{% endif %} {% if vendor.logo%}<img class="rounded-circle" src="{{ vendor.logo.url }}" alt="" />{% endif %}
</div> </div>
<div class="card-footer d-flex">
{% if perms.django_ledger.change_vendormodel %}
<a class="btn btn-sm btn-phoenix-primary me-3"
href="{% url 'vendor_update' request.dealer.slug vendor.slug %}">
<i class="fa fa-pencil me-1"></i>
{% trans "Edit" %}
</a>
{% endif %}
{% if perms.django_ledger.delete_vendormodel %}
<button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'vendor_delete' request.dealer.slug vendor.slug %}"
data-message="{{ _("Are you sure you want to delete this vendor") }}?"
data-bs-toggle="modal"
data-bs-target="#deleteModal">
<i class="fas fa-trash me-1"></i>
{{ _("Delete") }}
</button>
{% endif %}
</div> </div>
</div>
<div class="col-6 col-sm-auto mb-sm-2">
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
<li class="list-group-item"> <li class="list-group-item">
<strong>{% trans "Name" %}:</strong> {{ vendor.get_local_name }} <strong>{% trans "Name" %}:</strong> {{ vendor.get_local_name }} </li>
</li>
<li class="list-group-item"> <li class="list-group-item">
<strong>{% trans "Contact Person" %}:</strong> {{ vendor.contact_person }} <strong>{% trans "Contact Person" %}:</strong> {{ vendor.contact_person }}
</li> </li>
@ -32,27 +55,52 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="card-footer d-flex"> </div>
{% if perms.django_ledger.change_vendormodel %} </div>
<a class="btn btn-sm btn-phoenix-primary me-1"
href="{% url 'vendor_update' request.dealer.slug vendor.slug %}"> </div>
{% trans "Edit" %} <div class="table-responsive px-1 scrollbar mt-3">
<i class="fa fa-pencil"></i> <table class= "table align-items-center table-flush table-hover">
</a> <thead>
{% endif %} <tr class="bg-body-highlight">
{% if perms.django_ledger.delete_vendormodel %} <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Bill") |capfirst }}</th>
<button class="btn btn-phoenix-danger btn-sm delete-btn" <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Bill Status") |capfirst }}</th>
data-url="{% url 'vendor_delete' request.dealer.slug vendor.slug %}" <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Bill Amount Paid") |capfirst }}</th>
data-message="{{ _("Are you sure you want to delete this vendor") }}?" <th class="sort white-space-nowrap align-middle" scope="col">{{ _("Bill Amount Due") |capfirst }}</th>
data-bs-toggle="modal"
data-bs-target="#deleteModal"> </tr>
{{ _("Delete") }} </thead>
<i class="fas fa-trash"></i> <tbody class="list">
</button>
{% for bill in vendor_bills%}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="align-middle product white-space-nowrap ps-1">
<a class="text-body-highlight" href="{% url 'bill-detail' request.dealer.slug request.dealer.entity.slug bill.pk%}">{{ bill.bill_number }}</a>
</td>
<td class="align-middle product white-space-nowrap">{{ bill.bill_status }}</td>
<td class="align-middle product white-space-nowrap">{{ bill.amount_paid}}</td>
<td class="align-middle product white-space-nowrap">{{ bill.amount_due}}</td>
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center text-muted">{% trans "No Bills Found For the Vendor: {vendor.get_local_name}" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="d-flex justify-content-end mt-3">
<div class="d-flex">
{% if is_paginated %}
{% include 'partials/pagination.html' %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>
{% include 'modal/delete_modal.html' %} {% include 'modal/delete_modal.html' %}
{% endblock %} {% endblock %}