2637 lines
119 KiB
Python
2637 lines
119 KiB
Python
import json
|
||
from decimal import Decimal
|
||
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.http import JsonResponse, Http404
|
||
from django.shortcuts import render, get_object_or_404
|
||
from django.template.loader import render_to_string
|
||
from django.urls import reverse
|
||
from django.views.decorators.csrf import csrf_protect
|
||
from django.views.decorators.http import require_POST, require_http_methods
|
||
|
||
from application.fac_mgnt.forms import *
|
||
from application.fac_mgnt.models import *
|
||
from application.hrm_mgnt.models import PerformanceEvaluation
|
||
from common.auth import custom_permission_required
|
||
from common.utils.page_helper import paginate_query_and_assign_numbers
|
||
|
||
from django.http import JsonResponse
|
||
from django.core.files.storage import default_storage
|
||
from django.conf import settings
|
||
from openpyxl import load_workbook
|
||
from django.apps import apps
|
||
from rest_framework.serializers import ModelSerializer
|
||
from django.core.exceptions import ValidationError
|
||
import os
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_expensetype')
|
||
def exp_type_list_view(request):
|
||
query_set = ExpenseType.objects.filter().order_by('-type_id')
|
||
expense_type = request.GET.get('expense_type', '')
|
||
if expense_type:
|
||
query_set = query_set.filter(expense_type__icontains=expense_type)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&expense_type={}'.format(expense_type)
|
||
template_name = "财会管理-费用类型-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.ExpenseType',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "费用类型", "name": "exp_type_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "select", "id": "expense_type", "name": "expense_type", "label": "费用类型",
|
||
"options": [{"value": "差旅费", "display": "差旅费"}, {"value": "办公费", "display": "办公费"}]}
|
||
],
|
||
"table_exclude_field_name": ['type_id'],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"type_id": {"type": "text", "width": "180px"},
|
||
"expense_type": {"type": "text", "width": "180px"},
|
||
"actions": {"type": "actions", "width": "100px"}
|
||
}
|
||
},
|
||
"query_params": query_params,
|
||
"form_action_url": 'exp_type_list',
|
||
"modify_url": reverse("exp_type_list_modify"),
|
||
"add_url": reverse("exp_type_list_add"),
|
||
"delete_url": reverse("exp_type_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_expensetype')
|
||
def exp_type_list_add(request):
|
||
if request.method == 'POST':
|
||
form = ExpenseTypeForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = ExpenseTypeForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_expensetype')
|
||
def exp_type_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = ExpenseType.objects.get(type_id=request.POST['id'])
|
||
form = ExpenseTypeForm(request.POST, instance=instance)
|
||
else:
|
||
form = ExpenseTypeForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = ExpenseType.objects.get(type_id=request.GET['id'])
|
||
form = ExpenseTypeForm(instance=instance)
|
||
except ExpenseType.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = ExpenseTypeForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_expensetype')
|
||
def exp_type_list_delete(request):
|
||
if request.method == 'GET':
|
||
type_id = request.GET.get('type_id')
|
||
ExpenseType.objects.filter(type_id=type_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_expensedetail')
|
||
def exp_detail_list_view(request):
|
||
query_set = ExpenseDetail.objects.filter().order_by('-detail_id')
|
||
expense_detail = request.GET.get('expense_detail', '')
|
||
if expense_detail:
|
||
query_set = query_set.filter(expense_detail__icontains=expense_detail)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&expense_detail={}'.format(expense_detail)
|
||
template_name = "财会管理-费用明细-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.ExpenseDetail',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "费用明细", "name": "exp_detail_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "select", "id": "expense_detail", "name": "expense_detail", "label": "费用明细",
|
||
"options": [{"value": "工资", "display": "工资"}, {"value": "社保", "display": "社保"},
|
||
{"value": "公积金", "display": "公积金"}]}
|
||
],
|
||
"table_exclude_field_name": ['detail_id'],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse_exp"),
|
||
"save_url": reverse("save_excel_table_data_exp"),
|
||
"fields_preview_config": {
|
||
"type_id": {"type": "text", "width": "180px"},
|
||
"expense_detail": {"type": "text", "width": "180px"},
|
||
}
|
||
},
|
||
"query_params": query_params,
|
||
"form_action_url": 'exp_detail_list',
|
||
"modify_url": reverse("exp_detail_list_modify"),
|
||
"add_url": reverse("exp_detail_list_add"),
|
||
"delete_url": reverse("exp_detail_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_expensedetail')
|
||
def exp_detail_list_add(request):
|
||
if request.method == 'POST':
|
||
form = ExpenseDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = ExpenseDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_expensedetail')
|
||
def exp_detail_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = ExpenseDetail.objects.get(detail_id=request.POST['id'])
|
||
form = ExpenseDetailForm(request.POST, instance=instance)
|
||
else:
|
||
form = ExpenseDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = ExpenseDetail.objects.get(detail_id=request.GET['id'])
|
||
form = ExpenseDetailForm(instance=instance)
|
||
except ExpenseDetail.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = ExpenseDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_expensedetail')
|
||
def exp_detail_list_delete(request):
|
||
if request.method == 'GET':
|
||
detail_id = request.GET.get('detail_id')
|
||
ExpenseDetail.objects.filter(detail_id=detail_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_groupannualbudget')
|
||
def gpb_list_view(request):
|
||
query_set = GroupAnnualBudget.objects.filter().order_by('-budget_id')
|
||
primary_department = request.GET.get('primary_department', '')
|
||
expense_detail = request.GET.get('expense_detail', '')
|
||
expense_type = request.GET.get('expense_type', '')
|
||
year = request.GET.get('year', '')
|
||
if primary_department:
|
||
query_set = query_set.filter(primary_department__icontains=primary_department)
|
||
if expense_detail:
|
||
query_set = query_set.filter(expense_detail__expense_detail__icontains=expense_detail)
|
||
if expense_type:
|
||
query_set = query_set.filter(expense_type__expense_type__icontains=expense_type)
|
||
if year:
|
||
query_set = query_set.filter(year__icontains=year)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&primary_department={}&expense_detail={}&expense_type={}&year={}'.format(
|
||
primary_department, expense_detail, expense_type, year)
|
||
template_name = "财会管理-集团年度预算-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.GroupAnnualBudget',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "集团年度预算", "name": "gpb_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "select", "id": "primary_department", "name": "primary_department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]},
|
||
{"type": "select", "id": "expense_detail", "name": "expense_detail", "label": "费用明细",
|
||
"options": [{"value": "办公用品购置", "display": "办公用品购置"},
|
||
{"value": "员工出差住宿费", "display": "员工出差住宿费"},
|
||
{"value": "员工技能培训", "display": "员工技能培训"},
|
||
{"value": "软件订阅服务费", "display": "软件订阅服务费"},
|
||
{"value": "市场推广活动费", "display": "市场推广活动费"}]},
|
||
{"type": "select", "id": "expense_type", "name": "expense_type", "label": "费用类型",
|
||
"options": [{"value": "办公费用", "display": "办公费用"},
|
||
{"value": "差旅费用", "display": "差旅费用"},
|
||
{"value": "培训费用", "display": "培训费用"},
|
||
{"value": "技术服务费", "display": "技术服务费"},
|
||
{"value": "营销推广费", "display": "营销推广费"}]},
|
||
{"type": "select", "id": "year", "name": "year", "label": "年度",
|
||
"options": [{"value": "2024", "display": "2024"}, {"value": "2023", "display": "2023"},
|
||
{"value": "2022", "display": "2022"}, {"value": "2021", "display": "2021"},
|
||
{"value": "2020", "display": "2020"}]}
|
||
],
|
||
"table_exclude_field_name": ['budget_id'],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse_gab"),
|
||
"save_url": reverse("save_excel_table_data_gab"),
|
||
"fields_preview_config": {
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"year": {"type": "number", "width": "100px"},
|
||
"expense_type": {"type": "text", "width": "180px"},
|
||
"expense_detail": {"type": "text", "width": "180px"},
|
||
"amount": {"type": "number", "width": "100px"},
|
||
}
|
||
},
|
||
"query_params": query_params,
|
||
"form_action_url": 'gpb_list',
|
||
"modify_url": reverse("gpb_list_modify"),
|
||
"add_url": reverse("gpb_list_add"),
|
||
"delete_url": reverse("gpb_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_groupannualbudget')
|
||
def gpb_list_add(request):
|
||
if request.method == 'POST':
|
||
form = GroupAnnualBudgetForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = GroupAnnualBudgetForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_groupannualbudget')
|
||
def gpb_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = GroupAnnualBudget.objects.get(budget_id=request.POST['id'])
|
||
form = GroupAnnualBudgetForm(request.POST, instance=instance)
|
||
else:
|
||
form = GroupAnnualBudgetForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = GroupAnnualBudget.objects.get(budget_id=request.GET['id'])
|
||
form = GroupAnnualBudgetForm(instance=instance)
|
||
except GroupAnnualBudget.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = GroupAnnualBudgetForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_groupannualbudget')
|
||
def gpb_list_delete(request):
|
||
if request.method == 'GET':
|
||
budget_id = request.GET.get('budget_id')
|
||
GroupAnnualBudget.objects.filter(budget_id=budget_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_laborcostdetail')
|
||
def lcb_list_view(request):
|
||
query_set = LaborCostDetail.objects.filter().order_by('-record_id')
|
||
name = request.GET.get('name', '')
|
||
department = request.GET.get('department', '')
|
||
if name:
|
||
query_set = query_set.filter(name__icontains=name)
|
||
if department:
|
||
query_set = query_set.filter(primary_department__icontains=department)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&name={}&department={}'.format(name, department)
|
||
template_name = "财会管理-人工费用明细-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.LaborCostDetail',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "人工费明细", "name": "lcb_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "name", "name": "name", "label": "姓名", "placeholder": "请输入姓名"},
|
||
{"type": "select", "id": "department", "name": "department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"year_month": {"type": "text", "width": "180px"},
|
||
"name": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"secondary_department": {"type": "text", "width": "180px"},
|
||
"attendance_days": {"type": "number", "width": "100px"},
|
||
"gross_salary": {"type": "number", "width": "100px"},
|
||
"attendance_reward": {"type": "number", "width": "100px"},
|
||
"lunch_allowance": {"type": "number", "width": "100px"},
|
||
"other_monetary_benefits": {"type": "number", "width": "100px"},
|
||
"social_security_deduction": {"type": "number", "width": "100px"},
|
||
"housing_fund_deduction": {"type": "number", "width": "100px"},
|
||
"net_salary": {"type": "number", "width": "100px"},
|
||
"employer_social_security": {"type": "number", "width": "100px"},
|
||
"employer_housing_fund": {"type": "number", "width": "100px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['record_id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'lcb_list',
|
||
"modify_url": reverse("lcb_list_modify"),
|
||
"add_url": reverse("lcb_list_add"),
|
||
"delete_url": reverse("lcb_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_laborcostdetail')
|
||
def lcb_list_add(request):
|
||
if request.method == 'POST':
|
||
form = LaborCostDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = LaborCostDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_laborcostdetail')
|
||
def lcb_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = LaborCostDetail.objects.get(record_id=request.POST['id'])
|
||
form = LaborCostDetailForm(request.POST, instance=instance)
|
||
else:
|
||
form = LaborCostDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = LaborCostDetail.objects.get(record_id=request.GET['id'])
|
||
form = LaborCostDetailForm(instance=instance)
|
||
except LaborCostDetail.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = LaborCostDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_laborcostdetail')
|
||
def lcb_list_delete(request):
|
||
if request.method == 'GET':
|
||
record_id = request.GET.get('record_id')
|
||
LaborCostDetail.objects.filter(record_id=record_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_reimbursementdetail')
|
||
def rbm_detail_list_view(request):
|
||
query_set = ReimbursementDetail.objects.filter().order_by('-record_id')
|
||
name = request.GET.get('name', '')
|
||
year_month = request.GET.get('year_month', '')
|
||
primary_department = request.GET.get('primary_department', '')
|
||
project_name = request.GET.get('project_name', '')
|
||
if name:
|
||
query_set = query_set.filter(name__icontains=name)
|
||
if year_month:
|
||
query_set = query_set.filter(year_month__icontains=year_month)
|
||
if primary_department:
|
||
query_set = query_set.filter(primary_department__icontains=primary_department)
|
||
if project_name:
|
||
query_set = query_set.filter(project_name__icontains=project_name)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&name={}&year_month={}&primary_department={}&project_name={}'.format(
|
||
name, year_month, primary_department, project_name
|
||
)
|
||
template_name = "财会管理-报销明细-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.ReimbursementDetail',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "报销明细", "name": "rbm_detail_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "name", "name": "name", "label": "姓名", "placeholder": "请输入姓名"},
|
||
{"type": "month", "id": "year_month", "name": "year_month", "label": "年月"},
|
||
{"type": "select", "id": "primary_department", "name": "primary_department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]},
|
||
{"type": "text", "id": "project_name", "name": "project_name", "label": "项目名称",
|
||
"placeholder": "请输入项目名称"}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"record_id": {"type": "number", "width": "180px"},
|
||
"year_month": {"type": "date", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"name": {"type": "text", "width": "180px"},
|
||
"is_project_based": {"type": "select", "width": "100px", "options": ["是", "否"]},
|
||
"project_id": {"type": "number", "width": "180px"},
|
||
"project_name": {"type": "text", "width": "180px"},
|
||
"expense_type": {"type": "text", "width": "180px"},
|
||
"expense_details": {"type": "text", "width": "180px"},
|
||
"expense_description": {"type": "textarea", "width": "300px"},
|
||
"expense_date": {"type": "date", "width": "180px"},
|
||
"amount": {"type": "number", "width": "100px"},
|
||
"actions": {"type": "actions", "width": "100px"}
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['record_id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'rbm_detail_list',
|
||
"modify_url": reverse("rbm_detail_list_modify"),
|
||
"add_url": reverse("rbm_detail_list_add"),
|
||
"delete_url": reverse("rbm_detail_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_reimbursementdetail')
|
||
def rbm_detail_list_add(request):
|
||
if request.method == 'POST':
|
||
form = ReimbursementDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = ReimbursementDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_reimbursementdetail')
|
||
def rbm_detail_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = ReimbursementDetail.objects.get(record_id=request.POST['id'])
|
||
form = ReimbursementDetailForm(request.POST, instance=instance)
|
||
else:
|
||
form = ReimbursementDetailForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = ReimbursementDetail.objects.get(record_id=request.GET['id'])
|
||
form = ReimbursementDetailForm(instance=instance)
|
||
except ReimbursementDetail.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = ReimbursementDetailForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_reimbursementdetail')
|
||
def rbm_detail_list_delete(request):
|
||
if request.method == 'GET':
|
||
record_id = request.GET.get('record_id')
|
||
ReimbursementDetail.objects.filter(record_id=record_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_bonuscategoty')
|
||
def bns_cat_list_view(request):
|
||
query_set = BonusCategory.objects.filter().order_by('-category_id')
|
||
category_name = request.GET.get('category_name', '')
|
||
if category_name:
|
||
query_set = query_set.filter(category_name__icontains=category_name)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&category_name={}'.format(category_name)
|
||
template_name = "财会管理-奖金类别-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.BonusCategory',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "奖金类别表", "name": "bns_cat_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "category_name", "name": "category_name", "label": "奖金类别",
|
||
"placeholder": "请输入奖金类别"}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"category_name": {"type": "text", "width": "180px"},
|
||
"description": {"type": "text", "width": "300px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['category_id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'bns_cat_list',
|
||
"modify_url": reverse("bns_cat_list_modify"),
|
||
"add_url": reverse("bns_cat_list_add"),
|
||
"delete_url": reverse("bns_cat_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_bonuscategoty')
|
||
def bns_cat_list_add(request):
|
||
if request.method == 'POST':
|
||
form = BonusCategoryForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = BonusCategoryForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_bonuscategoty')
|
||
def bns_cat_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = BonusCategory.objects.get(category_id=request.POST['id'])
|
||
form = BonusCategoryForm(request.POST, instance=instance)
|
||
else:
|
||
form = BonusCategoryForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = BonusCategory.objects.get(category_id=request.GET['id'])
|
||
form = BonusCategoryForm(instance=instance)
|
||
except BonusCategory.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = BonusCategoryForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_bonuscategoty')
|
||
def bns_cat_list_delete(request):
|
||
if request.method == 'GET':
|
||
category_id = request.GET.get('category_id')
|
||
BonusCategory.objects.filter(category_id=category_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_bonuscategoty')
|
||
def bns_alloc_list_view(request):
|
||
query_set = BonusAllocation.objects.filter().order_by('-record_id')
|
||
name = request.GET.get('name', '')
|
||
year_month = request.GET.get('year_month', '')
|
||
department = request.GET.get('department', '')
|
||
if name:
|
||
query_set = query_set.filter(name__icontains=name)
|
||
if year_month:
|
||
query_set = query_set.filter(year_month__icontains=year_month)
|
||
if department:
|
||
query_set = query_set.filter(primary_department__icontains=department)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&name={}&year_month={}&department={}'.format(name, year_month, department)
|
||
template_name = "财会管理-奖金分配-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.BonusAllocation',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "奖金分配表", "name": "bns_alloc_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "name", "name": "name", "label": "姓名", "placeholder": "请输入姓名"},
|
||
{"type": "month", "id": "year_month", "name": "year_month", "label": "年月"},
|
||
{"type": "select", "id": "department", "name": "department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"year_month": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"secondary_department": {"type": "text", "width": "180px"},
|
||
"name": {"type": "text", "width": "180px"},
|
||
"bonus_category": {"type": "text", "width": "180px"},
|
||
"award_amount": {"type": "number", "width": "100px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['record_id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'bns_alloc_list',
|
||
"modify_url": reverse("bns_alloc_list_modify"),
|
||
"add_url": reverse("bns_alloc_list_add"),
|
||
"delete_url": reverse("bns_alloc_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_bonuscategoty')
|
||
def bns_alloc_list_add(request):
|
||
if request.method == 'POST':
|
||
form = BonusAllocationForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = BonusAllocationForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_bonuscategoty')
|
||
def bns_alloc_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = BonusAllocation.objects.get(record_id=request.POST['id'])
|
||
form = BonusAllocationForm(request.POST, instance=instance)
|
||
else:
|
||
form = BonusAllocationForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = BonusAllocation.objects.get(record_id=request.GET['id'])
|
||
form = BonusAllocationForm(instance=instance)
|
||
except BonusAllocation.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = BonusAllocationForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_bonuscategoty')
|
||
def bns_alloc_list_delete(request):
|
||
if request.method == 'GET':
|
||
record_id = request.GET.get('record_id')
|
||
BonusAllocation.objects.filter(record_id=record_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_taxrecord')
|
||
def tax_rec_list_view(request):
|
||
query_set = TaxRecord.objects.filter().order_by('-id')
|
||
tax_entity = request.GET.get('tax_entity', '')
|
||
year = request.GET.get('year', '')
|
||
if tax_entity:
|
||
query_set = query_set.filter(tax_entity__icontains=tax_entity)
|
||
if year:
|
||
query_set = query_set.filter(year__icontains=year)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&tax_entity={}&year={}'.format(tax_entity, year)
|
||
template_name = "财会管理-纳税记录-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.TaxRecord',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "纳税记录表", "name": "tax_rec_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "tax_entity", "name": "tax_entity", "label": "纳税主体",
|
||
"placeholder": "请输入纳税主体"},
|
||
{"type": "select", "id": "year", "name": "year", "label": "年度",
|
||
"options": [{"value": "2024", "display": "2024"}, {"value": "2023", "display": "2023"},
|
||
{"value": "2022", "display": "2022"}, {"value": "2021", "display": "2021"},
|
||
{"value": "2020", "display": "2020"}]}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"tax_entity": {"type": "text", "width": "180px"},
|
||
"year": {"type": "number", "width": "100px"},
|
||
"tax_type": {"type": "select", "width": "180px", "options": ["增值税", "消费税"]},
|
||
"tax_period": {"type": "select", "width": "180px", "options": ["月度", "季度", "年度"]},
|
||
"tax_date": {"type": "date", "width": "180px"},
|
||
"tax_amount": {"type": "number", "width": "100px"},
|
||
"annual_cumulative": {"type": "number", "width": "100px"},
|
||
"note": {"type": "text", "width": "300px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'tax_rec_list',
|
||
"modify_url": reverse("tax_rec_list_modify"),
|
||
"add_url": reverse("tax_rec_list_add"),
|
||
"delete_url": reverse("tax_rec_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_taxrecord')
|
||
def tax_rec_list_add(request):
|
||
if request.method == 'POST':
|
||
form = TaxRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = TaxRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_taxrecord')
|
||
def tax_rec_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = TaxRecord.objects.get(id=request.POST['id'])
|
||
form = TaxRecordForm(request.POST, instance=instance)
|
||
else:
|
||
form = TaxRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = TaxRecord.objects.get(id=request.GET['id'])
|
||
form = TaxRecordForm(instance=instance)
|
||
except TaxRecord.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = TaxRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_taxrecord')
|
||
def tax_rec_list_delete(request):
|
||
if request.method == 'GET':
|
||
target_id = request.GET.get('target_id')
|
||
TaxRecord.objects.filter(id=target_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_electronicinvoiceledger')
|
||
def inv_ledger_list_view(request):
|
||
query_set = ElectronicInvoiceLedger.objects.filter().order_by('-invoice_number')
|
||
expense_party = request.GET.get('expense_party', '')
|
||
primary_department = request.GET.get('primary_department', '')
|
||
invoice_code = request.GET.get('invoice_code', '')
|
||
invoice_number = request.GET.get('invoice_number', '')
|
||
invoice_date = request.GET.get('invoice_date', '')
|
||
if expense_party:
|
||
query_set = query_set.filter(expense_party__icontains=expense_party)
|
||
if primary_department:
|
||
query_set = query_set.filter(primary_department__icontains=primary_department)
|
||
if invoice_code:
|
||
query_set = query_set.filter(invoice_code__icontains=invoice_code)
|
||
if invoice_number:
|
||
query_set = query_set.filter(invoice_number__icontains=invoice_number)
|
||
if invoice_date:
|
||
query_set = query_set.filter(invoice_date__icontains=invoice_date)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&expense_party={}&primary_department={}&invoice_code={}&invoice_number={}&invoice_date={}'.format(
|
||
expense_party, primary_department, invoice_code, invoice_number, invoice_date)
|
||
template_name = "财会管理-电子发票台账-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.ElectronicInvoiceLedger',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "电子发票台账", "name": "inv_ledger_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "expense_party", "name": "expense_party", "label": "费用当事人",
|
||
"placeholder": "请输入费用当事人"},
|
||
{"type": "select", "id": "primary_department", "name": "primary_department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]},
|
||
{"type": "text", "id": "invoice_code", "name": "invoice_code", "label": "发票代码",
|
||
"placeholder": "请输入发票代码"},
|
||
{"type": "text", "id": "invoice_number", "name": "invoice_number", "label": "发票号码",
|
||
"placeholder": "请输入发票号码"},
|
||
{"type": "date", "id": "invoice_date", "name": "invoice_date", "label": "开票日期"}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"expense_party": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"submission_date": {"type": "date", "width": "180px"},
|
||
"invoice_code": {"type": "text", "width": "180px"},
|
||
"invoice_number": {"type": "text", "width": "180px"},
|
||
"invoice_date": {"type": "date", "width": "180px"},
|
||
"buyer_name": {"type": "text", "width": "180px"},
|
||
"buyer_tax_number": {"type": "text", "width": "180px"},
|
||
"seller_name": {"type": "text", "width": "180px"},
|
||
"seller_tax_number": {"type": "text", "width": "180px"},
|
||
"goods_or_services_name": {"type": "text", "width": "180px"},
|
||
"tax_rate": {"type": "number", "width": "100px"},
|
||
"total_amount_including_tax": {"type": "number", "width": "100px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'inv_ledger_list',
|
||
"modify_url": reverse("inv_ledger_list_modify"),
|
||
"add_url": reverse("inv_ledger_list_add"),
|
||
"delete_url": reverse("inv_ledger_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_electronicinvoiceledger')
|
||
def inv_ledger_list_add(request):
|
||
if request.method == 'POST':
|
||
form = ElectronicInvoiceLedgerForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = ElectronicInvoiceLedgerForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_electronicinvoiceledger')
|
||
def inv_ledger_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = ElectronicInvoiceLedger.objects.get(invoice_number=request.POST['id'])
|
||
form = ElectronicInvoiceLedgerForm(request.POST, instance=instance)
|
||
else:
|
||
form = ElectronicInvoiceLedgerForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = ElectronicInvoiceLedger.objects.get(invoice_number=request.GET['id'])
|
||
form = ElectronicInvoiceLedgerForm(instance=instance)
|
||
except ElectronicInvoiceLedger.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = ElectronicInvoiceLedgerForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_electronicinvoiceledger')
|
||
def inv_ledger_list_delete(request):
|
||
if request.method == 'GET':
|
||
target_id = request.GET.get('target_id')
|
||
ElectronicInvoiceLedger.objects.filter(invoice_number=target_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_invoicerecord')
|
||
def inv_rec_list_view(request):
|
||
query_set = InvoiceRecord.objects.filter().order_by('-record_id')
|
||
project_name = request.GET.get('project_name', '')
|
||
project_nature = request.GET.get('project_nature', '')
|
||
department = request.GET.get('department', '')
|
||
invoice_date = request.GET.get('invoice_date', '')
|
||
project_manager = request.GET.get('project_manager', '')
|
||
if project_name:
|
||
query_set = query_set.filter(project_name__icontains=project_name)
|
||
if project_nature:
|
||
query_set = query_set.filter(project_nature__icontains=project_nature)
|
||
if department:
|
||
query_set = query_set.filter(primary_department__icontains=department)
|
||
if invoice_date:
|
||
query_set = query_set.filter(invoice_date__icontains=invoice_date)
|
||
if project_manager:
|
||
query_set = query_set.filter(project_manager__icontains=project_manager)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&project_name={}&project_nature={}&department={}&invoice_date={}&project_manager={}'.format(
|
||
project_name, project_nature, department, invoice_date, project_manager)
|
||
template_name = "财会管理-开票记录-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.InvoiceRecord',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "开票记录", "name": "inv_rec_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "project_name", "name": "project_name", "label": "项目名称",
|
||
"placeholder": "请输入项目名称"},
|
||
{"type": "select", "id": "project_nature", "name": "project_nature", "label": "项目性质",
|
||
"options": [{"value": "新增", "display": "新增"}, {"value": "存续", "display": "存续"},
|
||
{"value": "新增及存续", "display": "新增及存续"},
|
||
{"value": "老客户新业务", "display": "老客户新业务"}]},
|
||
{"type": "select", "id": "department", "name": "department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]},
|
||
{"type": "date", "id": "invoice_date", "name": "invoice_date", "label": "开票日期"},
|
||
{"type": "text", "id": "project_manager", "name": "project_manager", "label": "项目负责人",
|
||
"placeholder": "请输入项目负责人"}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse_pjt"),
|
||
"save_url": reverse("save_excel_table_data_pjt"),
|
||
"fields_preview_config": {
|
||
"project_name": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"project_manager": {"type": "text", "width": "180px"},
|
||
"nature": {"type": "select", "width": "100px", "options": ["新增", "开票"]},
|
||
"billing_entity": {"type": "text", "width": "180px"},
|
||
"invoice_number": {"type": "text", "width": "180px"},
|
||
"purchase_info": {"type": "text", "width": "180px"},
|
||
"invoice_date": {"type": "date", "width": "180px"},
|
||
"invoice_content": {"type": "text", "width": "180px"},
|
||
"total_amount": {"type": "number", "width": "100px"},
|
||
"tax_rate": {"type": "number", "width": "100px"},
|
||
"amount_excluding_tax": {"type": "number", "width": "100px"},
|
||
"tax_amount": {"type": "number", "width": "100px"},
|
||
"invoice_type": {"type": "select", "width": "100px", "options": ["专票", "普票"]},
|
||
}
|
||
},
|
||
"query_params": query_params,
|
||
"table_exclude_field_name": ['record_id', 'project_id'],
|
||
"form_action_url": 'inv_rec_list',
|
||
"modify_url": reverse("inv_rec_list_modify"),
|
||
"add_url": reverse("inv_rec_list_add"),
|
||
"delete_url": reverse("inv_rec_list_delete"),
|
||
}
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_invoicerecord')
|
||
def inv_rec_list_add(request):
|
||
if request.method == 'POST':
|
||
form = InvoiceRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = InvoiceRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_invoicerecord')
|
||
def inv_rec_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = InvoiceRecord.objects.get(record_id=request.POST['id'])
|
||
form = InvoiceRecordForm(request.POST, instance=instance)
|
||
else:
|
||
form = InvoiceRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = InvoiceRecord.objects.get(record_id=request.GET['id'])
|
||
form = InvoiceRecordForm(instance=instance)
|
||
except InvoiceRecord.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = InvoiceRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_invoicerecord')
|
||
def inv_rec_list_delete(request):
|
||
if request.method == 'GET':
|
||
target_id = request.GET.get('target_id')
|
||
InvoiceRecord.objects.filter(record_id=target_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_repaymentrecord')
|
||
def rep_rec_list_view(request):
|
||
query_set = RepaymentRecord.objects.filter().order_by('-record_id')
|
||
project_name = request.GET.get('project_name', '')
|
||
if project_name:
|
||
query_set = query_set.filter(project_name__icontains=project_name)
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&project_name={}'.format(project_name)
|
||
template_name = "财会管理-回款记录-Excel上传模板.xlsx"
|
||
context = {
|
||
"model_config": 'fac_mgnt.RepaymentRecord',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "回款记录表", "name": "rep_rec_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "project_name", "name": "project_name", "label": "项目名称",
|
||
"placeholder": "请输入项目名称"}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse_rr"),
|
||
"save_url": reverse("save_excel_table_data_rr"),
|
||
"fields_preview_config": {
|
||
"project_name": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"project_manager": {"type": "text", "width": "180px"},
|
||
"repayment_amount": {"type": "number", "width": "100px"},
|
||
}
|
||
},
|
||
"table_exclude_field_name": ['record_id'],
|
||
"query_params": query_params,
|
||
"form_action_url": 'rep_rec_list',
|
||
"modify_url": reverse("rep_rec_list_modify"),
|
||
"add_url": reverse("rep_rec_list_add"),
|
||
"delete_url": reverse("rep_rec_list_delete"),
|
||
}
|
||
return render(request, 'rep_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_repaymentrecord')
|
||
def rep_rec_list_add(request):
|
||
if request.method == 'POST':
|
||
form = RepaymentRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = RepaymentRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_repaymentrecord')
|
||
def rep_rec_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = RepaymentRecord.objects.get(record_id=request.POST['id'])
|
||
form = RepaymentRecordForm(request.POST, instance=instance)
|
||
else:
|
||
form = RepaymentRecordForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = RepaymentRecord.objects.get(record_id=request.GET['id'])
|
||
form = RepaymentRecordForm(instance=instance)
|
||
except RepaymentRecord.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = RepaymentRecordForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_repaymentrecord')
|
||
def rep_rec_list_delete(request):
|
||
if request.method == 'GET':
|
||
target_id = request.GET.get('target_id')
|
||
RepaymentRecord.objects.filter(record_id=target_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_repaymentdetail')
|
||
def get_repayment_details(request, repayment_record_id):
|
||
details = RepaymentDetail.objects.filter(repayment_record_id=repayment_record_id).values(
|
||
'repayment_date', 'repayment_amount')
|
||
return JsonResponse(list(details), safe=False)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.add_repaymentdetail')
|
||
@require_POST
|
||
def add_repayment_detail(request):
|
||
repayment_record_id = request.POST.get('repayment_record_id')
|
||
repayment_date = request.POST.get('repayment_date')
|
||
repayment_amount = request.POST.get('repayment_amount')
|
||
|
||
repayment_record = get_object_or_404(RepaymentRecord, pk=repayment_record_id)
|
||
|
||
# 新增回款详情
|
||
detail = RepaymentDetail.objects.create(
|
||
repayment_record=repayment_record,
|
||
repayment_date=repayment_date,
|
||
repayment_amount=Decimal(repayment_amount)
|
||
)
|
||
|
||
# 更新回款记录表中的回款金额字段
|
||
repayment_record.repayment_amount += Decimal(repayment_amount)
|
||
repayment_record.save()
|
||
|
||
return JsonResponse({
|
||
'record_id': detail.record_id,
|
||
'repayment_date': detail.repayment_date,
|
||
'repayment_amount': detail.repayment_amount,
|
||
})
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.view_employeecommission')
|
||
def emp_comm_list_view(request):
|
||
query_set = EmployeeCommission.objects.filter().order_by('-record_id')
|
||
project_name = request.GET.get('project_name', '')
|
||
name = request.GET.get('name', '')
|
||
primary_department = request.GET.get('primary_department', '')
|
||
|
||
if project_name:
|
||
query_set = query_set.filter(project_name__icontains=project_name)
|
||
if name:
|
||
query_set = query_set.filter(name__icontains=name)
|
||
if primary_department:
|
||
query_set = query_set.filter(primary_department__icontains=primary_department)
|
||
|
||
items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10)
|
||
query_params = '&project_name={}&name={}&primary_department={}'.format(project_name, name, primary_department)
|
||
template_name = "财会管理-员工提成情况-Excel上传模板.xlsx"
|
||
|
||
context = {
|
||
"model_config": 'fac_mgnt.EmployeeCommission',
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "财会管理", "name": "index"},
|
||
{"title": "员工提成情况表", "name": "emp_comm_list"}
|
||
],
|
||
"filters": [
|
||
{"type": "text", "id": "project_name", "name": "project_name", "label": "项目名称",
|
||
"placeholder": "请输入项目名称"},
|
||
{"type": "text", "id": "name", "name": "name", "label": "姓名", "placeholder": "请输入姓名"},
|
||
{"type": "select", "id": "primary_department", "name": "primary_department", "label": "一级部门",
|
||
"options": [{"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"},
|
||
{"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"},
|
||
{"value": "星海", "display": "星海"}]}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse"),
|
||
"save_url": reverse("save_excel_table_data"),
|
||
"fields_preview_config": {
|
||
"project_name": {"type": "text", "width": "180px"},
|
||
"year_month": {"type": "date", "width": "180px"},
|
||
"company_retained": {"type": "number", "width": "100px"},
|
||
"name": {"type": "text", "width": "180px"},
|
||
"primary_department": {"type": "text", "width": "180px"},
|
||
"total_commission": {"type": "number", "width": "100px"},
|
||
"amount_paid": {"type": "number", "width": "100px"},
|
||
"accrued_amount": {"type": "number", "width": "100px"},
|
||
"chairman_fund": {"type": "number", "width": "100px"},
|
||
"actions": {"type": "actions", "width": "100px"}
|
||
}
|
||
},
|
||
"query_params": query_params,
|
||
"table_exclude_field_name": ['record_id'],
|
||
"form_action_url": 'emp_comm_list',
|
||
"modify_url": reverse("emp_comm_list_modify"),
|
||
"add_url": reverse("emp_comm_list_add"),
|
||
"delete_url": reverse("emp_comm_list_delete"),
|
||
}
|
||
|
||
return render(request, 'items_list.html', context)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.add_employeecommission')
|
||
def emp_comm_list_add(request):
|
||
if request.method == 'POST':
|
||
form = EmployeeCommissionForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = EmployeeCommissionForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.change_employeecommission')
|
||
def emp_comm_list_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = EmployeeCommission.objects.get(record_id=request.POST['id'])
|
||
form = EmployeeCommissionForm(request.POST, instance=instance)
|
||
else:
|
||
form = EmployeeCommissionForm(request.POST)
|
||
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = EmployeeCommission.objects.get(record_id=request.GET['id'])
|
||
form = EmployeeCommissionForm(instance=instance)
|
||
except EmployeeCommission.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = EmployeeCommissionForm()
|
||
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
@custom_permission_required('fac_mgnt.delete_employeecommission')
|
||
def emp_comm_list_delete(request):
|
||
if request.method == 'GET':
|
||
target_id = request.GET.get('target_id')
|
||
EmployeeCommission.objects.filter(record_id=target_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_projectcommission')
|
||
def project_commission_list_view(request):
|
||
# 声明查询集
|
||
query_set = ProjectCommission.objects.all().order_by('-record_id')
|
||
|
||
# 获取查询参数
|
||
project_name = request.GET.get('project_name', '')
|
||
|
||
# 根据提供的参数进行筛选
|
||
if project_name:
|
||
query_set = query_set.filter(project_name__icontains=project_name)
|
||
|
||
# 对查询结果进行分页,每页10条记录
|
||
items = paginate_query_and_assign_numbers(
|
||
request=request,
|
||
queryset=query_set,
|
||
per_page=10
|
||
)
|
||
|
||
# 构建上下文查询参数字符串
|
||
query_params = '&project_name={}'.format(project_name)
|
||
|
||
# Excel上传模板
|
||
template_name = "财会管理-项目提成情况-Excel上传模板.xlsx"
|
||
|
||
# 构建上下文
|
||
context = {
|
||
"model_config": "fac_mgnt.ProjectCommission",
|
||
"items": items,
|
||
"breadcrumb_list": [
|
||
{"title": "首页", "name": "index"},
|
||
{"title": "人力资源管理", "name": "index"},
|
||
{"title": "项目提成情况表", "name": "project_commission_list"}
|
||
],
|
||
"filters": [
|
||
{
|
||
"type": "text",
|
||
"id": "project_name",
|
||
"name": "project_name",
|
||
"label": "项目名称",
|
||
"placeholder": "请输入项目名称"
|
||
}
|
||
],
|
||
"excel_upload_config": {
|
||
"template_url": reverse("download_template", kwargs={'template_name': template_name}),
|
||
"parse_url": reverse("common_excel_parse_pc"),
|
||
"save_url": reverse("save_excel_table_data_pc"),
|
||
"fields_preview_config": {
|
||
"project_name": {"type": "text", "width": "180px"},
|
||
"year_month": {"type": "text", "width": "220px"},
|
||
"company_retained": {"type": "text", "width": "120px"},
|
||
"total_commission": {"type": "number", "width": "120px"},
|
||
"chairman_fund": {"type": "number", "width": "120px"},
|
||
}
|
||
},
|
||
|
||
"query_params": query_params,
|
||
"table_exclude_field_name": ['record_id'],
|
||
"form_action_url": "project_commission_list",
|
||
"modify_url": reverse("project_commission_modify"),
|
||
"add_url": reverse("project_commission_add"),
|
||
"delete_url": reverse("project_commission_delete"),
|
||
}
|
||
|
||
return render(request, 'pc_list.html', context)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.add_projectcommission')
|
||
def project_commission_add(request):
|
||
if request.method == 'POST':
|
||
form = ProjectCommissionForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "添加成功"})
|
||
else:
|
||
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':
|
||
form = ProjectCommissionForm()
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.change_projectcommission')
|
||
def project_commission_modify(request):
|
||
if request.method == 'POST':
|
||
if 'id' in request.POST:
|
||
instance = ProjectCommission.objects.get(record_id=request.POST['id'])
|
||
form = ProjectCommissionForm(request.POST, instance=instance)
|
||
else:
|
||
form = ProjectCommissionForm(request.POST)
|
||
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"message": "保存成功"})
|
||
else:
|
||
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 'id' in request.GET:
|
||
try:
|
||
instance = ProjectCommission.objects.get(record_id=request.GET['id'])
|
||
form = ProjectCommissionForm(instance=instance)
|
||
except ProjectCommission.DoesNotExist:
|
||
raise Http404("对象不存在")
|
||
else:
|
||
form = ProjectCommissionForm()
|
||
|
||
form_html = render_to_string('form_partial.html', {'form': form}, request)
|
||
return JsonResponse({"form_html": form_html})
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.delete_projectcommission')
|
||
def project_commission_delete(request):
|
||
if request.method == 'GET':
|
||
record_id = request.GET.get('record_id')
|
||
ProjectCommission.objects.filter(record_id=record_id).delete()
|
||
return JsonResponse({"message": "删除成功"})
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_employeecommissiondetail')
|
||
def get_employee_commission_details(request, project_commission_id):
|
||
employee_commissions = EmployeeCommissionDetail.objects.filter(project_commission_id=project_commission_id)
|
||
data = [
|
||
{
|
||
"record_id": ec.record_id,
|
||
"employee_name": ec.employee.name,
|
||
"primary_department": ec.primary_department,
|
||
"year": ec.year,
|
||
"performance_score": ec.performance_score,
|
||
"total_commission": ec.total_commission,
|
||
"amount_paid": ec.amount_paid,
|
||
"accrued_amount": ec.accrued_amount,
|
||
"back_pay_amount": ec.back_pay_amount,
|
||
"deduction_amount": ec.deduction_amount,
|
||
}
|
||
for ec in employee_commissions
|
||
]
|
||
return JsonResponse(data, safe=False)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_employeeinformation')
|
||
def get_employees(request):
|
||
employees = EmployeeInformation.objects.all()
|
||
data = [{"id": emp.employee_id, "name": emp.name} for emp in employees]
|
||
return JsonResponse({"employees": data})
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_employeeinformation')
|
||
def get_employee_info(request, employee_id):
|
||
employee = get_object_or_404(EmployeeInformation, pk=employee_id)
|
||
data = {
|
||
"primary_department": employee.primary_department,
|
||
}
|
||
return JsonResponse(data)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.view_performanceevaluation')
|
||
def get_performance_score(request, employee_id, year):
|
||
try:
|
||
performance = PerformanceEvaluation.objects.get(employee_id=employee_id, year=year)
|
||
data = {"performance_score": performance.performance_score}
|
||
except PerformanceEvaluation.DoesNotExist:
|
||
data = {"performance_score": ""}
|
||
return JsonResponse(data)
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('hrm_mgnt.add_employeecommissiondetail')
|
||
def add_employee_commission_detail(request):
|
||
if request.method == 'POST':
|
||
employee_id = request.POST.get('employee')
|
||
project_commission_id = request.POST.get('project_commission')
|
||
primary_department = request.POST.get('primary_department')
|
||
year = request.POST.get('year')
|
||
performance_score = request.POST.get('performance_score')
|
||
total_commission = request.POST.get('total_commission')
|
||
amount_paid = request.POST.get('amount_paid')
|
||
accrued_amount = request.POST.get('accrued_amount')
|
||
back_pay_amount = request.POST.get('back_pay_amount')
|
||
deduction_amount = request.POST.get('deduction_amount')
|
||
|
||
employee = get_object_or_404(EmployeeInformation, pk=employee_id)
|
||
project_commission = get_object_or_404(ProjectCommission, pk=project_commission_id)
|
||
|
||
EmployeeCommissionDetail.objects.create(
|
||
project_commission=project_commission,
|
||
employee=employee,
|
||
primary_department=primary_department,
|
||
year=year,
|
||
performance_score=performance_score,
|
||
total_commission=total_commission,
|
||
amount_paid=amount_paid,
|
||
accrued_amount=accrued_amount,
|
||
back_pay_amount=back_pay_amount,
|
||
deduction_amount=deduction_amount
|
||
)
|
||
|
||
return JsonResponse({"success": True})
|
||
|
||
return JsonResponse({"success": False, "message": "Invalid request method."})
|
||
|
||
|
||
@login_required
|
||
@require_http_methods(["DELETE"])
|
||
def delete_employee_commission(request, commission_id):
|
||
commission = get_object_or_404(EmployeeCommissionDetail, record_id=commission_id)
|
||
commission.delete()
|
||
return JsonResponse({"success": True})
|
||
|
||
|
||
@login_required
|
||
# @custom_permission_required('fm.change_employeecommission')
|
||
def edit_employee_commission_detail(request, commission_id):
|
||
commission = get_object_or_404(EmployeeCommissionDetail, record_id=commission_id)
|
||
if request.method == 'POST':
|
||
form = EmployeeCommissionDetailForm(request.POST, instance=commission)
|
||
if form.is_valid():
|
||
form.save()
|
||
return JsonResponse({"success": True})
|
||
else:
|
||
return JsonResponse({"success": False, "message": "表单无效",
|
||
"form_html": render_to_string('form_partial.html', {'form': form}, request)})
|
||
elif request.method == 'GET':
|
||
data = {
|
||
'record_id': commission.record_id,
|
||
'employee': commission.employee.name,
|
||
'primary_department': commission.primary_department,
|
||
'year': commission.year,
|
||
'performance_score': commission.performance_score,
|
||
'total_commission': commission.total_commission,
|
||
'amount_paid': commission.amount_paid,
|
||
'accrued_amount': commission.accrued_amount,
|
||
'back_pay_amount': commission.back_pay_amount,
|
||
'deduction_amount': commission.deduction_amount
|
||
}
|
||
return JsonResponse(data)
|
||
else:
|
||
return JsonResponse({"message": "无效的请求方法"}, status=405)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def common_excel_parse_exp(request):
|
||
"""
|
||
该函数用于解析上传的Excel文件并返回数据。
|
||
|
||
Args:
|
||
request: HTTP请求对象,包含上传的Excel文件。
|
||
|
||
Returns:
|
||
JsonResponse: 包含解析后的Excel数据的JSON响应,或包含错误消息的JSON响应。
|
||
|
||
Raises:
|
||
N/A
|
||
"""
|
||
# 如果是POST请求并且有上传的文件
|
||
if request.method == 'POST' and request.FILES:
|
||
# 获取上传的Excel文件
|
||
excel_file = request.FILES.get('excel_file')
|
||
|
||
# 如果没有提供文件,返回错误响应
|
||
if not excel_file:
|
||
return JsonResponse({'error': '请先选择文件。'}, status=400)
|
||
|
||
# 获取模型名称
|
||
model_config = request.POST.get('model_config', '')
|
||
|
||
# 动态获取模型
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
model = apps.get_model(app_label, model_name)
|
||
except (LookupError, KeyError, ValueError):
|
||
return JsonResponse({'error': '模型配置错误。'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(model, 'excluded_fields', [])
|
||
|
||
# 保存文件到服务器
|
||
file_name = default_storage.save(excel_file.name, excel_file)
|
||
file_path = os.path.join(settings.MEDIA_ROOT, file_name)
|
||
|
||
def create_dynamic_serializer(mod, include):
|
||
class DynamicSerializer(ModelSerializer):
|
||
class Meta:
|
||
model = mod
|
||
fields = include
|
||
|
||
def to_representation(self, instance):
|
||
representation = super().to_representation(instance)
|
||
if 'type_id' in representation and instance.type_id:
|
||
representation['type_id'] = instance.type_id.expense_type
|
||
return representation
|
||
|
||
return DynamicSerializer
|
||
|
||
try:
|
||
# 打开并解析Excel文件
|
||
workbook = load_workbook(file_path, data_only=True)
|
||
sheet = workbook.active
|
||
data = []
|
||
|
||
# 读取第一行作为表头
|
||
header_row = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取字段名和 verbose_name,排除索引字段
|
||
model_fields = [field.name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in exclude_fields]
|
||
model_verbose_name = [field.verbose_name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in exclude_fields]
|
||
|
||
if not all(item in model_verbose_name for item in header_row):
|
||
return JsonResponse({'error': '表头不匹配,请使用正确的Excel上传模板。'}, status=400)
|
||
|
||
# 组成 fields_map
|
||
fields_map = dict(zip(model_fields, header_row))
|
||
fields_map_nf = dict(zip(header_row, model_fields))
|
||
|
||
# 创建一个映射,将Excel表头映射到模型字段名
|
||
header_to_field_map = {header: fields_map_nf[header] for header in header_row}
|
||
header_fields = [header_to_field_map[header] for header in header_row]
|
||
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
if not all(value is None for value in row):
|
||
instance_data = dict(zip(model_fields, row))
|
||
|
||
# 处理type_id字段,假设模型中有type_id字段并且Excel文件中的表头包含费用类型名称
|
||
expense_type_name = instance_data.get('type_id')
|
||
if expense_type_name:
|
||
try:
|
||
expense_type_instance = ExpenseType.objects.get(expense_type=expense_type_name)
|
||
instance_data['type_id'] = expense_type_instance
|
||
except ExpenseType.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_type_name} 的费用类型信息。'},
|
||
status=400)
|
||
|
||
instance = model(**instance_data)
|
||
try:
|
||
instance.full_clean()
|
||
data.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
|
||
# 动态获取序列化器
|
||
serializer_class = create_dynamic_serializer(model, include=header_fields)
|
||
|
||
serializer = serializer_class(data, many=True)
|
||
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
|
||
return JsonResponse({"table_data": serializer.data, "fields_map": fields_map}, safe=False)
|
||
except Exception as e:
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
return JsonResponse({'error': f'解析文件时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'error': '请求错误'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def save_excel_table_data_exp(request):
|
||
if request.method == 'POST':
|
||
try:
|
||
data = json.loads(request.body)
|
||
model_config = data.get('model_config')
|
||
table_data = data.get('table_data')
|
||
|
||
if not model_config or not table_data:
|
||
return JsonResponse({'error': '缺少必要的参数'}, status=400)
|
||
|
||
# 分割 model_config 以获取 app_label 和 model_name
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
Model = apps.get_model(app_label, model_name)
|
||
except (ValueError, LookupError):
|
||
return JsonResponse({'error': '无效的 model_config'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(Model, 'excluded_fields', [])
|
||
|
||
# 创建模型实例列表
|
||
instances = []
|
||
for row_data in table_data:
|
||
# 处理type_id字段,假设模型中有type_id字段并且table_data中包含费用类型名称
|
||
expense_type_name = row_data.get('type_id')
|
||
if expense_type_name:
|
||
try:
|
||
expense_type_instance = ExpenseType.objects.get(expense_type=expense_type_name)
|
||
row_data['type_id'] = expense_type_instance
|
||
except ExpenseType.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_type_name} 的费用类型信息。'}, status=400)
|
||
|
||
try:
|
||
# 排除不需要的字段
|
||
instance_data = {key: value for key, value in row_data.items() if key not in exclude_fields}
|
||
instance = Model(**instance_data)
|
||
instance.full_clean() # 验证数据
|
||
instances.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'创建实例时出错: {str(e)}'}, status=500)
|
||
|
||
# 批量创建模型实例
|
||
try:
|
||
Model.objects.bulk_create(instances)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'批量保存数据时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'message': '表格数据保存成功'}, status=200)
|
||
except json.JSONDecodeError:
|
||
return JsonResponse({'error': '无效的JSON格式'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
|
||
return JsonResponse({'error': '无效的请求方法'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def common_excel_parse_gab(request):
|
||
"""
|
||
该函数用于解析上传的Excel文件并返回数据。
|
||
|
||
Args:
|
||
request: HTTP请求对象,包含上传的Excel文件。
|
||
|
||
Returns:
|
||
JsonResponse: 包含解析后的Excel数据的JSON响应,或包含错误消息的JSON响应。
|
||
|
||
Raises:
|
||
N/A
|
||
"""
|
||
# 如果是POST请求并且有上传的文件
|
||
if request.method == 'POST' and request.FILES:
|
||
# 获取上传的Excel文件
|
||
excel_file = request.FILES.get('excel_file')
|
||
|
||
# 如果没有提供文件,返回错误响应
|
||
if not excel_file:
|
||
return JsonResponse({'error': '请先选择文件。'}, status=400)
|
||
|
||
# 获取模型名称
|
||
model_config = request.POST.get('model_config', '')
|
||
|
||
# 动态获取模型
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
model = apps.get_model(app_label, model_name)
|
||
except (LookupError, KeyError, ValueError):
|
||
return JsonResponse({'error': '模型配置错误。'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(model, 'excluded_fields', [])
|
||
|
||
# 保存文件到服务器
|
||
file_name = default_storage.save(excel_file.name, excel_file)
|
||
file_path = os.path.join(settings.MEDIA_ROOT, file_name)
|
||
|
||
def create_dynamic_serializer(mod, include):
|
||
class DynamicSerializer(ModelSerializer):
|
||
class Meta:
|
||
model = mod
|
||
fields = include
|
||
|
||
def to_representation(self, instance):
|
||
representation = super().to_representation(instance)
|
||
if 'type_id' in representation and instance.type_id:
|
||
representation['type_id'] = instance.type_id.expense_type
|
||
if 'expense_detail' in representation and instance.expense_detail:
|
||
representation['expense_detail'] = instance.expense_detail.expense_detail
|
||
return representation
|
||
|
||
return DynamicSerializer
|
||
|
||
try:
|
||
# 打开并解析Excel文件
|
||
workbook = load_workbook(file_path, data_only=True)
|
||
sheet = workbook.active
|
||
data = []
|
||
|
||
# 读取第一行作为表头
|
||
header_row = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取字段名和 verbose_name,排除索引字段
|
||
model_fields = [field.name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in exclude_fields]
|
||
model_verbose_name = [field.verbose_name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in exclude_fields]
|
||
|
||
if not all(item in model_verbose_name for item in header_row):
|
||
return JsonResponse({'error': '表头不匹配,请使用正确的Excel上传模板。'}, status=400)
|
||
|
||
# 组成 fields_map
|
||
fields_map = dict(zip(model_fields, header_row))
|
||
fields_map_nf = dict(zip(header_row, model_fields))
|
||
|
||
# 创建一个映射,将Excel表头映射到模型字段名
|
||
header_to_field_map = {header: fields_map_nf[header] for header in header_row}
|
||
header_fields = [header_to_field_map[header] for header in header_row]
|
||
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
if not all(value is None for value in row):
|
||
instance_data = dict(zip(model_fields, row))
|
||
|
||
# 处理type_id字段,假设模型中有type_id字段并且Excel文件中的表头包含费用类型名称
|
||
expense_type_name = instance_data.get('expense_type')
|
||
if expense_type_name:
|
||
try:
|
||
expense_type_instance = ExpenseType.objects.get(expense_type=expense_type_name)
|
||
instance_data['expense_type'] = expense_type_instance
|
||
except ExpenseType.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_type_name} 的费用类型信息。'},
|
||
status=400)
|
||
|
||
# 处理expense_detail字段,假设模型中有expense_detail字段并且Excel文件中的表头包含费用明细名称
|
||
expense_detail_name = instance_data.get('expense_detail')
|
||
if expense_detail_name:
|
||
try:
|
||
expense_detail_instance = ExpenseDetail.objects.get(expense_detail=expense_detail_name)
|
||
instance_data['expense_detail'] = expense_detail_instance
|
||
except ExpenseDetail.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_detail_name} 的费用明细信息。'},
|
||
status=400)
|
||
|
||
instance = model(**instance_data)
|
||
try:
|
||
instance.full_clean()
|
||
data.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
|
||
# 动态获取序列化器
|
||
serializer_class = create_dynamic_serializer(model, include=header_fields)
|
||
|
||
serializer = serializer_class(data, many=True)
|
||
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
|
||
return JsonResponse({"table_data": serializer.data, "fields_map": fields_map}, safe=False)
|
||
except Exception as e:
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
return JsonResponse({'error': f'解析文件时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'error': '请求错误'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def save_excel_table_data_gab(request):
|
||
if request.method == 'POST':
|
||
try:
|
||
data = json.loads(request.body)
|
||
model_config = data.get('model_config')
|
||
table_data = data.get('table_data')
|
||
|
||
if not model_config or not table_data:
|
||
return JsonResponse({'error': '缺少必要的参数'}, status=400)
|
||
|
||
# 分割 model_config 以获取 app_label 和 model_name
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
Model = apps.get_model(app_label, model_name)
|
||
except (ValueError, LookupError):
|
||
return JsonResponse({'error': '无效的 model_config'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(Model, 'excluded_fields', [])
|
||
|
||
# 创建模型实例列表
|
||
instances = []
|
||
for row_data in table_data:
|
||
# 处理type_id字段,假设模型中有type_id字段并且table_data中包含费用类型名称
|
||
expense_type_name = row_data.get('expense_type')
|
||
if expense_type_name:
|
||
try:
|
||
expense_type_instance = ExpenseType.objects.get(type_id=expense_type_name)
|
||
row_data['expense_type'] = expense_type_instance
|
||
except ExpenseType.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_type_name} 的费用类型信息。'}, status=400)
|
||
|
||
# 处理expense_detail字段,假设模型中有expense_detail字段并且table_data中包含费用明细名称
|
||
expense_detail_name = row_data.get('expense_detail')
|
||
if expense_detail_name:
|
||
try:
|
||
expense_detail_instance = ExpenseDetail.objects.get(expense_detail=expense_detail_name)
|
||
row_data['expense_detail'] = expense_detail_instance
|
||
except ExpenseDetail.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {expense_detail_name} 的费用明细信息。'},
|
||
status=400)
|
||
|
||
try:
|
||
# 排除不需要的字段
|
||
instance_data = {key: value for key, value in row_data.items() if key not in exclude_fields}
|
||
instance = Model(**instance_data)
|
||
instance.full_clean() # 验证数据
|
||
instances.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'创建实例时出错: {str(e)}'}, status=500)
|
||
|
||
# 批量创建模型实例
|
||
try:
|
||
Model.objects.bulk_create(instances)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'批量保存数据时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'message': '表格数据保存成功'}, status=200)
|
||
except json.JSONDecodeError:
|
||
return JsonResponse({'error': '无效的JSON格式'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
|
||
return JsonResponse({'error': '无效的请求方法'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def common_excel_parse_pjt(request):
|
||
"""
|
||
该函数用于解析上传的Excel文件并返回数据。
|
||
|
||
Args:
|
||
request: HTTP请求对象,包含上传的Excel文件。
|
||
|
||
Returns:
|
||
JsonResponse: 包含解析后的Excel数据的JSON响应,或包含错误消息的JSON响应。
|
||
|
||
Raises:
|
||
N/A
|
||
"""
|
||
# 如果是POST请求并且有上传的文件
|
||
if request.method == 'POST' and request.FILES:
|
||
# 获取上传的Excel文件
|
||
excel_file = request.FILES.get('excel_file')
|
||
|
||
# 如果没有提供文件,返回错误响应
|
||
if not excel_file:
|
||
return JsonResponse({'error': '请先选择文件。'}, status=400)
|
||
|
||
# 获取模型名称
|
||
model_config = request.POST.get('model_config', '')
|
||
|
||
# 动态获取模型
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
model = apps.get_model(app_label, model_name)
|
||
except (LookupError, KeyError, ValueError):
|
||
return JsonResponse({'error': '模型配置错误。'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(model, 'excluded_fields', ['项目编号'])
|
||
|
||
# 保存文件到服务器
|
||
file_name = default_storage.save(excel_file.name, excel_file)
|
||
file_path = os.path.join(settings.MEDIA_ROOT, file_name)
|
||
|
||
def create_dynamic_serializer(mod, include):
|
||
class DynamicSerializer(ModelSerializer):
|
||
class Meta:
|
||
model = mod
|
||
fields = include
|
||
|
||
def to_representation(self, instance):
|
||
representation = super().to_representation(instance)
|
||
if 'project_id' in representation and instance.project_id:
|
||
representation['project_id'] = instance.project_id.project_name
|
||
return representation
|
||
|
||
return DynamicSerializer
|
||
|
||
try:
|
||
# 打开并解析Excel文件
|
||
workbook = load_workbook(file_path, data_only=True)
|
||
sheet = workbook.active
|
||
data = []
|
||
|
||
# 读取第一行作为表头
|
||
header_row = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取字段名和 verbose_name,排除索引字段
|
||
model_fields = [field.name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['project_id']]
|
||
model_verbose_name = [field.verbose_name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['project_id']]
|
||
|
||
if not all(item in model_verbose_name for item in header_row):
|
||
return JsonResponse({'error': '表头不匹配,请使用正确的Excel上传模板。'}, status=400)
|
||
|
||
# 组成 fields_map
|
||
fields_map = dict(zip(model_fields, header_row))
|
||
fields_map_nf = dict(zip(header_row, model_fields))
|
||
|
||
# 创建一个映射,将Excel表头映射到模型字段名
|
||
header_to_field_map = {header: fields_map_nf[header] for header in header_row}
|
||
header_fields = [header_to_field_map[header] for header in header_row]
|
||
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
if not all(value is None for value in row):
|
||
instance_data = dict(zip(model_fields, row))
|
||
|
||
# 处理project_id字段,假设模型中有project_id字段并且Excel文件中的表头包含项目名称
|
||
project_name = instance_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
instance_data['project_id'] = project_instance
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
instance = model(**instance_data)
|
||
try:
|
||
instance.full_clean()
|
||
data.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
|
||
# 动态获取序列化器
|
||
serializer_class = create_dynamic_serializer(model, include=header_fields)
|
||
|
||
serializer = serializer_class(data, many=True)
|
||
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
|
||
return JsonResponse({"table_data": serializer.data, "fields_map": fields_map}, safe=False)
|
||
except Exception as e:
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
return JsonResponse({'error': f'解析文件时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'error': '请求错误'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def save_excel_table_data_pjt(request):
|
||
if request.method == 'POST':
|
||
try:
|
||
data = json.loads(request.body)
|
||
model_config = data.get('model_config')
|
||
table_data = data.get('table_data')
|
||
|
||
if not model_config or not table_data:
|
||
return JsonResponse({'error': '缺少必要的参数'}, status=400)
|
||
|
||
# 分割 model_config 以获取 app_label 和 model_name
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
Model = apps.get_model(app_label, model_name)
|
||
except (ValueError, LookupError):
|
||
return JsonResponse({'error': '无效的 model_config'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(Model, 'excluded_fields', [])
|
||
|
||
# 创建模型实例列表
|
||
instances = []
|
||
for row_data in table_data:
|
||
# 处理project_id字段,假设模型中有project_id字段并且table_data中包含项目名称
|
||
project_name = row_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
row_data['project_id'] = project_instance
|
||
row_data['project_name'] = project_instance.project_name
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
try:
|
||
# 排除不需要的字段
|
||
instance_data = {key: value for key, value in row_data.items() if key not in exclude_fields}
|
||
instance = Model(**instance_data)
|
||
instance.full_clean() # 验证数据
|
||
instances.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'创建实例时出错: {str(e)}'}, status=500)
|
||
|
||
# 批量创建模型实例
|
||
try:
|
||
Model.objects.bulk_create(instances)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'批量保存数据时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'message': '表格数据保存成功'}, status=200)
|
||
except json.JSONDecodeError:
|
||
return JsonResponse({'error': '无效的JSON格式'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
|
||
return JsonResponse({'error': '无效的请求方法'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def common_excel_parse_rr(request):
|
||
"""
|
||
该函数用于解析上传的Excel文件并返回数据。
|
||
|
||
Args:
|
||
request: HTTP请求对象,包含上传的Excel文件。
|
||
|
||
Returns:
|
||
JsonResponse: 包含解析后的Excel数据的JSON响应,或包含错误消息的JSON响应。
|
||
|
||
Raises:
|
||
N/A
|
||
"""
|
||
# 如果是POST请求并且有上传的文件
|
||
if request.method == 'POST' and request.FILES:
|
||
# 获取上传的Excel文件
|
||
excel_file = request.FILES.get('excel_file')
|
||
|
||
# 如果没有提供文件,返回错误响应
|
||
if not excel_file:
|
||
return JsonResponse({'error': '请先选择文件。'}, status=400)
|
||
|
||
# 获取模型名称
|
||
model_config = request.POST.get('model_config', '')
|
||
|
||
# 动态获取模型
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
model = apps.get_model(app_label, model_name)
|
||
except (LookupError, KeyError, ValueError):
|
||
return JsonResponse({'error': '模型配置错误。'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(model, 'excluded_fields', ['项目编号'])
|
||
|
||
# 保存文件到服务器
|
||
file_name = default_storage.save(excel_file.name, excel_file)
|
||
file_path = os.path.join(settings.MEDIA_ROOT, file_name)
|
||
|
||
def create_dynamic_serializer(mod, include):
|
||
class DynamicSerializer(ModelSerializer):
|
||
class Meta:
|
||
model = mod
|
||
fields = include
|
||
|
||
def to_representation(self, instance):
|
||
representation = super().to_representation(instance)
|
||
if 'project_id' in representation and instance.project_id:
|
||
representation['project_id'] = instance.project_id.project_name
|
||
return representation
|
||
|
||
return DynamicSerializer
|
||
|
||
try:
|
||
# 打开并解析Excel文件
|
||
workbook = load_workbook(file_path, data_only=True)
|
||
sheet = workbook.active
|
||
data = []
|
||
|
||
# 读取第一行作为表头
|
||
header_row = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取字段名和 verbose_name,排除索引字段
|
||
model_fields = [field.name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['project_id', 'invoice']]
|
||
model_verbose_name = [field.verbose_name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['project_id', 'invoice']]
|
||
|
||
if not all(item in model_verbose_name for item in header_row):
|
||
return JsonResponse({'error': '表头不匹配,请使用正确的Excel上传模板。'}, status=400)
|
||
|
||
# 组成 fields_map
|
||
fields_map = dict(zip(model_fields, header_row))
|
||
fields_map_nf = dict(zip(header_row, model_fields))
|
||
|
||
# 创建一个映射,将Excel表头映射到模型字段名
|
||
header_to_field_map = {header: fields_map_nf[header] for header in header_row}
|
||
header_fields = [header_to_field_map[header] for header in header_row]
|
||
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
if not all(value is None for value in row):
|
||
instance_data = dict(zip(model_fields, row))
|
||
|
||
# 处理project_id字段,假设模型中有project_id字段并且Excel文件中的表头包含项目名称
|
||
project_name = instance_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
invoice_instance = InvoiceRecord.objects.get(project_name=project_name)
|
||
instance_data['invoice'] = invoice_instance
|
||
instance_data['project_id'] = project_instance
|
||
instance_data['project_name'] = project_instance.project_name
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
instance = model(**instance_data)
|
||
try:
|
||
instance.full_clean()
|
||
data.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
|
||
# 动态获取序列化器
|
||
serializer_class = create_dynamic_serializer(model, include=header_fields)
|
||
|
||
serializer = serializer_class(data, many=True)
|
||
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
|
||
return JsonResponse({"table_data": serializer.data, "fields_map": fields_map}, safe=False)
|
||
except Exception as e:
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
return JsonResponse({'error': f'解析文件时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'error': '请求错误'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def save_excel_table_data_rr(request):
|
||
if request.method == 'POST':
|
||
try:
|
||
data = json.loads(request.body)
|
||
model_config = data.get('model_config')
|
||
table_data = data.get('table_data')
|
||
|
||
if not model_config or not table_data:
|
||
return JsonResponse({'error': '缺少必要的参数'}, status=400)
|
||
|
||
# 分割 model_config 以获取 app_label 和 model_name
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
Model = apps.get_model(app_label, model_name)
|
||
except (ValueError, LookupError):
|
||
return JsonResponse({'error': '无效的 model_config'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(Model, 'excluded_fields', [])
|
||
|
||
# 创建模型实例列表
|
||
instances = []
|
||
for row_data in table_data:
|
||
# 处理project_id字段,假设模型中有project_id字段并且table_data中包含项目名称
|
||
project_name = row_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
invoice_instance = InvoiceRecord.objects.get(project_name=project_name)
|
||
|
||
row_data['invoice'] = invoice_instance
|
||
row_data['project_id'] = project_instance
|
||
row_data['project_name'] = project_instance.project_name
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
try:
|
||
# 排除不需要的字段
|
||
instance_data = {key: value for key, value in row_data.items() if key not in exclude_fields}
|
||
instance = Model(**instance_data)
|
||
instance.full_clean() # 验证数据
|
||
instances.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'创建实例时出错: {str(e)}'}, status=500)
|
||
|
||
# 批量创建模型实例
|
||
try:
|
||
Model.objects.bulk_create(instances)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'批量保存数据时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'message': '表格数据保存成功'}, status=200)
|
||
except json.JSONDecodeError:
|
||
return JsonResponse({'error': '无效的JSON格式'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
|
||
return JsonResponse({'error': '无效的请求方法'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def common_excel_parse_pc(request):
|
||
"""
|
||
该函数用于解析上传的Excel文件并返回数据。
|
||
|
||
Args:
|
||
request: HTTP请求对象,包含上传的Excel文件。
|
||
|
||
Returns:
|
||
JsonResponse: 包含解析后的Excel数据的JSON响应,或包含错误消息的JSON响应。
|
||
|
||
Raises:
|
||
N/A
|
||
"""
|
||
# 如果是POST请求并且有上传的文件
|
||
if request.method == 'POST' and request.FILES:
|
||
# 获取上传的Excel文件
|
||
excel_file = request.FILES.get('excel_file')
|
||
|
||
# 如果没有提供文件,返回错误响应
|
||
if not excel_file:
|
||
return JsonResponse({'error': '请先选择文件。'}, status=400)
|
||
|
||
# 获取模型名称
|
||
model_config = request.POST.get('model_config', '')
|
||
|
||
# 动态获取模型
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
model = apps.get_model(app_label, model_name)
|
||
except (LookupError, KeyError, ValueError):
|
||
return JsonResponse({'error': '模型配置错误。'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(model, 'excluded_fields', ['记录编号'])
|
||
|
||
# 保存文件到服务器
|
||
file_name = default_storage.save(excel_file.name, excel_file)
|
||
file_path = os.path.join(settings.MEDIA_ROOT, file_name)
|
||
|
||
def create_dynamic_serializer(mod, include):
|
||
class DynamicSerializer(ModelSerializer):
|
||
class Meta:
|
||
model = mod
|
||
fields = include
|
||
|
||
def to_representation(self, instance):
|
||
representation = super().to_representation(instance)
|
||
if 'project_id' in representation and instance.project_id:
|
||
representation['project_id'] = instance.project_id.project_name
|
||
if 'project_name' in representation and instance.project_name:
|
||
representation['project_name'] = instance.project_name.project_name
|
||
return representation
|
||
|
||
return DynamicSerializer
|
||
|
||
try:
|
||
# 打开并解析Excel文件
|
||
workbook = load_workbook(file_path, data_only=True)
|
||
sheet = workbook.active
|
||
data = []
|
||
|
||
# 读取第一行作为表头
|
||
header_row = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取字段名和 verbose_name,排除索引字段
|
||
model_fields = [field.name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['record_id']]
|
||
model_verbose_name = [field.verbose_name for field in model._meta.fields if
|
||
not field.primary_key and field.name not in ['record_id']]
|
||
|
||
if not all(item in model_verbose_name for item in header_row):
|
||
return JsonResponse({'error': '表头不匹配,请使用正确的Excel上传模板。'}, status=400)
|
||
|
||
# 组成 fields_map
|
||
fields_map = dict(zip(model_fields, header_row))
|
||
fields_map_nf = dict(zip(header_row, model_fields))
|
||
|
||
# 创建一个映射,将Excel表头映射到模型字段名
|
||
header_to_field_map = {header: fields_map_nf[header] for header in header_row}
|
||
header_fields = [header_to_field_map[header] for header in header_row]
|
||
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
if not all(value is None for value in row):
|
||
instance_data = dict(zip(model_fields, row))
|
||
|
||
# 处理project_id字段,假设模型中有project_id字段并且Excel文件中的表头包含项目名称
|
||
project_name = instance_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
instance_data['project_name'] = project_instance
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
instance = model(**instance_data)
|
||
try:
|
||
instance.full_clean()
|
||
data.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
|
||
# 动态获取序列化器
|
||
serializer_class = create_dynamic_serializer(model, include=header_fields)
|
||
|
||
serializer = serializer_class(data, many=True)
|
||
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
|
||
return JsonResponse({"table_data": serializer.data, "fields_map": fields_map}, safe=False)
|
||
except Exception as e:
|
||
# 清理,删除上传的文件
|
||
os.remove(file_path)
|
||
return JsonResponse({'error': f'解析文件时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'error': '请求错误'}, status=400)
|
||
|
||
|
||
@csrf_protect
|
||
@login_required
|
||
def save_excel_table_data_pc(request):
|
||
if request.method == 'POST':
|
||
try:
|
||
data = json.loads(request.body)
|
||
model_config = data.get('model_config')
|
||
table_data = data.get('table_data')
|
||
|
||
if not model_config or not table_data:
|
||
return JsonResponse({'error': '缺少必要的参数'}, status=400)
|
||
|
||
# 分割 model_config 以获取 app_label 和 model_name
|
||
try:
|
||
app_label, model_name = model_config.split('.')
|
||
Model = apps.get_model(app_label, model_name)
|
||
except (ValueError, LookupError):
|
||
return JsonResponse({'error': '无效的 model_config'}, status=400)
|
||
|
||
# 获取模型中配置的不需要的字段
|
||
exclude_fields = getattr(Model, 'excluded_fields', [])
|
||
|
||
# 创建模型实例列表
|
||
instances = []
|
||
for row_data in table_data:
|
||
# 处理project_id字段,假设模型中有project_id字段并且table_data中包含项目名称
|
||
project_name = row_data.get('project_name')
|
||
if project_name:
|
||
try:
|
||
project_instance = ProjectLedger.objects.get(project_name=project_name)
|
||
row_data['project_name'] = project_instance
|
||
except ProjectLedger.DoesNotExist:
|
||
return JsonResponse({'error': f'找不到名称为 {project_name} 的项目台账记录。'}, status=400)
|
||
|
||
try:
|
||
# 排除不需要的字段
|
||
instance_data = {key: value for key, value in row_data.items() if key not in exclude_fields}
|
||
instance = Model(**instance_data)
|
||
instance.full_clean() # 验证数据
|
||
instances.append(instance)
|
||
except ValidationError as e:
|
||
return JsonResponse({'error': f'数据校验错误: {e.message_dict}'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'创建实例时出错: {str(e)}'}, status=500)
|
||
|
||
# 批量创建模型实例
|
||
try:
|
||
Model.objects.bulk_create(instances)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'批量保存数据时出错: {str(e)}'}, status=500)
|
||
|
||
return JsonResponse({'message': '表格数据保存成功'}, status=200)
|
||
except json.JSONDecodeError:
|
||
return JsonResponse({'error': '无效的JSON格式'}, status=400)
|
||
except Exception as e:
|
||
return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
|
||
return JsonResponse({'error': '无效的请求方法'}, status=400)
|