Ver 12 Working
This commit is contained in:
parent
0fbf30ddc5
commit
d54bf8a44c
Binary file not shown.
Binary file not shown.
103
core/management/commands/update_permission_names.py
Normal file
103
core/management/commands/update_permission_names.py
Normal file
@ -0,0 +1,103 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Renames permissions to be more user-friendly'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Dictionary mapping (app_label, model_name, codename) -> New Name
|
||||
# Or just (codename) -> New Name if unique enough, but (app, model) is safer.
|
||||
|
||||
# We can also map just the model's permissions generically if we want.
|
||||
|
||||
renames = {
|
||||
# Core App - Business Logic
|
||||
('core', 'project', 'add_project'): 'Manage: Create New Project',
|
||||
('core', 'project', 'change_project'): 'Manage: Edit Project Details',
|
||||
('core', 'project', 'delete_project'): 'Manage: Delete Project',
|
||||
('core', 'project', 'view_project'): 'Manage: View Projects (Dashboard Access)',
|
||||
|
||||
('core', 'worker', 'add_worker'): 'Manage: Add New Worker',
|
||||
('core', 'worker', 'change_worker'): 'Manage: Edit Worker Details',
|
||||
('core', 'worker', 'delete_worker'): 'Manage: Delete Worker',
|
||||
('core', 'worker', 'view_worker'): 'Manage: View Worker Profiles',
|
||||
|
||||
('core', 'team', 'add_team'): 'Manage: Create Team',
|
||||
('core', 'team', 'change_team'): 'Manage: Edit Team Structure',
|
||||
('core', 'team', 'delete_team'): 'Manage: Delete Team',
|
||||
('core', 'team', 'view_team'): 'Manage: View Teams',
|
||||
|
||||
('core', 'worklog', 'add_worklog'): 'Log Work: Add Attendance Entry',
|
||||
('core', 'worklog', 'change_worklog'): 'Log Work: Edit Attendance Entry',
|
||||
('core', 'worklog', 'delete_worklog'): 'Log Work: Delete Attendance Entry',
|
||||
('core', 'worklog', 'view_worklog'): 'Log Work: View Attendance History',
|
||||
|
||||
('core', 'payrollrecord', 'add_payrollrecord'): 'Payroll: Generate Payment Record',
|
||||
('core', 'payrollrecord', 'change_payrollrecord'): 'Payroll: Edit Payment Record',
|
||||
('core', 'payrollrecord', 'delete_payrollrecord'): 'Payroll: Delete Payment Record',
|
||||
('core', 'payrollrecord', 'view_payrollrecord'): 'Payroll: View Payment History',
|
||||
|
||||
('core', 'loan', 'add_loan'): 'Loans: Create New Loan',
|
||||
('core', 'loan', 'change_loan'): 'Loans: Edit Loan Details',
|
||||
('core', 'loan', 'delete_loan'): 'Loans: Delete Loan',
|
||||
('core', 'loan', 'view_loan'): 'Loans: View Loan Registry',
|
||||
|
||||
('core', 'expensereceipt', 'add_expensereceipt'): 'Receipts: Add Expense Receipt',
|
||||
('core', 'expensereceipt', 'change_expensereceipt'): 'Receipts: Edit Expense Receipt',
|
||||
('core', 'expensereceipt', 'delete_expensereceipt'): 'Receipts: Delete Expense Receipt',
|
||||
('core', 'expensereceipt', 'view_expensereceipt'): 'Receipts: View Expense History',
|
||||
|
||||
# Auth App
|
||||
('auth', 'user', 'add_user'): 'Admin: Create User Accounts',
|
||||
('auth', 'user', 'change_user'): 'Admin: Edit User Accounts',
|
||||
('auth', 'user', 'delete_user'): 'Admin: Delete User Accounts',
|
||||
('auth', 'user', 'view_user'): 'Admin: View User Accounts',
|
||||
|
||||
('auth', 'group', 'add_group'): 'Admin: Create Permission Groups',
|
||||
('auth', 'group', 'change_group'): 'Admin: Edit Permission Groups',
|
||||
('auth', 'group', 'delete_group'): 'Admin: Delete Permission Groups',
|
||||
('auth', 'group', 'view_group'): 'Admin: View Permission Groups',
|
||||
|
||||
# System / Technical (Marking as Technical to help user ignore them)
|
||||
('sessions', 'session', 'add_session'): 'System (Tech): Add Session',
|
||||
('sessions', 'session', 'change_session'): 'System (Tech): Manage Sessions',
|
||||
('sessions', 'session', 'delete_session'): 'System (Tech): Clear Sessions',
|
||||
('sessions', 'session', 'view_session'): 'System (Tech): View Sessions',
|
||||
|
||||
('admin', 'logentry', 'add_logentry'): 'System (Tech): Add Admin Log',
|
||||
('admin', 'logentry', 'change_logentry'): 'System (Tech): Edit Admin Log',
|
||||
('admin', 'logentry', 'delete_logentry'): 'System (Tech): Clear Admin Log',
|
||||
('admin', 'logentry', 'view_logentry'): 'System (Tech): View Admin Log',
|
||||
|
||||
('contenttypes', 'contenttype', 'add_contenttype'): 'System (Tech): Add Content Type',
|
||||
('contenttypes', 'contenttype', 'change_contenttype'): 'System (Tech): Edit Content Type',
|
||||
('contenttypes', 'contenttype', 'delete_contenttype'): 'System (Tech): Delete Content Type',
|
||||
('contenttypes', 'contenttype', 'view_contenttype'): 'System (Tech): View Content Types',
|
||||
}
|
||||
|
||||
count = 0
|
||||
for (app_label, model, codename), new_name in renames.items():
|
||||
try:
|
||||
# We need to find the content type first to be safe, or filter by codename + content_type__app_label
|
||||
# but direct filter is easiest if unique.
|
||||
# However, codenames can be shared across models (though rare for standard CRUD).
|
||||
# Safer to lookup ContentType.
|
||||
|
||||
ct = ContentType.objects.filter(app_label=app_label, model=model).first()
|
||||
if not ct:
|
||||
self.stdout.write(self.style.WARNING(f"Model {app_label}.{model} not found, skipping."))
|
||||
continue
|
||||
|
||||
perm = Permission.objects.filter(content_type=ct, codename=codename).first()
|
||||
if perm:
|
||||
perm.name = new_name
|
||||
perm.save()
|
||||
self.stdout.write(f"Renamed {codename} -> {new_name}")
|
||||
count += 1
|
||||
else:
|
||||
self.stdout.write(self.style.WARNING(f"Permission {codename} for {app_label}.{model} not found."))
|
||||
except Exception as e:
|
||||
self.stdout.write(self.style.ERROR(f"Error renaming {codename}: {e}"))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f"Successfully updated {count} permission names."))
|
||||
@ -0,0 +1,53 @@
|
||||
# Generated by Django 5.2.7 on 2026-02-04 20:45
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0009_worker_date_of_employment_worker_id_photo_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='expenselineitem',
|
||||
options={'verbose_name': 'Expense Line Item', 'verbose_name_plural': 'Expense Line Items'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='expensereceipt',
|
||||
options={'verbose_name': 'Expense Receipt', 'verbose_name_plural': 'Expense Receipts'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='loan',
|
||||
options={'verbose_name': 'Loan', 'verbose_name_plural': 'Loans'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='payrolladjustment',
|
||||
options={'verbose_name': 'Payroll Adjustment', 'verbose_name_plural': 'Payroll Adjustments'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='payrollrecord',
|
||||
options={'verbose_name': 'Payroll Record', 'verbose_name_plural': 'Payroll Records'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='project',
|
||||
options={'verbose_name': 'Project', 'verbose_name_plural': 'Projects'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='team',
|
||||
options={'verbose_name': 'Team', 'verbose_name_plural': 'Teams'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='userprofile',
|
||||
options={'verbose_name': 'User Profile', 'verbose_name_plural': 'User Profiles'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='worker',
|
||||
options={'verbose_name': 'Worker', 'verbose_name_plural': 'Workers'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='worklog',
|
||||
options={'verbose_name': 'Work Log / Attendance', 'verbose_name_plural': 'Work Logs / Attendance'},
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -9,6 +9,10 @@ class UserProfile(models.Model):
|
||||
pin = models.CharField(max_length=4, help_text="4-digit PIN for login")
|
||||
is_admin = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "User Profile"
|
||||
verbose_name_plural = "User Profiles"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username}'s profile"
|
||||
|
||||
@ -19,6 +23,10 @@ class Project(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Project"
|
||||
verbose_name_plural = "Projects"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@ -37,6 +45,10 @@ class Worker(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Worker"
|
||||
verbose_name_plural = "Workers"
|
||||
|
||||
@property
|
||||
def day_rate(self):
|
||||
return self.monthly_salary / Decimal('20.0')
|
||||
@ -56,6 +68,10 @@ class Team(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Team"
|
||||
verbose_name_plural = "Teams"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@ -66,6 +82,10 @@ class WorkLog(models.Model):
|
||||
supervisor = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
|
||||
notes = models.TextField(blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Work Log / Attendance"
|
||||
verbose_name_plural = "Work Logs / Attendance"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.date} - {self.project.name}"
|
||||
|
||||
@ -76,6 +96,10 @@ class PayrollRecord(models.Model):
|
||||
work_logs = models.ManyToManyField(WorkLog, related_name='paid_in')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Payroll Record"
|
||||
verbose_name_plural = "Payroll Records"
|
||||
|
||||
def __str__(self):
|
||||
return f"Payment to {self.worker.name} on {self.date}"
|
||||
|
||||
@ -87,6 +111,10 @@ class Loan(models.Model):
|
||||
reason = models.TextField(blank=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Loan"
|
||||
verbose_name_plural = "Loans"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk: # On creation
|
||||
self.balance = self.amount
|
||||
@ -112,6 +140,10 @@ class PayrollAdjustment(models.Model):
|
||||
description = models.CharField(max_length=255)
|
||||
type = models.CharField(max_length=20, choices=ADJUSTMENT_TYPES, default='DEDUCTION')
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Payroll Adjustment"
|
||||
verbose_name_plural = "Payroll Adjustments"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.get_type_display()} - {self.amount} for {self.worker.name}"
|
||||
|
||||
@ -142,6 +174,10 @@ class ExpenseReceipt(models.Model):
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Expense Receipt"
|
||||
verbose_name_plural = "Expense Receipts"
|
||||
|
||||
def __str__(self):
|
||||
return f"Receipt from {self.vendor} - {self.date}"
|
||||
|
||||
@ -150,5 +186,9 @@ class ExpenseLineItem(models.Model):
|
||||
product = models.CharField(max_length=255, verbose_name="Product/Item")
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Expense Line Item"
|
||||
verbose_name_plural = "Expense Line Items"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.product} - {self.amount}"
|
||||
Loading…
x
Reference in New Issue
Block a user