Merge branch 'user_group'

This commit is contained in:
gitea 2025-02-20 14:19:07 +00:00
commit 475518c37e
10 changed files with 217 additions and 72 deletions

View File

@ -1,3 +1,4 @@
from django.core.cache import cache
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from appointment.models import Appointment, Service, StaffMember from appointment.models import Appointment, Service, StaffMember
@ -10,7 +11,7 @@ from django.core.validators import RegexValidator
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from phonenumber_field.phonenumber import PhoneNumber from phonenumber_field.phonenumber import PhoneNumber
from .models import Status, Stage from .models import CustomGroup, Status, Stage
from .mixins import AddClassMixin from .mixins import AddClassMixin
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from django_ledger.forms.invoice import ( from django_ledger.forms.invoice import (
@ -900,25 +901,29 @@ class OpportunityStatusForm(forms.Form):
class GroupForm(forms.ModelForm): class GroupForm(forms.ModelForm):
class Meta: class Meta:
model = Group model = CustomGroup
fields = ["name"] fields = ["name"]
class PermissionForm(forms.ModelForm): class PermissionForm(forms.ModelForm):
name = forms.ModelMultipleChoiceField( name = forms.ModelMultipleChoiceField(
queryset=Permission.objects.filter(content_type__app_label='inventory'), queryset=cache.get('permissions_queryset', Permission.objects.filter(content_type__app_label__in=["inventory","django_ledger"])),
widget=forms.CheckboxSelectMultiple(), widget=forms.CheckboxSelectMultiple(),
required=True required=True
) )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
cache.set('permissions_queryset', Permission.objects.filter(content_type__app_label__in=["inventory","django_ledger"]), 60*60)
class Meta: class Meta:
model = Permission model = Permission
fields = ["name"] fields = ["name"]
class UserGroupForm(forms.ModelForm): class UserGroupForm(forms.ModelForm):
name = forms.ModelMultipleChoiceField( name = forms.ModelMultipleChoiceField(
queryset= Group.objects.all(), queryset= CustomGroup.objects.all(),
widget=forms.CheckboxSelectMultiple(), widget=forms.CheckboxSelectMultiple(),
required=True required=True
) )
class Meta: class Meta:
model = Group model = CustomGroup
fields = ["name"] fields = ["name"]

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.17 on 2025-02-20 08:16
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('inventory', '0037_alter_schedule_scheduled_type'),
]
operations = [
migrations.CreateModel(
name='CustomGroup',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.dealer')),
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='auth.group', verbose_name='')),
],
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.2.17 on 2025-02-20 08:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inventory', '0038_customgroup'),
]
operations = [
migrations.AlterField(
model_name='customgroup',
name='dealer',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='groups', to='inventory.dealer'),
),
]

View File

