diff --git a/apps/enm/migrations/0011_auto_20230718_1357.py b/apps/enm/migrations/0011_auto_20230718_1357.py new file mode 100644 index 00000000..9972174c --- /dev/null +++ b/apps/enm/migrations/0011_auto_20230718_1357.py @@ -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='统计维度'), + ), + ] diff --git a/apps/enm/models.py b/apps/enm/models.py index 583ec237..e39fed1f 100644 --- a/apps/enm/models.py +++ b/apps/enm/models.py @@ -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) diff --git a/apps/enm/tasks.py b/apps/enm/tasks.py index 1bbc9c5b..18397fd6 100644 --- a/apps/enm/tasks.py +++ b/apps/enm/tasks.py @@ -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) \ No newline at end of file diff --git a/apps/enm/views.py b/apps/enm/views.py index 7da01bc8..d18c36f0 100644 --- a/apps/enm/views.py +++ b/apps/enm/views.py @@ -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):