added the logic for car_purchase and sale report
This commit is contained in:
parent
f5feee2372
commit
d5d895789a
@ -639,6 +639,7 @@ class Car(Base):
|
|||||||
default=CarStatusChoices.AVAILABLE,
|
default=CarStatusChoices.AVAILABLE,
|
||||||
verbose_name=_("Status"),
|
verbose_name=_("Status"),
|
||||||
)
|
)
|
||||||
|
|
||||||
stock_type = models.CharField(
|
stock_type = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
choices=CarStockTypeChoices.choices,
|
choices=CarStockTypeChoices.choices,
|
||||||
@ -648,6 +649,7 @@ class Car(Base):
|
|||||||
remarks = models.TextField(blank=True, null=True, verbose_name=_("Remarks"))
|
remarks = models.TextField(blank=True, null=True, verbose_name=_("Remarks"))
|
||||||
mileage = models.IntegerField(blank=True, null=True, verbose_name=_("Mileage"))
|
mileage = models.IntegerField(blank=True, null=True, verbose_name=_("Mileage"))
|
||||||
receiving_date = models.DateTimeField(verbose_name=_("Receiving Date"))
|
receiving_date = models.DateTimeField(verbose_name=_("Receiving Date"))
|
||||||
|
sold_date=models.DateTimeField(verbose_name=_("Sold Date"))
|
||||||
hash = models.CharField(
|
hash = models.CharField(
|
||||||
max_length=64, blank=True, null=True, verbose_name=_("Hash")
|
max_length=64, blank=True, null=True, verbose_name=_("Hash")
|
||||||
)
|
)
|
||||||
@ -763,6 +765,7 @@ class Car(Base):
|
|||||||
"remarks": self.remarks,
|
"remarks": self.remarks,
|
||||||
"mileage": self.mileage,
|
"mileage": self.mileage,
|
||||||
"receiving_date": self.receiving_date.strftime("%Y-%m-%d %H:%M:%S"),
|
"receiving_date": self.receiving_date.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
"sold_date":self.sold_date.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
"hash": self.get_hash,
|
"hash": self.get_hash,
|
||||||
"id": str(self.id),
|
"id": str(self.id),
|
||||||
}
|
}
|
||||||
@ -901,7 +904,8 @@ class CarFinance(models.Model):
|
|||||||
verbose_name=_("Discount Amount"),
|
verbose_name=_("Discount Amount"),
|
||||||
default=Decimal("0.00"),
|
default=Decimal("0.00"),
|
||||||
)
|
)
|
||||||
is_sold = models.BooleanField(default=False)
|
# is_sold = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total(self):
|
def total(self):
|
||||||
|
|||||||
@ -292,7 +292,8 @@ def update_item_model_cost(sender, instance, created, **kwargs):
|
|||||||
:param kwargs: Additional keyword arguments passed during the signal invocation.
|
:param kwargs: Additional keyword arguments passed during the signal invocation.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if created and not instance.is_sold:
|
# if created and not instance.is_sold:
|
||||||
|
if created:
|
||||||
entity = instance.car.dealer.entity
|
entity = instance.car.dealer.entity
|
||||||
coa = entity.get_default_coa()
|
coa = entity.get_default_coa()
|
||||||
inventory_account = (
|
inventory_account = (
|
||||||
|
|||||||
@ -1107,6 +1107,22 @@ urlpatterns = [
|
|||||||
views.PurchaseOrderMarkAsVoidView.as_view(),
|
views.PurchaseOrderMarkAsVoidView.as_view(),
|
||||||
name="po-action-mark-as-void",
|
name="po-action-mark-as-void",
|
||||||
),
|
),
|
||||||
|
|
||||||
|
# reports
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/purchase-report/",
|
||||||
|
views.purchase_report_view,
|
||||||
|
name="po-report",
|
||||||
|
),
|
||||||
|
path('purchase-report/<slug:dealer_slug>/csv/', views.purchase_report_csv_export, name='purchase-report-csv-export'),
|
||||||
|
|
||||||
|
path(
|
||||||
|
"<slug:dealer_slug>/car-sale-report/",
|
||||||
|
views.car_sale_report_view,
|
||||||
|
name="car-sale-report",
|
||||||
|
),
|
||||||
|
path('car-sale-report/<slug:dealer_slug>/csv/', views.car_sale_report_csv_export, name='car-sale-report-csv-export'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
handler404 = "inventory.views.custom_page_not_found_view"
|
handler404 = "inventory.views.custom_page_not_found_view"
|
||||||
|
|||||||
@ -1470,7 +1470,6 @@ class CarFinanceCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateVi
|
|||||||
permission_required = ["inventory.add_carfinance"]
|
permission_required = ["inventory.add_carfinance"]
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
print(self.car)
|
|
||||||
self.car = get_object_or_404(models.Car, slug=self.kwargs["slug"])
|
self.car = get_object_or_404(models.Car, slug=self.kwargs["slug"])
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
@ -4233,22 +4232,16 @@ def sales_list_view(request, dealer_slug):
|
|||||||
:rtype: HttpResponse
|
:rtype: HttpResponse
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
||||||
entity = dealer.entity
|
|
||||||
print(entity)
|
|
||||||
staff = getattr(request.user.staffmember, "staff", None)
|
staff = getattr(request.user.staffmember, "staff", None)
|
||||||
print(staff)
|
|
||||||
qs = []
|
qs = []
|
||||||
try:
|
try:
|
||||||
if any([request.is_dealer, request.is_manager, request.is_accountant]):
|
if any([request.is_dealer, request.is_manager, request.is_accountant]):
|
||||||
qs = models.ExtraInfo.get_sale_orders(staff=staff,is_dealer=True)
|
qs = models.ExtraInfo.get_sale_orders(staff=staff,is_dealer=True)
|
||||||
print(qs)
|
|
||||||
elif request.is_staff:
|
elif request.is_staff:
|
||||||
qs = models.ExtraInfo.get_sale_orders(staff=staff)
|
qs = models.ExtraInfo.get_sale_orders(staff=staff)
|
||||||
print(qs)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
pass
|
||||||
print(qs)
|
|
||||||
|
|
||||||
|
|
||||||
paginator = Paginator(qs, 30)
|
paginator = Paginator(qs, 30)
|
||||||
@ -4322,15 +4315,13 @@ class EstimateListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
staff = getattr(self.request.user.staffmember, "staff", None)
|
staff = getattr(self.request.user.staffmember, "staff", None)
|
||||||
|
|
||||||
if any([self.request.is_dealer ,self.request.is_manager ,self.request.is_accountant]):
|
if any([self.request.is_dealer ,self.request.is_manager ,self.request.is_accountant]):
|
||||||
qs = models.ExtraInfo.objects.filter(
|
qs = models.ExtraInfo.objects.filter(
|
||||||
dealer=dealer,
|
dealer=dealer,
|
||||||
content_type=ContentType.objects.get_for_model(EstimateModel),
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
||||||
)
|
)
|
||||||
eqs=qs
|
|
||||||
print(qs)
|
|
||||||
elif self.request.is_staff and self.request.is_sales:
|
elif self.request.is_staff and self.request.is_sales:
|
||||||
qs = models.ExtraInfo.objects.filter(
|
qs = models.ExtraInfo.objects.filter(
|
||||||
dealer=dealer,
|
dealer=dealer,
|
||||||
@ -4338,19 +4329,15 @@ class EstimateListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
||||||
related_object_id=staff.pk,
|
related_object_id=staff.pk,
|
||||||
)
|
)
|
||||||
|
context["staff_estimates"] = EstimateModel.objects.filter(pk__in=[x.content_object.pk for x in qs])
|
||||||
context["staff_estimates"] = qs
|
|
||||||
return context
|
return context
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
entity = dealer.entity
|
entity = dealer.entity
|
||||||
status = self.request.GET.get("status")
|
status = self.request.GET.get("status")
|
||||||
queryset = entity.get_estimates()
|
queryset = entity.get_estimates()
|
||||||
|
|
||||||
if status:
|
if status:
|
||||||
queryset = queryset.filter(status=status)
|
queryset = queryset.filter(status=status)
|
||||||
|
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
@ -4462,7 +4449,7 @@ def create_estimate(request, dealer_slug, slug=None):
|
|||||||
for item in items_list:
|
for item in items_list:
|
||||||
car_instance = models.Car.objects.filter(
|
car_instance = models.Car.objects.filter(
|
||||||
hash=item.get("item_id"),
|
hash=item.get("item_id"),
|
||||||
finances__is_sold=False,
|
# finances__is_sold=False,
|
||||||
colors__isnull=False,
|
colors__isnull=False,
|
||||||
finances__isnull=False,
|
finances__isnull=False,
|
||||||
finances__marked_price__gt=1,
|
finances__marked_price__gt=1,
|
||||||
@ -10444,3 +10431,155 @@ def bulk_update_car_price(request):
|
|||||||
class InventoryListView(InventoryListViewBase):
|
class InventoryListView(InventoryListViewBase):
|
||||||
template_name = "inventory/list.html"
|
template_name = "inventory/list.html"
|
||||||
permission_required = ["django_ledger.view_purchaseordermodel"]
|
permission_required = ["django_ledger.view_purchaseordermodel"]
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def purchase_report_view(request,dealer_slug):
|
||||||
|
pos = request.entity.get_purchase_orders()
|
||||||
|
data = []
|
||||||
|
total_po_amount=0
|
||||||
|
total_po_cars=0
|
||||||
|
for po in pos:
|
||||||
|
items = [{"total":x.total_amount,"q":x.quantity} for x in po.get_itemtxs_data()[0].all()]
|
||||||
|
|
||||||
|
po_amount=0
|
||||||
|
po_quantity=0
|
||||||
|
for item in items:
|
||||||
|
po_amount+=item["total"]
|
||||||
|
po_quantity+=item["q"]
|
||||||
|
|
||||||
|
total_po_amount+=po_amount
|
||||||
|
total_po_cars+=po_quantity
|
||||||
|
bills=po.get_po_bill_queryset()
|
||||||
|
vendors=set([bill.vendor.vendor_name for bill in bills])
|
||||||
|
vendors_str = ", ".join(sorted(list(vendors))) if vendors else "N/A"
|
||||||
|
data.append({"po_number":po.po_number,"po_created":po.created,"po_status":po.po_status,"po_fulfilled_date":po.date_fulfilled,"po_amount":po_amount,
|
||||||
|
"po_quantity":po_quantity,"vendors_str":vendors_str})
|
||||||
|
|
||||||
|
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
context={
|
||||||
|
"dealer":request.entity.name,
|
||||||
|
"time":current_time,
|
||||||
|
"data":data,
|
||||||
|
"total_po_amount":total_po_amount,
|
||||||
|
"total_po_cars":total_po_cars,
|
||||||
|
"current_time":current_time
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return render(request,'ledger/reports/purchase_report.html',context)
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_report_csv_export(request,dealer_slug):
|
||||||
|
response = HttpResponse(content_type='text/csv')
|
||||||
|
|
||||||
|
|
||||||
|
current_time = timezone.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
|
filename = f"purchase_report_{dealer_slug}_{current_time}.csv"
|
||||||
|
response['Content-Disposition'] = f'attachment; filename="{filename}"'
|
||||||
|
|
||||||
|
writer = csv.writer(response)
|
||||||
|
|
||||||
|
|
||||||
|
header = [
|
||||||
|
'PO Number',
|
||||||
|
'Created Date',
|
||||||
|
'Status',
|
||||||
|
'Fulfilled Date',
|
||||||
|
'PO Amount',
|
||||||
|
'PO Quantity',
|
||||||
|
'Vendors'
|
||||||
|
]
|
||||||
|
writer.writerow(header)
|
||||||
|
pos = request.entity.get_purchase_orders()
|
||||||
|
|
||||||
|
for po in pos:
|
||||||
|
po_amount = 0
|
||||||
|
po_quantity = 0
|
||||||
|
items = [{"total":x.total_amount,"q":x.quantity} for x in po.get_itemtxs_data()[0].all()]
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
po_amount += item["total"]
|
||||||
|
po_quantity += item["q"]
|
||||||
|
|
||||||
|
bills = po.get_po_bill_queryset()
|
||||||
|
vendors = set([bill.vendor.vendor_name for bill in bills ])
|
||||||
|
vendors_str = ", ".join(sorted(list(vendors))) if vendors else "N/A"
|
||||||
|
|
||||||
|
|
||||||
|
writer.writerow([
|
||||||
|
po.po_number,
|
||||||
|
po.created.strftime("%Y-%m-%d %H:%M:%S") if po.created else '',
|
||||||
|
po.get_po_status_display(),
|
||||||
|
po.date_fulfilled.strftime("%Y-%m-%d") if po.date_fulfilled else '',
|
||||||
|
f"{po_amount:.2f}",
|
||||||
|
po_quantity,
|
||||||
|
vendors_str
|
||||||
|
])
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def car_sale_report_csv_export(request,dealer_slug):
|
||||||
|
|
||||||
|
response = HttpResponse(content_type='text/csv')
|
||||||
|
|
||||||
|
|
||||||
|
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
filename = f"sales_report_{dealer_slug}_{current_time}.csv"
|
||||||
|
response['Content-Disposition'] = f'attachment; filename="{filename}"'
|
||||||
|
|
||||||
|
writer = csv.writer(response)
|
||||||
|
|
||||||
|
header=[
|
||||||
|
'Make',
|
||||||
|
'VIN',
|
||||||
|
'Model',
|
||||||
|
'Year',
|
||||||
|
'Serie',
|
||||||
|
'Trim',
|
||||||
|
'Mileage',
|
||||||
|
'Stock Type',
|
||||||
|
'Created Date',
|
||||||
|
'Sold Date',
|
||||||
|
'Cost Price',
|
||||||
|
'Marked Price',
|
||||||
|
'Discount Amount',
|
||||||
|
'Selling Price',
|
||||||
|
'Tax Amount',
|
||||||
|
'Invoice Number',
|
||||||
|
]
|
||||||
|
writer.writerow(header)
|
||||||
|
|
||||||
|
dealer=get_object_or_404(models.Dealer,slug=dealer_slug)
|
||||||
|
cars_sold=models.Car.objects.filter(dealer=dealer,status='sold')
|
||||||
|
for car in cars_sold:
|
||||||
|
writer.writerow([
|
||||||
|
car.vin,
|
||||||
|
car.id_car_make.name,
|
||||||
|
car.id_car_model.name,
|
||||||
|
car.year,
|
||||||
|
car.id_car_serie.name,
|
||||||
|
car.id_car_trim.name,
|
||||||
|
car.mileage,
|
||||||
|
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.finances.cost_price,
|
||||||
|
car.finances.marked_price,
|
||||||
|
car.finances.discount_amount,
|
||||||
|
car.finances.selling_price,
|
||||||
|
car.finances.vat_amount,
|
||||||
|
car.item_model.invoicemodel_set.first().invoice_number
|
||||||
|
])
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
@ -5,7 +5,7 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<h2 class="mb-5">{{ _("Notifications") }}</h2>
|
<h2 class="mb-5">{{ _("Notifications") }}</h2>
|
||||||
<div class="d-flex justify-content-end mb-3">
|
<div class="d-flex justify-content-end mb-3">
|
||||||
<a href="{% url 'mark_all_notifications_as_read' %}" class="btn btn-primary"><i class="far fa-envelope fs-8 me-2"></i>{{ _("Mark all as read") }}</a>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{% if notifications %}
|
{% if notifications %}
|
||||||
<div class="mx-n4 mx-lg-n6 mb-5 border-bottom">
|
<div class="mx-n4 mx-lg-n6 mb-5 border-bottom">
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid mt-4 mb-3">
|
||||||
<div class="row g-3 mb-4 align-items-center">
|
<div class="row g-3 mb-4 align-items-center">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h2 class="mb-0">
|
<h2 class="mb-0">
|
||||||
|
|||||||
@ -12,8 +12,8 @@
|
|||||||
<div class="col-lg-8 col-md-10">
|
<div class="col-lg-8 col-md-10">
|
||||||
<div class="card shadow-sm border-0 rounded-3">
|
<div class="card shadow-sm border-0 rounded-3">
|
||||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||||
<h3 class="mb-0 fs-4 text-center text-white">
|
<h3 class="mb-0 fs-4 text-center">
|
||||||
{{ _("Update Dealer Information") }}
|
{{ _("Update Dealer Information") }}<span class="fas fa-car ms-2 text-primary"></span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body bg-light-subtle">
|
<div class="card-body bg-light-subtle">
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer> {% endcomment %}
|
</footer> {% endcomment %}
|
||||||
|
|
||||||
<footer class="footer position-absolute fs-9 bg-info-subtle">
|
{% comment %} <footer class="footer position-absolute fs-9 bg-info-subtle">
|
||||||
<div class="row g-0 justify-content-between align-items-center h-100">
|
<div class="row g-0 justify-content-between align-items-center h-100">
|
||||||
<div class="col-12 col-sm-auto text-center text-warning">
|
<div class="col-12 col-sm-auto text-center text-warning">
|
||||||
<span class="text-body "> © 2025 {{ _("All right reserved")}}</span>
|
<span class="text-body "> © 2025 {{ _("All right reserved")}}</span>
|
||||||
@ -31,9 +31,9 @@
|
|||||||
<span class="fas fa-registered fs-10 fw-light text-opacity-85 text-warning"></span>
|
<span class="fas fa-registered fs-10 fw-light text-opacity-85 text-warning"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer> {% endcomment %}
|
||||||
|
|
||||||
{% comment %} <footer class="footer position-absolute fs-9 bg-gray-900 text-white">
|
<footer class="footer position-absolute fs-9 bg-white text-secondary">
|
||||||
<div class="row g-0 justify-content-between align-items-center h-100">
|
<div class="row g-0 justify-content-between align-items-center h-100">
|
||||||
<div class="col-12 col-sm-auto text-center">
|
<div class="col-12 col-sm-auto text-center">
|
||||||
<span class="text-body"> © 2025 {{ _("All right reserved")}}</span>
|
<span class="text-body"> © 2025 {{ _("All right reserved")}}</span>
|
||||||
@ -43,11 +43,11 @@
|
|||||||
<div class="col-12 col-sm-auto text-center ">
|
<div class="col-12 col-sm-auto text-center ">
|
||||||
<span>{{ _("Powered by")}} </span>
|
<span>{{ _("Powered by")}} </span>
|
||||||
<span>
|
<span>
|
||||||
<a class="mx-1 text-white" href="https://tenhal.sa">
|
<a class="mx-1 text-secondary" href="https://tenhal.sa">
|
||||||
<span>TENHAL</span> | <span>تنحل</span>
|
<span>TENHAL</span> | <span>تنحل</span>
|
||||||
</a>
|
</a>
|
||||||
<span>
|
<span>
|
||||||
<span class="uil-trademark-circle fs-10"></span>
|
<span class="fas fa-registered fs-10 fw-light text-opacity-85 text-secondary"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer> {% endcomment %}
|
</footer>
|
||||||
|
|||||||
@ -346,6 +346,28 @@
|
|||||||
<i class="fa-solid fa-scale-balanced"></i><span class="nav-link-text">{% trans 'Balance Sheet'|capfirst %}</span>
|
<i class="fa-solid fa-scale-balanced"></i><span class="nav-link-text">{% trans 'Balance Sheet'|capfirst %}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<!--car purchase report-->
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<a class="nav-link" href="{% url 'po-report' request.dealer.slug %}">
|
||||||
|
{% else %}
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
{% endif %}
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-shopping-cart"></i><span class="nav-link-text">{% trans 'Car purchase Report'|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!--car sale report-->
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<a class="nav-link" href="{% url 'car-sale-report' request.dealer.slug %}">
|
||||||
|
{% else %}
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
{% endif %}
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-car"></i><span class="nav-link-text">{% trans 'Car Sale Report'|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
111
templates/ledger/reports/car_sale_report.html
Normal file
111
templates/ledger/reports/car_sale_report.html
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Car Sale Report") |capfirst }}
|
||||||
|
{% endblock title %}
|
||||||
|
|
||||||
|
{% block content%}
|
||||||
|
|
||||||
|
<div class="container-fluid report-container">
|
||||||
|
<header class="report-header text-center">
|
||||||
|
<h1 class="display-4">Car Sale Report <span class="fas fa-car mx-2 text-primary"></span><span class="fas fa-money-bill mx-2 text-primary"></span></h1>
|
||||||
|
<p class="lead text-muted"><strong>{{dealer}}</strong></p>
|
||||||
|
<p class="text-muted">Report Date: {{current_time}}</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section id="summary" class="mb-1">
|
||||||
|
<h2 class="section-heading mb-2">Report Summary</h2>
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-6 col-lg-4 mb-2">
|
||||||
|
<div class="card summary-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary">Total Revenue Amount<span class="fas fa-solid fa-dollar-sign mx-1"></span><span class="fas fa-car"></span></h5>
|
||||||
|
<p class="card-text fs-4 fw-bold">120000000</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-lg-4 mb-2">
|
||||||
|
<div class="card summary-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary">Total Vat Amount<span class="fas fa-solid fa-percent mx-1"></span><span class="fas fa-car"></span></h5>
|
||||||
|
<p class="card-text fs-4 fw-bold">12000</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-lg-4 mb-2">
|
||||||
|
<div class="card summary-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary">Total Discount Amount <span class="fas fa-solid fa-tag mx-1"></span><span class="fas fa-car"></span></h5>
|
||||||
|
<p class="card-text fs-4 fw-bold">12000</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="purchase-details" class="mb-3">
|
||||||
|
<h2 class="section-heading">Detailed Purchase List</h2>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end mb-3 d-print-none">
|
||||||
|
<a href="{% url 'car-sale-report-csv-export' request.dealer.slug %}" class="btn btn-phoenix-primary">
|
||||||
|
<i class="bi bi-download me-2"></i> Download as CSV
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-hover table-bordered table-sm">
|
||||||
|
<thead >
|
||||||
|
<tr>
|
||||||
|
<th>VIN</th>
|
||||||
|
<th>Make</th>
|
||||||
|
<th>Model</th>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Serie</th>
|
||||||
|
<th>Trim</th>
|
||||||
|
<th>Mileage</th>
|
||||||
|
<th>Stock Type</th>
|
||||||
|
<th>Created Date</th>
|
||||||
|
<th>Sold Date</th>
|
||||||
|
<th>Cost Price</th>
|
||||||
|
<th>Marked Price</th>
|
||||||
|
<th>Discount Amount</th>
|
||||||
|
<th>Selling Price</th>
|
||||||
|
<th>Tax Amount</th>
|
||||||
|
<th>Invoice Number</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{% for car in cars_sold%}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-1">{{car.vin}}</td>
|
||||||
|
<td>{{car.id_car_make.name}}</td>
|
||||||
|
<td>{{car.id_car_model.name}}</td>
|
||||||
|
<td>{{car.year}}</td>
|
||||||
|
<td>{{car.id_car_serie.name}}</td>
|
||||||
|
<td>{{car.id_car_trim.name}}</td>
|
||||||
|
<td>{{car.mileage}}</td>
|
||||||
|
<td>{{car.stock_type}}</td>
|
||||||
|
<td>{{car.created_at}}</td>
|
||||||
|
<td>{{car.sold_date}}</td>
|
||||||
|
<td>{{car.finances.cost_price}}</td>
|
||||||
|
<td>{{car.finances.marked_price}}</td>
|
||||||
|
<td>{{car.finances.discount_amount}}</td>
|
||||||
|
<td>{{car.finances.selling_price}}</td>
|
||||||
|
<td>{{car.finances.vat_amount}}</td>
|
||||||
|
<td>{{car.item_model.invoicemodel_set.first.invoice_number}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
97
templates/ledger/reports/purchase_report.html
Normal file
97
templates/ledger/reports/purchase_report.html
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Car Purchase Report") |capfirst }}
|
||||||
|
{% endblock title %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content%}
|
||||||
|
|
||||||
|
<div class="container-fluid report-container">
|
||||||
|
<header class="report-header text-center">
|
||||||
|
<h1 class="display-4">Car Purchase Report <span class="fas fa-car mx-2 text-primary"></span><span class="fas fa-chart-bar mx-2 text-primary"></span></h1>
|
||||||
|
<p class="lead text-muted"><strong>{{dealer}}</strong></p>
|
||||||
|
<p class="text-muted">Report Date: {{current_time}}</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section id="summary" class="mb-1">
|
||||||
|
<h2 class="section-heading mb-2">Report Summary</h2>
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-6 col-lg-4 mb-2">
|
||||||
|
<div class="card summary-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary">Total Purchase Amount<span class="fas fa-money-bill ms-1"><span></h5>
|
||||||
|
<p class="card-text fs-4 fw-bold">{{total_po_amount}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-lg-4 mb-2">
|
||||||
|
<div class="card summary-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary">Total Cars Purchased<span class="fas fa-shopping-bag mx-1"></span><span class="fas fa-car"></span></h5>
|
||||||
|
<p class="card-text fs-4 fw-bold">{{total_po_cars}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="purchase-details" class="mb-3">
|
||||||
|
<h2 class="section-heading">Detailed Purchase List</h2>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end mb-3 d-print-none">
|
||||||
|
<a href="{% url 'purchase-report-csv-export' request.dealer.slug %}" class="btn btn-phoenix-primary">
|
||||||
|
<i class="bi bi-download me-2"></i> Download as CSV
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-hover table-bordered table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Purchase ID</th>
|
||||||
|
<th>Date Created</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>PO Amount</th>
|
||||||
|
<th>Date Fulfilled</th>
|
||||||
|
<th>Created By</th>
|
||||||
|
<th>Cars Purchased</th>
|
||||||
|
<th>Vendor</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{% for po in data %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-1">{{po.po_number}}</td>
|
||||||
|
<td>{{po.po_created}}</td>
|
||||||
|
<td>{{po.po_status}}</td>
|
||||||
|
<td>{{po.po_amount}}</td>
|
||||||
|
<td>{{po.date_fulfilled}}</td>
|
||||||
|
<td>staff</td>
|
||||||
|
<td>{{po.po_quantity}}</td>
|
||||||
|
<td>
|
||||||
|
{{po.vendors_str}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-end fw-bold">Total Purchase:</td>
|
||||||
|
<td class="fw-bold text-primary">{{total_po_amount}}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Dropdown menu -->
|
<!-- Dropdown menu -->
|
||||||
<div class="dropdown-menu dropdown-menu-end notification-dropdown-menu py-0 shadow border navbar-dropdown-caret" id="navbarDropdownNotfication">
|
<div class="dropdown-menu dropdown-menu-end notification-dropdown-menu py-1 shadow border navbar-dropdown-caret" id="navbarDropdownNotfication">
|
||||||
<div class="card position-relative border-0">
|
<div class="card position-relative border-0">
|
||||||
<div class="card-header p-2">
|
<div class="card-header p-2">
|
||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
@ -50,8 +50,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer p-0 border-top border-translucent border-0">
|
<div class="card-footer p-0 border-top border-translucent border-0">
|
||||||
<div class="my-2 text-center fw-bold fs-10 text-body-tertiary text-opactity-85">
|
<div class="my-3 text-center fw-bold fs-9 text-body-tertiary text-opactity-85">
|
||||||
<a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history</a>
|
<a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history<i class="fa-solid fa-history ms-1"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -181,7 +181,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu py-2">
|
<div class="dropdown-menu py-2">
|
||||||
<a class="dropdown-item mark-as-read" href="#"
|
<a class="dropdown-item mark-as-read" href="#"
|
||||||
data-notification-id="${data.id}">Mark as read</a>
|
data-notification-id="${data.id}">Mark as read<i class="fa-solid fa-check ms-1"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -30,8 +30,8 @@
|
|||||||
<div class="col-lg-8 col-md-10">
|
<div class="col-lg-8 col-md-10">
|
||||||
<div class="card shadow-sm border-0 rounded-3">
|
<div class="card shadow-sm border-0 rounded-3">
|
||||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||||
<h3 class="mb-0 fs-4 text-center text-white">
|
<h3 class="mb-0 fs-4 text-center">
|
||||||
{% trans "Provide billing data"|upper %}
|
{% trans "Provide billing data"|upper %}<span class="fas fa-file-invoice-dollar ms-2 text-primary"></span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body bg-light-subtle">
|
<div class="card-body bg-light-subtle">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user