add admin management+more fixes to the overall logic + lint and formating + more
This commit is contained in:
parent
41feca462d
commit
8e6d62273d
@ -1,5 +1,3 @@
|
|||||||
import hashlib
|
|
||||||
import json
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
@ -1,17 +1,15 @@
|
|||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from rest_framework import permissions, status, viewsets, generics
|
from rest_framework import permissions, status, viewsets
|
||||||
from inventory.utils import get_user_type
|
from inventory.utils import get_user_type
|
||||||
from . import models, serializers
|
from . import models, serializers
|
||||||
from .services import get_car_data
|
from .services import get_car_data
|
||||||
from inventory import models as inventory_models
|
from inventory import models as inventory_models
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from inventory import models as inventory_models
|
from inventory.services import decodevin
|
||||||
from inventory.services import get_make, get_model, decodevin
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
|||||||
@ -7,7 +7,6 @@ from django_ledger import models as ledger_models
|
|||||||
from import_export.admin import ExportMixin
|
from import_export.admin import ExportMixin
|
||||||
from import_export.resources import ModelResource
|
from import_export.resources import ModelResource
|
||||||
|
|
||||||
from .models import Car
|
|
||||||
|
|
||||||
# # Define resource class
|
# # Define resource class
|
||||||
# class CarSerieResource(ModelResource):
|
# class CarSerieResource(ModelResource):
|
||||||
|
|||||||
@ -5,7 +5,7 @@ class InventoryConfig(AppConfig):
|
|||||||
name = 'inventory'
|
name = 'inventory'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
import inventory.signals
|
pass
|
||||||
#from decimal import Decimal
|
#from decimal import Decimal
|
||||||
#from inventory.models import VatRate
|
#from inventory.models import VatRate
|
||||||
#VatRate.objects.get_or_create(rate=Decimal('0.15'), is_active=True)
|
#VatRate.objects.get_or_create(rate=Decimal('0.15'), is_active=True)
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import re
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from luhnchecker.luhn import Luhn
|
from luhnchecker.luhn import Luhn
|
||||||
from django.core.validators import RegexValidator
|
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from appointment.models import Service
|
from appointment.models import Service
|
||||||
from phonenumber_field.formfields import PhoneNumberField
|
|
||||||
from django.core.validators import MinLengthValidator
|
from django.core.validators import MinLengthValidator
|
||||||
from django import forms
|
from django import forms
|
||||||
from plans.models import PlanPricing
|
from plans.models import PlanPricing
|
||||||
@ -17,9 +14,6 @@ from .mixins import AddClassMixin
|
|||||||
from django_ledger.forms.invoice import (
|
from django_ledger.forms.invoice import (
|
||||||
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
||||||
)
|
)
|
||||||
from django_ledger.forms.estimate import (
|
|
||||||
EstimateModelCreateForm as EstimateModelCreateFormBase,
|
|
||||||
)
|
|
||||||
|
|
||||||
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
||||||
from django_ledger.forms.journal_entry import JournalEntryModelCreateForm as JournalEntryModelCreateFormBase
|
from django_ledger.forms.journal_entry import JournalEntryModelCreateForm as JournalEntryModelCreateFormBase
|
||||||
@ -1062,6 +1056,7 @@ class LeadForm(forms.ModelForm):
|
|||||||
"crn",
|
"crn",
|
||||||
"vrn",
|
"vrn",
|
||||||
"year",
|
"year",
|
||||||
|
"salary",
|
||||||
"source",
|
"source",
|
||||||
"channel",
|
"channel",
|
||||||
"staff",
|
"staff",
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
import re
|
import re
|
||||||
from itertools import cycle
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
def vin_year(vin_char: str) -> int:
|
def vin_year(vin_char: str) -> int:
|
||||||
@ -1830,7 +1827,7 @@ def decode_vin_haikalna(vin):
|
|||||||
|
|
||||||
pattern = r"^[A-HJ-NPR-Z0-9]{17}$"
|
pattern = r"^[A-HJ-NPR-Z0-9]{17}$"
|
||||||
if not re.match(pattern, vin):
|
if not re.match(pattern, vin):
|
||||||
raise Exception(f"VIN number must only contain alphanumeric symbols except 'I', 'O', and 'Q' ")
|
raise Exception("VIN number must only contain alphanumeric symbols except 'I', 'O', and 'Q' ")
|
||||||
|
|
||||||
vin = vin.upper()
|
vin = vin.upper()
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import os
|
|
||||||
import json
|
import json
|
||||||
import pymysql
|
import pymysql
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from tqdm import tqdm # Progress bar support
|
from tqdm import tqdm # Progress bar support
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Database connection details
|
# Database connection details
|
||||||
db_config = {
|
db_config = {
|
||||||
|
|||||||
@ -11,19 +11,19 @@ class Command(BaseCommand):
|
|||||||
def handle(self, *args, **kwargs):
|
def handle(self, *args, **kwargs):
|
||||||
vin,description = self.generate_vin()
|
vin,description = self.generate_vin()
|
||||||
result = decodevin(vin)
|
result = decodevin(vin)
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'Generated VIN: {vin}'))
|
self.stdout.write(self.style.SUCCESS(f'Generated VIN: {vin}'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'Description: {description}'))
|
self.stdout.write(self.style.SUCCESS(f'Description: {description}'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'Decoded VIN: {result}'))
|
self.stdout.write(self.style.SUCCESS(f'Decoded VIN: {result}'))
|
||||||
make,model,year_model = result.values()
|
make,model,year_model = result.values()
|
||||||
self.stdout.write(self.style.SUCCESS(f'VIN: {vin} - Make {make} - Model {model} - Model Year {year_model}'))
|
self.stdout.write(self.style.SUCCESS(f'VIN: {vin} - Make {make} - Model {model} - Model Year {year_model}'))
|
||||||
m = get_model(model)
|
m = get_model(model)
|
||||||
self.stdout.write(self.style.SUCCESS(f'Make: {m.id_car_make} - Model: {m}'))
|
self.stdout.write(self.style.SUCCESS(f'Make: {m.id_car_make} - Model: {m}'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
self.stdout.write(self.style.SUCCESS(f'####################################################################################################'))
|
self.stdout.write(self.style.SUCCESS('####################################################################################################'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# management/commands/create_plans.py
|
# management/commands/create_plans.py
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from plans.models import Plan, Quota, PlanQuota, Pricing, PlanPricing
|
from plans.models import Plan, Quota, Pricing, PlanPricing
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,7 @@
|
|||||||
# management/commands/create_plans.py
|
# management/commands/create_plans.py
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import timedelta
|
|
||||||
from django.db.models import Q
|
|
||||||
from django.utils import timezone
|
|
||||||
from plans.quota import get_user_quota
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from plans.models import Plan, Quota, PlanQuota, Pricing, PlanPricing,UserPlan,Order,BillingInfo,AbstractOrder
|
from plans.models import Plan, Quota, PlanQuota, Pricing, PlanPricing
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Create basic subscription plans structure'
|
help = 'Create basic subscription plans structure'
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.mail import send_mail
|
|
||||||
from allauth.account.models import EmailConfirmation
|
|
||||||
from inventory.tasks import send_email
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
import re
|
|
||||||
from inventory.tasks import create_coa_accounts
|
from inventory.tasks import create_coa_accounts
|
||||||
from inventory.models import Dealer
|
from inventory.models import Dealer
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from django.conf import settings
|
|
||||||
from inventory import models
|
from inventory import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.shortcuts import redirect
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
|
||||||
from fpdf import FPDF
|
|
||||||
import os
|
|
||||||
|
|
||||||
from inventory.utils import get_user_type
|
from inventory.utils import get_user_type
|
||||||
|
|
||||||
@ -67,7 +61,7 @@ class InjectParamsMiddleware:
|
|||||||
try:
|
try:
|
||||||
# request.entity = request.user.dealer.entity
|
# request.entity = request.user.dealer.entity
|
||||||
request.dealer = get_user_type(request)
|
request.dealer = get_user_type(request)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
return response
|
return response
|
||||||
@ -98,7 +92,7 @@ class InjectDealerMiddleware:
|
|||||||
request.is_dealer = True
|
request.is_dealer = True
|
||||||
if hasattr(request.user, "staffmember"):
|
if hasattr(request.user, "staffmember"):
|
||||||
request.is_staff = True
|
request.is_staff = True
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
return response
|
return response
|
||||||
|
|||||||
18
inventory/migrations/0006_organization_slug.py
Normal file
18
inventory/migrations/0006_organization_slug.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-21 10:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0005_notes_dealer'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='slug',
|
||||||
|
field=models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
inventory/migrations/0007_staff_active_staff_slug.py
Normal file
23
inventory/migrations/0007_staff_active_staff_slug.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-21 13:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0006_organization_slug'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='staff',
|
||||||
|
name='active',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Active'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='staff',
|
||||||
|
name='slug',
|
||||||
|
field=models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
inventory/migrations/0008_lead_salary.py
Normal file
18
inventory/migrations/0008_lead_salary.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-21 15:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0007_staff_active_staff_slug'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='lead',
|
||||||
|
name='salary',
|
||||||
|
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Salary'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,6 +1,4 @@
|
|||||||
from django import forms
|
|
||||||
from django.utils.translation import get_language
|
from django.utils.translation import get_language
|
||||||
from django.urls import reverse, reverse_lazy
|
|
||||||
|
|
||||||
class AddClassMixin:
|
class AddClassMixin:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from django.contrib.auth.models import Permission
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
import hashlib
|
import hashlib
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
@ -23,12 +23,12 @@ from django.contrib.auth.models import Group
|
|||||||
|
|
||||||
from inventory.utils import get_user_type, to_dict
|
from inventory.utils import get_user_type, to_dict
|
||||||
from .mixins import LocalizedNameMixin
|
from .mixins import LocalizedNameMixin
|
||||||
from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel,AccountModel,EntityManagementModel
|
from django_ledger.models import EstimateModel,InvoiceModel,AccountModel,EntityManagementModel
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from appointment.models import StaffMember
|
from appointment.models import StaffMember
|
||||||
from plans.quota import get_user_quota
|
from plans.quota import get_user_quota
|
||||||
from plans.models import UserPlan,Quota,PlanQuota
|
from plans.models import UserPlan
|
||||||
# from plans.models import AbstractPlan
|
# from plans.models import AbstractPlan
|
||||||
# from simple_history.models import HistoricalRecords
|
# from simple_history.models import HistoricalRecords
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ class Car(Base):
|
|||||||
def ready(self):
|
def ready(self):
|
||||||
try:
|
try:
|
||||||
return all([self.colors ,self.finances,])
|
return all([self.colors ,self.finances,])
|
||||||
except Exception as e:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
def get_transfer(self):
|
def get_transfer(self):
|
||||||
return self.transfer_logs.filter(active=True).first()
|
return self.transfer_logs.filter(active=True).first()
|
||||||
@ -1000,11 +1000,37 @@ class Staff(models.Model, LocalizedNameMixin):
|
|||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
||||||
staff_type = models.CharField(choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type"))
|
staff_type = models.CharField(choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type"))
|
||||||
|
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
||||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||||
|
slug = models.SlugField(max_length=255, unique=True, editable=False, null=True, blank=True)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.slug:
|
||||||
|
base_slug = slugify(f"{self.name}")
|
||||||
|
self.slug = base_slug
|
||||||
|
counter = 1
|
||||||
|
|
||||||
|
while self.__class__.objects.filter(slug=self.slug).exclude(pk=self.pk).exists():
|
||||||
|
self.slug = f"{base_slug}-{counter}"
|
||||||
|
counter += 1
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
objects = StaffUserManager()
|
objects = StaffUserManager()
|
||||||
|
def deactivate_account(self):
|
||||||
|
self.active = False
|
||||||
|
self.user.is_active = False
|
||||||
|
self.user.save()
|
||||||
|
self.save()
|
||||||
|
def activate_account(self):
|
||||||
|
self.active = True
|
||||||
|
self.user.is_active = True
|
||||||
|
self.user.save()
|
||||||
|
self.save()
|
||||||
|
def permenant_delete(self):
|
||||||
|
# self.user.delete()
|
||||||
|
self.staff_member.delete()
|
||||||
|
self.delete()
|
||||||
@property
|
@property
|
||||||
def email(self):
|
def email(self):
|
||||||
return self.staff_member.user.email
|
return self.staff_member.user.email
|
||||||
@ -1256,7 +1282,17 @@ class Customer(models.Model):
|
|||||||
self.customer_model.save()
|
self.customer_model.save()
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.save()
|
self.save()
|
||||||
|
def activate_account(self):
|
||||||
|
self.active = True
|
||||||
|
self.customer_model.active = True
|
||||||
|
self.user.is_active = True
|
||||||
|
self.customer_model.save()
|
||||||
|
self.user.save()
|
||||||
|
self.save()
|
||||||
|
def permenant_delete(self):
|
||||||
|
self.customer_model.delete()
|
||||||
|
self.user.delete()
|
||||||
|
self.delete()
|
||||||
class Organization(models.Model, LocalizedNameMixin):
|
class Organization(models.Model, LocalizedNameMixin):
|
||||||
dealer = models.ForeignKey(
|
dealer = models.ForeignKey(
|
||||||
Dealer, on_delete=models.CASCADE, related_name="organizations"
|
Dealer, on_delete=models.CASCADE, related_name="organizations"
|
||||||
@ -1282,6 +1318,18 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
||||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||||
|
slug = models.SlugField(max_length=255, unique=True, editable=False, null=True, blank=True)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.slug:
|
||||||
|
base_slug = slugify(f"{self.name}")
|
||||||
|
self.slug = base_slug
|
||||||
|
counter = 1
|
||||||
|
|
||||||
|
while self.__class__.objects.filter(slug=self.slug).exclude(pk=self.pk).exists():
|
||||||
|
self.slug = f"{base_slug}-{counter}"
|
||||||
|
counter += 1
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Organization")
|
verbose_name = _("Organization")
|
||||||
@ -1348,6 +1396,17 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
self.user.save()
|
self.user.save()
|
||||||
self.customer_model.save()
|
self.customer_model.save()
|
||||||
self.save()
|
self.save()
|
||||||
|
def activate_account(self):
|
||||||
|
self.active = True
|
||||||
|
self.customer_model.active = True
|
||||||
|
self.user.is_active = True
|
||||||
|
self.customer_model.save()
|
||||||
|
self.user.save()
|
||||||
|
self.save()
|
||||||
|
def permenant_delete(self):
|
||||||
|
self.user.delete()
|
||||||
|
self.customer_model.delete()
|
||||||
|
self.delete()
|
||||||
|
|
||||||
class Representative(models.Model, LocalizedNameMixin):
|
class Representative(models.Model, LocalizedNameMixin):
|
||||||
dealer = models.ForeignKey(
|
dealer = models.ForeignKey(
|
||||||
@ -1447,7 +1506,6 @@ class Lead(models.Model):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
next_action_date = models.DateTimeField(
|
next_action_date = models.DateTimeField(
|
||||||
verbose_name=_("Next Action Date"),
|
verbose_name=_("Next Action Date"),
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -1455,6 +1513,7 @@ class Lead(models.Model):
|
|||||||
)
|
)
|
||||||
is_converted = models.BooleanField(default=False)
|
is_converted = models.BooleanField(default=False)
|
||||||
converted_at = models.DateTimeField(null=True, blank=True)
|
converted_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
salary = models.PositiveIntegerField(verbose_name=_("Salary"), blank=True, null=True)
|
||||||
created = models.DateTimeField(
|
created = models.DateTimeField(
|
||||||
auto_now_add=True, verbose_name=_("Created"), db_index=True
|
auto_now_add=True, verbose_name=_("Created"), db_index=True
|
||||||
)
|
)
|
||||||
@ -1548,7 +1607,6 @@ class Lead(models.Model):
|
|||||||
return Activity.objects.filter(dealer=self.dealer,content_type__model="lead", object_id=self.pk).order_by('-updated').first()
|
return Activity.objects.filter(dealer=self.dealer,content_type__model="lead", object_id=self.pk).order_by('-updated').first()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.status = self.get_status()
|
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
base_slug = slugify(f"{self.last_name} {self.first_name}")
|
base_slug = slugify(f"{self.last_name} {self.first_name}")
|
||||||
self.slug = base_slug
|
self.slug = base_slug
|
||||||
@ -1882,7 +1940,13 @@ class Vendor(models.Model, LocalizedNameMixin):
|
|||||||
balance_type="credit",
|
balance_type="credit",
|
||||||
active=True
|
active=True
|
||||||
)
|
)
|
||||||
|
def activate_account(self):
|
||||||
|
self.active = True
|
||||||
|
self.vendor_model.active = True
|
||||||
|
self.save()
|
||||||
|
def permenant_delete(self):
|
||||||
|
self.vendor_model.delete()
|
||||||
|
self.delete()
|
||||||
class Payment(models.Model):
|
class Payment(models.Model):
|
||||||
METHOD_CHOICES = [
|
METHOD_CHOICES = [
|
||||||
("cash", _("cash")),
|
("cash", _("cash")),
|
||||||
@ -2034,7 +2098,7 @@ class CustomGroup(models.Model):
|
|||||||
try:
|
try:
|
||||||
for perm in Permission.objects.filter(content_type__app_label="inventory"):
|
for perm in Permission.objects.filter(content_type__app_label="inventory"):
|
||||||
self.add_permission(perm)
|
self.add_permission(perm)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_default_permissions(self):
|
def set_default_permissions(self):
|
||||||
|
|||||||
@ -5,14 +5,10 @@ Services module
|
|||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django_ledger.models import EntityModel
|
|
||||||
|
|
||||||
from inventory.utils import get_jwt_token, get_user_type
|
|
||||||
from pyvin import VIN
|
from pyvin import VIN
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from openai import OpenAI
|
from .models import CarMake
|
||||||
from .models import Car,CarMake,CarModel
|
|
||||||
from inventory.haikalna import decode_vin_haikalna
|
|
||||||
|
|
||||||
|
|
||||||
def get_make(item):
|
def get_make(item):
|
||||||
|
|||||||
@ -1,33 +1,20 @@
|
|||||||
from inventory.tasks import create_coa_accounts,create_accounts_for_make,create_settings
|
from inventory.tasks import create_coa_accounts
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from decimal import Decimal
|
from django.db.models.signals import post_save, post_delete
|
||||||
from django.db.models.signals import post_save, post_delete, pre_delete, pre_save
|
|
||||||
from inventory.models import VatRate
|
|
||||||
from plans.quota import get_user_quota
|
|
||||||
from .utils import to_dict
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib.auth import get_user_model
|
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 (
|
from django_ledger.models import (
|
||||||
EntityModel,
|
EntityModel,
|
||||||
AccountModel,
|
|
||||||
ItemModel,
|
ItemModel,
|
||||||
ItemModelAbstract,
|
|
||||||
UnitOfMeasureModel,
|
|
||||||
VendorModel,
|
|
||||||
EstimateModel,
|
|
||||||
CustomerModel,
|
|
||||||
JournalEntryModel,
|
JournalEntryModel,
|
||||||
TransactionModel,
|
TransactionModel,
|
||||||
LedgerModel,
|
LedgerModel
|
||||||
BillModel,
|
|
||||||
ItemTransactionModel
|
|
||||||
)
|
)
|
||||||
from . import models
|
from . import models
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
|
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from django.conf import settings
|
|||||||
from django.utils.timesince import timesince
|
from django.utils.timesince import timesince
|
||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from .models import Car, CarFinance, ExteriorColors, InteriorColors, CarColors
|
from .models import Car
|
||||||
from .utils import get_local_name
|
from .utils import get_local_name
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
from time import sleep
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from background_task import background
|
from background_task import background
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from inventory.models import DealerSettings,CarMake,Dealer
|
from inventory.models import DealerSettings,Dealer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from django.urls import reverse
|
|||||||
from django.utils.formats import number_format
|
from django.utils.formats import number_format
|
||||||
from django_ledger.io.io_core import get_localdate,validate_activity
|
from django_ledger.io.io_core import get_localdate,validate_activity
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import get_language
|
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|||||||
@ -7,19 +7,16 @@
|
|||||||
# """
|
# """
|
||||||
|
|
||||||
from calendar import month_abbr
|
from calendar import month_abbr
|
||||||
from random import randint
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.db.models import Sum
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.formats import number_format
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
# from django_ledger import __version__
|
# from django_ledger import __version__
|
||||||
# from django_ledger.forms.app_filters import EntityFilterForm, ActivityFilterForm
|
# from django_ledger.forms.app_filters import EntityFilterForm, ActivityFilterForm
|
||||||
# from django_ledger.forms.feedback import BugReportForm, RequestNewFeatureForm
|
# from django_ledger.forms.feedback import BugReportForm, RequestNewFeatureForm
|
||||||
# from django_ledger.io import CREDIT, DEBIT, ROLES_ORDER_ALL
|
# from django_ledger.io import CREDIT, DEBIT, ROLES_ORDER_ALL
|
||||||
from django_ledger.io.io_core import validate_activity, get_localdate
|
from django_ledger.io.io_core import get_localdate
|
||||||
# from django_ledger.models import TransactionModel, BillModel, InvoiceModel, EntityUnitModel
|
# from django_ledger.models import TransactionModel, BillModel, InvoiceModel, EntityUnitModel
|
||||||
# from django_ledger.settings import (
|
# from django_ledger.settings import (
|
||||||
# DJANGO_LEDGER_FINANCIAL_ANALYSIS, DJANGO_LEDGER_CURRENCY_SYMBOL,
|
# DJANGO_LEDGER_FINANCIAL_ANALYSIS, DJANGO_LEDGER_CURRENCY_SYMBOL,
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from . import models as m
|
from . import models as m
|
||||||
from datetime import datetime
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_ledger import models as lm
|
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django_ledger.io.io_core import get_localdate
|
from django_ledger.io.io_core import get_localdate
|
||||||
|
|||||||
@ -3,7 +3,6 @@ from django.urls import path
|
|||||||
from django_tables2.export.export import TableExport
|
from django_tables2.export.export import TableExport
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
from allauth.account import views as allauth_views
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@ -395,12 +394,12 @@ path(
|
|||||||
# ),
|
# ),
|
||||||
|
|
||||||
# Users URLs
|
# Users URLs
|
||||||
path("user/create/", views.UserCreateView.as_view(), name="user_create"),
|
|
||||||
path("user/<int:pk>/update/", views.UserUpdateView.as_view(), name="user_update"),
|
|
||||||
path("user/<int:pk>/", views.UserDetailView.as_view(), name="user_detail"),
|
|
||||||
path("user/", views.UserListView.as_view(), name="user_list"),
|
path("user/", views.UserListView.as_view(), name="user_list"),
|
||||||
path("user/<int:pk>/confirm/", views.UserDeleteview, name="user_delete"),
|
path("user/create/", views.UserCreateView.as_view(), name="user_create"),
|
||||||
path("user/<int:pk>/groups/", views.UserGroupView, name="user_groups"),
|
path("user/<slug:slug>/", views.UserDetailView.as_view(), name="user_detail"),
|
||||||
|
path("user/<slug:slug>/groups/", views.UserGroupView, name="user_groups"),
|
||||||
|
path("user/<slug:slug>/update/", views.UserUpdateView.as_view(), name="user_update"),
|
||||||
|
path("user/<slug:slug>/confirm/", views.UserDeleteview, name="user_delete"),
|
||||||
# Group URLs
|
# Group URLs
|
||||||
path("group/create/", views.GroupCreateView.as_view(), name="group_create"),
|
path("group/create/", views.GroupCreateView.as_view(), name="group_create"),
|
||||||
path("group/<int:pk>/update/", views.GroupUpdateView.as_view(), name="group_update"),
|
path("group/<int:pk>/update/", views.GroupUpdateView.as_view(), name="group_update"),
|
||||||
@ -409,26 +408,26 @@ path(
|
|||||||
path("group/<int:pk>/confirm/", views.GroupDeleteview, name="group_delete"),
|
path("group/<int:pk>/confirm/", views.GroupDeleteview, name="group_delete"),
|
||||||
path("group/<int:pk>/permission/", views.GroupPermissionView, name="group_permission"),
|
path("group/<int:pk>/permission/", views.GroupPermissionView, name="group_permission"),
|
||||||
# Organization URLs
|
# Organization URLs
|
||||||
path(
|
|
||||||
"organizations/", views.OrganizationListView.as_view(), name="organization_list"
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"organizations/<int:pk>/",
|
|
||||||
views.OrganizationDetailView.as_view(),
|
|
||||||
name="organization_detail",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"organizations/create/",
|
"organizations/create/",
|
||||||
views.OrganizationCreateView.as_view(),
|
views.OrganizationCreateView.as_view(),
|
||||||
name="organization_create",
|
name="organization_create",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"organizations/<int:pk>/update/",
|
"organizations/", views.OrganizationListView.as_view(), name="organization_list"
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"organizations/<slug:slug>/",
|
||||||
|
views.OrganizationDetailView.as_view(),
|
||||||
|
name="organization_detail",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"organizations/<slug:slug>/update/",
|
||||||
views.OrganizationUpdateView.as_view(),
|
views.OrganizationUpdateView.as_view(),
|
||||||
name="organization_update",
|
name="organization_update",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"organizations/<int:pk>/delete/",
|
"organizations/<slug:slug>/delete/",
|
||||||
views.OrganizationDeleteView,
|
views.OrganizationDeleteView,
|
||||||
name="organization_delete",
|
name="organization_delete",
|
||||||
),
|
),
|
||||||
@ -802,6 +801,11 @@ path(
|
|||||||
path('entity/<slug:entity_slug>/data/pnl/',
|
path('entity/<slug:entity_slug>/data/pnl/',
|
||||||
views.PnLAPIView.as_view(),
|
views.PnLAPIView.as_view(),
|
||||||
name='entity-json-pnl'),
|
name='entity-json-pnl'),
|
||||||
|
# Admin Management...
|
||||||
|
path('management/', views.management_view, name='management'),
|
||||||
|
path('management/user_management/', views.user_management, name='user_management'),
|
||||||
|
path('management/<str:content_type>/<slug:slug>/activate_account/', views.activate_account, name='activate_account'),
|
||||||
|
path('management/<str:content_type>/<slug:slug>/permenant_delete_account/', views.permenant_delete_account, name='permenant_delete_account'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from inventory import models
|
|
||||||
from django_ledger.models.items import ItemModel
|
from django_ledger.models.items import ItemModel
|
||||||
def calculate_vat(value):
|
def calculate_vat(value):
|
||||||
"""Helper to calculate VAT dynamically for a given value."""
|
"""Helper to calculate VAT dynamically for a given value."""
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
|||||||
import pymysql
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
from vininfo.utils import merge_wmi
|
from vininfo.utils import merge_wmi
|
||||||
from vininfo.dicts import WMI
|
|
||||||
|
|
||||||
|
|
||||||
wmi_manufacturer_mapping = {
|
wmi_manufacturer_mapping = {
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
import json
|
|
||||||
import requests
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from inventory.models import PaymentHistory,Notification
|
from inventory.models import Notification
|
||||||
from plans.models import Order, PlanPricing,AbstractOrder
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
user = User.objects.first()
|
user = User.objects.first()
|
||||||
|
|||||||
@ -1,41 +1,13 @@
|
|||||||
from django_ledger.forms.account import AccountModelUpdateForm, AccountModelCreateForm
|
|
||||||
import requests
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from django.contrib.auth.models import Permission
|
|
||||||
from django.contrib.auth.models import Group
|
|
||||||
from django_ledger.models.invoice import InvoiceModel
|
|
||||||
from django_ledger.utils import accruable_net_summary
|
|
||||||
from decimal import Decimal
|
|
||||||
from django_ledger.models import (
|
from django_ledger.models import (
|
||||||
EstimateModel,
|
|
||||||
EntityModel,
|
EntityModel,
|
||||||
ItemModel,
|
|
||||||
ItemTransactionModel,
|
|
||||||
AccountModel,
|
AccountModel,
|
||||||
CustomerModel,
|
|
||||||
EntityManagementModel,
|
|
||||||
)
|
)
|
||||||
# from rich import print
|
# from rich import print
|
||||||
from datetime import date
|
|
||||||
from inventory.models import (
|
from inventory.models import (
|
||||||
Car,
|
|
||||||
Dealer,
|
|
||||||
VatRate,
|
|
||||||
Lead,
|
|
||||||
CarMake,
|
CarMake,
|
||||||
CarModel,
|
|
||||||
Schedule,
|
|
||||||
CustomGroup,
|
|
||||||
)
|
)
|
||||||
from inventory.utils import CarFinanceCalculator
|
|
||||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
|
||||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django_ledger.io.io_core import get_localdate
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from django.utils import timezone
|
|
||||||
import hashlib
|
|
||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|||||||
@ -1,23 +1,8 @@
|
|||||||
from django_ledger.forms.account import AccountModelUpdateForm,AccountModelCreateForm
|
|
||||||
import requests
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from django.contrib.auth.models import Permission
|
from django_ledger.models import EntityModel
|
||||||
from django.contrib.auth.models import Group
|
|
||||||
from django_ledger.models.invoice import InvoiceModel
|
|
||||||
from django_ledger.utils import accruable_net_summary
|
|
||||||
from decimal import Decimal
|
|
||||||
from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel,EntityManagementModel
|
|
||||||
# from rich import print
|
# from rich import print
|
||||||
from datetime import date
|
from inventory.models import CarMake
|
||||||
from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule,CustomGroup
|
|
||||||
from inventory.utils import CarFinanceCalculator
|
|
||||||
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django_ledger.io.io_core import get_localdate
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from django.utils import timezone
|
|
||||||
import hashlib
|
|
||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|||||||
@ -1,24 +1,9 @@
|
|||||||
from django_ledger.forms.account import AccountModelUpdateForm,AccountModelCreateForm
|
|
||||||
import requests
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from django.contrib.auth.models import Permission
|
|
||||||
from django.contrib.auth.models import Group
|
|
||||||
from django_ledger.models.invoice import InvoiceModel
|
from django_ledger.models.invoice import InvoiceModel
|
||||||
from django_ledger.utils import accruable_net_summary
|
|
||||||
from decimal import Decimal
|
|
||||||
from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel,EntityManagementModel
|
|
||||||
from rich import print
|
from rich import print
|
||||||
from datetime import date
|
from inventory.models import Car
|
||||||
from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule,CustomGroup
|
|
||||||
from inventory.utils import CarFinanceCalculator
|
from inventory.utils import CarFinanceCalculator
|
||||||
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django_ledger.io.io_core import get_localdate
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from django.utils import timezone
|
|
||||||
import hashlib
|
|
||||||
from django_ledger.io import roles
|
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|||||||
17
templates/admin_management/confirm_activate_account.html
Normal file
17
templates/admin_management/confirm_activate_account.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="d-flex justify-content-center align-items-center mt-10">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1>Activate Account</h1>
|
||||||
|
<p>Are you sure you want to activate this account "{{ obj.email }}"?</p>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<button class="btn btn-primary mx-2" type="submit">Activate</button>
|
||||||
|
<a class="btn btn-secondary mx-2" href="{% url 'user_management' %}">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
16
templates/admin_management/management.html
Normal file
16
templates/admin_management/management.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<h1><i class="fas fa-tools me-2"></i>Admin Management</h1>
|
||||||
|
<div class="row row-cols-1 row-cols-md-4 g-4 mt-10">
|
||||||
|
<div class="col">
|
||||||
|
<a href="{% url 'user_management' %}">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header text-center">
|
||||||
|
<h5 class="card-title">User Management</h5>
|
||||||
|
<span style="font-size: 2rem; font-weight: 500;" class="me-2"><i class="fas fa-user"></i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
18
templates/admin_management/permenant_delete_account.html
Normal file
18
templates/admin_management/permenant_delete_account.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="d-flex justify-content-center align-items-center mt-10">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Delete Account</h1>
|
||||||
|
<p class="lead">Are you sure you want to delete this account "{{ obj.email }}"? This will delete all associated information for this user.</p>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<button class="btn btn-danger mx-2" type="submit"><i class="fas fa-trash me-2"></i> Delete Permenantly</button>
|
||||||
|
<a class="btn btn-secondary mx-2" href="{% url 'user_management' %}"><i class="fas fa-ban me-2"></i>Cancel</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
243
templates/admin_management/user_management.html
Normal file
243
templates/admin_management/user_management.html
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n static humanize %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans 'User Management' %}
|
||||||
|
{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="pt-5 pb-9">
|
||||||
|
<div class="row">
|
||||||
|
<h2 class="mb-4">{% trans 'User Management' %}</h2>
|
||||||
|
<div class="row g-3 justify-content-between mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3 class="mb-3">{% trans 'Customers' %}</h3>
|
||||||
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
<table class="table table-hover fs-9 mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('First Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Last Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Email') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" style="width:15%;">{{ _('Status') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" style="width:15%;">{{ _('Created date') }}</th>
|
||||||
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col">{{ _('Actions') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list" id="leal-tables-body">
|
||||||
|
{% for customer in customers %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-0">{{ customer.first_name }}</td>
|
||||||
|
<td class="ps-0">{{ customer.last_name }}</td>
|
||||||
|
<td class="ps-0">{{ customer.email }}</td>
|
||||||
|
<td class="ps-0">
|
||||||
|
{% if customer.active %}
|
||||||
|
<span class="fas fa-check-circle text-success"></span> {{ _('Active') }}
|
||||||
|
{% else %}
|
||||||
|
<span class="fas fa-times-circle text-danger"></span> {{ _('Inactive') }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="ps-0">{{ customer.created|naturalday|capfirst }}</td>
|
||||||
|
<td class="align-middle white-space-nowrap text-end">
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
|
<a href="{% url 'activate_account' 'customer' customer.slug %}"><button class="dropdown-item">{% trans "Activate" %}</button></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a href="{% url 'permenant_delete_account' 'customer' customer.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<td colspan="6" class="text-center">{% trans 'No data available in table' %}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3 class="mb-3">{% trans 'Organizations' %}</h3>
|
||||||
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
<table class="table table-hover fs-9 mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Arabic Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Email') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" style="width:15%;">{{ _('Status') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" style="width:15%;">{{ _('Create date') }}</th>
|
||||||
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col">{{ _('Actions') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list" id="leal-tables-body">
|
||||||
|
{% for organization in organizations %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-0">{{ organization.name }}</td>
|
||||||
|
<td class="ps-0">{{ organization.arabic_name }}</td>
|
||||||
|
<td class="ps-0">{{ organization.email }}</td>
|
||||||
|
<td class="ps-0">
|
||||||
|
{% if customer.active %}
|
||||||
|
<span class="fas fa-check-circle text-success"></span> {{ _('Active') }}
|
||||||
|
{% else %}
|
||||||
|
<span class="fas fa-times-circle text-danger"></span> {{ _('Inactive') }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="ps-0">{{ organization.created|naturalday|capfirst }}</td>
|
||||||
|
<td class="align-middle white-space-nowrap text-end">
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
|
<a href="{% url 'activate_account' 'organization' organization.slug %}"><button class="dropdown-item">{% trans "Activate" %}</button></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a href="{% url 'permenant_delete_account' 'organization' organization.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<td colspan="6" class="text-center">{% trans 'No data available in table' %}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3 class="mb-3">{% trans 'Vendors' %}</h3>
|
||||||
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
<table class="table table-hover fs-9 mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Arabic Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Email') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:15%;">{{ _('Status') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" style="width:15%;">{{ _('Create date') }}</th>
|
||||||
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col">{{ _('Actions') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list" id="leal-tables-body">
|
||||||
|
{% for vendor in vendors %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-0">{{ vendor.name }}</td>
|
||||||
|
<td class="ps-0">{{ vendor.arabic_name }}</td>
|
||||||
|
<td class="ps-0">{{ vendor.email }}</td>
|
||||||
|
<td class="ps-0">
|
||||||
|
{% if customer.active %}
|
||||||
|
<span class="fas fa-check-circle text-success"></span> {{ _('Active') }}
|
||||||
|
{% else %}
|
||||||
|
<span class="fas fa-times-circle text-danger"></span> {{ _('Inactive') }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="ps-0">{{ vendor.created_at|naturalday|capfirst }}</td>
|
||||||
|
<td class="align-middle white-space-nowrap text-end">
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
|
<a href="{% url 'activate_account' 'vendor' vendor.slug %}"><button class="dropdown-item">{% trans "Activate" %}</button></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a href="{% url 'permenant_delete_account' 'vendor' vendor.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<td colspan="6" class="text-center">{% trans 'No data available in table' %}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3 class="mb-3">{% trans 'Staff' %}</h3>
|
||||||
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
<table class="table table-hover fs-9 mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Arabic Name') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:20%;">{{ _('Email') }}</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle text-uppercase ps-0" scope="col" style="width:15%;">{{ _('Status') }}</th>
|
||||||
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" style="width:15%;">{{ _('Create date') }}</th>
|
||||||
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col">{{ _('Actions') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list" id="leal-tables-body">
|
||||||
|
{% for obj in staff %}
|
||||||
|
<tr>
|
||||||
|
<td class="ps-0">{{ obj.name }}</td>
|
||||||
|
<td class="ps-0">{{ obj.arabic_name }}</td>
|
||||||
|
<td class="ps-0">{{ obj.email }}</td>
|
||||||
|
<td class="ps-0">
|
||||||
|
{% if obj.active %}
|
||||||
|
<span class="fas fa-check-circle text-success"></span> {{ _('Active') }}
|
||||||
|
{% else %}
|
||||||
|
<span class="fas fa-times-circle text-danger"></span> {{ _('Inactive') }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="ps-0">{{ obj.created|naturalday|capfirst }}</td>
|
||||||
|
<td class="align-middle white-space-nowrap text-end">
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
|
<a href="{% url 'activate_account' 'staff' obj.slug %}"><button class="dropdown-item">{% trans "Activate" %}</button></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a href="{% url 'permenant_delete_account' 'staff' obj.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<td colspan="6" class="text-center">{% trans 'No data available in table' %}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@ -130,14 +130,16 @@
|
|||||||
<h5 class="text-body-highlight mb-0 text-end">{{ _("Status")}}
|
<h5 class="text-body-highlight mb-0 text-end">{{ _("Status")}}
|
||||||
{% if lead.status == "new" %}
|
{% if lead.status == "new" %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-primary"><span class="badge-label">{{_("New")}}</span><span class="fa fa-bell ms-1"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-primary"><span class="badge-label">{{_("New")}}</span><span class="fa fa-bell ms-1"></span></span>
|
||||||
{% elif lead.status == "pending" %}
|
{% elif lead.status == "follow_up" %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-warning"><span class="badge-label">{{_("Pending")}}</span><span class="fa fa-clock-o ms-1"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-warning"><span class="badge-label">{{_("Follow Up")}}</span><span class="fa fa-clock-o ms-1"></span></span>
|
||||||
{% elif lead.status == "in_progress" %}
|
{% elif lead.status == "negotiation" %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-info"><span class="badge-label">{{_("In Progress")}}</span><span class="fa fa-wrench ms-1"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-info"><span class="badge-label">{{_("Negotiation")}}</span><span class="fa fa-wrench ms-1"></span></span>
|
||||||
{% elif lead.status == "qualified" %}
|
{% elif lead.status == "won" %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-success"><span class="badge-label">{{_("Qualified")}}</span><span class="fa fa-check ms-1"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-success"><span class="badge-label">{{_("Won")}}</span><span class="fa fa-check ms-1"></span></span>
|
||||||
{% elif lead.status == "canceled" %}
|
{% elif lead.status == "lost" %}
|
||||||
<span class="badge badge-phoenix badge-phoenix-danger"><span class="badge-label">{{_("Canceled")}}</span><span class="fa fa-times ms-1"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-danger"><span class="badge-label">{{_("Lost")}}</span><span class="fa fa-times ms-1"></span></span>
|
||||||
|
{% elif lead.status == "closed" %}
|
||||||
|
<span class="badge badge-phoenix badge-phoenix-danger"><span class="badge-label">{{_("Closed")}}</span><span class="fa fa-times ms-1"></span></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
@ -158,51 +160,51 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-envelope-alt"> </span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-envelope-alt"> </span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Email") }}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Email") }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ lead.email}}">{{ lead.email }}</a>
|
<span class="text-body-secondary">{{ lead.email }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-phone"> </span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-phone"> </span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Phone") }}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Phone") }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ lead.phone_number}}">{{ lead.phone_number}} </a>
|
<span class="text-body-secondary">{{ lead.phone_number}} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-dollar-alt"></span>
|
<div class="d-flex align-items-center mb-1"><span class="currency">{{CURRENCY}}</span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Salary")}}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Salary")}}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{lead.salary}} </p>
|
<p class="mb-0 text-body-secondary"><small><span class="currency">{{CURRENCY}}</span></small> {{lead.salary}} </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-clock"></span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-clock"></span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Created")}}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Created")}}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{ lead.created|naturalday|capfirst }}</p>
|
<span class="text-body-secondary">{{ lead.created|naturalday|capfirst }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-file-check-alt"></span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-file-check-alt"></span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Lead Source")}}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Lead Source")}}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{ lead.source|upper }}</p>
|
<span class="text-body-secondary">{{ lead.source|upper }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-file-check-alt"></span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-file-check-alt"></span>
|
||||||
<h5 class="text-body-highlight mb-0">{{ _("Lead Channel")}}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Lead Channel")}}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{ lead.channel|upper }}</p>
|
<span class="text-body-secondary">{{ lead.channel|upper }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-estate"></span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-estate"></span>
|
||||||
<h5 class="mb-0">{{ _("Address") }}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("Address") }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{ lead.address}}</p>
|
<span class="text-body-secondary">{{ lead.address}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-map"></span>
|
<div class="d-flex align-items-center mb-1"><span class="me-2 uil uil-map"></span>
|
||||||
<h5 class="mb-0 text-body-highlight">{{ _("City") }}</h5>
|
<h5 class="text-body-highlight fw-bold mb-0">{{ _("City") }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-body-secondary">{{ lead.city }}</p>
|
<span class="text-body-secondary">{{ lead.city }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -213,7 +215,7 @@
|
|||||||
<div class="col-md-7 col-lg-7 col-xl-8">
|
<div class="col-md-7 col-lg-7 col-xl-8">
|
||||||
<div class="d-flex w-100 gap-5">
|
<div class="d-flex w-100 gap-5">
|
||||||
<div class="kanban-header bg-success w-50 text-white fw-bold"><i class="fa-solid fa-circle-check me-2"></i>{{lead.status|capfirst}} <br> <small>{% trans "Current Stage" %}</small></div>
|
<div class="kanban-header bg-success w-50 text-white fw-bold"><i class="fa-solid fa-circle-check me-2"></i>{{lead.status|capfirst}} <br> <small>{% trans "Current Stage" %}</small></div>
|
||||||
<div class="kanban-header bg-secondary w-50 text-white fw-bold"><i class="fa-solid fa-circle-info me-2"></i>{{lead.next_action|capfirst}} <br> <small>{% trans "Next Action" %}</small></div>
|
<div class="kanban-header bg-secondary w-50 text-white fw-bold"><i class="fa-solid fa-circle-info me-2"></i>{{lead.next_action|capfirst}} <br> <small>{% trans "Next Action" %} :</small> <small>{{lead.next_action_date|naturalday|capfirst}}</small></div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="nav main-tab nav-underline fs-9 deal-details scrollbar flex-nowrap w-100 pb-1 mb-6 justify-content-end mt-5" id="myTab" role="tablist" style="overflow-y: hidden;">
|
<ul class="nav main-tab nav-underline fs-9 deal-details scrollbar flex-nowrap w-100 pb-1 mb-6 justify-content-end mt-5" id="myTab" role="tablist" style="overflow-y: hidden;">
|
||||||
<li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link active" id="activity-tab" data-bs-toggle="tab" href="#tab-activity" role="tab" aria-controls="tab-activity" aria-selected="false" tabindex="-1"> <span class="fa-solid fa-chart-line me-2 tab-icon-color fs-8"></span>{{ _("Activity") }}</a></li>
|
<li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link active" id="activity-tab" data-bs-toggle="tab" href="#tab-activity" role="tab" aria-controls="tab-activity" aria-selected="false" tabindex="-1"> <span class="fa-solid fa-chart-line me-2 tab-icon-color fs-8"></span>{{ _("Activity") }}</a></li>
|
||||||
@ -329,17 +331,17 @@
|
|||||||
<td class="align-middle text-end white-space-nowrap pe-0 action py-2">
|
<td class="align-middle text-end white-space-nowrap pe-0 action py-2">
|
||||||
{% if note.created_by == request.user %}
|
{% if note.created_by == request.user %}
|
||||||
<a id="updateBtn"
|
<a id="updateBtn"
|
||||||
href="#"
|
href="#"
|
||||||
onclick="updateNote(this)"
|
onclick="updateNote(this)"
|
||||||
class="btn btn-sm btn-phoenix-primary me-2"
|
class="btn btn-sm btn-phoenix-primary me-2"
|
||||||
data-pk="{{ note.pk }}"
|
data-pk="{{ note.pk }}"
|
||||||
data-note="{{ note.note|escapejs }}"
|
data-note="{{ note.note|escapejs }}"
|
||||||
data-url="{% url 'update_note' note.pk %}"
|
data-url="{% url 'update_note' note.pk %}"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#noteModal"
|
data-bs-target="#noteModal"
|
||||||
data-note-title="{{ _('Update') }}<i class='fas fa-pen-square text-primary ms-2'></i>">
|
data-note-title="{{ _('Update') }}<i class='fas fa-pen-square text-primary ms-2'></i>">
|
||||||
{{ _("Update") }}
|
{{ _("Update") }}
|
||||||
</a>
|
</a>
|
||||||
<button class="btn btn-phoenix-danger btn-sm delete-btn"
|
<button class="btn btn-phoenix-danger btn-sm delete-btn"
|
||||||
data-url="{% url 'delete_note_to_lead' note.pk %}"
|
data-url="{% url 'delete_note_to_lead' note.pk %}"
|
||||||
data-message="Are you sure you want to delete this note?"
|
data-message="Are you sure you want to delete this note?"
|
||||||
@ -582,7 +584,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- note Modal -->
|
<!-- note Modal -->
|
||||||
<div class="modal fade" id="noteModal" tabindex="-1" aria-labelledby="noteModalLabel" aria-hidden="true">
|
<div class="modal fade" id="noteModal" tabindex="-1" aria-labelledby="noteModalLabel" aria-hidden="true">
|
||||||
|
|
||||||
<div class="modal-dialog modal-md">
|
<div class="modal-dialog modal-md">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header justify-content-between align-items-start gap-5 px-4 pt-4 pb-3 border-0">
|
<div class="modal-header justify-content-between align-items-start gap-5 px-4 pt-4 pb-3 border-0">
|
||||||
@ -606,103 +607,120 @@
|
|||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
function updateNote(e) {
|
function updateNote(e) {
|
||||||
let url = e.getAttribute('data-url')
|
let url = e.getAttribute('data-url')
|
||||||
let note = e.getAttribute('data-note')
|
let note = e.getAttribute('data-note')
|
||||||
document.querySelector('#id_note').value = note
|
document.querySelector('#id_note').value = note
|
||||||
let form = document.querySelector('.add_note_form')
|
let form = document.querySelector('.add_note_form')
|
||||||
form.action = url
|
form.action = url
|
||||||
}
|
}
|
||||||
function reset_form() {
|
function reset_form() {
|
||||||
document.querySelector('#id_note').value = ""
|
document.querySelector('#id_note').value = ""
|
||||||
let form = document.querySelector('.add_note_form')
|
let form = document.querySelector('.add_note_form')
|
||||||
form.action = "{% url 'add_note' 'lead' lead.slug %}"
|
form.action = "{% url 'add_note' 'lead' lead.slug %}"
|
||||||
}
|
}
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
let Toast = Swal.mixin({
|
||||||
let Toast = Swal.mixin({
|
|
||||||
toast: true,
|
|
||||||
position: "top-end",
|
|
||||||
showConfirmButton: false,
|
|
||||||
timer: 3000,
|
|
||||||
timerProgressBar: true,
|
|
||||||
didOpen: (toast) => {
|
|
||||||
toast.onmouseenter = Swal.stopTimer;
|
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display Django messages
|
|
||||||
{% if messages %}
|
|
||||||
{% for message in messages %}
|
|
||||||
Toast.fire({
|
|
||||||
icon: "{{ message.tags }}",
|
|
||||||
titleText: "{{ message|safe }}"
|
|
||||||
});
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
function openActionModal(leadId, currentAction, nextAction, nextActionDate) {
|
|
||||||
const modal = new bootstrap.Modal(document.getElementById('actionTrackingModal'));
|
|
||||||
document.getElementById('leadId').value = leadId;
|
|
||||||
document.getElementById('currentAction').value = currentAction;
|
|
||||||
document.getElementById('nextAction').value = nextAction;
|
|
||||||
document.getElementById('nextActionDate').value = nextActionDate;
|
|
||||||
modal.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('actionTrackingForm').addEventListener('submit', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const formData = new FormData(this);
|
|
||||||
|
|
||||||
// Show loading indicator
|
|
||||||
Swal.fire({
|
|
||||||
toast: true,
|
toast: true,
|
||||||
icon: 'info',
|
|
||||||
text: 'Please wait...',
|
|
||||||
allowOutsideClick: false,
|
|
||||||
position: "top-end",
|
position: "top-end",
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
timer: 2000,
|
timer: 3000,
|
||||||
timerProgressBar: false,
|
timerProgressBar: true,
|
||||||
didOpen: (toast) => {
|
didOpen: (toast) => {
|
||||||
toast.onmouseenter = Swal.stopTimer;
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fetch("{% url 'update_lead_actions' %}", {
|
// Display Django messages
|
||||||
method: 'POST',
|
{% if messages %}
|
||||||
body: formData,
|
{% for message in messages %}
|
||||||
headers: {
|
Toast.fire({
|
||||||
'X-CSRFToken': '{{ csrf_token }}'
|
icon: "{{ message.tags }}",
|
||||||
}
|
titleText: "{{ message|safe }}"
|
||||||
})
|
});
|
||||||
.then(response => response.json())
|
{% endfor %}
|
||||||
.then(data => {
|
{% endif %}
|
||||||
Swal.close();
|
|
||||||
if (data.success) {
|
function openActionModal(leadId, currentAction, nextAction, nextActionDate) {
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('actionTrackingModal'));
|
||||||
|
document.getElementById('leadId').value = leadId;
|
||||||
|
document.getElementById('currentAction').value = currentAction;
|
||||||
|
document.getElementById('nextAction').value = nextAction;
|
||||||
|
document.getElementById('nextActionDate').value = nextActionDate;
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('actionTrackingForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData(this);
|
||||||
|
|
||||||
|
// Show loading indicator
|
||||||
|
Swal.fire({
|
||||||
|
toast: true,
|
||||||
|
icon: 'info',
|
||||||
|
text: 'Please wait...',
|
||||||
|
allowOutsideClick: false,
|
||||||
|
position: "top-end",
|
||||||
|
showConfirmButton: false,
|
||||||
|
timer: 2000,
|
||||||
|
timerProgressBar: false,
|
||||||
|
didOpen: (toast) => {
|
||||||
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch("{% url 'update_lead_actions' %}", {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
Swal.close();
|
||||||
|
if (data.success) {
|
||||||
// Success notification
|
// Success notification
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
toast: true,
|
toast: true,
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
position: "top-end",
|
position: "top-end",
|
||||||
text: data.message || 'Actions updated successfully',
|
text: data.message || 'Actions updated successfully',
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
timer: 2000,
|
timer: 2000,
|
||||||
timerProgressBar: false,
|
timerProgressBar: false,
|
||||||
didOpen: (toast) => {
|
didOpen: (toast) => {
|
||||||
toast.onmouseenter = Swal.stopTimer;
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
location.reload(); // Refresh after user clicks OK
|
location.reload(); // Refresh after user clicks OK
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Error notification
|
// Error notification
|
||||||
|
Swal.fire({
|
||||||
|
toast: true,
|
||||||
|
icon: 'error',
|
||||||
|
position: "top-end",
|
||||||
|
text: data.message || 'Failed to update actions',
|
||||||
|
showConfirmButton: false,
|
||||||
|
timer: 2000,
|
||||||
|
timerProgressBar: false,
|
||||||
|
didOpen: (toast) => {
|
||||||
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Swal.close();
|
||||||
|
console.error('Error:', error);
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
toast: true,
|
toast: true,
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
position: "top-end",
|
position: "top-end",
|
||||||
text: data.message || 'Failed to update actions',
|
text: 'An unexpected error occurred',
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
timer: 2000,
|
timer: 2000,
|
||||||
timerProgressBar: false,
|
timerProgressBar: false,
|
||||||
@ -711,34 +729,16 @@
|
|||||||
toast.onmouseleave = Swal.resumeTimer;
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
Swal.close();
|
|
||||||
console.error('Error:', error);
|
|
||||||
Swal.fire({
|
|
||||||
toast: true,
|
|
||||||
icon: 'error',
|
|
||||||
position: "top-end",
|
|
||||||
text: 'An unexpected error occurred',
|
|
||||||
showConfirmButton: false,
|
|
||||||
timer: 2000,
|
|
||||||
timerProgressBar: false,
|
|
||||||
didOpen: (toast) => {
|
|
||||||
toast.onmouseenter = Swal.stopTimer;
|
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Helper function for notifications
|
// Helper function for notifications
|
||||||
function notify(tag, msg) {
|
function notify(tag, msg) {
|
||||||
Toast.fire({
|
Toast.fire({
|
||||||
icon: tag,
|
icon: tag,
|
||||||
titleText: msg
|
titleText: msg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n static crispy_forms_filters %}
|
{% load i18n static crispy_forms_filters %}
|
||||||
{% block customcss %}
|
{% block customcss %}
|
||||||
<style>
|
<style>
|
||||||
.htmx-indicator{
|
.htmx-indicator{
|
||||||
opacity:0;
|
opacity:0;
|
||||||
transition: opacity 500ms ease-in;
|
transition: opacity 500ms ease-in;
|
||||||
}
|
}
|
||||||
.htmx-request .htmx-indicator{
|
.htmx-request .htmx-indicator{
|
||||||
opacity:1;
|
opacity:1;
|
||||||
}
|
}
|
||||||
.htmx-request.htmx-indicator{
|
.htmx-request.htmx-indicator{
|
||||||
opacity:1;
|
opacity:1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customcss %}
|
{% endblock customcss %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<h1>{% if object %}{{ _("Update") }}{% else %}{{ _("Create") }}{% endif %}</h1>
|
<h1>{% if object %}{{ _("Update") }}{% else %}{{ _("Create") }}{% endif %}</h1>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-sm-6 col-md-8">
|
<div class="col-sm-6 col-md-8">
|
||||||
|
|
||||||
<form class="form" method="post">
|
<form class="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// First, create the spinner div (or use the existing one)
|
// First, create the spinner div (or use the existing one)
|
||||||
const spinner = document.createElement('div');
|
const spinner = document.createElement('div');
|
||||||
|
|||||||
@ -182,6 +182,7 @@
|
|||||||
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="">{{ lead.email }}</a></td>
|
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="">{{ lead.email }}</a></td>
|
||||||
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="tel:{{ lead.phone_number }}">{{ lead.phone_number }}</a></td>
|
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="tel:{{ lead.phone_number }}">{{ lead.phone_number }}</a></td>
|
||||||
<td class="align-middle white-space-nowrap fw-semibold">
|
<td class="align-middle white-space-nowrap fw-semibold">
|
||||||
|
{% if request.user.staffmember.staff %}
|
||||||
<div class="accordion" id="accordionExample">
|
<div class="accordion" id="accordionExample">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="headingTwo">
|
<h2 class="accordion-header" id="headingTwo">
|
||||||
@ -221,7 +222,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle white-space-nowrap text-body-tertiary text-opacity-85 fw-semibold text-body-highlight">{{ lead.get_status|upper }}</td>
|
<td class="align-middle white-space-nowrap text-body-tertiary text-opacity-85 fw-semibold text-body-highlight">{{ lead.get_status|upper }}</td>
|
||||||
<td class="align-middle white-space-nowrap text-body-tertiary text-opacity-85 fw-semibold text-body-highlight">{{ lead.staff|upper }}</td>
|
<td class="align-middle white-space-nowrap text-body-tertiary text-opacity-85 fw-semibold text-body-highlight">{{ lead.staff|upper }}</td>
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
{% load i18n static humanize %}
|
{% load i18n static humanize %}
|
||||||
{% load custom_filters %}
|
{% load custom_filters %}
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
.bg-success-soft {
|
.bg-success-soft {
|
||||||
background-color: rgba(25, 135, 84, 0.1) !important;
|
background-color: rgba(25, 135, 84, 0.1) !important;
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
}
|
}
|
||||||
.bg-danger-soft {
|
.bg-danger-soft {
|
||||||
background-color: rgba(220, 53, 69, 0.1) !important;
|
background-color: rgba(220, 53, 69, 0.1) !important;
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
|
|
||||||
{% for opportunity in opportunities %}
|
{% for opportunity in opportunities %}
|
||||||
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
|
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
|
||||||
<div class="card h-100
|
<div class="card h-100
|
||||||
{% if opportunity.get_stage_display == 'Closed Won' %}bg-success-soft
|
{% if opportunity.get_stage_display == 'Closed Won' %}bg-success-soft
|
||||||
{% elif opportunity.get_stage_display == 'Closed Lost' %}bg-danger-soft{% endif %}">
|
{% elif opportunity.get_stage_display == 'Closed Lost' %}bg-danger-soft{% endif %}">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="mb-4">Opportunity for {{ opportunity.customer.customer_name }}</h5>
|
<h5 class="mb-4">Opportunity for {{ opportunity.customer.customer_name }}</h5>
|
||||||
|
|
||||||
@ -35,8 +35,8 @@
|
|||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-danger">{{ opportunity.get_stage_display }}</span>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-danger">{{ opportunity.get_stage_display }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="badge badge-phoenix fs-10
|
<span class="badge badge-phoenix fs-10
|
||||||
{% if opportunity.get_stage_display == 'Won' %}badge-phoenix-success
|
{% if opportunity.get_stage_display == 'Won' %}badge-phoenix-success
|
||||||
{% elif opportunity.get_stage_display == 'Lost' %}badge-phoenix-danger{% endif %}">
|
{% elif opportunity.get_stage_display == 'Lost' %}badge-phoenix-danger{% endif %}">
|
||||||
{{ opportunity.get_status_display }}
|
{{ opportunity.get_status_display }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -61,7 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<p class="fw-semibold fs-9 mb-0 text-body-emphasis"><span class="currency">{{ CURRENCY }}</span>{{ opportunity.expected_revenue }}</p>
|
<p class="fw-semibold fs-9 mb-0 text-body-emphasis"><span class="currency">{{ CURRENCY }}</span>{{ opportunity.expected_revenue }}</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
<!--<i class="bi bi-save"></i> -->
|
<!--<i class="bi bi-save"></i> -->
|
||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -6,6 +6,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<div class="row g-2 g-sm-3">
|
<div class="row g-2 g-sm-3">
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="{% url 'order_list' %}" class="btn btn-phoenix-success"><span class="fas fa-list me-2"></span>{{ _("Orders") }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="{% url 'billing_info' %}" class="btn btn-phoenix-info"><span class="fas fa-credit-card me-2"></span>{{ _("Billing Information") }}</a>
|
||||||
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="{% url 'account_change_password' %}" class="btn btn-phoenix-danger"><span class="fas fa-key me-2"></span>{{ _("Change Password") }}</a>
|
<a href="{% url 'account_change_password' %}" class="btn btn-phoenix-danger"><span class="fas fa-key me-2"></span>{{ _("Change Password") }}</a>
|
||||||
</div>
|
</div>
|
||||||
@ -108,7 +114,7 @@
|
|||||||
<a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Renew") }}</a>
|
<a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Renew") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if dealer.user.userplan.plan.name != "Enterprise" %}
|
{% if dealer.user.userplan.plan.name != "Enterprise" %}
|
||||||
<a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Upgrade") }}</a>
|
<a href="{% url 'pricing_page' %}" class="btn btn-sm btn-phoenix-primary ms-2"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="text-body-tertiary fw-semibold">You have no active plan.</span> <a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Subscribe") }}</a>
|
<span class="text-body-tertiary fw-semibold">You have no active plan.</span> <a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Subscribe") }}</a>
|
||||||
|
|||||||
@ -435,6 +435,11 @@
|
|||||||
<a class="nav-link px-3 d-block" href="{% url 'dealer_settings' request.user.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>{{ _("Settings") }}</a>
|
<a class="nav-link px-3 d-block" href="{% url 'dealer_settings' request.user.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="settings"></span>{{ _("Settings") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
{% if request.is_dealer %}
|
||||||
|
<a class="nav-link px-3 d-block" href="{% url 'management' %}"> <span class="me-2 text-body align-bottom" data-feather="shield"></span>{{ _("Admin Managemnet") }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<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>
|
<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>
|
||||||
|
|||||||
@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% comment %} <div class="row justify-content-center g-1 mt-4">
|
{% comment %} <div class="row justify-content-center g-1 mt-4">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -44,15 +44,15 @@
|
|||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
|
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
|
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
|
||||||
<!--<i class="bi bi-save"></i> -->
|
|
||||||
{{ _("Save") }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
|
<!--<i class="bi bi-save"></i> -->
|
||||||
|
{{ _("Save") }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@
|
|||||||
<button type="submit" class="btn btn-sm btn-success me-1">{% trans "Save" %}</button>
|
<button type="submit" class="btn btn-sm btn-success me-1">{% trans "Save" %}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger me-1">{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger me-1">{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i> {{ _("Save") }}</button>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i> {{ _("Save") }}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,39 +4,39 @@
|
|||||||
{% block title %}{% trans "bank account" %}{% endblock title %}
|
{% block title %}{% trans "bank account" %}{% endblock title %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<div class="card shadow rounded bg-body">
|
<div class="card shadow rounded bg-body">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<p class="mb-0">
|
<p class="mb-0">
|
||||||
{% if customer.created %}
|
{% if customer.created %}
|
||||||
<!--<i class="bi bi-pencil-square"></i>-->
|
<!--<i class="bi bi-pencil-square"></i>-->
|
||||||
{{ _("Edit Bank Account") }}
|
{{ _("Edit Bank Account") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<!--<i class="bi bi-person-plus"></i> -->
|
<!--<i class="bi bi-person-plus"></i> -->
|
||||||
{{ _("Add Bank Account") }}
|
{{ _("Add Bank Account") }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form method="post" class="form" novalidate>
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form|crispy }}
|
|
||||||
{% for error in form.errors %}
|
|
||||||
<div class="text-danger">{{ error }}</div>
|
|
||||||
{% endfor %}
|
|
||||||
<div class="d-flex justify-content-start">
|
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
|
||||||
<!--<i class="bi bi-save"></i> -->
|
|
||||||
{{ _("Save") }}
|
|
||||||
</button>
|
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div class="card-body">
|
||||||
|
<form method="post" class="form" novalidate>
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
{% for error in form.errors %}
|
||||||
|
<div class="text-danger">{{ error }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="d-flex justify-content-start">
|
||||||
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
|
<!--<i class="bi bi-save"></i> -->
|
||||||
|
{{ _("Save") }}
|
||||||
|
</button>
|
||||||
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -43,14 +43,14 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
<div class="text-danger">{{ error }}</div>
|
<div class="text-danger">{{ error }}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="d-flex justify-content-start">
|
<div class="d-flex justify-content-start">
|
||||||
|
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
<!--<i class="bi bi-save"></i> -->
|
<!--<i class="bi bi-save"></i> -->
|
||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -17,11 +17,11 @@
|
|||||||
<a href="{% url 'ledger_list' %}" class="btn btn-danger"><i class="fa-solid fa-ban"></i> {% trans "Cancel" %}</a>
|
<a href="{% url 'ledger_list' %}" class="btn btn-danger"><i class="fa-solid fa-ban"></i> {% trans "Cancel" %}</a>
|
||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
|
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a href="{% url 'organization_update' organization.pk %}" class="btn btn-sm btn-warning me-2">{% trans "Edit" %}</a>
|
<a href="{% url 'organization_update' organization.pk %}" class="btn btn-sm btn-warning me-2">{% trans "Edit" %}</a>
|
||||||
<button class="btn btn-phoenix-danger btn-sm delete-btn"
|
<button class="btn btn-phoenix-danger btn-sm delete-btn"
|
||||||
data-url="{% url 'organization_delete' organization.pk %}"
|
data-url="{% url 'organization_delete' organization.slug %}"
|
||||||
data-message="Are you sure you want to delete this organization?"
|
data-message="Are you sure you want to delete this organization?"
|
||||||
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||||
{% trans 'Delete' %}<i class="fas fa-trash ms-1"></i>
|
{% trans 'Delete' %}<i class="fas fa-trash ms-1"></i>
|
||||||
|
|||||||
@ -93,7 +93,7 @@
|
|||||||
{% trans 'Are you sure you want to delete this Organization?' %}
|
{% trans 'Are you sure you want to delete this Organization?' %}
|
||||||
</p>
|
</p>
|
||||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">{% trans 'No' %}</button>
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">{% trans 'No' %}</button>
|
||||||
<a type="button" class="btn btn-danger btn-sm" href="{% url 'organization_delete' org.pk %}">{% trans 'Yes' %}</a>
|
<a type="button" class="btn btn-danger btn-sm" href="{% url 'organization_delete' org.slug %}">{% trans 'Yes' %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -102,7 +102,7 @@
|
|||||||
<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>
|
<div>
|
||||||
<a class="fs-8 fw-bold" href="{% url 'organization_detail' org.pk %}">{{ org.name }}</a>
|
<a class="fs-8 fw-bold" href="{% url 'organization_detail' org.slug %}">{{ org.name }}</a>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2"></p><span class="badge badge-phoenix badge-phoenix-primary">{{ org.name }}</span>
|
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2"></p><span class="badge badge-phoenix badge-phoenix-primary">{{ org.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -121,7 +121,7 @@
|
|||||||
<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">
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
<a href="{% url 'organization_update' org.pk %}" class="dropdown-item text-success-dark">{% trans 'Edit' %}</a>
|
<a href="{% url 'organization_update' org.slug %}" class="dropdown-item text-success-dark">{% trans 'Edit' %}</a>
|
||||||
{% if perms.django_ledger.delete_customermodel %}
|
{% if perms.django_ledger.delete_customermodel %}
|
||||||
<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>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<div class="container text-center" data-aos="fade-up">
|
<div class="container text-center" data-aos="fade-up">
|
||||||
<div class="py-5">
|
<div class="py-5">
|
||||||
<i class="bi bi-x-circle-fill text-danger" style="font-size: 5rem;"></i>
|
<i class="bi bi-x-circle-fill text-danger" style="font-size: 5rem;"></i>
|
||||||
<h2 class="mt-4">{% trans "Payment Failed"%}</h2>
|
<h2 class="mt-4">{% trans "Payment Failed"%}</h2>
|
||||||
{% if message %}
|
{% if message %}
|
||||||
<p class="lead">{{message}}.</p>
|
<p class="lead">{{message}}.</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@ -207,26 +207,26 @@
|
|||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const form = document.getElementById('wizardForm');
|
const form = document.getElementById('wizardForm');
|
||||||
|
|
||||||
form.addEventListener('submit', function(e) {
|
form.addEventListener('submit', function(e) {
|
||||||
e.preventDefault(); // Prevent default form submission
|
e.preventDefault(); // Prevent default form submission
|
||||||
|
|
||||||
// Show loading alert
|
// Show loading alert
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Processing...',
|
title: 'Processing...',
|
||||||
html: 'Please wait while we submit your form',
|
html: 'Please wait while we submit your form',
|
||||||
allowOutsideClick: false,
|
allowOutsideClick: false,
|
||||||
didOpen: () => {
|
didOpen: () => {
|
||||||
Swal.showLoading();
|
Swal.showLoading();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Submit the form after a slight delay to ensure Swal is shown
|
// Submit the form after a slight delay to ensure Swal is shown
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
form.submit();
|
form.submit();
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
const radios = document.querySelectorAll('.btn-check');
|
const radios = document.querySelectorAll('.btn-check');
|
||||||
radios.forEach(radio => {
|
radios.forEach(radio => {
|
||||||
|
|||||||
@ -68,13 +68,13 @@
|
|||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
|
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
<!--<i class="bi bi-save"></i> -->
|
<!--<i class="bi bi-save"></i> -->
|
||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="align-middle product white-space-nowrap">{{ invoice.created }}</td>
|
<td class="align-middle product white-space-nowrap">{{ invoice.created }}</td>
|
||||||
<td class="align-middle product white-space-nowrap">
|
<td class="align-middle product white-space-nowrap">
|
||||||
<a href="{% url 'invoice_detail' invoice.pk %}"
|
<a href="{% url 'invoice_detail' invoice.pk %}"
|
||||||
class="btn btn-sm btn-phoenix-success">
|
class="btn btn-sm btn-phoenix-success">
|
||||||
<i class="fa-regular fa-eye me-1"></i>
|
<i class="fa-regular fa-eye me-1"></i>
|
||||||
{% trans "View" %}
|
{% trans "View" %}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<h4 class="my-4">Groups</h4>
|
<h4 class="my-4">Groups</h4>
|
||||||
<a class="btn btn-sm btn-primary mt-2 mb-4" href="{% url 'user_groups' user_.pk %}"><i class="fa-solid fa-users"></i> Manage Groups</a>
|
<a class="btn btn-sm btn-primary mt-2 mb-4" href="{% url 'user_groups' user_.slug %}"><i class="fa-solid fa-users"></i> Manage Groups</a>
|
||||||
<table class="table table-hover table-responsive-sm fs-9 mb-0">
|
<table class="table table-hover table-responsive-sm fs-9 mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -48,13 +48,13 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer d-flex ">
|
<div class="card-footer d-flex ">
|
||||||
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'user_update' user_.id %}">
|
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'user_update' user_.slug %}">
|
||||||
{{ _("Edit") }}
|
{{ _("Edit") }}
|
||||||
<i class="fa-solid fa-pen-to-square"></i>
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button class="btn btn-phoenix-danger btn-sm delete-btn me-1"
|
<button class="btn btn-phoenix-danger btn-sm delete-btn me-1"
|
||||||
data-url="{% url 'user_delete' user_.id %}"
|
data-url="{% url 'user_delete' user_.slug %}"
|
||||||
data-message="{{ _("Are you sure you want to delete this user?")}}"
|
data-message="{{ _("Are you sure you want to delete this user?")}}"
|
||||||
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||||
{{ _("Delete") }}
|
{{ _("Delete") }}
|
||||||
|
|||||||
@ -2,10 +2,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load crispy_forms_filters %}
|
{% load crispy_forms_filters %}
|
||||||
{% block title %}{% trans "Group" %}{% endblock title %}
|
{% block title %}{% trans "Group" %}{% endblock title %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -16,7 +13,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
|
||||||
<form class="row g-3 mb-9" method="post" class="form" novalidate>
|
<form class="row g-3 mb-9" method="post" class="form" novalidate>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
|
|||||||
@ -11,8 +11,16 @@
|
|||||||
<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 'user_create' %}" class="btn btn-sm btn-phoenix-primary"><i class="fa-solid fa-user-tie"></i> {% trans "Add New Staff" %}</a>
|
{% if request.user.userplan %}
|
||||||
<a href="{% url 'group_list' %}" class="btn btn-sm btn-phoenix-success"><i class="fa-solid fa-user-group"></i> {% trans "Manage Groups & Permissions" %}</a>
|
<a href="{% url 'user_create' %}" class="btn btn-sm btn-phoenix-primary"><i class="fa-solid fa-user-tie"></i> {% trans "Add New Staff" %}</a>
|
||||||
|
<a href="{% url 'group_list' %}" class="btn btn-sm btn-phoenix-success"><i class="fa-solid fa-user-group"></i> {% trans "Manage Groups & Permissions" %}</a>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-outline-info d-flex align-items-center" role="alert">
|
||||||
|
<i class="fa-solid fa-circle-info fs-6"></i>
|
||||||
|
<p class="mb-0 flex-1">{{ _("No Active Subscription,please activate your subscription.") }}<a href="{% url 'pricing_page' %}" class="ms-3 text-body-primary fs-9">Manage Subscription</a></p>
|
||||||
|
<button class="btn-close" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -33,7 +41,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="align-middle white-space-nowrap ps-0">
|
<td class="align-middle white-space-nowrap ps-0">
|
||||||
<div>
|
<div>
|
||||||
<a class="fs-8 fw-bold" href="{% url 'user_detail' user.pk%}">{{ user.arabic_name }}</a>
|
<a class="fs-8 fw-bold" href="{% url 'user_detail' user.slug%}">{{ user.arabic_name }}</a>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2">{{ user.name }}</p>
|
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2">{{ user.name }}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -47,7 +55,7 @@
|
|||||||
|
|
||||||
<td class="align-middle white-space-nowrap">
|
<td class="align-middle white-space-nowrap">
|
||||||
<a class="btn btn-phoenix-success"
|
<a class="btn btn-phoenix-success"
|
||||||
href="{% url 'user_detail' user.id %}">
|
href="{% url 'user_detail' user.slug %}">
|
||||||
<i class="fa-solid fa-eye"></i>
|
<i class="fa-solid fa-eye"></i>
|
||||||
{% trans 'view'|capfirst %}
|
{% trans 'view'|capfirst %}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
8
templates/vendors/vendor_form.html
vendored
8
templates/vendors/vendor_form.html
vendored
@ -35,11 +35,11 @@
|
|||||||
<div class="text-danger">{{ error }}</div>
|
<div class="text-danger">{{ error }}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="d-flex justify-content-start">
|
<div class="d-flex justify-content-start">
|
||||||
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
<button class="btn btn-sm btn-success me-2" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>
|
||||||
<!--<i class="bi bi-save"></i> -->
|
<!--<i class="bi bi-save"></i> -->
|
||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
</button>
|
</button>
|
||||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger"><i class="fa-solid fa-ban me-1"></i>{% trans "Cancel" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
156
templates/vendors/vendors_list.html
vendored
156
templates/vendors/vendors_list.html
vendored
@ -38,92 +38,92 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-responsive scrollbar mx-n1 px-1">
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
|
|
||||||
<table class="table table-hover fs-9 mb-0">
|
<table class="table table-hover fs-9 mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<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">
|
||||||
<div class="d-flex align-items-center px-1 py-1 bg-success-subtle rounded me-2"><span class="text-success-dark" data-feather="mail"></span></div><span>{{ _("email")|capfirst }}</span>
|
<div class="d-flex align-items-center px-1 py-1 bg-success-subtle rounded me-2"><span class="text-success-dark" data-feather="mail"></span></div><span>{{ _("email")|capfirst }}</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="phone" style="width:15%; min-width: 180px;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="phone" style="width:15%; min-width: 180px;">
|
||||||
<div class="d-inline-flex flex-center">
|
<div class="d-inline-flex flex-center">
|
||||||
<div class="d-flex align-items-center px-1 py-1 bg-primary-subtle rounded me-2"><span class="text-primary-dark" data-feather="phone"></span></div><span>{{ _("Phone") }}</span>
|
<div class="d-flex align-items-center px-1 py-1 bg-primary-subtle rounded me-2"><span class="text-primary-dark" data-feather="phone"></span></div><span>{{ _("Phone") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="contact" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="contact" style="width:15%;">
|
||||||
<div class="d-inline-flex flex-center">
|
<div class="d-inline-flex flex-center">
|
||||||
<div class="d-flex align-items-center px-1 py-1 bg-info-subtle rounded me-2"><span class="text-info-dark" data-feather="user"></span></div><span>{{ _("Contact name")|capfirst }}</span>
|
<div class="d-flex align-items-center px-1 py-1 bg-info-subtle rounded me-2"><span class="text-info-dark" data-feather="user"></span></div><span>{{ _("Contact name")|capfirst }}</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase border-end border-translucent" scope="col" data-sort="company" style="width:15%;">
|
||||||
<div class="d-inline-flex flex-center">
|
<div class="d-inline-flex flex-center">
|
||||||
<div class="d-flex align-items-center px-1 py-1 bg-warning-subtle rounded me-2"><span class="text-warning-dark" data-feather="grid"></span></div><span>{{ _("Address")|capfirst }}</span>
|
<div class="d-flex align-items-center px-1 py-1 bg-warning-subtle rounded me-2"><span class="text-warning-dark" data-feather="grid"></span></div><span>{{ _("Address")|capfirst }}</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" data-sort="date" style="width:15%;">
|
<th class="sort align-middle ps-4 pe-5 text-uppercase" scope="col" data-sort="date" style="width:15%;">
|
||||||
{{ _("Create date") }}</th>
|
{{ _("Create date") }}</th>
|
||||||
<th class="sort text-end align-middle pe-0 ps-4" scope="col"></th>
|
<th class="sort text-end align-middle pe-0 ps-4" scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="leal-tables-body">
|
<tbody class="list" id="leal-tables-body">
|
||||||
{% for vendor in vendors %}
|
{% for vendor in vendors %}
|
||||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||||
|
|
||||||
<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">
|
||||||
|
{% if vendor.logo %}
|
||||||
|
<div class="avatar avatar-xl me-3"><img class="rounded-circle" src="{{ vendor.logo.url }}" alt="" />
|
||||||
|
{% else %}
|
||||||
|
<div class="avatar avatar-xl me-3"><img class="rounded-circle" src="{% static 'images/icons/picture.svg' %}" alt="" />
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div><a class="fs-8 fw-bold" href="{% url 'vendor_detail' vendor.slug %}">{{ vendor.arabic_name }}</a>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
{% if vendor.logo %}
|
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2">{{ vendor.name}}</p><!--<span class="badge badge-phoenix badge-phoenix-primary">{{ vendor.vendor_model.uuid }}</span>-->
|
||||||
<div class="avatar avatar-xl me-3"><img class="rounded-circle" src="{{ vendor.logo.url }}" alt="" />
|
|
||||||
{% else %}
|
|
||||||
<div class="avatar avatar-xl me-3"><img class="rounded-circle" src="{% static 'images/icons/picture.svg' %}" alt="" />
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div><a class="fs-8 fw-bold" href="{% url 'vendor_detail' vendor.slug %}">{{ vendor.arabic_name }}</a>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2">{{ vendor.name}}</p><!--<span class="badge badge-phoenix badge-phoenix-primary">{{ vendor.vendor_model.uuid }}</span>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</div>
|
||||||
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="">{{ vendor.email }}</a></td>
|
</td>
|
||||||
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="tel:{{ vendor.phone }}">{{ vendor.phone_number }}</a></td>
|
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="">{{ vendor.email }}</a></td>
|
||||||
<td class="contact align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ vendor.contact_person }}</td>
|
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="tel:{{ vendor.phone }}">{{ vendor.phone_number }}</a></td>
|
||||||
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">
|
<td class="contact align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ vendor.contact_person }}</td>
|
||||||
{{ vendor.address }}</td>
|
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">
|
||||||
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ vendor.created_at|date }}</td>
|
{{ vendor.address }}</td>
|
||||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ vendor.created_at|date }}</td>
|
||||||
<div class="btn-reveal-trigger position-static">
|
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
||||||
<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="btn-reveal-trigger position-static">
|
||||||
<div class="dropdown-menu dropdown-menu-end py-2">
|
<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>
|
||||||
<a href="{% url 'vendor_update' vendor.slug %}" class="dropdown-item text-success-dark">
|
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||||
{% trans "Edit" %}
|
<a href="{% url 'vendor_update' vendor.slug %}" class="dropdown-item text-success-dark">
|
||||||
</a>
|
{% trans "Edit" %}
|
||||||
<div class="dropdown-divider"></div>
|
</a>
|
||||||
<button class="delete-btn dropdown-item text-danger"
|
<div class="dropdown-divider"></div>
|
||||||
data-url="{% url 'vendor_delete' vendor.slug %}"
|
<button class="delete-btn dropdown-item text-danger"
|
||||||
data-message="{{ _("Are you sure you want to delete this vendor")}}?"
|
data-url="{% url 'vendor_delete' vendor.slug %}"
|
||||||
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
data-message="{{ _("Are you sure you want to delete this vendor")}}?"
|
||||||
{{ _("Delete") }}
|
data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||||
</button>
|
{{ _("Delete") }}
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</td>
|
||||||
{% endfor %}
|
</tr>
|
||||||
</tbody>
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="row align-items-center justify-content-end py-4 pe-0 fs-9">
|
<div class="row align-items-center justify-content-end py-4 pe-0 fs-9">
|
||||||
<!-- Optional: Pagination -->
|
<!-- Optional: Pagination -->
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
{% include 'partials/pagination.html' %}
|
{% include 'partials/pagination.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% include 'modal/delete_modal.html' %}
|
{% include 'modal/delete_modal.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user