1. accounts新增role
2. 修改权限校验逻辑
3. 修改使用pandas导出
This commit is contained in:
彭森 2024-06-26 11:09:07 +08:00
parent dd96f1dcdb
commit dd5faba1de
7 changed files with 69 additions and 46 deletions

View File

@ -5,13 +5,20 @@ from application.hrm_mgnt.models import EmployeeInformation
class AccountProfile(models.Model):
ROLE_CHOICES = [
('all_permissions', 'All Permissions'),
('department_permissions', 'Department Permissions'),
('own_permissions', 'Own Permissions'),
]
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
employee_information = models.OneToOneField(EmployeeInformation, on_delete=models.CASCADE, related_name='account_profile', verbose_name='员工信息')
role = models.CharField(max_length=255, choices=ROLE_CHOICES, verbose_name='角色', default='own_permissions')
class Meta:
verbose_name = '账户信息'
verbose_name_plural = '账户信息'
def __str__(self):
return self.user.username
return self.employee_information.name

View File

@ -55,3 +55,11 @@ class EmployeeProjectIncomeSettlementForm(forms.ModelForm):
'contribution_rate': forms.TextInput(attrs={'class': 'form-control', 'placeholder': '贡献率'}),
'sales_income': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '销售收入(元)'}),
}
def __init__(self, *args, **kwargs):
super(EmployeeProjectIncomeSettlementForm, self).__init__(*args, **kwargs)
self.fields['primary_department'] = forms.ChoiceField(
choices=[('', '---------')] + [(dept.department_name, dept.department_name) for dept in PrimaryDepartment.objects.all()],
widget=forms.Select(attrs={'class': 'form-control'}),
label="一级部门")

View File

