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 Group
from appointment.models import Appointment, Service, StaffMember
@ -10,7 +11,7 @@ from django.core.validators import RegexValidator
from django import forms
from django.contrib.auth import get_user_model
from phonenumber_field.phonenumber import PhoneNumber
from .models import Status, Stage
from .models import CustomGroup, Status, Stage
from .mixins import AddClassMixin
from django.forms.models import inlineformset_factory
from django_ledger.forms.invoice import (
@ -900,25 +901,29 @@ class OpportunityStatusForm(forms.Form):
class GroupForm(forms.ModelForm):
class Meta:
model = Group
model = CustomGroup
fields = ["name"]
class PermissionForm(forms.ModelForm):
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(),
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:
model = Permission
fields = ["name"]
class UserGroupForm(forms.ModelForm):
name = forms.ModelMultipleChoiceField(
queryset= Group.objects.all(),
queryset= CustomGroup.objects.all(),
widget=forms.CheckboxSelectMultiple(),
required=True
)
class Meta:
model = Group
model = CustomGroup
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
import hashlib
from django.db import models
@ -957,11 +958,20 @@ class Staff(models.Model, LocalizedNameMixin):
@property
def user(self):
return self.staff_member.user
return self.staff_member.user
@property
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:
verbose_name = _("Staff")
verbose_name_plural = _("Staff")
@ -1783,4 +1793,78 @@ class SaleOrder(models.Model):
@property
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 django.db.models.signals import post_save, post_delete, pre_delete, pre_save
from .utils import to_dict
@ -16,6 +17,7 @@ from django_ledger.models import (
)
from . import models
from django.utils.timezone import now
from django.db import transaction
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="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
@receiver(post_save, sender=models.Vendor)
def create_ledger_vendor(sender, instance, created, **kwargs):

View File

@ -1871,65 +1871,60 @@ def delete_vendor(request, pk):
#group
class GroupListView(LoginRequiredMixin, ListView):
model = Group
model = models.CustomGroup
context_object_name = "groups"
paginate_by = 10
template_name = "groups/group_list.html"
# def get_queryset(self):
# query = self.request.GET.get("q")
# dealer = get_user_type(self.request)
# staff = models.Staff.objects.filter(dealer=dealer).all()
# return apply_search_filters(staff, query)
def get_queryset(self):
dealer = get_user_type(self.request)
return dealer.groups.all()
class GroupDetailView(LoginRequiredMixin, DetailView):
model = Group
model = models.CustomGroup
template_name = "groups/group_detail.html"
context_object_name = "group"
context_object_name = "group"
class GroupCreateView(
LoginRequiredMixin,
SuccessMessageMixin,
CreateView,
):
model = Group
model = models.CustomGroup
form_class = forms.GroupForm
template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list")
success_message = _("Group created successfully.")
# def form_valid(self, form):
# dealer = get_user_type(self.request)
# email = form.cleaned_data["email"]
# password = "Tenhal@123"
# user = User.objects.create_user(username=form.cleaned_data["name"], email=email, password=password)
# user.is_staff = True
# user.save()
# 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)
def form_valid(self, form):
dealer = get_user_type(self.request)
instance = form.save(commit=False)
group = Group.objects.create(name=f"{dealer.pk}_{instance.name}")
instance.dealer = dealer
instance.group = group
instance.save()
return super().form_valid(form)
class GroupUpdateView(
LoginRequiredMixin,
SuccessMessageMixin,
UpdateView,
):
model = Group
model = models.CustomGroup
form_class = forms.GroupForm
template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list")
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):
# kwargs = super().get_form_kwargs()
# kwargs["instance"] = self.get_object() # Pass the Staff instance to the form
@ -1961,28 +1956,22 @@ class GroupUpdateView(
# return super().form_valid(form)
def GroupDeleteview(request, pk):
group = get_object_or_404(Group, pk=pk)
group = get_object_or_404(models.CustomGroup, pk=pk)
group.delete()
messages.success(request, _("Group deleted successfully."))
return redirect("group_list")
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":
form = forms.PermissionForm(request.POST)
group.permissions.clear()
form = forms.PermissionForm(request.POST)
group.clear_permissions()
permissions = request.POST.getlist("name")
for i in permissions:
try:
group.permissions.add(Permission.objects.get(id=int(i)))
except Permission.DoesNotExist:
continue
for i in permissions:
group.add_permission(Permission.objects.get(id=int(i)))
messages.success(request, _("Permission added successfully."))
return redirect("group_detail", pk=group.pk)
form = forms.PermissionForm(initial={"name": group.permissions.all()})
return redirect("group_detail", pk=group.pk)
form = forms.PermissionForm(initial={"name": group.permissions})
return render(request,"groups/group_permission_form.html",{"group": group, "form": form})
# Users
@ -1991,18 +1980,16 @@ def UserGroupView(request, pk):
staff = get_object_or_404(models.Staff, pk=pk)
if request.method == "POST":
form = forms.UserGroupForm(request.POST)
groups = request.POST.getlist("name")
staff.groups.clear()
for i in groups:
try:
staff.groups.add(Group.objects.get(id=int(i)))
except Group.DoesNotExist:
continue
groups = request.POST.getlist("name")
staff.clear_groups()
for i in groups:
cg = models.CustomGroup.objects.get(id=int(i))
staff.add_group(cg.group)
messages.success(request, _("Group added successfully."))
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})
class UserListView(LoginRequiredMixin, ListView):
@ -2049,9 +2036,9 @@ class UserCreateView(
staff = form.save(commit=False)
staff.staff_member = staff_member
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:
staff.groups.add(group)
staff.add_group(group)
staff.save()
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.utils import accruable_net_summary
from decimal import Decimal
from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel
from rich import print
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 appointment.models import Appointment,AppointmentRequest,Service,StaffMember
from django.contrib.auth import get_user_model
@ -121,6 +122,18 @@ def run():
# print(CustomerModel.objects.all())
# 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()
customer = CustomerModel.objects.filter(dealer=dealer).first()
print(Car.objects.filter(dealer=dealer,status="available"))
group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"]
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>
</thead>
<tbody>
{% for user in group.user_set.all %}
{% for user in group.users %}
<tr>
<td><p><strong>{{ _("Name") }}:</strong> {{ user.staffmember.staff }}</p></td>
<td><p><strong>{{ _("Email") }}:</strong> {{ user }}</p></td>
@ -84,7 +84,7 @@
</tr>
</thead>
<tbody>
{% for permission in group.permissions.all %}
{% for permission in group.permissions %}
<tr>
<td>{{ permission.codename }}</td>
<td>{{ permission.name }}</td>

View File

@ -31,7 +31,7 @@
{% for group in groups %}
<tr>
<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>
<a class="btn btn-phoenix-success"

View File

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