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 django.db import models
from apps.utils.models import BaseModel, CommonBModel, CommonADModel from apps.utils.models import BaseModel, CommonBModel, CommonADModel
from apps.wpm.models import SfLog from apps.wpm.models import SfLog
from apps.mtm.models import Material, Mgroup from apps.mtm.models import Material, Mgroup, Shift
class Mpoint(CommonBModel): class Mpoint(CommonBModel):
@ -18,6 +18,7 @@ class Mpoint(CommonBModel):
mgroups_allocate = models.JSONField('各工段分配', default=list, blank=True, help_text='[{"mgroup":"x", "ratio": 1}]') mgroups_allocate = models.JSONField('各工段分配', default=list, blank=True, help_text='[{"mgroup":"x", "ratio": 1}]')
is_auto = models.BooleanField('是否自动采集', default=True) is_auto = models.BooleanField('是否自动采集', default=True)
is_all = models.BooleanField('是否记录是整个工段', default=False) is_all = models.BooleanField('是否记录是整个工段', default=False)
formula = models.TextField('计算公式', default='')
class MpLog(BaseModel): 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) 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) mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE)
year = models.PositiveSmallIntegerField('', null=True, blank=True) year = models.PositiveSmallIntegerField('', null=True, blank=True)
month = models.PositiveSmallIntegerField('', null=True, blank=True) month = models.PositiveSmallIntegerField('', null=True, blank=True)

View File

@ -1,7 +1,7 @@
# Create your tasks here # Create your tasks here
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from apps.utils.tasks import CustomTask 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 apps.utils.sql import DbConnection
from server.settings import get_sysconfig from server.settings import get_sysconfig
from django.core.cache import cache from django.core.cache import cache
@ -46,7 +46,7 @@ def get_tag_val():
cache.set('last_tag_id', last_tag_id) cache.set('last_tag_id', last_tag_id)
@shared_task(base=CustomTask) @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.val = sum_dict_sflog_s['sum']
ms_sflog_s.save() ms_sflog_s.save()
cal_mpointstat_manual(mpoint.id, mgroup.id, 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)
compute_enstat('hour_s', sflog.id, mgroup.id, year, month, day, hour, year_s, month_s, day_s)
@shared_task(base=CustomTask) @shared_task(base=CustomTask)
def cal_mpointstats(is_now=1): def cal_mpointstats(is_now=1, year=None, month=None, day=None, hour=None):
""" """
计算所有自动采集测点的统计值默认当前小时 计算所有自动采集测点的统计值默认当前小时, 可手动传入时间
""" """
if year and month and day and hour:
pass
else:
now, pre = get_current_and_previous_time() now, pre = get_current_and_previous_time()
if is_now: if is_now:
for mpoint in Mpoint.objects.filter(is_auto=True): year, month, day, hour = now.year, now.month, now.day, now.hour
cal_mpointstat_hour.delay(mpoint.id, now.year, now.month, now.day, now.hour)
else: else:
for mpoint in Mpoint.objects.filter(is_auto=True): year, month, day, hour = pre.year, pre.month, pre.day, pre.hour
cal_mpointstat_hour.delay(mpoint.id, 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) @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):
""" """
手动录入的测点数据进行往上统计一级一级往上 手动录入的测点数据进行往上统计一级一级往上
""" """
@ -157,14 +176,21 @@ def cal_mpointstat_manual(mpointId: str, mgroupId: str, year_s: int, month_s: in
ms_year_s.val = sum_dict_year_s['sum'] ms_year_s.val = sum_dict_year_s['sum']
ms_year_s.save() 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) mgroup = Mgroup.objects.get(id=mgroupId)
sflog = SfLog.objects.get(id=sflogId) sflog = SfLog.objects.get(id=sflogId)
shift = sflog.shift
if type == 'hour_s': if type == 'hour_s':
enstat, _ = EnStat.objects.get_or_create(type="hour_s", mgroup=mgroup, year=year, month=month, day=day, hour=hour, 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, 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': 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, 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}) 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': elif type == 'month_s':
enstat, _ = EnStat.objects.get_or_create(type="month_s", mgroup=mgroup, year_s=year_s, month_s=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}) 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) input_materials.insert(0, mgroup.product.id)
cost_unit_total = 0 cost_unit_total = 0
imaterial_data = [] imaterial_data = []
for mid in input_materials: for ind, mid in enumerate(input_materials):
material = Material.objects.get(id=mid) material = Material.objects.get(id=mid)
if type == 'hour_s': 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) 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) mps = MpointStat.objects.filter(type='sflog', sflog=sflog, mpoint__material=material)
elif type == 'day_s': 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) 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': elif type == 'month_s':
mps = MpointStat.objects.filter(type='month_s', mgroup=mgroup, year_s=year_s, month_s=month_s, mpoint__material=material) mps = MpointStat.objects.filter(type='month_s', mgroup=mgroup, year_s=year_s, month_s=month_s, mpoint__material=material)
elif type == 'year_s': 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'] amount_consume = mps.aggregate(sum=Sum('val'))['sum']
if amount_consume is None: if amount_consume is None:
amount_consume = 0 amount_consume = 0
if mid == mgroup.product.id: if ind == 0: # 如果是产量
enstat.total_production = amount_consume enstat.total_production = amount_consume
enstat.save() enstat.save()
else: else:
@ -220,7 +251,7 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
if material.code == 'elec': if material.code == 'elec':
enstat.elec_consume = amount_consume enstat.elec_consume = amount_consume
enstat.save() 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.imaterial_data = imaterial_data
enstat.save() enstat.save()
other_cost_data = [] other_cost_data = []
@ -238,6 +269,8 @@ def compute_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, mont
elif type == 'sflog': elif type == 'sflog':
compute_enstat('day_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s) compute_enstat('day_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)
elif type == '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) compute_enstat('month_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s)
elif type == 'month_s': elif type == 'month_s':
compute_enstat('year_s', sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_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): def perform_create(self, serializer):
ins = serializer.save() 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): 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() 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): class EnStatViewSet(ListModelMixin, CustomGenericViewSet):