Compare commits

...

4 Commits

18 changed files with 183 additions and 120 deletions

View File

@ -144,11 +144,10 @@ class StaffForm(forms.ModelForm):
queryset=CustomGroup.objects.all(),
required=True,
)
name = forms.CharField(
label=_("Full Name"))
class Meta:
model = Staff
fields = ["first_name","last_name","name", "arabic_name", "phone_number", "address", "logo", "group"]
fields = ["first_name","last_name", "arabic_name", "phone_number", "address", "logo", "group"]
# Dealer Form

View File

@ -594,7 +594,7 @@ class AdditionalServices(models.Model, LocalizedNameMixin):
if self.taxable
else self.price
)
@property
def service_tax(self):
vat = VatRate.objects.filter(dealer=self.dealer, is_active=True).first()
@ -896,18 +896,18 @@ class Car(Base):
def vat_amount(self):
vat = VatRate.objects.filter(dealer=self.dealer,is_active=True).first()
return Decimal(self.final_price) * (vat.rate)
@property
def total_services_and_car_vat(self):
return self.vat_amount+self.get_additional_services()['services_vat']
@property
def final_price_plus_vat(self):
return Decimal(self.final_price) + Decimal(self.vat_amount)
@property
def final_price_plus_services_plus_vat(self):
return Decimal(self.final_price_plus_vat) + Decimal(self.get_additional_services()['total_']) #total services with vat and car_sell price with vat
return Decimal(self.final_price_plus_vat) + Decimal(self.get_additional_services()['total_']) #total services with vat and car_sell price with vat
# to be used after invoice is created
@property
def invoice(self):
@ -929,8 +929,8 @@ class Car(Base):
except ExtraInfo.DoesNotExist:
return Decimal(0)
# def get_discount_amount(self,estimate,user):
# try:
# instance = models.ExtraInfo.objects.get(
@ -1419,7 +1419,7 @@ class StaffTypes(models.TextChoices):
# AGENT = "agent", _("Agent")
class Staff(models.Model, LocalizedNameMixin):
class Staff(models.Model):
# staff_member = models.OneToOneField(
# StaffMember, on_delete=models.CASCADE, related_name="staff"
# )
@ -1429,7 +1429,7 @@ class Staff(models.Model, LocalizedNameMixin):
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="staff")
first_name = models.CharField(max_length=255, verbose_name=_("First Name"))
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
name = models.CharField(max_length=255, verbose_name=_("Name"))
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
staff_type = models.CharField(
@ -1456,7 +1456,7 @@ class Staff(models.Model, LocalizedNameMixin):
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(f"{self.name}")
base_slug = slugify(f"{self.first_name}-{self.last_name}")
self.slug = base_slug
counter = 1
@ -1471,6 +1471,9 @@ class Staff(models.Model, LocalizedNameMixin):
objects = StaffUserManager()
@property
def fullname(self):
return self.first_name + " " + self.last_name
def deactivate_account(self):
self.active = False
self.user.is_active = False
@ -1530,7 +1533,6 @@ class Staff(models.Model, LocalizedNameMixin):
verbose_name = _("Staff")
verbose_name_plural = _("Staff")
indexes = [
models.Index(fields=["name"]),
models.Index(fields=["staff_type"]),
]
permissions = []
@ -1542,7 +1544,7 @@ class Staff(models.Model, LocalizedNameMixin):
]
def __str__(self):
return f"{self.name}"
return f"{self.first_name} {self.last_name}"
class Sources(models.TextChoices):

View File

