feat: 增加month_sf统计维度, 优化二次计算逻辑

This commit is contained in:
caoqianming 2023-07-18 14:15:52 +08:00
parent f8bc2294f0
commit a8afccdfca
4 changed files with 87 additions and 22 deletions

View File

@ -0,0 +1,30 @@
# Generated by Django 3.2.12 on 2023-07-18 05:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0005_auto_20230706_1032'),
('enm', '0010_auto_20230717_1532'),
]
operations = [
migrations.AddField(
model_name='enstat',
name='shift',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.shift', verbose_name='关联班组'),
),
migrations.AddField(
model_name='mpoint',
name='formula',
field=models.TextField(default='', verbose_name='计算公式'),
),
migrations.AlterField(
model_name='enstat',
name='type',
field=models.CharField(default='hour', help_text='year_s/month_s/month_sf/day_s/sflog/hour_s', max_length=50, verbose_name='统计维度'),
),
]

View File

@ -1,7 +1,7 @@
from django.db import models
from apps.utils.models import BaseModel, CommonBModel, CommonADModel
from apps.wpm.models import SfLog
from apps.mtm.models import Material, Mgroup
from apps.mtm.models import Material, Mgroup, Shift
class Mpoint(CommonBModel):
@ -18,6 +18,7 @@ class Mpoint(CommonBModel):
mgroups_allocate = models.JSONField('各工段分配', default=list, blank=True, help_text='[{"mgroup":"x", "ratio": 1}]')
is_auto = models.BooleanField('是否自动采集', default=True)
is_all = models.BooleanField('是否记录是整个工段', default=False)
formula = models.TextField('计算公式', default='')
class MpLog(BaseModel):
@ -53,8 +54,9 @@ class EnStat(BaseModel):
"""
能源数据统计表
"""
type = models.CharField('统计维度', max_length=50, default='hour', help_text='year_s/month_s/day_s/sflog/hour_s')
type = models.CharField('统计维度', max_length=50, default='hour', help_text='year_s/month_s/month_sf/day_s/sflog/hour_s')
sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True)
shift = models.ForeignKey(Shift, verbose_name='关联班组', on_delete=models.CASCADE, null=True, blank=True)
mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
year = models.PositiveSmallIntegerField('', null=True, blank=True)
month = models.PositiveSmallIntegerField('', null=True, blank=True)

View File

