update
@ -30,6 +30,7 @@ admin.site.register(models.VatRate)
|
|||||||
admin.site.register(models.Customer)
|
admin.site.register(models.Customer)
|
||||||
admin.site.register(models.Opportunity)
|
admin.site.register(models.Opportunity)
|
||||||
admin.site.register(models.Notification)
|
admin.site.register(models.Notification)
|
||||||
|
admin.site.register(models.OpportunityLog)
|
||||||
|
|
||||||
@admin.register(models.CarMake)
|
@admin.register(models.CarMake)
|
||||||
class CarMakeAdmin(admin.ModelAdmin):
|
class CarMakeAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.1.4 on 2024-12-31 15:48
|
# Generated by Django 5.1.4 on 2024-12-31 16:13
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
|||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Log',
|
name='OpportunityLog',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('action', models.CharField(choices=[('create', 'Create'), ('update', 'Update'), ('delete', 'Delete'), ('status_change', 'Status Change')], max_length=50, verbose_name='Action')),
|
('action', models.CharField(choices=[('create', 'Create'), ('update', 'Update'), ('delete', 'Delete'), ('status_change', 'Status Change')], max_length=50, verbose_name='Action')),
|
||||||
18
inventory/migrations/0022_alter_customer_is_lead.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.4 on 2024-12-31 21:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0021_opportunitylog'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customer',
|
||||||
|
name='is_lead',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is Lead'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# Generated by Django 5.1.4 on 2024-12-31 15:49
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('inventory', '0021_log'),
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameModel(
|
|
||||||
old_name='Log',
|
|
||||||
new_name='OportunityLog',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.4 on 2025-01-01 01:24
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0022_alter_customer_is_lead'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='opportunitylog',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='opportunitylog',
|
||||||
|
name='staff',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.staff', verbose_name='Staff'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -260,6 +260,11 @@ class Car(models.Model):
|
|||||||
active_reservations = self.reservations.filter(reserved_until__gt=now())
|
active_reservations = self.reservations.filter(reserved_until__gt=now())
|
||||||
return active_reservations.exists()
|
return active_reservations.exists()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_car_group(self):
|
||||||
|
return f"{self.id_car_make.get_local_name} {self.id_car_model.get_local_name}"
|
||||||
|
|
||||||
|
|
||||||
# class CarData(models.Model):
|
# class CarData(models.Model):
|
||||||
# vin = models.CharField(max_length=17, unique=True, verbose_name=_("VIN"))
|
# vin = models.CharField(max_length=17, unique=True, verbose_name=_("VIN"))
|
||||||
# make = models.CharField(max_length=255, verbose_name=_("Make"))
|
# make = models.CharField(max_length=255, verbose_name=_("Make"))
|
||||||
@ -623,7 +628,7 @@ class Staff(models.Model, LocalizedNameMixin):
|
|||||||
permissions = []
|
permissions = []
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name} - {self.dealer}"
|
return f"{self.name} - {self.get_staff_type_display()}"
|
||||||
|
|
||||||
|
|
||||||
# Vendor Model
|
# Vendor Model
|
||||||
@ -677,7 +682,7 @@ class Customer(models.Model):
|
|||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||||
is_lead = models.BooleanField(default=True, verbose_name=_("Is Lead"))
|
is_lead = models.BooleanField(default=False, verbose_name=_("Is Lead"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Customer")
|
verbose_name = _("Customer")
|
||||||
@ -753,10 +758,10 @@ class ActionChoices(models.TextChoices):
|
|||||||
STATUS_CHANGE = "status_change", _("Status Change")
|
STATUS_CHANGE = "status_change", _("Status Change")
|
||||||
|
|
||||||
|
|
||||||
class OportunityLog(models.Model):
|
class OpportunityLog(models.Model):
|
||||||
opportunity = models.ForeignKey(Opportunity, on_delete=models.CASCADE, related_name="logs")
|
opportunity = models.ForeignKey(Opportunity, on_delete=models.CASCADE, related_name="logs")
|
||||||
action = models.CharField(max_length=50, choices=ActionChoices.choices, verbose_name=_("Action"))
|
action = models.CharField(max_length=50, choices=ActionChoices.choices, verbose_name=_("Action"))
|
||||||
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name=_("User"))
|
staff = models.ForeignKey(Staff, on_delete=models.SET_NULL, null=True, verbose_name=_("Staff"))
|
||||||
old_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("Old Status"))
|
old_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("Old Status"))
|
||||||
new_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("New Status"))
|
new_status = models.CharField(max_length=50, choices=DealStatus.choices, null=True, blank=True, verbose_name=_("New Status"))
|
||||||
details = models.TextField(blank=True, null=True, verbose_name=_("Details"))
|
details = models.TextField(blank=True, null=True, verbose_name=_("Details"))
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
from django_ledger.models import EntityModel,AccountModel,ItemModel,ItemModelAbstract,UnitOfMeasureModel, VendorModel
|
from django_ledger.models import EntityModel,AccountModel,ItemModel,ItemModelAbstract,UnitOfMeasureModel, VendorModel
|
||||||
from . import models
|
from . import models
|
||||||
|
from .models import OpportunityLog
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@ -342,3 +343,35 @@ def notify_staff_on_deal_status_change(sender, instance, **kwargs):
|
|||||||
message = f"Deal '{instance.deal_name}' status changed from {previous.deal_status} to {instance.deal_status}."
|
message = f"Deal '{instance.deal_name}' status changed from {previous.deal_status} to {instance.deal_status}."
|
||||||
models.Notification.objects.create(staff=instance.created_by, message=message)
|
models.Notification.objects.create(staff=instance.created_by, message=message)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=models.Opportunity)
|
||||||
|
def log_opportunity_creation(sender, instance, created, **kwargs):
|
||||||
|
if created:
|
||||||
|
models.OpportunityLog.objects.create(
|
||||||
|
opportunity=instance,
|
||||||
|
action='create',
|
||||||
|
user=instance.created_by,
|
||||||
|
details=f"Opportunity '{instance.deal_name}' was created."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_save, sender=models.Opportunity)
|
||||||
|
def log_opportunity_update(sender, instance, **kwargs):
|
||||||
|
if instance.pk:
|
||||||
|
previous = models.Opportunity.objects.get(pk=instance.pk)
|
||||||
|
if previous.deal_status != instance.deal_status:
|
||||||
|
models.OpportunityLog.objects.create(
|
||||||
|
opportunity=instance,
|
||||||
|
action='status_change',
|
||||||
|
user=instance.created_by,
|
||||||
|
old_status=previous.deal_status,
|
||||||
|
new_status=instance.deal_status,
|
||||||
|
details=f"Status changed from {previous.deal_status} to {instance.deal_status}."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
models.OpportunityLog.objects.create(
|
||||||
|
opportunity=instance,
|
||||||
|
action='update',
|
||||||
|
user=instance.created_by,
|
||||||
|
details=f"Opportunity '{instance.deal_name}' was updated."
|
||||||
|
)
|
||||||
@ -27,7 +27,6 @@ urlpatterns = [
|
|||||||
path('login/code/', allauth_views.RequestLoginCodeView.as_view(template_name='account/request_login_code.html')),
|
path('login/code/', allauth_views.RequestLoginCodeView.as_view(template_name='account/request_login_code.html')),
|
||||||
#Dashboards
|
#Dashboards
|
||||||
path('dashboards/accounting/', views.AccountingDashboard.as_view(), name='accounting'),
|
path('dashboards/accounting/', views.AccountingDashboard.as_view(), name='accounting'),
|
||||||
path('dashboards/crm/', views.notifications_view, name='staff_dashboard'),
|
|
||||||
|
|
||||||
# Dealer URLs
|
# Dealer URLs
|
||||||
path('dealers/<int:pk>/', views.DealerDetailView.as_view(), name='dealer_detail'),
|
path('dealers/<int:pk>/', views.DealerDetailView.as_view(), name='dealer_detail'),
|
||||||
@ -48,7 +47,9 @@ urlpatterns = [
|
|||||||
path('opportunities/<int:pk>/edit/', views.OpportunityUpdateView.as_view(), name='update_opportunity'),
|
path('opportunities/<int:pk>/edit/', views.OpportunityUpdateView.as_view(), name='update_opportunity'),
|
||||||
path('opportunities/', views.OpportunityListView.as_view(), name='opportunity_list'),
|
path('opportunities/', views.OpportunityListView.as_view(), name='opportunity_list'),
|
||||||
path('opportunities/<int:pk>/delete/', views.delete_opportunity, name='delete_opportunity'),
|
path('opportunities/<int:pk>/delete/', views.delete_opportunity, name='delete_opportunity'),
|
||||||
|
path('opportunities/<int:pk>/logs/', views.OpportunityLogsView.as_view(), name='opportunity_logs'),
|
||||||
path('notifications/', views.NotificationListView.as_view(), name='notifications_history'),
|
path('notifications/', views.NotificationListView.as_view(), name='notifications_history'),
|
||||||
|
path('fetch_notifications/', views.fetch_notifications, name='fetch_notifications'),
|
||||||
path('notifications/<int:pk>/mark_as_read/', views.mark_notification_as_read, name='mark_notification_as_read'),
|
path('notifications/<int:pk>/mark_as_read/', views.mark_notification_as_read, name='mark_notification_as_read'),
|
||||||
|
|
||||||
#Vendor URLs
|
#Vendor URLs
|
||||||
|
|||||||
@ -674,8 +674,10 @@ class CustomerListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
|
if self.request.user.is_staff:
|
||||||
|
dealer = self.request.user.staff.dealer
|
||||||
customers = models.Customer.objects.filter(
|
customers = models.Customer.objects.filter(
|
||||||
dealer=self.request.user.dealer
|
dealer=dealer,
|
||||||
)
|
)
|
||||||
|
|
||||||
if query:
|
if query:
|
||||||
@ -2059,9 +2061,19 @@ def delete_opportunity(request, pk):
|
|||||||
return redirect("opportunity_list")
|
return redirect("opportunity_list")
|
||||||
|
|
||||||
|
|
||||||
def notifications_view(request):
|
class OpportunityLogsView(LoginRequiredMixin, ListView):
|
||||||
notifications = models.Notification.objects.filter(user=request.user, is_read=False).order_by('-created_at')
|
model = models.OpportunityLog
|
||||||
return render(request, 'notifications.html', {'notifications': notifications})
|
template_name = 'crm/opportunity_logs.html'
|
||||||
|
context_object_name = 'logs'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
opportunity_id = self.kwargs['pk']
|
||||||
|
return models.OpportunityLog.objects.filter(opportunity_id=opportunity_id).order_by('-created_at')
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['opportunity'] = models.Opportunity.objects.get(pk=self.kwargs['pk'])
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class NotificationListView(LoginRequiredMixin, ListView):
|
class NotificationListView(LoginRequiredMixin, ListView):
|
||||||
@ -2074,10 +2086,25 @@ class NotificationListView(LoginRequiredMixin, ListView):
|
|||||||
return models.Notification.objects.filter(user=self.request.user).order_by('-created_at')
|
return models.Notification.objects.filter(user=self.request.user).order_by('-created_at')
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
def mark_notification_as_read(request, pk):
|
def mark_notification_as_read(request, pk):
|
||||||
notification = get_object_or_404(models.Notification, pk=pk)
|
notification = get_object_or_404(models.Notification, pk=pk, user=request.user)
|
||||||
notification.is_read = True
|
notification.is_read = True
|
||||||
notification.save()
|
notification.save()
|
||||||
|
messages.success(request, _("Notification marked as read."))
|
||||||
return redirect('notifications_history')
|
return redirect('notifications_history')
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def fetch_notifications(request):
|
||||||
|
notifications = models.Notification.objects.filter(user=request.user, is_read=False).order_by('-created_at')
|
||||||
|
notifications_data = [
|
||||||
|
{
|
||||||
|
'id': notification.id,
|
||||||
|
'message': notification.message,
|
||||||
|
'created_at': notification.created_at.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
|
}
|
||||||
|
for notification in notifications
|
||||||
|
]
|
||||||
|
return JsonResponse({'notifications': notifications_data})
|
||||||
|
|
||||||
|
|||||||
BIN
static/.DS_Store
vendored
BIN
static/images/.DS_Store
vendored
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 3.0 KiB |
BIN
static/images/favicons/favicon2.ico
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.6 KiB |
@ -15,11 +15,209 @@ function getCookie(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getDataTableInit = () => {
|
||||||
|
const togglePaginationButtonDisable = (button, disabled) => {
|
||||||
|
button.disabled = disabled;
|
||||||
|
button.classList[disabled ? 'add' : 'remove']('disabled');
|
||||||
|
};
|
||||||
|
// Selectors
|
||||||
|
const table = document.getElementById('opportunityTable');
|
||||||
|
|
||||||
|
if (table) {
|
||||||
|
const options = {
|
||||||
|
page: 10,
|
||||||
|
pagination: {
|
||||||
|
item: "<li><button class='page' type='button'></button></li>"
|
||||||
|
},
|
||||||
|
item: values => {
|
||||||
|
const {
|
||||||
|
orderId,
|
||||||
|
id,
|
||||||
|
customer,
|
||||||
|
date,
|
||||||
|
address,
|
||||||
|
deliveryType,
|
||||||
|
status,
|
||||||
|
badge,
|
||||||
|
amount
|
||||||
|
} = values;
|
||||||
|
return `
|
||||||
|
<tr class="btn-reveal-trigger">
|
||||||
|
<td class="order py-2 ps-3 align-middle white-space-nowrap">
|
||||||
|
<a class="fw-semibold" href="https://prium.github.io/phoenix/v1.12.0/apps/e-commerce/admin/order-details.html">
|
||||||
|
${orderId}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle fw-bold">
|
||||||
|
<a class="fw-semibold text-body" href="#!">
|
||||||
|
${customer}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle">
|
||||||
|
${date}
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle white-space-nowrap">
|
||||||
|
${address}
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle white-space-nowrap">
|
||||||
|
<p class="mb-0">${deliveryType}</p>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle text-center fs-8 white-space-nowrap">
|
||||||
|
<span class="badge fs-10 badge-phoenix badge-phoenix-${badge.type}">
|
||||||
|
${status}
|
||||||
|
<span class="ms-1 ${badge.icon}" data-fa-transform="shrink-2"></span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle text-end fs-8 fw-medium">
|
||||||
|
${amount}
|
||||||
|
</td>
|
||||||
|
<td class="py-2 align-middle white-space-nowrap text-end">
|
||||||
|
<div class="dropstart position-static d-inline-block">
|
||||||
|
<button class="btn btn-link text-body btn-sm dropdown-toggle btn-reveal" type='button' id="order-dropdown-${id}" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent">
|
||||||
|
<span class="fas fa-ellipsis-h fs-9"></span>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end border py-2" aria-labelledby="order-dropdown-${id}">
|
||||||
|
<a href="#!" class="dropdown-item">View</a>
|
||||||
|
<a href="#!" class="dropdown-item">Edit</a>
|
||||||
|
<div class"dropdown-divider"></div>
|
||||||
|
<a href="#!" class="dropdown-item text-warning">Archive</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const paginationButtonNext = table.querySelector(
|
||||||
|
'[data-list-pagination="next"]'
|
||||||
|
);
|
||||||
|
const paginationButtonPrev = table.querySelector(
|
||||||
|
'[data-list-pagination="prev"]'
|
||||||
|
);
|
||||||
|
const viewAll = table.querySelector('[data-list-view="*"]');
|
||||||
|
const viewLess = table.querySelector('[data-list-view="less"]');
|
||||||
|
const listInfo = table.querySelector('[data-list-info]');
|
||||||
|
const listFilter = document.querySelector('[data-list-filter]');
|
||||||
|
|
||||||
function notify(tag,msg){
|
const orderList = new window.List(table, options, orders);
|
||||||
Toast.fire({
|
|
||||||
icon: tag,
|
// Fallback
|
||||||
titleText: msg
|
orderList.on('updated', item => {
|
||||||
|
const fallback =
|
||||||
|
table.querySelector('.fallback') ||
|
||||||
|
document.getElementById(options.fallback);
|
||||||
|
|
||||||
|
if (fallback) {
|
||||||
|
if (item.matchingItems.length === 0) {
|
||||||
|
fallback.classList.remove('d-none');
|
||||||
|
} else {
|
||||||
|
fallback.classList.add('d-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalItem = orderList.items.length;
|
||||||
|
const itemsPerPage = orderList.page;
|
||||||
|
const btnDropdownClose =
|
||||||
|
orderList.listContainer.querySelector('.btn-close');
|
||||||
|
let pageQuantity = Math.ceil(totalItem / itemsPerPage);
|
||||||
|
let numberOfcurrentItems = orderList.visibleItems.length;
|
||||||
|
let pageCount = 1;
|
||||||
|
|
||||||
|
btnDropdownClose &&
|
||||||
|
btnDropdownClose.addEventListener('search.close', () =>
|
||||||
|
orderList.fuzzySearch('')
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateListControls = () => {
|
||||||
|
listInfo &&
|
||||||
|
(listInfo.innerHTML = `${orderList.i} to ${numberOfcurrentItems} of ${totalItem}`);
|
||||||
|
paginationButtonPrev &&
|
||||||
|
togglePaginationButtonDisable(paginationButtonPrev, pageCount === 1);
|
||||||
|
paginationButtonNext &&
|
||||||
|
togglePaginationButtonDisable(
|
||||||
|
paginationButtonNext,
|
||||||
|
pageCount === pageQuantity
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pageCount > 1 && pageCount < pageQuantity) {
|
||||||
|
togglePaginationButtonDisable(paginationButtonNext, false);
|
||||||
|
togglePaginationButtonDisable(paginationButtonPrev, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateListControls();
|
||||||
|
|
||||||
|
if (paginationButtonNext) {
|
||||||
|
paginationButtonNext.addEventListener('click', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
pageCount += 1;
|
||||||
|
|
||||||
|
const nextInitialIndex = orderList.i + itemsPerPage;
|
||||||
|
nextInitialIndex <= orderList.size() &&
|
||||||
|
orderList.show(nextInitialIndex, itemsPerPage);
|
||||||
|
numberOfcurrentItems += orderList.visibleItems.length;
|
||||||
|
updateListControls();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paginationButtonPrev) {
|
||||||
|
paginationButtonPrev.addEventListener('click', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
pageCount -= 1;
|
||||||
|
|
||||||
|
numberOfcurrentItems -= orderList.visibleItems.length;
|
||||||
|
const prevItem = orderList.i - itemsPerPage;
|
||||||
|
prevItem > 0 && orderList.show(prevItem, itemsPerPage);
|
||||||
|
updateListControls();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleViewBtn = () => {
|
||||||
|
viewLess.classList.toggle('d-none');
|
||||||
|
viewAll.classList.toggle('d-none');
|
||||||
|
};
|
||||||
|
|
||||||
|
if (viewAll) {
|
||||||
|
viewAll.addEventListener('click', () => {
|
||||||
|
orderList.show(1, totalItem);
|
||||||
|
pageQuantity = 1;
|
||||||
|
pageCount = 1;
|
||||||
|
numberOfcurrentItems = totalItem;
|
||||||
|
updateListControls();
|
||||||
|
toggleViewBtn();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (viewLess) {
|
||||||
|
viewLess.addEventListener('click', () => {
|
||||||
|
orderList.show(1, itemsPerPage);
|
||||||
|
pageQuantity = Math.ceil(totalItem / itemsPerPage);
|
||||||
|
pageCount = 1;
|
||||||
|
numberOfcurrentItems = orderList.visibleItems.length;
|
||||||
|
updateListControls();
|
||||||
|
toggleViewBtn();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.pagination) {
|
||||||
|
table.querySelector('.pagination').addEventListener('click', e => {
|
||||||
|
if (e.target.classList[0] === 'page') {
|
||||||
|
pageCount = Number(e.target.innerText);
|
||||||
|
updateListControls();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.filter) {
|
||||||
|
const { key } = options.filter;
|
||||||
|
listFilter.addEventListener('change', e => {
|
||||||
|
orderList.filter(item => {
|
||||||
|
if (e.target.value === '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
.values()
|
||||||
|
[key].toLowerCase()
|
||||||
|
.includes(e.target.value.toLowerCase());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<main class="main" id="top">
|
<main class="main" id="top">
|
||||||
{% include 'messages.html' %}
|
|
||||||
{% include 'header.html' %}
|
{% include 'header.html' %}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
||||||
@ -77,6 +77,42 @@
|
|||||||
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
|
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
|
||||||
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
||||||
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% if messages %}
|
||||||
|
{% for message in messages %}
|
||||||
|
|
||||||
|
const Toast = Swal.mixin({
|
||||||
|
toast: true,
|
||||||
|
position: "top-end",
|
||||||
|
showConfirmButton: false,
|
||||||
|
timer: 2000,
|
||||||
|
timerProgressBar: false,
|
||||||
|
didOpen: (toast) => {
|
||||||
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Toast.fire({
|
||||||
|
icon: "{{ message.tags }}",
|
||||||
|
titleText: "{{ message| safe }}"
|
||||||
|
});
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
function notify(tag,msg){
|
||||||
|
Toast.fire({
|
||||||
|
icon: tag,
|
||||||
|
titleText: msg
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
35
templates/crm/opportunity_logs.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Logs for {{ opportunity.deal_name }}</h1>
|
||||||
|
<div class="table-list" id="opportunityTable">
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Old Status</th>
|
||||||
|
<th>New Status</th>
|
||||||
|
<th>Details</th>
|
||||||
|
<th>Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for log in logs %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ log.get_action_display }}</td>
|
||||||
|
<td>{{ log.user }}</td>
|
||||||
|
<td>{{ log.get_old_status_display }}</td>
|
||||||
|
<td>{{ log.get_new_status_display }}</td>
|
||||||
|
<td>{{ log.details }}</td>
|
||||||
|
<td>{{ log.created_at }}</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="6">No logs found.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
@ -6,17 +6,13 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="pt-5 pb-9">
|
<section class="pt-5 pb-9">
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
|
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
|
||||||
|
|
||||||
<div class="row g-3 justify-content-between mb-4">
|
<div class="row g-3 justify-content-between mb-4">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<div class="d-md-flex justify-content-between">
|
<div class="d-md-flex justify-content-between">
|
||||||
<div>
|
<div>
|
||||||
<a href="{% url 'customer_create' %}" class="btn btn-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a>
|
<a href="{% url 'customer_create' %}" class="btn btn-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -24,12 +20,12 @@
|
|||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="search-box me-2">
|
<div class="search-box me-2">
|
||||||
<form method="get" class="d-inline-block position-relative">
|
<form method="get" class="d-inline-block position-relative">
|
||||||
<input name="q" class="form-control search-input search" type="search" placeholder="{{ _('Enter customer name') }}" aria-label="Search" value="{{ request.GET.q }}"/>
|
<div class="input-group">
|
||||||
<span class="fas fa-search search-box-icon"></span>
|
<button type="submit" class="btn btn-phoenix-primary"><span class="fas fa-search search-box-icon"></span></button>
|
||||||
|
<input name="q" class="form-control search-input search" type="search" placeholder="{{ _('Enter customer name') }}" value="{{ request.GET.q }}"/>
|
||||||
{% if request.GET.q %}
|
{% if request.GET.q %}
|
||||||
<a href="{% url request.resolver_match.view_name %}" class="btn btn-outline-danger ms-1">
|
<a href="{% url request.resolver_match.view_name %}" class="btn btn-close"></a>
|
||||||
<i class="bi bi-x-lg"></i>
|
</div>
|
||||||
</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -43,6 +39,7 @@
|
|||||||
<table class="table fs-9 mb-0 border-top border-translucent">
|
<table class="table fs-9 mb-0 border-top border-translucent">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th></th>
|
||||||
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" data-sort="name" style="width:25%;">{{ _("Name")|capfirst }}</th>
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" data-sort="name" style="width:25%;">{{ _("Name")|capfirst }}</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="email" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="email" style="width:15%;">
|
||||||
<div class="d-inline-flex flex-center">
|
<div class="d-inline-flex flex-center">
|
||||||
@ -73,7 +70,7 @@
|
|||||||
|
|
||||||
{% for customer in customers %}
|
{% for customer in customers %}
|
||||||
<!-- Delete Modal -->
|
<!-- Delete Modal -->
|
||||||
<div class="modal fade" id="deleteModal"
|
<div class="modal fade" id="deleteModal"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
data-bs-keyboard="false"
|
data-bs-keyboard="false"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@ -105,7 +102,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||||
|
<td>
|
||||||
|
{% if customer.is_lead %}
|
||||||
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success">
|
||||||
|
<span class="badge-label">{{ _("Lead") }}</span>
|
||||||
|
<span class="ms-1" data-feather="check" style="height:13px;width:13px;"></span>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td class="name align-middle white-space-nowrap ps-0">
|
<td class="name align-middle white-space-nowrap ps-0">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div><a class="fs-8 fw-bold" href="{% url 'customer_detail' customer.id %}">{{ customer.first_name }} {{ customer.middle_name }} {{ customer.last_name }}</a>
|
<div><a class="fs-8 fw-bold" href="{% url 'customer_detail' customer.id %}">{{ customer.first_name }} {{ customer.middle_name }} {{ customer.last_name }}</a>
|
||||||
@ -123,9 +127,13 @@
|
|||||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
||||||
<div class="btn-reveal-trigger position-static">
|
<div class="btn-reveal-trigger position-static">
|
||||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
||||||
<div class="dropdown-menu dropdown-menu-end py-2"><a href="{% url 'customer_update' customer.id %}" class="dropdown-item text-success-dark">
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
{% trans "Edit" %}
|
<a href="{% url 'customer_update' customer.id %}" class="dropdown-item text-success-dark">{% trans "Edit" %}</a>
|
||||||
</a>
|
{% if customer.is_lead %}
|
||||||
|
<a href="{% url 'create_opportunity' customer.pk %}" class="dropdown-item text-warning-dark">{{_("Opportunity")}}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'create_lead' customer.pk %}" class="dropdown-item text-success-dark">{{ _("Mark as Lead")}}</a>
|
||||||
|
{% endif %}
|
||||||
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button>
|
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -52,11 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="{% url 'customer_update' customer.pk %}" class="btn btn-phoenix-warning"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a>
|
<a href="{% url 'customer_update' customer.pk %}" class="btn btn-phoenix-warning"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a>
|
||||||
{% if not customer.is_lead %}
|
|
||||||
<a href="{% url 'create_lead' customer.pk %}" class="btn btn-phoenix-success"><span class="fa-solid far fa-plus-square me-2"></span>{{ _("Mark as Lead")}}</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="{% url 'create_opportunity' customer.pk %}" class="btn btn-phoenix-primary"><span class="fa-solid far fa-plus-square me-2"></span>{{_("Opportunity")}}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<footer class="footer position-absolute">
|
<footer class="footer position-absolute">
|
||||||
<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">
|
||||||
|
|||||||
@ -1,197 +1,248 @@
|
|||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
<nav class="navbar navbar-vertical navbar-expand-lg">
|
|
||||||
<div class="collapse navbar-collapse" id="navbarVerticalCollapse">
|
|
||||||
<!-- scrollbar removed-->
|
|
||||||
<div class="navbar-vertical-content">
|
|
||||||
<ul class="navbar-nav flex-column" id="navbarVerticalNav">
|
|
||||||
<li class="nav-item">
|
|
||||||
<!-- parent pages-->
|
|
||||||
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-dashboards" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-dashboards">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span data-feather="pie-chart"></span></span><span class="nav-link-text">Dashboards</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="parent-wrapper label-1">
|
|
||||||
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-dashboards">
|
|
||||||
<li class="collapsed-nav-item-title d-none">Dashboards
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'accounting' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-text">Accounting</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#">
|
<nav class="navbar navbar-vertical navbar-expand-lg">
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-text">Inventory</span>
|
<div class="collapse navbar-collapse" id="navbarVerticalCollapse">
|
||||||
</div>
|
<!-- scrollbar removed-->
|
||||||
</a>
|
<div class="navbar-vertical-content">
|
||||||
</li>
|
<ul class="navbar-nav flex-column" id="navbarVerticalNav">
|
||||||
<li class="nav-item"><a class="nav-link" href="#">
|
<li class="nav-item">
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-text">Sales</span>
|
<!-- parent pages-->
|
||||||
</div>
|
<div class="nav-item-wrapper">
|
||||||
</a>
|
<a class="nav-link dropdown-indicator label-1" href="#nv-dashboards" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-dashboards">
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-text">Leads</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<hr class="my-0" />
|
|
||||||
<li class="nav-item">
|
|
||||||
|
|
||||||
<!-- label-->
|
|
||||||
<p class="navbar-vertical-label">Apps</p>
|
|
||||||
<hr class="navbar-vertical-line" />
|
|
||||||
<!-- parent pages-->
|
|
||||||
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-inventory" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-inventory">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="parent-wrapper label-1">
|
|
||||||
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory">
|
|
||||||
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'car_add' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add car"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'inventory_stats' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-car-side"></span></span><span class="nav-link-text">{% trans 'Cars'|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- parent pages-->
|
|
||||||
|
|
||||||
<!-- parent pages-->
|
|
||||||
|
|
||||||
<!-- parent pages-->
|
|
||||||
<div class="nav-item-wrapper"><a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div><span class="nav-link-icon"><span data-feather="shopping-cart"></span></span><span class="nav-link-text">{% trans 'sales'|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="parent-wrapper label-1">
|
|
||||||
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-sales">
|
|
||||||
<li class="collapsed-nav-item-title d-none">{% trans 'sales'|capfirst %}
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'vendor_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'vendors'|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'customer_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="users"></span></span><span class="nav-link-text">{% trans 'customers'|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'organization_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span data-feather="activity"></span></span><span class="nav-link-text">{% trans "Organizations"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'representative_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-users-cog"></span></span><span class="nav-link-text">{% trans "Representatives"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'estimate_create' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-list-ul"></span></span><span class="nav-link-text">{% trans "create quotation"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'estimate_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-clipboard-list"></span></span><span class="nav-link-text">{% trans "quotations"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-cart-plus"></span></span><span class="nav-link-text">{% trans "orders"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'invoice_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-file-invoice"></span></span><span class="nav-link-text">{% trans "invoices"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{% url 'payment_list' %}">
|
|
||||||
<div class="d-flex align-items-center"><span class="nav-link-icon"><span class="fas fa-money-check"></span></span><span class="nav-link-text">{% trans "payments"|capfirst %}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!-- more inner pages-->
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--Add Above -->
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="navbar-vertical-footer">
|
|
||||||
<button class="btn navbar-vertical-toggle border-0 fw-semibold w-100 white-space-nowrap d-flex align-items-center"><span class="uil uil-left-arrow-to-left fs-8"></span><span class="uil uil-arrow-from-right fs-8"></span><span class="navbar-vertical-footer-text ms-2">Collapsed View</span></button>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
|
|
||||||
<div class="collapse navbar-collapse justify-content-between">
|
|
||||||
<div class="navbar-logo">
|
|
||||||
|
|
||||||
<button class="btn navbar-toggler navbar-toggler-humburger-icon hover-bg-transparent" type="button" data-bs-toggle="collapse" data-bs-target="#navbarVerticalCollapse" aria-controls="navbarVerticalCollapse" aria-expanded="false" aria-label="Toggle Navigation"><span class="navbar-toggle-icon"><span class="toggle-line"></span></span></button>
|
|
||||||
<a class="navbar-brand me-1 me-sm-3" href="{% url 'landing_page' %}">
|
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img class="logo-img d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="haikal" width="27" />
|
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
|
||||||
<img class="logo-img d-light-none" src="{% static 'images/logos/logo.png' %}" alt="haikal" width="27" />
|
<span class="nav-link-icon"><span data-feather="pie-chart"></span></span><span class="nav-link-text">Dashboards</span>
|
||||||
<h5 class="logo-text ms-2 d-none d-sm-block">{% trans 'Haikal' %}</h5>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="parent-wrapper label-1">
|
||||||
|
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-dashboards">
|
||||||
|
<li class="collapsed-nav-item-title d-none">Dashboards</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'accounting' %}">
|
||||||
|
<div class="d-flex align-items-center"><span class="nav-link-text">Accounting</span></div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
<div class="d-flex align-items-center"><span class="nav-link-text">Inventory</span></div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
<div class="d-flex align-items-center"><span class="nav-link-text">Sales</span></div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
<div class="d-flex align-items-center"><span class="nav-link-text">Leads</span></div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</li>
|
||||||
|
<hr class="my-0" />
|
||||||
|
<li class="nav-item">
|
||||||
|
<!-- label-->
|
||||||
|
<p class="navbar-vertical-label">Apps</p>
|
||||||
|
<hr class="navbar-vertical-line" />
|
||||||
|
<!-- parent pages-->
|
||||||
|
<div class="nav-item-wrapper">
|
||||||
|
<a class="nav-link dropdown-indicator label-1" href="#nv-inventory" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-inventory">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="parent-wrapper label-1">
|
||||||
|
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory">
|
||||||
|
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'car_add' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add car"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'inventory_stats' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-car-side"></span></span><span class="nav-link-text">{% trans 'Cars'|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- parent pages-->
|
||||||
|
|
||||||
<ul class="navbar-nav navbar-nav-icons flex-row">
|
<!-- parent pages-->
|
||||||
<li class="nav-item">
|
|
||||||
<div class="theme-control-toggle fa-icon-wait px-2">
|
|
||||||
|
|
||||||
<input class="form-check-input ms-0 theme-control-toggle-input" type="checkbox" data-theme-control="phoenixTheme" value="dark" id="themeControlToggle" />
|
<!-- parent pages-->
|
||||||
<label class="mb-0 theme-control-toggle-label theme-control-toggle-light" for="themeControlToggle" data-bs-theme-value="light" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="Switch theme" style="height:32px;width:32px;"><span class="icon" data-feather="moon"></span></label>
|
<div class="nav-item-wrapper">
|
||||||
<label class="mb-0 theme-control-toggle-label theme-control-toggle-dark" for="themeControlToggle" data-bs-theme-value="dark" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="Switch theme" style="height:32px;width:32px;"><span class="icon" data-feather="sun"></span></label>
|
<a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales">
|
||||||
</div>
|
<div class="d-flex align-items-center">
|
||||||
</li>
|
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
|
||||||
<li class="nav-item dropdown">
|
<span class="nav-link-icon"><span data-feather="shopping-cart"></span></span><span class="nav-link-text">{% trans 'sales'|capfirst %}</span>
|
||||||
<a class="nav-link" href="#" style="min-width: 2.25rem" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="outside"><span class="d-block" style="height:20px;width:20px;"><span data-feather="bell" style="height:20px;width:20px;"></span></span></a>
|
</div>
|
||||||
|
</a>
|
||||||
{% include 'notifications.html' %}
|
<div class="parent-wrapper label-1">
|
||||||
</li>
|
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-sales">
|
||||||
<li class="nav-item dropdown">
|
<li class="collapsed-nav-item-title d-none">{% trans 'sales'|capfirst %}</li>
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside" aria-haspopup="true">
|
<li class="nav-item">
|
||||||
{% if request.LANGUAGE_CODE == 'ar' %}
|
<a class="nav-link" href="{% url 'vendor_list' %}">
|
||||||
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">اللغة</span>
|
<div class="d-flex align-items-center">
|
||||||
{% else %}
|
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'vendors'|capfirst %}</span>
|
||||||
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">Language</span>
|
</div>
|
||||||
{% endif %}
|
</a>
|
||||||
</a>
|
</li>
|
||||||
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="languageDropdown">
|
<li class="nav-item">
|
||||||
<div class="card position-relative border-0">
|
<a class="nav-link" href="{% url 'customer_list' %}">
|
||||||
<div class="card-body p-0">
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span data-feather="users"></span></span><span class="nav-link-text">{% trans 'customers'|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'organization_list' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span data-feather="activity"></span></span><span class="nav-link-text">{% trans "Organizations"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'representative_list' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-users-cog"></span></span><span class="nav-link-text">{% trans "Representatives"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'estimate_create' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-list-ul"></span></span><span class="nav-link-text">{% trans "create quotation"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'estimate_list' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-clipboard-list"></span></span><span class="nav-link-text">{% trans "quotations"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-cart-plus"></span></span><span class="nav-link-text">{% trans "orders"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'invoice_list' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-file-invoice"></span></span><span class="nav-link-text">{% trans "invoices"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'payment_list' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-money-check"></span></span><span class="nav-link-text">{% trans "payments"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<!-- more inner pages-->
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--Add Above -->
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-vertical-footer">
|
||||||
|
<button class="btn navbar-vertical-toggle border-0 fw-semibold w-100 white-space-nowrap d-flex align-items-center">
|
||||||
|
<span class="uil uil-left-arrow-to-left fs-8"></span><span class="uil uil-arrow-from-right fs-8"></span><span class="navbar-vertical-footer-text ms-2">Collapsed View</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<nav class="navbar navbar-top fixed-top navbar-expand" id="navbarDefault">
|
||||||
|
<div class="collapse navbar-collapse justify-content-between">
|
||||||
|
<div class="navbar-logo">
|
||||||
|
<button
|
||||||
|
class="btn navbar-toggler navbar-toggler-humburger-icon hover-bg-transparent"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarVerticalCollapse"
|
||||||
|
aria-controls="navbarVerticalCollapse"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle Navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggle-icon"><span class="toggle-line"></span></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand me-1 me-sm-3" href="{% url 'landing_page' %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<img class="logo-img d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="haikal" width="27" />
|
||||||
|
<img class="logo-img d-light-none" src="{% static 'images/logos/logo.png' %}" alt="haikal" width="27" />
|
||||||
|
<h5 class="logo-text ms-2 d-none d-sm-block">{% trans 'Haikal' %}</h5>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="navbar-nav navbar-nav-icons flex-row">
|
||||||
|
<li class="nav-item">
|
||||||
|
<div class="theme-control-toggle fa-icon-wait px-2">
|
||||||
|
<input class="form-check-input ms-0 theme-control-toggle-input" type="checkbox" data-theme-control="phoenixTheme" value="dark" id="themeControlToggle" />
|
||||||
|
<label
|
||||||
|
class="mb-0 theme-control-toggle-label theme-control-toggle-light"
|
||||||
|
for="themeControlToggle"
|
||||||
|
data-bs-theme-value="light"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="left"
|
||||||
|
data-bs-title="Switch theme"
|
||||||
|
style="height: 32px; width: 32px;"
|
||||||
|
>
|
||||||
|
<span class="icon" data-feather="moon"></span>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
class="mb-0 theme-control-toggle-label theme-control-toggle-dark"
|
||||||
|
for="themeControlToggle"
|
||||||
|
data-bs-theme-value="dark"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="left"
|
||||||
|
data-bs-title="Switch theme"
|
||||||
|
style="height: 32px; width: 32px;"
|
||||||
|
>
|
||||||
|
<span class="icon" data-feather="sun"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link" href="#" style="min-width: 2.25rem;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="outside">
|
||||||
|
<span class="d-block" style="height: 20px; width: 20px;"><span data-feather="bell" style="height: 20px; width: 20px;"></span></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside" aria-haspopup="true">
|
||||||
|
{% if request.LANGUAGE_CODE == 'ar' %}
|
||||||
|
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">اللغة</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="me-1 text-body" data-feather="globe"></span><span class="ms-1">Language</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="languageDropdown">
|
||||||
|
<div class="card position-relative border-0">
|
||||||
|
<div class="card-body p-0">
|
||||||
<ul class="nav d-flex flex-column mb-2 pb-1">
|
<ul class="nav d-flex flex-column mb-2 pb-1">
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=en">English</a>
|
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=en">English</a>
|
||||||
@ -200,58 +251,82 @@
|
|||||||
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=ar">العربية</a>
|
<a class="dropdown-item fw-lighter" href="{% url 'switch_language' %}?language=ar">العربية</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% if user.is_authenticated and user.dealer or user.staff%}
|
|
||||||
<li class="nav-item dropdown"><a class="nav-link lh-1 pe-0" id="navbarDropdownUser" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<div class="avatar avatar-l ">
|
|
||||||
{% if user.dealer.logo %}
|
|
||||||
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="navbarDropdownUser">
|
|
||||||
<div class="card position-relative border-0">
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<div class="text-center pt-4 pb-3">
|
|
||||||
<div class="avatar avatar-xl ">
|
|
||||||
{% if user.dealer.logo %}
|
|
||||||
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overflow-auto scrollbar" style="height: 10rem;">
|
|
||||||
<ul class="nav d-flex flex-column mb-2 pb-1">
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'dealer_detail' user.dealer.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff") }}</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activity") }}</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>Settings & Privacy </a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>Help Center</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> Language</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer p-0 border-top border-translucent">
|
|
||||||
<ul class="nav d-flex flex-column my-3">
|
|
||||||
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="user-plus"></span>Add another account</a></li>
|
|
||||||
</ul>
|
|
||||||
<hr />
|
|
||||||
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_logout' %}"> <span class="me-2" data-feather="log-out"> </span>{% trans 'Sign Out' %}</a></div>
|
|
||||||
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary"><a class="text-body-quaternary me-1" href="#!">Privacy policy</a>•<a class="text-body-quaternary mx-1" href="#!">Terms</a>•<a class="text-body-quaternary ms-1" href="#!">Cookies</a></div>
|
|
||||||
{% else %}
|
|
||||||
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_login' %}"> <span class="me-2" data-feather="log-in"> </span>{% trans 'Sign In' %}</a></div>
|
|
||||||
<div class="px-3"> <a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_signup' %}"> <span class="me-2" data-feather="user-plus"> </span>{% trans 'Sign Up' %}</a></div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</li>
|
||||||
|
{% if user.is_authenticated and user.dealer or user.staff %}
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link lh-1 pe-0" id="navbarDropdownUser" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<div class="avatar avatar-l">
|
||||||
|
{% if user.dealer.logo %}
|
||||||
|
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end navbar-dropdown-caret py-0 dropdown-profile shadow border" aria-labelledby="navbarDropdownUser">
|
||||||
|
<div class="card position-relative border-0">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="text-center pt-4 pb-3">
|
||||||
|
<div class="avatar avatar-xl">
|
||||||
|
{% if user.dealer.logo %}
|
||||||
|
<img class="rounded-circle" src="{{ user.dealer.logo.url }}" alt="" />
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-auto scrollbar" style="height: 10rem;">
|
||||||
|
<ul class="nav d-flex flex-column mb-2 pb-1">
|
||||||
|
{% if user.dealer %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="{% url 'dealer_detail' user.dealer.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="{% url 'user_detail' user.staff.pk %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff") }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activity") }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>Settings & Privacy </a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="help-circle"></span>Help Center</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item"><a class="nav-link px-3 d-block" href="#!"> Language</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer p-0 border-top border-translucent">
|
||||||
|
<ul class="nav d-flex flex-column my-3">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link px-3 d-block" href="#!"> <span class="me-2 text-body align-bottom" data-feather="user-plus"></span>Add another account</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr />
|
||||||
|
<div class="px-3">
|
||||||
|
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_logout' %}"> <span class="me-2" data-feather="log-out"> </span>{% trans 'Sign Out' %}</a>
|
||||||
|
</div>
|
||||||
|
<div class="my-2 text-center fw-bold fs-10 text-body-quaternary">
|
||||||
|
<a class="text-body-quaternary me-1" href="#!">Privacy policy</a>•<a class="text-body-quaternary mx-1" href="#!">Terms</a>•<a class="text-body-quaternary ms-1" href="#!">Cookies</a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="px-3">
|
||||||
|
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_login' %}"> <span class="me-2" data-feather="log-in"> </span>{% trans 'Sign In' %}</a>
|
||||||
|
</div>
|
||||||
|
<div class="px-3">
|
||||||
|
<a class="btn btn-phoenix-secondary d-flex flex-center w-100" href="{% url 'account_signup' %}"> <span class="me-2" data-feather="user-plus"> </span>{% trans 'Sign Up' %}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: #000;
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -43,15 +43,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-danger"
|
class="btn btn-sm btn-phoenix-danger"
|
||||||
data-bs-dismiss="modal">
|
data-bs-dismiss="modal">
|
||||||
{% trans 'No' %}
|
{% trans 'No' %}
|
||||||
</button>
|
</button>
|
||||||
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
|
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<button type="submit" class="btn btn-success btn-sm">{% trans "Yes" %}</button>
|
<button type="submit" class="btn btn-phoenix-success btn-sm">{% trans "Yes" %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<div id="specificationsContent"></div>
|
<div id="specificationsContent"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-outline-primary" type="button" data-bs-dismiss="modal">{% trans 'Close' %}</button>
|
<button class="btn btn-phoenix-primary" type="button" data-bs-dismiss="modal">{% trans 'Close' %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -85,91 +85,79 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="card rounded shadow d-flex align-content-center">
|
<div class="card rounded shadow d-flex align-content-center">
|
||||||
<div class="card overflow-hidden m-3 " style="max-width:25rem;">
|
<p class="card-header rounded-top fw-bold">{% trans 'Car Details' %}</p>
|
||||||
<img class="card-img-top shadow-info" src="{% static 'images/generic/2022-lincoln-corsair.jpg' %}" alt="...">
|
|
||||||
<div class="card-img-overlay d-flex align-items-end">
|
|
||||||
<div>
|
|
||||||
<h4 class="card-title">{{ car.year }} - {{ car.id_car_make.get_local_name }}</h4>
|
|
||||||
<p class="card-text">{{ car.id_car_model.get_local_name }} - {{ car.id_car_serie.name }} - {{ car.id_car_trim.name }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table fs-9 mb-0">
|
<table class="table fs-9 mb-0">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "VIN" %}</th>
|
<th>{% trans "VIN" %}</th>
|
||||||
<td>{{ car.vin }}</td>
|
<td>{{ car.vin }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "year" %}</th>
|
<th>{% trans "year"|capfirst %}</th>
|
||||||
<td>{{ car.year }}</td>
|
<td>{{ car.year }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "make" %}</th>
|
<th>{% trans "make"|capfirst %}</th>
|
||||||
<td>{{ car.id_car_make.get_local_name }}</td>
|
<td>{{ car.id_car_make.get_local_name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "model" %}</th>
|
<th>{% trans "model"|capfirst %}</th>
|
||||||
<td>{{ car.id_car_model.get_local_name }}</td>
|
<td>{{ car.id_car_model.get_local_name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "series" %}</th>
|
<th>{% trans "series"|capfirst %}</th>
|
||||||
<td>{{ car.id_car_serie.name }}</td>
|
<td>{{ car.id_car_serie.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "trim" %}</th>
|
<th>{% trans "trim"|capfirst %}</th>
|
||||||
<td>{{ car.id_car_trim.name }}</td>
|
<td>{{ car.id_car_trim.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Status" %}</th>
|
<th>{% trans "Status"|capfirst %}</th>
|
||||||
<td>{{ car.get_status_display }}</td>
|
<td>{{ car.get_status_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Stock Type" %}</th>
|
<th>{% trans "Stock Type"|capfirst %}</th>
|
||||||
<td>{{ car.get_stock_type_display }}</td>
|
<td>{{ car.get_stock_type_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Mileage" %}</th>
|
<th>{% trans "Mileage"|capfirst %}</th>
|
||||||
<td>{{ car.mileage }}</td>
|
<td>{{ car.mileage }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Receiving Date" %}</th>
|
<th>{% trans "Receiving Date"|capfirst %}</th>
|
||||||
<td>{{ car.receiving_date|timesince }}</td>
|
<td>{{ car.receiving_date|timesince }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if car.branch %}
|
{% if car.vendor %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Branch" %}</th>
|
<th>{% trans "Vendor"|capfirst %}</th>
|
||||||
<td>{{ car.branch.get_local_name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %} {% if car.vendor %}
|
|
||||||
<tr>
|
|
||||||
<th>{% trans "Vendor" %}</th>
|
|
||||||
<td>{{ car.vendor.get_local_name }}</td>
|
<td>{{ car.vendor.get_local_name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Remarks" %}</th>
|
<th>{% trans "Remarks"|capfirst %}</th>
|
||||||
<td>{{ car.remarks }}</td>
|
<td>{{ car.remarks }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans 'specifications' %}</th>
|
<th>{% trans 'specifications'|capfirst %}</th>
|
||||||
<td>
|
<td>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-phoenix-primary btn-sm"
|
||||||
id="specification-btn"
|
id="specification-btn"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#specificationsModal">
|
data-bs-target="#specificationsModal">
|
||||||
{% trans 'view' %}
|
{% trans 'view'|capfirst %}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if car.custom_cards %}
|
{% if car.custom_cards %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Custom Number" %}</th>
|
<th>{% trans "Custom Number"|capfirst %}</th>
|
||||||
<td>{{ car.custom_cards.custom_number }}</td>
|
<td>{{ car.custom_cards.custom_number }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Custom Date" %}</th>
|
<th>{% trans "Custom Date"|capfirst %}</th>
|
||||||
<td>{{ car.custom_cards.custom_date|date }}</td>
|
<td>{{ car.custom_cards.custom_date|date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -177,7 +165,7 @@
|
|||||||
<th>{% trans "Custom Card" %}</th>
|
<th>{% trans "Custom Card" %}</th>
|
||||||
<td>
|
<td>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-success"
|
class="btn btn-sm btn-phoenix-success"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#customCardModal">
|
data-bs-target="#customCardModal">
|
||||||
{% trans 'Add' %}
|
{% trans 'Add' %}
|
||||||
@ -186,7 +174,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans 'Showroom Location' %}</th>
|
<th>{% trans 'Location'|capfirst %}</th>
|
||||||
<td>
|
<td>
|
||||||
{% if car.location %}
|
{% if car.location %}
|
||||||
{% if car.location.is_owner_showroom %}
|
{% if car.location.is_owner_showroom %}
|
||||||
@ -195,20 +183,21 @@
|
|||||||
{{ car.location.showroom.get_local_name }}
|
{{ car.location.showroom.get_local_name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% url 'transfer' car.location.pk %}"
|
<a href="{% url 'transfer' car.location.pk %}"
|
||||||
class="btn btn-danger btn-sm">
|
class="btn btn-phoenix-danger btn-sm">
|
||||||
{% trans "transfer"|capfirst %}
|
{% trans "transfer"|capfirst %}
|
||||||
</a>
|
</a>
|
||||||
{% else %} {% trans "No location available." %}
|
{% else %} {% trans "No location available." %}
|
||||||
<a href="{% url 'add_car_location' car.pk %}"
|
<a href="{% url 'add_car_location' car.pk %}"
|
||||||
class="btn btn-success btn-sm ms-2">
|
class="btn btn-phoenix-success btn-sm ms-2">
|
||||||
{% trans "Add" %}
|
{% trans "Add" %}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="{% url 'car_update' car.pk %}" class="btn btn-warning btn-sm">{% trans "Edit" %}</a>
|
<a href="{% url 'car_update' car.pk %}" class="btn btn-phoenix-warning btn-sm mt-1">{% trans "Edit" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -217,28 +206,28 @@
|
|||||||
<div class="col-lg-6 col-xl-6">
|
<div class="col-lg-6 col-xl-6">
|
||||||
<div class="card rounded shadow">
|
<div class="card rounded shadow">
|
||||||
<p class="card-header rounded-top fw-bold">{% trans 'Financial Details' %}</p>
|
<p class="card-header rounded-top fw-bold">{% trans 'Financial Details' %}</p>
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
{% if car.finances %}
|
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
{% if car.finances %}
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table fs-9 mb-0">
|
<table class="table fs-9 mb-0">
|
||||||
{% if perms.inventory.view_carfinance %}
|
{% if perms.inventory.view_carfinance %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Cost Price" %}</th>
|
<th>{% trans "Cost Price"|capfirst %}</th>
|
||||||
<td>{{ car.finances.cost_price }}</td>
|
<td>{{ car.finances.cost_price }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Selling Price" %}</th>
|
<th>{% trans "Selling Price"|capfirst %}</th>
|
||||||
<td>{{ car.finances.selling_price }}</td>
|
<td>{{ car.finances.selling_price }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Discount Amount" %}</th>
|
<th>{% trans "Discount Amount"|capfirst %}</th>
|
||||||
<td>{{ car.finances.discount_amount }} -</td>
|
<td>{{ car.finances.discount_amount }} -</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Additional Fee" %}</th>
|
<th>{% trans "Additional Fee"|capfirst %}</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if car.finances.additional_services.first.pk %}
|
{% if car.finances.additional_services.first.pk %}
|
||||||
@ -250,37 +239,39 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "VAT Amount" %}</th>
|
<th>{% trans "VAT Amount"|capfirst %}</th>
|
||||||
<td>{{ car.finances.vat_amount }}</td>
|
<td>{{ car.finances.vat_amount }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Total" %}</th>
|
<th>{% trans "Total"|capfirst %}</th>
|
||||||
<td>{{ car.finances.total }}</td>
|
<td>{{ car.finances.total }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{% if perms.inventory.change_carfinance %}
|
{% if perms.inventory.change_carfinance %}
|
||||||
<a href="{% url 'car_finance_update' car.finances.pk %}"
|
<a href="{% url 'car_finance_update' car.finances.pk %}"
|
||||||
class="btn btn-warning btn-sm mb-3">
|
class="btn btn-phoenix-warning btn-sm mb-3">
|
||||||
{% trans "Edit Finance Details" %}
|
{% trans "Edit" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>{% trans "No finance details available." %}</p>
|
<p>{% trans "No finance details available." %}</p>
|
||||||
<a href="{% url 'car_finance_create' car.pk %}"
|
<a href="{% url 'car_finance_create' car.pk %}"
|
||||||
class="btn btn-success btn-sm mb-3">
|
class="btn btn-phoenix-success btn-sm mb-3">
|
||||||
{% trans "Add Finance Details" %}
|
{% trans "Add" %}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card rounded shadow mt-3">
|
<div class="card rounded shadow mt-3">
|
||||||
<p class="card-header rounded-top fw-bold">{% trans 'Colors Details' %}</p>
|
<p class="card-header rounded-top fw-bold">{% trans 'Colors Details' %}</p>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table fs-9 mb-0">
|
<table class="table fs-9 mb-0">
|
||||||
<tbody class="align-middle">
|
<tbody class="align-middle">
|
||||||
{% if car.colors.exists %}
|
{% if car.colors.exists %}
|
||||||
@ -307,7 +298,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
@ -316,8 +307,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<a href="{% url 'add_color' car.pk %}" class="btn btn-success btn-sm">
|
<a href="{% url 'add_color' car.pk %}" class="btn btn-phoenix-success btn-sm">
|
||||||
{% trans "Get Colors" %}
|
{% trans "Add" %}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -325,11 +316,13 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card rounded shadow mt-3">
|
<div class="card rounded shadow mt-3">
|
||||||
<p class="card-header rounded-top fw-bold">{% trans 'Reservations Details' %}</p>
|
<p class="card-header rounded-top fw-bold">{% trans 'Reservations Details' %}</p>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
{% if car.is_reserved %}
|
{% if car.is_reserved %}
|
||||||
<table class="table fs-9 mb-0">
|
<table class="table fs-9 mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
@ -351,13 +344,13 @@
|
|||||||
<button type="submit"
|
<button type="submit"
|
||||||
name="action"
|
name="action"
|
||||||
value="renew"
|
value="renew"
|
||||||
class="btn btn-sm btn-success">
|
class="btn btn-sm btn-phoenix-success">
|
||||||
{% trans "Renew" %}
|
{% trans "Renew" %}
|
||||||
</button>
|
</button>
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
name="action"
|
name="action"
|
||||||
value="cancel"
|
value="cancel"
|
||||||
class="btn btn-sm btn-secondary">
|
class="btn btn-sm btn-phoenix-secondary">
|
||||||
{% trans "Cancel" %}
|
{% trans "Cancel" %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@ -374,7 +367,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-success"
|
class="btn btn-sm btn-phoenix-success"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#reserveModal">
|
data-bs-target="#reserveModal">
|
||||||
{% trans 'Reserve' %}
|
{% trans 'Reserve' %}
|
||||||
@ -384,6 +377,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="table-responsive">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -409,7 +403,7 @@
|
|||||||
return cookieValue;
|
return cookieValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const csrfToken = getCookie("csrftoken");
|
|
||||||
const ajaxUrl = "{% url 'ajax_handler' %}";
|
const ajaxUrl = "{% url 'ajax_handler' %}";
|
||||||
|
|
||||||
const modal = document.getElementById("customCardModal");
|
const modal = document.getElementById("customCardModal");
|
||||||
@ -442,7 +436,7 @@
|
|||||||
fetch(`${ajaxUrl}?action=get_specifications&trim_id={{ car.id_car_trim.id_car_trim }}`, {
|
fetch(`${ajaxUrl}?action=get_specifications&trim_id={{ car.id_car_trim.id_car_trim }}`, {
|
||||||
headers: {
|
headers: {
|
||||||
"X-Requested-With": "XMLHttpRequest",
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
"X-CSRFToken": csrfToken,
|
"X-CSRFToken": {% csrf_token %},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
@ -478,7 +472,7 @@
|
|||||||
const response = await fetch(`{% url 'reserve_car' car.pk %}`, {
|
const response = await fetch(`{% url 'reserve_car' car.pk %}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"X-CSRFToken": csrfToken,
|
"X-CSRFToken": {% csrf_token %},
|
||||||
"X-Requested-With": "XMLHttpRequest",
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n %}
|
{% load i18n static%}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans 'inventory'|capfirst %}
|
{% trans 'inventory'|capfirst %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -20,9 +20,39 @@
|
|||||||
</style>
|
</style>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row g-3 justify-content-between mb-4">
|
<div class="row g-3 justify-content-between mb-4">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<!---->
|
||||||
|
<div class="card border h-100 w-100 overflow-hidden">
|
||||||
|
<div class="bg-holder d-block bg-card" style="background-image:url({% static 'images/spot-illustrations/32.png' %});background-position: top right;">
|
||||||
|
</div>
|
||||||
|
<!--/.bg-holder-->
|
||||||
|
|
||||||
|
<div class="d-dark-none">
|
||||||
|
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/dark_21.png' %});background-position: bottom right; background-size: auto;">
|
||||||
|
</div>
|
||||||
|
<!--/.bg-holder-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="d-light-none">
|
||||||
|
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/21.png' %});background-position: bottom right; background-size: auto;">
|
||||||
|
</div>
|
||||||
|
<!--/.bg-holder-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="card-body px-5 position-relative">
|
||||||
|
<div class="badge badge-phoenix fs-10 badge-phoenix-warning mb-2">{{ _("Year") }}<span class="ms-1 fw-bold">{{ cars.first.year }}</span></div>
|
||||||
|
<h3 class="mb-2">{{ cars.first.id_car_make.get_local_name }}<span class="ms-2 text-body-tertiary fw-semibold">{{ cars.first.id_car_model.get_local_name }}</span></h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer border-0 py-0 px-5 z-1">
|
||||||
|
<p class="text-body-tertiary fw-semibold">{{ cars.first.id_car_serie.name }}, <span class="fs-10">{{ cars.first.id_car_trim.name }}</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-3 justify-content-between mb-4">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="table-responsive scrollbar mx-n1 px-1">
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
|
||||||
<table class="table fs-9 mb-0 leads-table border-top border-translucent">
|
<table class="table fs-9 mb-0 leads-table border-top border-translucent">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -67,7 +97,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'car_detail' car.pk %}" class="btn btn-success">
|
<a href="{% url 'car_detail' car.pk %}" class="btn btn-success">
|
||||||
{% trans "view" %}
|
{% trans "view"|capfirst %}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
<script>
|
|
||||||
|
|
||||||
{% if messages %}
|
|
||||||
{% for message in messages %}
|
|
||||||
|
|
||||||
const Toast = Swal.mixin({
|
|
||||||
toast: true,
|
|
||||||
position: "top-end",
|
|
||||||
showConfirmButton: false,
|
|
||||||
timer: 2000,
|
|
||||||
timerProgressBar: true,
|
|
||||||
didOpen: (toast) => {
|
|
||||||
toast.onmouseenter = Swal.stopTimer;
|
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Toast.fire({
|
|
||||||
icon: "{{ message.tags }}",
|
|
||||||
titleText: "{{ message| safe }}"
|
|
||||||
});
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@ -9,33 +9,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="scrollbar-overlay" style="height: 27rem;">
|
<div class="scrollbar-overlay" style="height: 27rem;">
|
||||||
|
|
||||||
{% for notification in notifications %}
|
|
||||||
{% if not notification.is_read %}
|
|
||||||
<div class="px-2 px-sm-3 py-3 notification-card position-relative border-bottom">
|
<div class="px-2 px-sm-3 py-3 notification-card position-relative border-bottom">
|
||||||
<div class="d-flex align-items-center justify-content-between position-relative">
|
<div class="d-flex align-items-center justify-content-between position-relative">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
|
|
||||||
<div class="flex-1 me-sm-3">
|
<div class="flex-1 me-sm-3">
|
||||||
<h4 class="fs-9 text-body-emphasis">{{ _("System") }}</h4>
|
<h4 class="fs-9 text-body-emphasis">{{ _("System") }}</h4>
|
||||||
<p class="fs-9 text-body-highlight mb-2 mb-sm-3 fw-normal"><span class='me-1 fs-10'><span class=""></span></span>{{ notification.message }}<span class="ms-2 text-body-quaternary text-opacity-75 fw-bold fs-10">{{ notification.created_at|timesince }}</span></p>
|
<ul id="notification-list">
|
||||||
<p class="text-body-secondary fs-9 mb-0"><span class="me-1 far fa-clock"></span>{{ notification.created_at }}</p>
|
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown notification-dropdown">
|
<div class="dropdown notification-dropdown">
|
||||||
<button class="btn fs-10 btn-sm dropdown-toggle dropdown-caret-none transition-none" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10 text-body"></span></button>
|
<button class="btn fs-10 btn-sm dropdown-toggle dropdown-caret-none transition-none" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10 text-body"></span></button>
|
||||||
<div class="dropdown-menu py-2"><a class="dropdown-item" href="{% url 'mark_notification_as_read' notification.pk %}">Mark as Read</a></div>
|
<div class="dropdown-menu py-2"><a class="dropdown-item">Mark as Read</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
{% empty %}
|
|
||||||
<p>No new notifications.</p>
|
|
||||||
{% endfor %}
|
|
||||||
</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"><a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history</a></div>
|
<div class="my-2 text-center fw-bold fs-10 text-body-tertiary text-opactity-85"><a class="fw-bolder" href="{% url 'notifications_history' %}">Notification history</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h2 class="mb-5">{{ _("Notifications") }}</h2>
|
<h2 class="mb-5">{{ _("Notifications") }}</h2>
|
||||||
|
|
||||||
{% 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">
|
||||||
{% for notification in notifications %}
|
{% for notification in notifications %}
|
||||||
@ -47,5 +48,8 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<p>No notifications found.</p>
|
<p>No notifications found.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||