@ -1,3 +1,4 @@
from django.contrib.auth.models import Permission
from decimal import Decimal from decimal import Decimal
import hashlib import hashlib
from django.db import models from django.db import models
@ -957,11 +958,20 @@ class Staff(models.Model, LocalizedNameMixin):
@property @property
def user(self): def user(self):
return self.staff_member.user return self.staff_member.user
@property @property
def groups(self): def groups(self):
return self.staff_member.user.groups return [x.customgroup for x in self.user.groups.all()]
def clear_groups(self):
return self.user.groups.clear()
def add_group(self,group):
try:
self.user.groups.add(group)
except Exception as e:
pass
class Meta: class Meta:
verbose_name = _("Staff") verbose_name = _("Staff")
verbose_name_plural = _("Staff") verbose_name_plural = _("Staff")
@ -1783,4 +1793,78 @@ class SaleOrder(models.Model):
@property @property
def customer(self): def customer(self):
return self.estimate.customer return self.estimate.customer
class CustomGroup(models.Model):
name = models.CharField(max_length=100)
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="groups")
group = models.OneToOneField("auth.Group", verbose_name=_(""), on_delete=models.CASCADE)
@property
def users(self):
return self.group.user_set.all()
@property
def permissions(self):
return self.group.permissions.all()
def clear_permissions(self):
self.group.permissions.clear()
def add_permission(self, permission):
try:
self.group.permissions.add(permission)
except Permission.DoesNotExist:
pass
def __str__(self):
return self.name
def set_default_manager_permissions(self):
self.clear_permissions()
try:
for perm in Permission.objects.filter(content_type__app_label="inventory"):
self.add_permission(perm)
except Exception as e:
pass
# def set_default_inventory_permissions(self):
# self.clear_permissions()
# allowed_models = ["car","carequipment","interiorcolors","exteriorcolors","carcolors","carlocation","customcard"]
# self.set_permissions(allowed_models=allowed_models,other_perms=['view_carfinance'])
# def set_default_accountant_permissions(self):
# self.clear_permissions()
# allowed_models = ["car","carfinance","carlocation","customcard"]
# allowed_models_ledger = ["accountmodel","chartofaccountmodel","customcard","billmodel"]
# self.set_permissions(allowed_models=allowed_models,other_perms=['view_carfinance'])
# self.set_permissions(app="django_ledger",allowed_models=allowed_models_ledger)
def set_default_permissions(self):
self.clear_permissions()
if self.name == "Manager":
self.set_permissions(app="inventory",allowed_models=["car","carfinance","carlocation","customcard"])
self.set_permissions(app="django_ledger",allowed_models=["accountmodel","chartofaccountmodel","customcard","billmodel"])
elif self.name == "Inventory":
self.set_permissions(allowed_models=["car","carequipment","interiorcolors","exteriorcolors","carcolors","carlocation","customcard"]
,other_perms=['view_carfinance'])
elif self.name == "Sales":
self.set_permissions(app="inventory",allowed_models=["lead","salequotation","salequotationcar"],
other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer'].
extend(['view_estimatemodel','view_invoicemodel','view_saleorder']))
elif self.name == "Accountant":
self.set_permissions(app="inventory",allowed_models=["carfinance"],other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer'])
self.set_permissions(app="django_ledger",allowed_models=["accountmodel","chartofaccountmodel","customcard","billmodel"])
elif self.name == "Agent":
# Todo : set permissions for agent
pass
def set_permissions(self,app="inventory", allowed_models=[],other_perms=[]):
try:
for perm in Permission.objects.filter(content_type__app_label=app,content_type__model__in=allowed_models):
self.add_permission(perm)
for perm in other_perms:
Permission.objects.get(codename=perm)
self.add_permission(perm)
except Exception as e:
pass

View File

@ -1,3 +1,4 @@
from django.contrib.auth.models import Group
from decimal import Decimal from decimal import Decimal
from django.db.models.signals import post_save, post_delete, pre_delete, pre_save from django.db.models.signals import post_save, post_delete, pre_delete, pre_save
from .utils import to_dict from .utils import to_dict
@ -16,6 +17,7 @@ from django_ledger.models import (
) )
from . import models from . import models
from django.utils.timezone import now from django.utils.timezone import now
from django.db import transaction
User = get_user_model() User = get_user_model()
@ -614,8 +616,19 @@ def create_ledger_entity(sender, instance, created, **kwargs):
entity.create_account(coa_model=coa, code="6303", role=roles.EXPENSE_OTHER, name=_("Foreign Currency Translation"), balance_type="debit", active=True) entity.create_account(coa_model=coa, code="6303", role=roles.EXPENSE_OTHER, name=_("Foreign Currency Translation"), balance_type="debit", active=True)
entity.create_account(coa_model=coa, code="6304", role=roles.EXPENSE_OTHER, name=_("Interest Expenses"), balance_type="debit", active=True) entity.create_account(coa_model=coa, code="6304", role=roles.EXPENSE_OTHER, name=_("Interest Expenses"), balance_type="debit", active=True)
@receiver(post_save, sender=models.Dealer)
def create_dealer_groups(sender, instance, created, **kwargs):
group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"]
def create_groups():
for group_name in group_names:
group, created = Group.objects.get_or_create(name=f"{instance.pk}_{group_name}")
group_manager,created = models.CustomGroup.objects.get_or_create(name=group_name, dealer=instance, group=group)
group_manager.set_default_permissions()
transaction.on_commit(create_groups)
# Create Vendor # Create Vendor
@receiver(post_save, sender=models.Vendor) @receiver(post_save, sender=models.Vendor)
def create_ledger_vendor(sender, instance, created, **kwargs): def create_ledger_vendor(sender, instance, created, **kwargs):

View File

