trace for the my way of writing the dashboard logic
This commit is contained in:
parent
0dcc7d56a3
commit
d0ac8eba9a
@ -602,7 +602,7 @@ def update_car_status_on_reservation_create(sender, instance, created, **kwargs)
|
||||
"""
|
||||
Signal handler to update the status of a car upon the creation of a car reservation.
|
||||
This function is triggered when a new instance of a CarReservation is created and saved
|
||||
to the database. It modifies the status of the associated car to reflect the RESERVED status.
|
||||
to the database. It modifies the status of the associated car to reflect the D status.
|
||||
|
||||
:param sender: The model class that sends the signal (CarReservation).
|
||||
:param instance: The specific instance of the CarReservation that triggered the signal.
|
||||
|
||||
@ -495,14 +495,22 @@ class TestView(TemplateView):
|
||||
|
||||
|
||||
|
||||
from django.db.models import Sum, F, Count
|
||||
from django.db.models.functions import ExtractMonth
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
|
||||
def DealerDashboard(request):
|
||||
dealer = request.dealer
|
||||
|
||||
# This part is correct as is, it filters cars by dealer and sold status
|
||||
cars_sold = models.Car.objects.filter(dealer=dealer, status='sold')
|
||||
|
||||
today_local = timezone.localdate()
|
||||
start_date_str = request.GET.get('start_date')
|
||||
end_date_str = request.GET.get('end_date')
|
||||
|
||||
# This part needs to be made timezone-aware and robust
|
||||
if not start_date_str:
|
||||
start_date = today_local - timedelta(days=30)
|
||||
else:
|
||||
@ -513,41 +521,143 @@ def DealerDashboard(request):
|
||||
else:
|
||||
end_date = timezone.datetime.strptime(end_date_str, '%Y-%m-%d').date()
|
||||
|
||||
# Existing inventory calculations
|
||||
active_cars = models.Car.objects.filter(status__in=['available', 'reserved', 'damaged'])
|
||||
total_cars_in_inventory = active_cars.count()
|
||||
new_cars_qs= active_cars.filter(stock_type='new')
|
||||
used_cars_qs=active_cars.filter(stock_type='old')
|
||||
total_new_cars_in_inventory = new_cars_qs.count()
|
||||
total_used_cars_in_inventory = used_cars_qs.count()
|
||||
total_inventory_value = sum([car.cost_price for car in active_cars])
|
||||
new_car_value=sum([car.cost_price for car in new_cars_qs])
|
||||
used_car_value=sum([car.cost_price for car in used_cars_qs])
|
||||
# Define the aging threshold (e.g., 90 days)
|
||||
aging_threshold_days = 60
|
||||
# Efficiently query the database for aging cars
|
||||
aging_inventory = active_cars.filter(created_at__lte=today_local - timedelta(days=aging_threshold_days))
|
||||
# You can get the count for display on the dashboard
|
||||
aging_inventory_count = aging_inventory.count()
|
||||
|
||||
|
||||
|
||||
|
||||
# The database query will automatically be handled in a timezone-aware manner
|
||||
cars_sold_filtered = cars_sold.filter(
|
||||
sold_date__date__gte=start_date,
|
||||
sold_date__date__lte=end_date
|
||||
)
|
||||
print(cars_sold_filtered)
|
||||
# # Calculate summary data for the filtered results
|
||||
total_cars_sold=cars_sold_filtered.count()
|
||||
print(total_cars_sold)
|
||||
total_revenue_from_cars = sum([ car.final_price for car in cars_sold_filtered])
|
||||
total_cost_of_cars_sold=sum([car.cost_price for car in cars_sold_filtered])
|
||||
net_profit_from_cars=total_revenue_from_cars-total_cost_of_cars_sold
|
||||
total_vat_collected_from_cars=sum([car.vat_amount for car in cars_sold_filtered])
|
||||
total_revenue_from_services=sum([car.get_additional_services()['total'] for car in cars_sold_filtered])
|
||||
total_vat_collected_from_services=sum([car.get_additional_services()['services_vat'] for car in cars_sold_filtered])
|
||||
total_vat_collected = total_vat_collected_from_cars+total_vat_collected_from_services
|
||||
total_revenue_generated=total_revenue_from_cars+total_revenue_from_services
|
||||
|
||||
# Calculate summary data for the filtered results
|
||||
total_cars_sold = cars_sold_filtered.count()
|
||||
new_cars_sold=cars_sold_filtered.filter(stock_type='new')
|
||||
used_cars_sold=cars_sold_filtered.filter(stock_type='used')
|
||||
total_new_cars_sold=new_cars_sold.count()
|
||||
total_used_cars_sold=used_cars_sold.count()
|
||||
|
||||
# Calculations for all cars
|
||||
total_cost_of_cars_sold = sum([car.cost_price for car in cars_sold_filtered])
|
||||
total_revenue_from_cars = sum([car.final_price for car in cars_sold_filtered])
|
||||
net_profit_from_cars = total_revenue_from_cars - total_cost_of_cars_sold
|
||||
total_vat_collected_from_cars = sum([car.vat_amount for car in cars_sold_filtered])
|
||||
|
||||
# Calculations specifically for used cars
|
||||
total_cost_of_used_cars_sold = sum([car.cost_price for car in used_cars_sold])
|
||||
total_revenue_from_used_cars = sum([car.final_price for car in used_cars_sold])
|
||||
net_profit_from_used_cars = total_revenue_from_used_cars - total_cost_of_used_cars_sold
|
||||
total_vat_collected_from_used_cars = sum([car.vat_amount for car in used_cars_sold])
|
||||
|
||||
# Calculations specifically for new cars
|
||||
total_cost_of_new_cars_sold = sum([car.cost_price for car in new_cars_sold])
|
||||
total_revenue_from_new_cars = sum([car.final_price for car in new_cars_sold])
|
||||
net_profit_from_new_cars = total_revenue_from_new_cars - total_cost_of_new_cars_sold
|
||||
total_vat_collected_from_new_cars = sum([car.vat_amount for car in new_cars_sold])
|
||||
|
||||
|
||||
total_revenue_from_services = sum([car.get_additional_services()['total'] for car in cars_sold_filtered])
|
||||
total_vat_collected_from_services = sum([car.get_additional_services()['services_vat'] for car in cars_sold_filtered])
|
||||
total_vat_collected = total_vat_collected_from_cars + total_vat_collected_from_services
|
||||
total_revenue_generated = total_revenue_from_cars + total_revenue_from_services
|
||||
total_discount = sum([car.discount for car in cars_sold_filtered])
|
||||
|
||||
# Filter for expenses
|
||||
expenses = ItemModel.objects.filter(entity__admin__dealer=dealer, item_role='expense')
|
||||
total_expenses = sum([expense.default_amount for expense in expenses])
|
||||
|
||||
gross_profit = net_profit_from_cars - total_expenses
|
||||
|
||||
# ----------------------------------------------------
|
||||
# NEW LOGIC FOR CHARTS - Aggregating data by month
|
||||
# ----------------------------------------------------
|
||||
|
||||
# Group cars sold by month and aggregate totals
|
||||
monthly_sales_data = cars_sold_filtered.annotate(
|
||||
month=ExtractMonth('sold_date')
|
||||
).values('month').annotate(
|
||||
total_cars=Count('pk'),
|
||||
total_revenue=Sum(F('marked_price') - F('discount_amount')), # Corrected for marked price and discount_amount
|
||||
total_profit=Sum(F('marked_price') - F('discount_amount') - F('cost_price')) # Corrected profit calculation
|
||||
).order_by('month')
|
||||
|
||||
# Initialize lists for chart data
|
||||
monthly_cars_sold = [0] * 12
|
||||
monthly_revenue = [0] * 12
|
||||
monthly_net_profit = [0] * 12
|
||||
|
||||
# Populate the lists from the queryset results
|
||||
for data in monthly_sales_data:
|
||||
month_index = data['month'] - 1 # Months are 1-12, so we need to adjust to 0-11
|
||||
monthly_cars_sold[month_index] = data['total_cars']
|
||||
monthly_revenue[month_index] = data['total_revenue']
|
||||
monthly_net_profit[month_index] = data['total_profit']
|
||||
# the monthly revenue is of this form: [0, 0, 0, 0, 0, 0, 0, Decimal('21000'), 0, 0, 0, 0] so javascript cannot recognise Decimale('21000') as no.
|
||||
|
||||
|
||||
# NEW: Convert the lists to JSON strings
|
||||
monthly_cars_sold_json = json.dumps(monthly_cars_sold)
|
||||
monthly_revenue_json = json.dumps([float(x) for x in monthly_revenue]) # Convert Decimal to float
|
||||
monthly_net_profit_json = json.dumps([float(x) for x in monthly_net_profit])
|
||||
|
||||
# Update the context dictionary with the new monthly data lists
|
||||
context = {
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'cars_sold': cars_sold_filtered,
|
||||
'total_cars_sold':total_cars_sold,
|
||||
'total_cost_of_cars_sold':total_cost_of_cars_sold,
|
||||
'total_revenue_from_cars':total_revenue_from_cars,
|
||||
'net_profit_from_cars':net_profit_from_cars,
|
||||
'total_cars_sold': total_cars_sold,
|
||||
'total_cost_of_cars_sold': total_cost_of_cars_sold,
|
||||
'total_revenue_from_cars': total_revenue_from_cars,
|
||||
'net_profit_from_cars': net_profit_from_cars,
|
||||
'total_vat_collected_from_cars': total_vat_collected_from_cars,
|
||||
'total_discount_on_cars':total_discount,
|
||||
'total_revenue_from_services':total_revenue_from_services,
|
||||
'total_discount_on_cars': total_discount,
|
||||
'total_revenue_from_services': total_revenue_from_services,
|
||||
'total_vat_collected_from_services': total_vat_collected_from_services,
|
||||
'total_revenue_generated': total_revenue_generated,
|
||||
'total_vat_collected':total_vat_collected,
|
||||
'total_vat_collected': total_vat_collected,
|
||||
'total_expenses': total_expenses,
|
||||
"gross_profit": gross_profit,
|
||||
'total_cars_in_inventory': total_cars_in_inventory,
|
||||
'total_used_cars_in_inventory': total_used_cars_in_inventory,
|
||||
'total_new_cars_in_inventory': total_new_cars_in_inventory,
|
||||
'total_inventory_value': total_inventory_value,
|
||||
'new_car_value':new_car_value,
|
||||
'used_car_value':used_car_value,
|
||||
'aging_inventory_count':aging_inventory_count,
|
||||
'total_new_cars_sold':total_new_cars_sold,
|
||||
'total_used_cars_sold':total_used_cars_sold,
|
||||
'total_cost_of_used_cars_sold': total_cost_of_used_cars_sold,
|
||||
'total_revenue_from_used_cars':total_revenue_from_used_cars,
|
||||
'net_profit_from_used_cars':net_profit_from_used_cars,
|
||||
'total_vat_collected_from_used_cars':total_vat_collected_from_used_cars,
|
||||
'total_cost_of_new_cars_sold': total_cost_of_new_cars_sold,
|
||||
'total_revenue_from_new_cars':total_revenue_from_new_cars,
|
||||
'net_profit_from_new_cars':net_profit_from_new_cars,
|
||||
'total_vat_collected_from_new_cars':total_vat_collected_from_new_cars,
|
||||
|
||||
|
||||
|
||||
# New variables for charts
|
||||
'monthly_cars_sold_json': monthly_cars_sold_json,
|
||||
'monthly_revenue_json': monthly_revenue_json,
|
||||
'monthly_net_profit_json': monthly_net_profit_json,
|
||||
}
|
||||
|
||||
return render(request, 'dashboards/dealer_dashboard.html', context)
|
||||
@ -580,76 +690,6 @@ class ManagerDashboard(LoginRequiredMixin, TemplateView):
|
||||
# )
|
||||
# return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
dealer = get_user_type(self.request)
|
||||
entity = dealer.entity
|
||||
|
||||
qs = models.Car.objects.filter(dealer=dealer)
|
||||
total_cars = qs.count()
|
||||
|
||||
stats = 0 # models.CarFinance.objects.filter(car__dealer=dealer).aggregate( #TODO:update_finance
|
||||
# total_cost_price=Sum("cost_price"),
|
||||
# total_selling_price=Sum("selling_price"),
|
||||
# )
|
||||
total_cost_price = stats["total_cost_price"] or 0
|
||||
total_selling_price = stats["total_selling_price"] or 0
|
||||
total_profit = total_selling_price - total_cost_price
|
||||
|
||||
new_leads = models.Lead.objects.filter(
|
||||
dealer=dealer, status=models.Status.NEW
|
||||
).count()
|
||||
pending_leads = models.Lead.objects.filter(
|
||||
dealer=dealer, status=models.Status.CONTACTED
|
||||
).count()
|
||||
canceled_leads = models.Lead.objects.filter(
|
||||
dealer=dealer, status=models.Status.UNQUALIFIED
|
||||
).count()
|
||||
|
||||
car_status_qs = qs.values("status").annotate(count=Count("status"))
|
||||
car_status = {status: count for status, count in car_status_qs}
|
||||
|
||||
car_by_make_qs = qs.values("id_car_make__name").annotate(count=Count("id"))
|
||||
car_by_make = list(car_by_make_qs)
|
||||
|
||||
context["dealer"] = dealer
|
||||
context["total_activity"] = models.UserActivityLog.objects.filter(
|
||||
user=dealer.user
|
||||
).count()
|
||||
context["total_cars"] = total_cars
|
||||
context["total_reservations"] = models.CarReservation.objects.filter(
|
||||
reserved_until__gte=timezone.now()
|
||||
).count()
|
||||
context["total_cost_price"] = total_cost_price
|
||||
context["total_selling_price"] = total_selling_price
|
||||
context["total_profit"] = total_profit
|
||||
context["new_leads"] = new_leads
|
||||
context["pending_leads"] = pending_leads
|
||||
context["canceled_leads"] = canceled_leads
|
||||
context["car"] = json.dumps(car_by_make)
|
||||
|
||||
|
||||
context["available_cars"] =qs.filter(status='available').count()
|
||||
context["sold_cars"] = qs.filter(status='sold').count()
|
||||
context["reserved_cars"] = qs.filter(status='reserved').count()
|
||||
context["hold_cars"] =qs.filter(status='hold').count()
|
||||
context["damaged_cars"] = qs.filter(status='damaged').count()
|
||||
context["transfer_cars"] = qs.filter(status='transfer').count()
|
||||
context["present_inventory_count"]=total_cars-context["sold_cars"]-context["damaged_cars"]
|
||||
cars_sold=qs.filter(status='sold')
|
||||
# cars_sold.aggregate(total_inventory_value=sum())
|
||||
|
||||
|
||||
context["customers"] = entity.get_customers().count()
|
||||
context["staff"] = models.Staff.objects.filter(dealer=dealer).count()
|
||||
context["total_leads"] = models.Lead.objects.filter(dealer=dealer).count()
|
||||
context["invoices"] = entity.get_invoices().count()
|
||||
context["estimates"] = entity.get_estimates().count()
|
||||
context["purchase_orders"] = entity.get_purchase_orders().count()
|
||||
|
||||
|
||||
|
||||
return context
|
||||
|
||||
|
||||
|
||||
|
||||
@ -152,8 +152,8 @@
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Total Expense</p>
|
||||
<h4 class="fw-bolder text-danger mb-3">$1.25M</h4>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans "Total Expense" %}</p>
|
||||
<h4 class="fw-bolder text-danger mb-3">{{total_expenses|floatformat:2}}<span class="icon-saudi_riyal"></span></h4>
|
||||
</div>
|
||||
<span class="badge bg-danger-subtle text-danger fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
-2% from last month
|
||||
@ -165,8 +165,8 @@
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Gross Profit</p>
|
||||
<h4 class="fw-bolder text-info mb-3">$1.25M</h4>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans "Gross Profit" %}</p>
|
||||
<h4 class="fw-bolder text-info mb-3">{{gross_profit|floatformat:2}}<span class="icon-saudi_riyal"></span></h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+8% from last month
|
||||
@ -179,7 +179,7 @@
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Total VAT Collected</p>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans "Total VAT Collected" %}</p>
|
||||
<h4 class="fw-bolder text-primary mb-3">{{total_vat_collected|floatformat:2}}<span class="icon-saudi_riyal"></span></h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
@ -201,8 +201,135 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">New Cars Sold</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_cars_sold }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Used Cars Sold</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_cars_sold }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">{% trans 'Inventory Value '%}</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_inventory_value|floatformat:2 }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+8% from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Total Cars in Inventory</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_cars_in_inventory }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Total Old Cars in Inventory</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_old_cars_in_inventory}}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Total New Cars in Inventory</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ total_new_cars_in_inventory }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">New Cars Value</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ new_car_value }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+8% from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Old Cars Value</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ old_car_value }}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+8% from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body d-flex flex-column justify-content-between p-4">
|
||||
<div>
|
||||
<p class="text-uppercase text-muted fw-bold small mb-1">Aging Inventory</p>
|
||||
<h4 class="fw-bolder text-success mb-3">{{ aging_inventory_count}}</h4>
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success fw-bold p-2 rounded-pill d-inline-flex align-self-start">
|
||||
+5 units from last month
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--charts-->
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
@ -225,6 +352,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
@ -247,7 +375,7 @@
|
||||
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
datasets: [{
|
||||
label: 'Total Cars Sold',
|
||||
data: [2, 3, 10, 4, 30, 12, 8, 9, 20, 12, 15, 35],
|
||||
data: {{monthly_cars_sold_json|safe}},
|
||||
backgroundColor: primaryColor,
|
||||
borderColor: primaryColor,
|
||||
borderWidth: 1
|
||||
@ -282,7 +410,7 @@
|
||||
datasets: [
|
||||
{
|
||||
label: 'Monthly Revenue',
|
||||
data: [120000, 150000, 130000, 180000, 200000, 175000, 190000, 220000, 210000, 250000, 240000, 280000],
|
||||
data: {{monthly_revenue_json|safe}},
|
||||
borderColor: primaryColor,
|
||||
backgroundColor: 'rgba(114, 73, 182, 0.1)', // Using primaryColor with transparency
|
||||
tension: 0.4,
|
||||
@ -293,7 +421,7 @@
|
||||
},
|
||||
{
|
||||
label: 'Monthly Net Profit',
|
||||
data: [25000, 35000, 28000, 40000, 45000, 38000, 42000, 50000, 48000, 55000, 52000, 60000],
|
||||
data: {{monthly_net_profit_json|safe}},
|
||||
borderColor: successColor,
|
||||
backgroundColor: 'rgba(0, 208, 116, 0.1)', // Using successColor with transparency
|
||||
tension: 0.4,
|
||||
@ -324,7 +452,7 @@
|
||||
label += ': ';
|
||||
}
|
||||
if (context.parsed.y !== null) {
|
||||
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y);
|
||||
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'SAR' }).format(context.parsed.y);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user