2024-07-14 16:38:15 +08:00
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
2024-05-16 21:23:15 +08:00
|
|
|
|
from django.db import models
|
2024-07-14 16:38:15 +08:00
|
|
|
|
from django.db.models import Sum
|
|
|
|
|
from django.utils import timezone
|
|
|
|
|
|
|
|
|
|
from application.busi_tbl.models import DepartmentExpense, UpdateLog
|
|
|
|
|
from application.fac_mgnt.models import GroupAnnualBudget, ReimbursementDetail
|
|
|
|
|
from application.org_mgnt.models import PrimaryDepartment
|
2024-05-16 21:23:15 +08:00
|
|
|
|
|
|
|
|
|
|
2024-06-06 15:08:38 +08:00
|
|
|
|
class DepartmentExpenseData(models.Model):
|
2024-07-14 16:38:15 +08:00
|
|
|
|
"""
|
|
|
|
|
费用情况
|
|
|
|
|
年月、费用类型、费用明细、费用限额(集团年度预算表-按一级部门年份费用类型费用明细筛选后取金额)
|
|
|
|
|
已报销额度(报销明细表-费用金额按时间、类型、明细筛选后汇总,算当年总额)
|
|
|
|
|
可用额度(=费用限额-已报销额度)
|
|
|
|
|
"""
|
2024-06-06 15:08:38 +08:00
|
|
|
|
primary_department = models.CharField(max_length=255, verbose_name="一级部门", help_text="用于筛选、区分一级部门")
|
|
|
|
|
year_month = models.CharField(max_length=7, verbose_name="年月", help_text="格式为'YYYY-MM',表示统计数据的年月")
|
2024-07-14 16:38:15 +08:00
|
|
|
|
expense_type = models.CharField(max_length=255, verbose_name="费用类型")
|
|
|
|
|
expense_detail = models.CharField(max_length=255, verbose_name="费用明细")
|
|
|
|
|
expense_limit = models.FloatField(verbose_name="费用限额(元)", null=True, blank=True)
|
|
|
|
|
reimbursed_amount = models.FloatField(verbose_name="已报销额度(元)", null=True, blank=True)
|
|
|
|
|
available_amount = models.FloatField(verbose_name="可用额度(元)", null=True, blank=True)
|
2024-05-16 21:23:15 +08:00
|
|
|
|
|
|
|
|
|
class Meta:
|
2024-07-14 16:38:15 +08:00
|
|
|
|
verbose_name = "费用情况"
|
|
|
|
|
verbose_name_plural = "费用情况"
|
|
|
|
|
db_table_comment = '存储业务部门费用情况数据,包括一级部门、年月、费用类型、费用明细、费用限额、已报销额度、可用额度等'
|
2024-05-16 21:23:15 +08:00
|
|
|
|
|
|
|
|
|
def __str__(self):
|
2024-07-14 16:38:15 +08:00
|
|
|
|
return f"{self.year_month} 年 {self.primary_department} 的费用情况"
|
2024-06-06 15:08:38 +08:00
|
|
|
|
|
|
|
|
|
@staticmethod
|
2024-07-14 16:38:15 +08:00
|
|
|
|
def calculate_and_update_for_month(year_month):
|
|
|
|
|
primary_departments = PrimaryDepartment.objects.all()
|
|
|
|
|
year, month = map(int, year_month.split('-'))
|
|
|
|
|
|
|
|
|
|
for department in primary_departments:
|
|
|
|
|
primary_department = department.department_name
|
|
|
|
|
|
|
|
|
|
# 从集团年度预算表获取费用类型和费用明细
|
|
|
|
|
budget_entries = GroupAnnualBudget.objects.filter(
|
|
|
|
|
primary_department=primary_department,
|
|
|
|
|
year=year
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
for entry in budget_entries:
|
|
|
|
|
expense_type = entry.expense_type.expense_type
|
|
|
|
|
expense_type_instance = entry.expense_type
|
|
|
|
|
expense_detail = entry.expense_detail.expense_detail
|
|
|
|
|
expense_detail_instance = entry.expense_detail
|
|
|
|
|
|
|
|
|
|
# 费用限额
|
|
|
|
|
expense_limit = entry.amount
|
|
|
|
|
|
|
|
|
|
# 已报销额度
|
|
|
|
|
reimbursed_amount = ReimbursementDetail.objects.filter(
|
|
|
|
|
primary_department=primary_department,
|
|
|
|
|
year_month__icontains=year_month,
|
|
|
|
|
expense_type=expense_type_instance,
|
|
|
|
|
expense_detail=expense_detail_instance
|
|
|
|
|
).aggregate(total=Sum('amount'))['total'] or Decimal('0')
|
|
|
|
|
|
|
|
|
|
# 可用额度
|
|
|
|
|
available_amount = expense_limit - reimbursed_amount
|
|
|
|
|
|
|
|
|
|
# 更新或创建模型实例
|
|
|
|
|
expense, created = DepartmentExpenseData.objects.update_or_create(
|
|
|
|
|
primary_department=primary_department,
|
|
|
|
|
year_month=year_month,
|
|
|
|
|
expense_type=expense_type,
|
|
|
|
|
expense_detail=expense_detail,
|
|
|
|
|
defaults={
|
|
|
|
|
'expense_limit': expense_limit,
|
|
|
|
|
'reimbursed_amount': reimbursed_amount,
|
|
|
|
|
'available_amount': available_amount,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 更新或创建更新时间记录
|
|
|
|
|
UpdateLog.objects.update_or_create(
|
|
|
|
|
table_name='DepartmentExpenseData',
|
|
|
|
|
defaults={'last_update': timezone.now().date()}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def update_all_departments_for_month(cls, year_month):
|
|
|
|
|
cls.calculate_and_update_for_month(year_month)
|