@ -1871,65 +1871,60 @@ def delete_vendor(request, pk):
#group #group
class GroupListView(LoginRequiredMixin, ListView): class GroupListView(LoginRequiredMixin, ListView):
model = Group model = models.CustomGroup
context_object_name = "groups" context_object_name = "groups"
paginate_by = 10 paginate_by = 10
template_name = "groups/group_list.html" template_name = "groups/group_list.html"
# def get_queryset(self): def get_queryset(self):
# query = self.request.GET.get("q") dealer = get_user_type(self.request)
# dealer = get_user_type(self.request) return dealer.groups.all()
# staff = models.Staff.objects.filter(dealer=dealer).all()
# return apply_search_filters(staff, query)
class GroupDetailView(LoginRequiredMixin, DetailView): class GroupDetailView(LoginRequiredMixin, DetailView):
model = Group model = models.CustomGroup
template_name = "groups/group_detail.html" template_name = "groups/group_detail.html"
context_object_name = "group" context_object_name = "group"
class GroupCreateView( class GroupCreateView(
LoginRequiredMixin, LoginRequiredMixin,
SuccessMessageMixin, SuccessMessageMixin,
CreateView, CreateView,
): ):
model = Group model = models.CustomGroup
form_class = forms.GroupForm form_class = forms.GroupForm
template_name = "groups/group_form.html" template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list") success_url = reverse_lazy("group_list")
success_message = _("Group created successfully.") success_message = _("Group created successfully.")
# def form_valid(self, form): def form_valid(self, form):
# dealer = get_user_type(self.request) dealer = get_user_type(self.request)
instance = form.save(commit=False)
# email = form.cleaned_data["email"] group = Group.objects.create(name=f"{dealer.pk}_{instance.name}")
# password = "Tenhal@123" instance.dealer = dealer
# user = User.objects.create_user(username=form.cleaned_data["name"], email=email, password=password) instance.group = group
# user.is_staff = True instance.save()
# user.save() return super().form_valid(form)
# staff_member = StaffMember.objects.create(user=user)
# services = form.cleaned_data["service_offered"]
# if services:
# for service in services:
# staff_member.services_offered.add(service)
# staff = form.save(commit=False)
# staff.staff_member = staff_member
# staff.dealer = dealer
# staff.save()
# return super().form_valid(form)
class GroupUpdateView( class GroupUpdateView(
LoginRequiredMixin, LoginRequiredMixin,
SuccessMessageMixin, SuccessMessageMixin,
UpdateView, UpdateView,
): ):
model = Group model = models.CustomGroup
form_class = forms.GroupForm form_class = forms.GroupForm
template_name = "groups/group_form.html" template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list") success_url = reverse_lazy("group_list")
success_message = _("Group updated successfully.") success_message = _("Group updated successfully.")
def form_valid(self, form):
dealer = get_user_type(self.request)
instance = form.save(commit=False)
instance.group.name = f"{dealer.pk}_{instance.name}"
instance.save()
return super().form_valid(form)
# def get_form_kwargs(self): # def get_form_kwargs(self):
# kwargs = super().get_form_kwargs() # kwargs = super().get_form_kwargs()
# kwargs["instance"] = self.get_object() # Pass the Staff instance to the form # kwargs["instance"] = self.get_object() # Pass the Staff instance to the form
@ -1961,28 +1956,22 @@ class GroupUpdateView(
# return super().form_valid(form) # return super().form_valid(form)
def GroupDeleteview(request, pk): def GroupDeleteview(request, pk):
group = get_object_or_404(Group, pk=pk) group = get_object_or_404(models.CustomGroup, pk=pk)
group.delete() group.delete()
messages.success(request, _("Group deleted successfully.")) messages.success(request, _("Group deleted successfully."))
return redirect("group_list") return redirect("group_list")
def GroupPermissionView(request, pk): def GroupPermissionView(request, pk):
group = get_object_or_404(Group, pk=pk) group = get_object_or_404(models.CustomGroup, pk=pk)
if request.method == "POST": if request.method == "POST":
form = forms.PermissionForm(request.POST) form = forms.PermissionForm(request.POST)
group.permissions.clear() group.clear_permissions()
permissions = request.POST.getlist("name") permissions = request.POST.getlist("name")
for i in permissions:
for i in permissions: group.add_permission(Permission.objects.get(id=int(i)))
try:
group.permissions.add(Permission.objects.get(id=int(i)))
except Permission.DoesNotExist:
continue
messages.success(request, _("Permission added successfully.")) messages.success(request, _("Permission added successfully."))
return redirect("group_detail", pk=group.pk) return redirect("group_detail", pk=group.pk)
form = forms.PermissionForm(initial={"name": group.permissions})
form = forms.PermissionForm(initial={"name": group.permissions.all()})
return render(request,"groups/group_permission_form.html",{"group": group, "form": form}) return render(request,"groups/group_permission_form.html",{"group": group, "form": form})
# Users # Users
@ -1991,18 +1980,16 @@ def UserGroupView(request, pk):
staff = get_object_or_404(models.Staff, pk=pk) staff = get_object_or_404(models.Staff, pk=pk)
if request.method == "POST": if request.method == "POST":
form = forms.UserGroupForm(request.POST) form = forms.UserGroupForm(request.POST)
groups = request.POST.getlist("name") groups = request.POST.getlist("name")
staff.groups.clear() staff.clear_groups()
for i in groups: for i in groups:
try: cg = models.CustomGroup.objects.get(id=int(i))
staff.groups.add(Group.objects.get(id=int(i))) staff.add_group(cg.group)
except Group.DoesNotExist:
continue
messages.success(request, _("Group added successfully.")) messages.success(request, _("Group added successfully."))
return redirect("user_detail", pk=staff.pk) return redirect("user_detail", pk=staff.pk)
form = forms.UserGroupForm(initial={"name": staff.user.groups.all()}) form = forms.UserGroupForm(initial={"name": staff.groups})
return render(request,"users/user_group_form.html",{"staff": staff, "form": form}) return render(request,"users/user_group_form.html",{"staff": staff, "form": form})
class UserListView(LoginRequiredMixin, ListView): class UserListView(LoginRequiredMixin, ListView):
@ -2049,9 +2036,9 @@ class UserCreateView(
staff = form.save(commit=False) staff = form.save(commit=False)
staff.staff_member = staff_member staff.staff_member = staff_member
staff.dealer = dealer staff.dealer = dealer
group = Group.objects.filter(name__iexact=staff.staff_type).first() group = Group.objects.filter(customgroup__name__iexact=staff.staff_type).first()
if group: if group:
staff.groups.add(group) staff.add_group(group)
staff.save() staff.save()
return super().form_valid(form) return super().form_valid(form)

View File

@ -1,10 +1,11 @@
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 django_ledger.utils import accruable_net_summary
from decimal import Decimal from decimal import Decimal
from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel
from rich import print from rich import print
from datetime import date from datetime import date
from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule 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 appointment.models import Appointment,AppointmentRequest,Service,StaffMember
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@ -121,6 +122,18 @@ def run():
# print(CustomerModel.objects.all()) # print(CustomerModel.objects.all())
# customer = CustomerModel.objects.first() # customer = CustomerModel.objects.first()
# dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first()
# customer = CustomerModel.objects.filter(dealer=dealer).first()
# print(Car.objects.filter(dealer=dealer,status="available"))
# CustomGroup.objects.all().delete()
# Group.objects.all().delete()
dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first() dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first()
customer = CustomerModel.objects.filter(dealer=dealer).first() group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"]
print(Car.objects.filter(dealer=dealer,status="available")) for group_name in group_names:
group,created = Group.objects.get_or_create(name=f"{dealer.pk}_{group_name}")
group_manager,created = CustomGroup.objects.get_or_create(name=group_name, dealer=dealer, group=group)
group_manager.set_default_permissions()
print(CustomGroup.objects.all())

View File

@ -55,7 +55,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in group.user_set.all %} {% for user in group.users %}
<tr> <tr>
<td><p><strong>{{ _("Name") }}:</strong> {{ user.staffmember.staff }}</p></td> <td><p><strong>{{ _("Name") }}:</strong> {{ user.staffmember.staff }}</p></td>
<td><p><strong>{{ _("Email") }}:</strong> {{ user }}</p></td> <td><p><strong>{{ _("Email") }}:</strong> {{ user }}</p></td>
@ -84,7 +84,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for permission in group.permissions.all %} {% for permission in group.permissions %}
<tr> <tr>
<td>{{ permission.codename }}</td> <td>{{ permission.codename }}</td>
<td>{{ permission.name }}</td> <td>{{ permission.name }}</td>

View File

@ -31,7 +31,7 @@
{% for group in groups %} {% for group in groups %}
<tr> <tr>
<td>{{ group.name }}</td> <td>{{ group.name }}</td>
<td><i class="fa-solid fa-users"></i> {{ group.user_set.count }}</td> <td><i class="fa-solid fa-users"></i> {{ group.users.count }}</td>
<td><i class="fa-solid fa-unlock"></i> {{ group.permissions.count }}</td> <td><i class="fa-solid fa-unlock"></i> {{ group.permissions.count }}</td>
<td> <td>
<a class="btn btn-phoenix-success" <a class="btn btn-phoenix-success"

View File

@ -66,7 +66,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for group in user_.groups.all %} {% for group in user_.groups %}
<tr> <tr>
<td>{{ group }}</td> <td>{{ group }}</td>
</tr> </tr>