@ -458,7 +458,7 @@ def general_dashboard(request,dealer_slug):
total_vat_collected_from_cars = cars_sold_filtered.aggregate(
total=Sum(F('selling_price') * VAT_RATE)
)['total'] or 0
net_profit_from_cars = total_revenue_from_cars - total_cost_of_cars_sold
total_discount = cars_sold_filtered.aggregate(total=Sum('discount_amount'))['total'] or 0
@ -519,7 +519,7 @@ def general_dashboard(request,dealer_slug):
monthly_cars_sold_json = json.dumps(monthly_cars_sold)
monthly_revenue_json = json.dumps(monthly_revenue)
monthly_net_profit_json = json.dumps(monthly_net_profit)
# ----------------------------------------------------
# Sales by MAKE
# ----------------------------------------------------
@ -529,9 +529,9 @@ def general_dashboard(request,dealer_slug):
sales_by_make_labels = [data['id_car_make__name'] for data in sales_by_make_data]
sales_by_make_counts = [data['car_count'] for data in sales_by_make_data]
# ----------------------------------------------------
# DATA FOR CAR SALES BY MODELS (for the new interactive chart)
# ----------------------------------------------------
@ -555,15 +555,15 @@ def general_dashboard(request,dealer_slug):
# If no make is selected, pass an empty list or some default data
sales_data_by_model = []
# 1. Inventory by Make (Pie Chart)
inventory_by_make_data = active_cars.values('id_car_make__name').annotate(
car_count=Count('id_car_make__name')
).order_by('-car_count')
inventory_by_make_labels = [data['id_car_make__name'] for data in inventory_by_make_data]
inventory_by_make_counts = [data['car_count'] for data in inventory_by_make_data]
@ -582,7 +582,7 @@ def general_dashboard(request,dealer_slug):
else:
# Default data
inventory_data_by_model = []
context = {
'start_date': start_date,
'end_date': end_date,
@ -631,14 +631,14 @@ def general_dashboard(request,dealer_slug):
'monthly_revenue_json': monthly_revenue_json,
'monthly_net_profit_json': monthly_net_profit_json,
# Sales Chart Data
'sales_by_make_labels_json': json.dumps(sales_by_make_labels),
'sales_by_make_counts_json': json.dumps(sales_by_make_counts),
'all_makes_sold': all_makes_sold,
'selected_make_sales': selected_make_sales,
'sales_data_by_model_json': json.dumps(list(sales_data_by_model)),
# New Inventory Chart Data
'inventory_by_make_labels_json': json.dumps(inventory_by_make_labels),
'inventory_by_make_counts_json': json.dumps(inventory_by_make_counts),
@ -646,9 +646,9 @@ def general_dashboard(request,dealer_slug):
'selected_make_inventory': selected_make_inventory,
'inventory_data_by_model_json': json.dumps(list(inventory_data_by_model)),
}
return render(request, 'dashboards/general_dashboard.html', context)
@ -670,7 +670,7 @@ def sales_dashboard(request,dealer_slug):
else:
start_date = today_local - timedelta(days=30)
end_date = today_local
# Filter leads by date range and dealer
leads_filtered = models.Lead.objects.filter(
dealer=dealer,
@ -678,7 +678,7 @@ def sales_dashboard(request,dealer_slug):
created__date__lte=end_date
)
# ----------------------------------------------------
# 2. Lead Sources Chart Logic
# ----------------------------------------------------
@ -748,7 +748,7 @@ def aging_inventory_list_view(request, dealer_slug):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
today_local = timezone.localdate()
aging_threshold_days = 60
# Get filter parameters from the request
selected_make = request.GET.get('make')
selected_model = request.GET.get('model')
@ -762,7 +762,7 @@ def aging_inventory_list_view(request, dealer_slug):
receiving_date__date__lt=today_local - timedelta(days=aging_threshold_days)
).exclude(status='sold')
total_aging_inventory_value=aging_cars_queryset.aggregate(total=Sum('cost_price'))['total']
# Apply filters to the queryset if they exist. Chaining is fine here.
if selected_make:
aging_cars_queryset = aging_cars_queryset.filter(id_car_make__name=selected_make)
@ -774,7 +774,7 @@ def aging_inventory_list_view(request, dealer_slug):
aging_cars_queryset = aging_cars_queryset.filter(id_car_year__year=selected_year)
if selected_stock_type:
aging_cars_queryset = aging_cars_queryset.filter(stock_type=selected_stock_type)
# Get distinct values for filter dropdowns based on the initial, unfiltered aging cars queryset.
# This ensures all possible filter options are always available.
@ -782,19 +782,19 @@ def aging_inventory_list_view(request, dealer_slug):
dealer=dealer,
receiving_date__date__lt=today_local - timedelta(days=aging_threshold_days)
).exclude(status='sold')
all_makes = aging_base_queryset.values_list('id_car_make__name', flat=True).distinct().order_by('id_car_make__name')
all_models = aging_base_queryset.values_list('id_car_model__name', flat=True).distinct().order_by('id_car_model__name')
all_series = aging_base_queryset.values_list('id_car_serie__name', flat=True).distinct().order_by('id_car_serie__name')
all_stock_types = aging_base_queryset.values_list('stock_type', flat=True).distinct().order_by('stock_type')
all_years = aging_base_queryset.values_list('year', flat=True).distinct().order_by('-year')
#
# Set up pagination
paginator = Paginator(aging_cars_queryset, 10)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
# Iterate only on the cars for the current page to add the age attribute.
for car in page_obj.object_list:
car.age_in_days = (today_local - car.receiving_date.date()).days
@ -803,7 +803,7 @@ def aging_inventory_list_view(request, dealer_slug):
"is_paginated": page_obj.has_other_pages,
"cars": page_obj.object_list,
'selected_make': selected_make,
'selected_model': selected_model,
'selected_model': selected_model,
'selected_series': selected_series, # Corrected variable name
'selected_year': selected_year,
'selected_stock_type': selected_stock_type,
@ -813,9 +813,9 @@ def aging_inventory_list_view(request, dealer_slug):
'all_stock_types': all_stock_types,
'all_years': all_years,
'total_aging_inventory_value':total_aging_inventory_value
}
return render(request, 'dashboards/aging_inventory_list.html', context)
def terms_and_privacy(request):
@ -2813,12 +2813,15 @@ def vendorDetailView(request, dealer_slug, slug):
"""
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
vendor = get_object_or_404(models.Vendor, slug=slug,dealer=dealer)
cars=vendor.cars.all()
total_cars_from_vendor=cars.count()
vendor_makes=cars.values('id_car_make__name').annotate(make_count=Count('id_car_make__name'))
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(
request, template_name="vendors/view_vendor.html", context={"vendor": vendor,"vendor_bills":page_obj}
request, template_name="vendors/view_vendor.html", context={"vendor": vendor,"vendor_bills":page_obj,"total_cars_from_vendor":total_cars_from_vendor,"vendor_makes":vendor_makes}
)
@ -3720,7 +3723,7 @@ class UserUpdateView(
staff = form.save(commit=False)
print(form.cleaned_data)
staff.name = form.cleaned_data["name"]
# staff.name = form.cleaned_data["name"]
staff.arabic_name = form.cleaned_data["arabic_name"]
staff.phone_number = form.cleaned_data["phone_number"]
for customgroup in form.cleaned_data["group"]:
@ -5027,7 +5030,7 @@ class EstimateDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
# calculator = CarFinanceCalculator(estimate)
# finance_data = calculator.get_finance_data()
finance_data = get_finance_data(estimate,dealer)
invoice_obj = InvoiceModel.objects.all().filter(ce_model=estimate).first()
kwargs["data"] = finance_data
@ -5036,7 +5039,7 @@ class EstimateDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
car = estimate.get_itemtxs_data()[0].first().item_model.car
selected_items = car.additional_services.filter(dealer=dealer)
form = forms.AdditionalFinancesForm()
form.fields["additional_finances"].queryset = form.fields["additional_finances"].queryset.filter(dealer=dealer) #
form.fields["additional_finances"].queryset = form.fields["additional_finances"].queryset.filter(dealer=dealer) #
form.initial["additional_finances"] = selected_items
kwargs["additionals_form"] = form
except Exception as e:
@ -7046,7 +7049,7 @@ def send_lead_email(request, dealer_slug, slug, email_pk=None):
تحياتي،
{lead.dealer.arabic_name}
{lead.dealer.address}
{lead.dealer.phone_number}
{lead.dealer.phone_number}
-----
Dear {lead.full_name},
@ -11065,7 +11068,7 @@ def purchase_report_csv_export(request,dealer_slug):
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')
@ -11089,8 +11092,8 @@ def car_sale_report_view(request, dealer_slug):
# # Calculate summary data for the filtered results
total_cars_sold=cars_sold.count()
total_revenue_from_cars = sum([ car.final_price for car in cars_sold])
total_vat_on_cars=sum([car.vat_amount for car in cars_sold])
total_revenue_from_cars = sum([ car.final_price for car in cars_sold])
total_vat_on_cars=sum([car.vat_amount for car in cars_sold])
total_revenue_from_additonals=sum([car.get_additional_services()['total'] for car in cars_sold])
total_vat_from_additonals=sum([car.get_additional_services()['services_vat'] for car in cars_sold])
@ -11104,11 +11107,11 @@ def car_sale_report_view(request, dealer_slug):
base_sold_cars_queryset = models.Car.objects.filter(dealer=dealer, status='sold')
makes =base_sold_cars_queryset.values_list('id_car_make__name', flat=True).distinct()
models_qs =base_sold_cars_queryset.values_list('id_car_model__name', flat=True).distinct()
series =base_sold_cars_queryset.values_list('id_car_serie__name', flat=True).distinct()
stock_types=base_sold_cars_queryset.values_list('stock_type', flat=True).distinct()
years = base_sold_cars_queryset.values_list('year', flat=True).distinct().order_by('-year')
context = {
'cars_sold': cars_sold,
'total_cars_sold':total_cars_sold,
@ -11182,7 +11185,7 @@ def car_sale_report_csv_export(request, dealer_slug):
additional_services = car.get_additional_services()
services_total_price = additional_services['total']
services_vat_amount = additional_services['services_vat']
# Checking for the invoice number to avoid errors on cars without one
invoice_number = None
sold_date = None

View File

@ -20,8 +20,12 @@
<h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Cash Account' %}:
<a href="{% url 'account_detail' request.dealer.slug bill.cash_account.uuid %}"
{% if bill.cash_account %}
<a href="{% url 'account_detail' request.dealer.slug bill.cash_account.coa_model.pk bill.cash_account.uuid %}"
class="text-decoration-none ms-1">{{ bill.cash_account.code }}</a>
{% else %}
{{ bill.cash_account.code }}
{% endif %}
</h6>
<h4 class="mb-0" id="djl-bill-detail-amount-paid">
{% currency_symbol %}{{ bill.get_amount_cash | absolute | currency_format }}
@ -33,10 +37,14 @@
<h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Prepaid Account' %}:
<a href="{% url 'account_detail' request.dealer.slug bill.prepaid_account.uuid %}"
{% if bill.prepaid_account %}
<a href="{% url 'account_detail' request.dealer.slug bill.prepaid_account.coa_model.pk bill.prepaid_account.uuid %}"
class="text-decoration-none ms-1">
{{ bill.prepaid_account.code }}
</a>
{% else %}
{{ bill.prepaid_account.code }}
{% endif %}
</h6>
<h4 class="text-success mb-0" id="djl-bill-detail-amount-prepaid">
{% currency_symbol %}{{ bill.get_amount_prepaid | currency_format }}
@ -47,10 +55,14 @@
<h6 class="text-uppercase text-xs text-muted mb-2">
{% trans 'Accounts Payable' %}:
<a href="{% url 'account_detail' request.dealer.slug bill.unearned_account.uuid %}"
class="text-decoration-none ms-1">
{{ bill.unearned_account.code }}
</a>
{% if bill.unearned_account %}
<a href="{% url 'account_detail' request.dealer.slug bill.unearned_account.coa_model.pk bill.unearned_account.uuid %}"
class="text-decoration-none ms-1">
{{ bill.unearned_account.code }}
</a>
{% else %}
{{ bill.unearned_account.code }}
{% endif %}
</h6>
<h4 class="text-danger mb-0" id="djl-bill-detail-amount-unearned">
{% currency_symbol %}{{ bill.get_amount_unearned | currency_format }}

View File

@ -39,9 +39,9 @@
</div>
<div class="d-grid gap-2 mt-4">
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
<a href="{% url 'coa-list' request.dealer.slug request.entity.slug %}" class="btn btn-outline-dark">
<div class="d-flex justify-content-center gap-2 mt-4">
<button type="submit" class="btn btn-phoenix-primary">Submit</button>
<a href="{% url 'coa-list' request.dealer.slug request.entity.slug %}" class="btn btn-phoenix-secondary">
{% trans 'Back' %}
</a>
</div>

View File

@ -9,18 +9,18 @@
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="display-4 mb-0">Chart of Accounts</h1>
<a href="{% url 'coa-create' request.dealer.slug request.entity.slug %}" class="btn btn-success btn-lg">
{% icon 'carbon:add-alt' 24 %} Add New
<h1 class="display-4 mb-0">{% trans "Chart of Accounts" %}</h1>
<a href="{% url 'coa-create' request.dealer.slug request.entity.slug %}" class="btn btn-phoenix-primary">
<i class="fa-solid fa-plus"></i> {% trans "Add New" %}
</a>
</div>
{% if not inactive %}
<a class="btn btn-warning mb-4" href="{% url 'coa-list-inactive' request.dealer.slug request.entity.slug %}">
<a class="btn btn-phoenix-warning mb-4" href="{% url 'coa-list-inactive' request.dealer.slug request.entity.slug %}">
{% trans 'Show Inactive' %}
</a>
{% else %}
<a class="btn btn-warning mb-4" href="{% url 'coa-list' request.dealer.slug request.entity.slug %}">
<a class="btn btn-phoenix-warning mb-4" href="{% url 'coa-list' request.dealer.slug request.entity.slug %}">
{% trans 'Show Active' %}
</a>
{% endif %}

View File

@ -32,13 +32,13 @@
</div>
<div class="d-grid gap-2 mt-4">
<button class="btn btn-primary" type="submit">
Update
<div class="d-flex justify-content-center gap-2 mt-4">
<button class="btn btn-phoenix-primary" type="submit">
{% trans 'Update'%}
</button>
<a class="btn btn-outline-secondary"
<a class="btn btn-phoenix-secondary"
href="{% url 'coa-list' request.dealer.slug request.entity.slug %}">
Back
{% trans 'Back'%}
</a>
</div>
</form>

View File

@ -3,33 +3,37 @@
{% now "Y" as current_year %}
<div class="card shadow-sm border-0 mb-4">
<div class="card-header {% if coa_model.is_default %}bg-success text-white{% elif not coa_model.is_active %}bg-danger text-white{% endif %} py-3">
<div class="d-flex align-items-center">
<div class="me-3">
<i class="fas fa-building fa-2x"></i>
</div>
<div class="fw-bold fs-5">
<div class="card-header {% if coa_model.is_default %}bg-gray-100{% elif not coa_model.is_active %}bg-danger text-white{% endif %} py-3 d-flex align-items-center">
<div class="me-3">
<i class="fas fa-building fa-2x"></i>
</div>
<div class="flex-grow-1">
<h5 class="fw-bold mb-0">
{{ coa_model.name }}
{% if coa_model.is_default %}
<span class="badge bg-light text-dark ms-2">{% trans 'DEFAULT' %}</span>
<span class="badge bg-light text-primary ms-2 d-none d-sm-inline">{% trans 'DEFAULT' %}</span>
{% endif %}
</div>
</h5>
{% if coa_model.is_default %}
<span class="badge bg-light text-primary mt-1 d-sm-none">{% trans 'DEFAULT' %}</span>
{% endif %}
</div>
<div class="ms-auto d-flex flex-column align-items-end">
{% if coa_model.is_active %}
<span class="badge bg-success"><i class="fas fa-check-circle"></i> {% trans 'Active' %}</span>
{% else %}
<span class="badge bg-danger"><i class="fas fa-times-circle"></i> {% trans 'Inactive' %}</span>
{% endif %}
{% if coa_model.is_default %}
<span class="badge bg-primary-subtle text-primary mt-1">{% trans 'Entity Default' %}</span>
{% endif %}
</div>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<div class="d-flex align-items-center mb-2">
<span class="fw-bold me-2">{% trans 'Entity Default' %}:</span>
{% if coa_model.is_default %}
<span class="badge bg-success"><i class="fas fa-check-circle"></i></span>
{% else %}
<span class="badge bg-danger"><i class="fas fa-times-circle"></i></span>
{% endif %}
</div>
<div class="d-flex align-items-center mb-2">
<div class="col-sm-6">
<div class="d-flex flex-wrap align-items-center mb-2">
<span class="fw-bold me-2">{% trans 'Is Active' %}:</span>
{% if coa_model.is_active %}
<span class="badge bg-success"><i class="fas fa-check-circle"></i></span>
@ -37,14 +41,13 @@
<span class="badge bg-danger"><i class="fas fa-times-circle"></i></span>
{% endif %}
</div>
<div class="mb-2">
<span class="fw-bold">CoA ID:</span>
<span class="text-muted ms-2">{{ coa_model.slug }}</span>
</div>
</div>
<div class="col-md-6">
<div class="col-sm-6">
<div class="mb-2">
<span class="fw-bold"><i class="fas fa-list-alt me-1"></i> {% trans 'Total Accounts' %}:</span>
<span class="ms-2">{{ coa_model.accountmodel_total__count }}</span>
@ -64,50 +67,50 @@
<hr class="my-3">
<div class="row">
<div class="col-md-6">
<small class="text-muted">
<div class="row g-2">
<div class="col-sm-6">
<small class="text-muted d-block">
<i class="far fa-calendar-plus me-1"></i>
<span class="fw-bold">{% trans 'Created' %}:</span>
{{ coa_model.created|date }}
<span class="d-block d-md-inline-block">{{ coa_model.created|date }}</span>
</small>
</div>
<div class="col-md-6">
<small class="text-muted">
<div class="col-sm-6">
<small class="text-muted d-block">
<i class="far fa-clock me-1"></i>
<span class="fw-bold">{% trans 'Updated' %}:</span>
{{ coa_model.created|timesince }} {% trans 'ago' %}
<span class="d-block d-md-inline-block">{{ coa_model.created|timesince }} {% trans 'ago' %}</span>
</small>
</div>
</div>
</div>
<div class="card-footer bg-transparent border-top-0">
<div class="card-footer bg-transparent border-top-0 pt-0 pt-sm-3">
<div class="d-flex flex-wrap gap-2">
<a href="{% url 'coa-update' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-outline-warning fw-bold">
<a href="{% url 'coa-update' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-phoenix-warning fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-edit me-1"></i> {% trans 'Update' %}
</a>
<a href="{% url 'account_list' request.dealer.slug coa_model.pk %}" class="btn btn-sm btn-outline-success fw-bold">
<a href="{% url 'account_list' request.dealer.slug coa_model.pk %}" class="btn btn-sm btn-phoenix-success fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-book me-1"></i> {% trans 'Accounts' %}
</a>
<a href="{% url 'account_create' request.dealer.slug coa_model.pk %}" class="btn btn-sm btn-outline-info fw-bold">
<a href="{% url 'account_create' request.dealer.slug coa_model.pk %}" class="btn btn-sm btn-phoenix-info fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-plus-circle me-1"></i> {% trans 'Add Account' %}
</a>
{% if coa_model.can_mark_as_default %}
<a href="{% url 'coa-action-mark-as-default' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-outline-danger fw-bold">
<a href="{% url 'coa-action-mark-as-default' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-phoenix-danger fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-star me-1"></i> {% trans 'Mark as Default' %}
</a>
{% endif %}
{% if coa_model.can_deactivate %}
<a href="{% url 'coa-action-mark-as-inactive' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-outline-warning fw-bold">
<a href="{% url 'coa-action-mark-as-inactive' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-phoenix-warning fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-toggle-off me-1"></i> {% trans 'Mark as Inactive' %}
</a>
{% elif coa_model.can_activate %}
<a href="{% url 'coa-action-mark-as-active' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-outline-success fw-bold">
<a href="{% url 'coa-action-mark-as-active' request.dealer.slug request.entity.slug coa_model.slug %}" class="btn btn-sm btn-phoenix-success fw-bold flex-grow-1 flex-sm-grow-0">
<i class="fas fa-toggle-on me-1"></i> {% trans 'Mark as Active' %}
</a>
{% endif %}

View File

@ -109,7 +109,7 @@
{% if lead.staff == request.staff %}
{{ _("Me") }}
{% elif LANGUAGE_CODE == "en" %}
{{ lead.staff.name|capfirst }}
{{ lead.staff.fullname|capfirst }}
{% else %}
{{ lead.staff.arabic_name }}
{% endif %}

View File

@ -199,7 +199,7 @@
{% if lead.staff == request.staff %}
{{ _("Me") }}
{% elif LANGUAGE_CODE == "en" %}
{{ lead.staff.name|capfirst }}
{{ lead.staff.fullname|capfirst }}
{% else %}
{{ lead.staff.arabic_name }}
{% endif %}

View File

@ -84,7 +84,7 @@
</div>
<div class="d-flex align-items-center">
<span class="uil uil-headphones me-2"></span>
<p class="text-body-secondary fw-bold fs-10 mb-0">{{ opportunity.staff.name }}</p>
<p class="text-body-secondary fw-bold fs-10 mb-0">{{ opportunity.staff.fullname }}</p>
</div>
</div>
<div class="collapse" id="collapseWidthDeals-1">

View File

@ -75,7 +75,7 @@
{% if request.user.email == opportunity.staff.email %}
{{ _("You") }}
{% else %}
{{ opportunity.staff.name }}
{{ opportunity.staff.fullname }}
</p>
{% endif %}
</div>

View File

@ -73,9 +73,9 @@
<td class="text-center">
{% if f.instance.bill_model %}
{% if f.instance.bill_model.is_paid %}
<span class="text-success">{% icon 'bi:check-circle-fill' 24 %}</span>
<span class="text-success">{% trans 'Yes' %}</span>
{% else %}
<span class="text-danger">{% icon 'clarity:no-access-solid' 24 %}</span>
<span class="text-danger">{% trans 'No' %}</span>
{% endif %}
{% endif %}
</td>

View File

@ -10,7 +10,7 @@
</div>
<div class="col-auto">
<a href="{% url 'staff_password_reset' request.dealer.slug staff.pk %}"
class="btn btn-phoenix-primary btn-lg shadow-sm">
class="btn btn-phoenix-danger btn-lg shadow-sm">
<i class="fas fa-key me-2"></i>{{ _("Change Password") }}
</a>
</div>

View File

@ -5,11 +5,12 @@
{{ user_.name }}
{% endblock title %}
{% block content %}
<div class="container py-4">
<div class="d-flex flex-wrap justify-content-between align-items-center mb-4">
<div class="d-flex align-items-center mb-3 mb-md-0">
<a href="{% url 'user_list' request.dealer.slug %}" class="btn btn-phoenix-secondary btn-sm me-3">
<i class="fa-regular fa-circle-left me-2"></i>{% trans "Back to Staff" %}
<i class="fa-regular fa-circle-left me-2"></i>{% trans "Back to Staffs" %}
</a>
<h1 class="h4 fw-bold mb-0">{% trans "Staff Profile" %}</h1>
</div>
@ -22,6 +23,10 @@
data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="fas fa-trash-alt me-2"></i>{% trans "Delete" %}
</button>
<a href="{% url 'staff_password_reset' request.dealer.slug user_.pk %}"
class="btn btn-phoenix-danger">
<i class="fas fa-key me-2"></i>{{ _("Change Password") }}
</a>
</div>
</div>
@ -32,12 +37,12 @@
<div class="position-relative d-inline-block mb-3">
{% if user_.logo %}
<img class="rounded-circle border border-4 border-body-tertiary"
src="{{ user_.logo.url }}" alt="{{ user_.name }}"
src="{{ user_.logo.url }}" alt="{{ user_.fullname }}"
style="object-fit: cover; width: 120px; height: 120px;">
{% else %}
<div class="rounded-circle d-inline-flex align-items-center justify-content-center bg-primary text-white border border-4 border-body-tertiary"
style="width: 120px; height: 120px; font-size: 3rem;">
{{ user_.name|first|upper }}
{{ user_.fullname|first|upper }}
</div>
{% endif %}
</div>

View File

@ -32,7 +32,6 @@
{{ redirect_field }}
{{ form.first_name|as_crispy_field }}
{{ form.last_name|as_crispy_field }}
{{ form.name|as_crispy_field }}
{{ form.arabic_name|as_crispy_field }}
{{ form.email|as_crispy_field }}
{{ form.phone_number|as_crispy_field }}

View File

@ -49,16 +49,16 @@
<img class="avatar-img rounded-circle"
src="{{ user.thumbnail.url }}"
onerror="this.src='/static/user-logo.jpg'"
alt="{{ user.name }}'s logo">
alt="{{ user.fullname }}'s logo">
{% else %}
<div class="rounded-circle bg-light d-flex justify-content-center align-items-center text-secondary" style="width: 2.5rem; height: 2.5rem; font-size: 1rem;">
{{ user.name|first|upper }}
{{ user.fullname|first|upper }}
</div>
{% endif %}
</div>
<a class="fw-bold text-decoration-none text-dark"
href="{% url 'user_detail' request.dealer.slug user.slug %}">
{{ user.name }}
{{ user.fullname }}
</a>
</div>
</td>

View File

@ -3,14 +3,17 @@
{% block title %}
{% trans "View Vendor" %}
{% endblock title %}
{% block customCSS %}
{% endblock %}
{% block content %}
<!-- Vendor Details -->
<div class="row mt-4">
<div class="card shadow rounded">
<p class="card-header mb-0 fs-5">{% trans "Vendor Details" %}</p>
<div class="card-body">
<div class="row justify-content-start">
<div class="col-6 col-sm-auto mb-sm-2">
<div class="col-md-4 col-sm-auto mb-sm-2">
<div class="avatar avatar-5xl">
{% if vendor.logo%}<img class="rounded-circle" src="{{ vendor.logo.url }}" alt="" />{% endif %}
</div>
@ -37,7 +40,7 @@
</div>
</div>
<div class="col-6 col-sm-auto mb-sm-2">
<div class="col-md-4 col-sm-auto mb-2">
<ul class="list-group list-group-flush">
<li class="list-group-item">
<strong>{% trans "Name" %}:</strong> {{ vendor.get_local_name }} </li>
@ -55,6 +58,43 @@
</li>
</ul>
</div>
<div class="col-md-4 col-sm-auto mb-sm-2">
<div class="table-responsive overflow-auto" style="max-height:250px;">
<table class="table">
<thead>
<tr>
<th scope="col">{% trans "Make" %}</th>
<th scope="col">{% trans "Total Cars Purchased" %}</th>
</tr>
</thead>
<tbody>
{% for make in vendor_makes%}
<tr>
<td class="align-middle">{{ make.id_car_make__name }}</td>
<td class="align-middle ">{{make.make_count}}</td>
</tr>
{% empty %}
<tr>
<td colspan="2" class="text-center text-muted">{% trans "There is no Purchase from this vendor yet" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
@ -86,7 +126,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center text-muted">{% trans "No Bills Found For the Vendor: {vendor.get_local_name}" %}</td>
<td colspan="6" class="text-center text-muted">{% trans "No Bills Found For the Vendor : " %}{{vendor.get_local_name}}</td>
</tr>
{% endfor %}
</tbody>