@ -62,12 +62,6 @@ class ProjectLedger(models.Model):
verbose_name = '项目台账'
verbose_name_plural = '项目台账'
permissions = [
('view_all', 'Can view all records'),
('view_department', 'Can view department records'),
('view_own', 'Can view own records')
]
def __str__(self):
return self.project_name
@ -254,6 +248,7 @@ class EmployeeProjectIncomeSettlement(models.Model):
blank=True
)
name = models.CharField(max_length=255, verbose_name='姓名', help_text='员工姓名', null=True, blank=True)
primary_department = models.CharField(max_length=255, verbose_name='一级部门', null=True, blank=True)
contribution_rate = models.DecimalField(
max_digits=5,
decimal_places=2,
@ -276,16 +271,26 @@ class EmployeeProjectIncomeSettlement(models.Model):
verbose_name = '项目组员收入结算表'
verbose_name_plural = '项目组员收入结算表'
permissions = [
('view_all', 'Can view all records'),
('view_department', 'Can view department records'),
('view_own', 'Can view own records')
]
def __str__(self):
return f"Record #{self.record_id} - Project: {self.project_name}, Year-Month: {self.year_month}, Employee: {self.name or 'N/A'}"
def save(self, *args, **kwargs):
primary_department_name = PrimaryDepartment.objects.filter(department_name=self.primary_department).first()
name = EmployeeInformation.objects.filter(name=self.name).first()
if self.primary_department:
if not primary_department_name:
raise ValueError("一级部门不存在")
if self.name:
if not name:
raise ValueError("姓名不存在")
if self.pk is None:
# 新增操作,进行唯一性校验
if EmployeeProjectIncomeSettlement.objects.filter(project_name=self.project_name, year_month=self.year_month, name=self.name, primary_department=self.primary_department).exists():
raise IntegrityError("该部门下的员工在同一年月的同一项目下已存在一个项目结算。")
# 只在贡献率不为空时计算销售收入
if all([self.contribution_rate, self.total_amount_including_tax]):
self.sales_income = self.total_amount_including_tax * (self.contribution_rate / 100)

View File

@ -241,7 +241,7 @@ def proj_ledger_list_delete(request):
@custom_permission_required('pjt_mgnt.view_employeeprojectincomesettlement')
@permission_based_queryset('pjt_mgnt', 'EmployeeProjectIncomeSettlement', 'record_id', 'name')
@permission_based_queryset('pjt_mgnt', 'EmployeeProjectIncomeSettlement', 'record_id', 'name', 'primary_department')
def emp_proj_income_list_view(request):
"""
基础数据-项目管理-项目组员收入结算表-列表视图
@ -354,8 +354,8 @@ def emp_proj_income_list_modify(request):
except ValueError:
return JsonResponse({"message": "无效的日期格式"}, status=400)
if 'record_id' in request.POST:
instance = EmployeeProjectIncomeSettlement.objects.get(record_id=request.POST['record_id'])
if 'id' in request.POST:
instance = EmployeeProjectIncomeSettlement.objects.get(record_id=request.POST['id'])
form = EmployeeProjectIncomeSettlementForm(data, instance=instance)
else:
form = EmployeeProjectIncomeSettlementForm(data)
@ -367,9 +367,9 @@ def emp_proj_income_list_modify(request):
form_html = render_to_string('form_partial.html', {'form': form}, request)
return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400)
elif request.method == 'GET':
if 'record_id' in request.GET:
if 'id' in request.GET:
try:
instance = EmployeeProjectIncomeSettlement.objects.get(record_id=request.GET['record_id'])
instance = EmployeeProjectIncomeSettlement.objects.get(record_id=request.GET['id'])
form = EmployeeProjectIncomeSettlementForm(instance=instance)
form.fields['year_month'].initial = instance.year_month.strftime('%Y-%m')
except EmployeeProjectIncomeSettlement.DoesNotExist:

View File

@ -67,7 +67,7 @@ class MembershipAccountsRegistryForm(forms.ModelForm):
class StoredValueCardRegistrationForm(forms.ModelForm):
class Meta:
model = StoredValueCardRegistration
fields = '__all__'
exclude = ['usage_records']
widgets = {
'merchant_name': forms.TextInput(attrs={'class': 'form-control'}),
'merchant_type': forms.TextInput(attrs={'class': 'form-control'}),

View File

@ -42,21 +42,18 @@ def permission_based_queryset(app_name, model_name, id_field, leader_field=None,
except AccountProfile.DoesNotExist:
return JsonResponse({'message': '您的账户未关联到员工信息,请联系管理员。'}, status=405)
view_all_perm = f'{app_name}.view_all'
view_department_perm = f'{app_name}.view_department'
model = apps.get_model(app_name, model_name)
if current_user.has_perm(view_all_perm):
if account_profile.role == 'all_permissions':
query_set = model.objects.all().order_by(f'-{id_field}')
elif department_field and current_user.has_perm(view_department_perm):
elif department_field and account_profile.role == 'department_permissions':
filter_kwargs = {department_field: employee.primary_department}
query_set = model.objects.filter(**filter_kwargs).order_by(f'-{id_field}')
elif leader_field:
elif leader_field and account_profile.role == 'own_permissions':
filter_kwargs = {leader_field: employee.name}
query_set = model.objects.filter(**filter_kwargs).order_by(f'-{id_field}')
else:
return JsonResponse({'message': '您没有权限查看任何数据。'}, status=403)
query_set = model.objects.none()
request.query_set = query_set

View File

@ -1,23 +1,17 @@
import json
import uuid
from datetime import datetime
from urllib.parse import quote
from django.apps import apps
from django.core.exceptions import ValidationError
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse, HttpResponse
from django.utils.module_loading import import_string
from django.utils.timezone import make_aware
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_protect
from application.fac_mgnt.models import InvoiceRecord
from application.org_mgnt.models import SecondaryDepartment, PrimaryDepartment
from application.pjt_mgnt.models import ProjectLedger
import pandas as pd
from django.http import HttpResponse
from django.utils.http import quote
from django.apps import apps
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from datetime import datetime
from django.utils.timezone import make_aware
def error_page(request):
return render(request, 'error_page.html')
@ -128,16 +122,28 @@ def export_data(request):
field_names = [field.name for field in model._meta.fields]
verbose_names = [field.verbose_name for field in model._meta.fields]
# 创建 DataFrame 并设置 verbose_name 作为列名
df = pd.DataFrame(data, columns=field_names)
df.columns = verbose_names
# 创建 Excel 工作簿
wb = Workbook()
ws = wb.active
# 写入表头
for col_num, verbose_name in enumerate(verbose_names, 1):
col_letter = get_column_letter(col_num)
ws[f'{col_letter}1'] = verbose_name
# 写入数据
for row_num, record in enumerate(data, 2):
for col_num, field_name in enumerate(field_names, 1):
col_letter = get_column_letter(col_num)
# 如果字段在记录中不存在,使用空字符串
ws[f'{col_letter}{row_num}'] = record.get(field_name, '')
# 使用模型的 verbose_name 作为文件名的一部分
model_verbose_name = model._meta.verbose_name + '导出结果.xlsx'
encoded_filename = quote(model_verbose_name)
response = HttpResponse(content_type='application/vnd.ms-excel')
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}'
df.to_excel(response, index=False)
wb.save(response)
return response
return response