@ -1,7 +1,7 @@
# Create your tasks here
from __future__ import absolute_import, unicode_literals
from apps.utils.tasks import CustomTask
from celery import shared_task
from celery import shared_task, group, chain
from apps.utils.sql import DbConnection
from server.settings import get_sysconfig
from django.core.cache import cache
@ -46,7 +46,7 @@ def get_tag_val():
cache.set('last_tag_id', last_tag_id)
@shared_task(base=CustomTask)
def cal_mpointstat_hour(mpointId: str, year: int, month: int, day: int, hour: int):
def cal_mpointstat_hour(mpointId: str, year: int, month: int, day: int, hour: int, next_cal=0):
"""
计算某一测点, 某一时间点某一小时的统计值
"""
@ -113,27 +113,46 @@ def cal_mpointstat_hour(mpointId: str, year: int, month: int, day: int, hour: in
ms_sflog_s.val = sum_dict_sflog_s['sum']
ms_sflog_s.save()
cal_mpointstat_manual(mpoint.id, mgroup.id, year_s, month_s, day_s)
compute_enstat('hour_s', sflog.id, mgroup.id, year, month, day, hour, year_s, month_s, day_s)
cal_mpointstat_manual(mpoint.id, sflog.id, mgroup.id, year_s, month_s, day_s, year, month, day, hour, next_cal)
@shared_task(base=CustomTask)
def cal_mpointstats(is_now=1):
def cal_mpointstats(is_now=1, year=None, month=None, day=None, hour=None):
"""
计算所有自动采集测点的统计值默认当前小时
计算所有自动采集测点的统计值默认当前小时, 可手动传入时间
"""
now, pre = get_current_and_previous_time()
if is_now:
for mpoint in Mpoint.objects.filter(is_auto=True):
cal_mpointstat_hour.delay(mpoint.id, now.year, now.month, now.day, now.hour)
if year and month and day and hour:
pass
else:
for mpoint in Mpoint.objects.filter(is_auto=True):
cal_mpointstat_hour.delay(mpoint.id, pre.year, pre.month, pre.day, pre.hour)
now, pre = get_current_and_previous_time()
if is_now:
year, month, day, hour = now.year, now.month, now.day, now.hour
else:
year, month, day, hour = pre.year, pre.month, pre.day, pre.hour
mgroups = Mgroup.objects.exclude(product=None)
# 先统计自动采集的产量值
caled_mpointids = []
for mgroup in mgroups:
product = mgroup.product
mpoints = Mpoint.objects.filter(material=product, is_auto=True)
len_mps = len(mpoints)
for ind, item in enumerate(mpoints):
caled_mpointids.append(item.id)
next_cal = 0
if ind == len_mps - 1: # 运行到最后一次再去进行二次计算, 因为产量要作为分母使用
next_cal = 1
cal_mpointstat_hour(item.id, year, month, day, hour, next_cal)
# 统计其他测点
mpoints = Mpoint.objects.filter(is_auto=True).exclude(id__in=caled_mpointids)
for i in mpoints:
cal_mpointstat_hour(i.id, year, month, day, hour, 1)
@shared_task(base=CustomTask)
def cal_mpointstat_manual(mpointId: str, mgroupId: str, year_s: int, month_s: int, day_s: int):
def cal_mpointstat_manual(mpointId: str, sflogId: str, mgroupId: str, year_s: int, month_s: int, day_s: int, year=None, month=None, day=None, hour=None, next_cal=0):
"""
手动录入的测点数据进行往上统计一级一级往上
"""
@ -156,15 +175,22 @@ def cal_mpointstat_manual(mpointId: str, mgroupId: str, year_s: int, month_s: in
ms_year_s, _ = MpointStat.objects.get_or_create(**params_year_s, defaults=params_year_s)
ms_year_s.val = sum_dict_year_s['sum']
ms_year_s.save()
if next_cal: # 二次计算
if hour:
compute_enstat('hour_s', sflogId, mgroupId, year_s, month_s, day_s, year, month, day, hour)
else:
compute_enstat('sflog', sflogId, mgroupId, year_s, month_s, day_s, year, month, day, hour)
def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s):
def compute_enstat(type, sflogId, mgroupId, year_s, month_s, day_s, year, month, day, hour):
"""
计算能源数据统计
"""
mgroup = Mgroup.objects.get(id=mgroupId)
sflog = SfLog.objects.get(id=sflogId)
shift = sflog.shift
if type == 'hour_s':
enstat, _ = EnStat.objects.get_or_create(type="hour_s", mgroup=mgroup, year=year, month=month, day=day, hour=hour,
defaults={'type': 'hour_s', 'mgroup': mgroup, 'year_s': year_s, 'month_s': month_s, 'day_s': day_s,
@ -176,6 +202,9 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
elif type == 'day_s':
enstat, _ = EnStat.objects.get_or_create(type="day_s", mgroup=mgroup, year_s=year_s, month_s=month_s, day_s=day_s,
defaults={'type': 'day_s', 'mgroup': mgroup, 'year_s': year_s, 'month_s': month_s, 'day_s': day_s, 'total_production': 0, 'elec_consume': 0})
elif type == 'month_sf':
enstat, _ = EnStat.objects.get_or_create(type="month_sf", mgroup=mgroup, shift=shift, year_s=year_s, month_s=month_s,
defaults={'type': 'month_sf', 'mgroup': mgroup, 'year_s': year_s, 'month_s': month_s, 'shift': shift, 'total_production': 0, 'elec_consume': 0})
elif type == 'month_s':
enstat, _ = EnStat.objects.get_or_create(type="month_s", mgroup=mgroup, year_s=year_s, month_s=month_s,
defaults={'type': 'month_s', 'mgroup': mgroup, 'year_s': year_s, 'month_s': month_s, 'total_production': 0, 'elec_consume': 0})
@ -189,7 +218,7 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
input_materials.insert(0, mgroup.product.id)
cost_unit_total = 0
imaterial_data = []
for mid in input_materials:
for ind, mid in enumerate(input_materials):
material = Material.objects.get(id=mid)
if type == 'hour_s':
mps = MpointStat.objects.filter(type='hour_s', mgroup=mgroup, year_s=year_s, month_s=month_s, day_s=day_s, hour=hour, mpoint__material=material)
@ -197,6 +226,8 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
mps = MpointStat.objects.filter(type='sflog', sflog=sflog, mpoint__material=material)
elif type == 'day_s':
mps = MpointStat.objects.filter(type='day_s', mgroup=mgroup, year_s=year_s, month_s=month_s, day_s=day_s, mpoint__material=material)
elif type == 'month_sf':
mps = MpointStat.objects.filter(type='sflog', mgroup=mgroup, sflog__shift=shift, year_s=year_s, month_s=month_s, mpoint__material=material)
elif type == 'month_s':
mps = MpointStat.objects.filter(type='month_s', mgroup=mgroup, year_s=year_s, month_s=month_s, mpoint__material=material)
elif type == 'year_s':
@ -206,7 +237,7 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
amount_consume = mps.aggregate(sum=Sum('val'))['sum']
if amount_consume is None:
amount_consume = 0
if mid == mgroup.product.id:
if ind == 0: # 如果是产量
enstat.total_production = amount_consume
enstat.save()
else:
@ -220,7 +251,7 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
if material.code == 'elec':
enstat.elec_consume = amount_consume
enstat.save()
imaterial_data.append({'material': mid, 'material_name': material.name, 'material_type': material.type, 'price_unit': price_unit, 'cost': cost, 'cost_unit': cost_unit})
imaterial_data.append({'material': mid, 'material_name': material.name, 'material_type': material.type, 'price_unit': price_unit, 'amount_consume': amount_consume, 'cost': cost, 'cost_unit': cost_unit})
enstat.imaterial_data = imaterial_data
enstat.save()
other_cost_data = []
@ -238,6 +269,8 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
elif type == 'sflog':
compute_enstat('day_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)
elif type == 'day_s':
compute_enstat('month_sf', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)
elif type == 'month_sf':
compute_enstat('month_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)
elif type == 'month_s':
compute_enstat('year_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)

View File

@ -48,12 +48,12 @@ class MpointStatViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, ListModelMi
def perform_create(self, serializer):
ins = serializer.save()
cal_mpointstat_manual(ins.mpoint.id, ins.mgroup.id, ins.year_s, ins.month_s, ins.day_s)
cal_mpointstat_manual.delay(ins.mpoint.id, ins.sflog.id, ins.mgroup.id, ins.year_s, ins.month_s, ins.day_s, nex_cal=1)
def perform_destroy(self, instance):
mpoint, mgroup, year_s, month_s, day_s = instance.mpoint, instance.mgroup, instance.year_s, instance.month_s, instance.day_s
mpoint, sflog, mgroup, year_s, month_s, day_s = instance.mpoint, instance.sflog, instance.mgroup, instance.year_s, instance.month_s, instance.day_s
instance.delete()
cal_mpointstat_manual(mpoint.id, mgroup.id, year_s, month_s, day_s)
cal_mpointstat_manual.delay(mpoint.id, sflog.id, mgroup.id, year_s, month_s, day_s)
class EnStatViewSet(ListModelMixin, CustomGenericViewSet):