diff --git a/apps/enm/migrations/0003_auto_20230704_1129.py b/apps/enm/migrations/0003_auto_20230704_1129.py new file mode 100644 index 00000000..40e68a36 --- /dev/null +++ b/apps/enm/migrations/0003_auto_20230704_1129.py @@ -0,0 +1,55 @@ +# Generated by Django 3.2.12 on 2023-07-04 03:29 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0004_mgroup_test_materials'), + ('wpm', '0003_auto_20230628_0859'), + ('enm', '0002_auto_20230630_1208'), + ] + + operations = [ + migrations.AddField( + model_name='mpointstat', + name='material', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='计量的物料'), + ), + migrations.AlterField( + model_name='mpointstat', + name='mpoint', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='enm.mpoint', verbose_name='关联测点'), + ), + migrations.CreateModel( + name='EnStat', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('type', models.CharField(default='hour', help_text='year_s/month_s/day_s/sflog/hour', max_length=50, verbose_name='统计维度')), + ('year_s', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='班年')), + ('month_s', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='班月')), + ('day_s', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='班日')), + ('total_production', models.FloatField(blank=True, help_text='t', null=True, verbose_name='总产量')), + ('elec_consume', models.FloatField(blank=True, help_text='kw·h', null=True, verbose_name='总电耗')), + ('production_cost_unit', models.FloatField(blank=True, help_text='y/t', null=True, verbose_name='单位产品成本')), + ('elec_consume_unit', models.FloatField(blank=True, help_text='kw·h/t', null=True, verbose_name='单位产品分布电耗')), + ('celec_consume_unit', models.FloatField(blank=True, help_text='kw·h/t', null=True, verbose_name='单位产品综合电耗')), + ('coal_consume_unit', models.FloatField(blank=True, help_text='kgce/t', null=True, verbose_name='单位产品标煤耗')), + ('cen_consume_unit', models.FloatField(blank=True, help_text='kgce/t', null=True, verbose_name='单位产品综合能耗')), + ('production_hour', models.FloatField(blank=True, help_text='t/h', null=True, verbose_name='台时产量')), + ('run_hour', models.FloatField(blank=True, help_text='h', null=True, verbose_name='运转时长')), + ('run_rate', models.FloatField(blank=True, help_text='%', null=True, verbose_name='运转率')), + ('mgroup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.mgroup', verbose_name='关联工段')), + ('sflog', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.sflog', verbose_name='关联值班记录')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/enm/models.py b/apps/enm/models.py index 1e977bc2..4ca480a7 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 from apps.wpm.models import SfLog -from apps.mtm.models import Material +from apps.mtm.models import Material, Mgroup class Mpoint(CommonBModel): @@ -41,14 +41,29 @@ class MpointStat(BaseModel): hour = models.PositiveSmallIntegerField('时', null=True, blank=True) sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True) - mpoint = models.ForeignKey(Mpoint, verbose_name='关联测点', on_delete=models.CASCADE) + mpoint = models.ForeignKey(Mpoint, verbose_name='关联测点', on_delete=models.CASCADE, null=True, blank=True) + material = models.ForeignKey(Material, verbose_name='计量的物料', on_delete=models.CASCADE, null=True, blank=True) val = models.FloatField('统计值', default=0) -# class EnStat(BaseModel): -# """ -# 能源数据统计表 -# """ -# type = models.CharField('统计种类', max_length=50, default='elec', help_text='year_s/month_s/day_s/sflog') -# sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True) -# mpoint = models.ForeignKey(Mpoint, verbose_name='关联测点', on_delete=models.CASCADE) +class EnStat(BaseModel): + """ + 能源数据统计表 + """ + type = models.CharField('统计维度', max_length=50, default='hour', help_text='year_s/month_s/day_s/sflog/hour') + sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True) + mgroup = models.ForeignKey(Mgroup, verbose_name='关联工段', on_delete=models.CASCADE) + year_s = models.PositiveSmallIntegerField('班年', null=True, blank=True) + month_s = models.PositiveSmallIntegerField('班月', null=True, blank=True) + day_s = models.PositiveSmallIntegerField('班日', null=True, blank=True) + total_production = models.FloatField('总产量', null=True, blank=True, help_text='t') + elec_consume = models.FloatField('总电耗', null=True, blank=True, help_text='kw·h') + production_cost_unit = models.FloatField('单位产品成本', null=True, blank=True, help_text='y/t') + elec_consume_unit = models.FloatField('单位产品分布电耗', null=True, blank=True, help_text='kw·h/t') + celec_consume_unit = models.FloatField('单位产品综合电耗', null=True, blank=True, help_text='kw·h/t') + coal_consume_unit = models.FloatField('单位产品标煤耗', null=True, blank=True, help_text='kgce/t') + cen_consume_unit = models.FloatField('单位产品综合能耗', null=True, blank=True, help_text='kgce/t') + production_hour = models.FloatField('台时产量', null=True, blank=True, help_text='t/h') + run_hour = models.FloatField('运转时长', null=True, blank=True, help_text='h') + run_rate = models.FloatField('运转率', null=True, blank=True, help_text='%') + diff --git a/apps/enm/serializers.py b/apps/enm/serializers.py index 2b563557..390d161d 100644 --- a/apps/enm/serializers.py +++ b/apps/enm/serializers.py @@ -3,6 +3,8 @@ from apps.enm.models import Mpoint, MpLog, MpointStat from apps.utils.constants import EXCLUDE_FIELDS from rest_framework import serializers from apps.mtm.models import Mgroup +from rest_framework.exceptions import ParseError +from django.utils.timezone import localtime class MpointSerializer(CustomModelSerializer): @@ -30,10 +32,35 @@ class MpLogSerializer(CustomModelSerializer): model = MpLog fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['mpoint_name'] + + + class MpointStatSerializer(CustomModelSerializer): mpoint_name = serializers.CharField(source='mpoint.name', read_only=True) class Meta: model = MpointStat - fields = '__all__' \ No newline at end of file + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS + ['mpoint_name', 'type', 'mpoint', 'year', 'month', 'day'] + + def check_required_keys(dictionary, keys): + for key in keys: + if key not in dictionary or not dictionary[key]: + return False + return True + + def validate(self, attrs): + if 'sflog' in attrs and attrs['sflog']: + attrs['type'] = 'sflog' + sflog = attrs['sflog'] + end_time_local = localtime(sflog.end_time) + attrs['year_s'], attrs['month_s'], attrs['day_s'] = end_time_local.year, end_time_local.month, end_time_local.day + else: + keys = ['hour', 'day_s', 'month_s', 'year_s'] + for ind, key in enumerate(keys): + if key in attrs and attrs['key']: + if not self.check_required_keys(attrs, keys[ind+1:]): + raise ParseError('缺少数据') + attrs['type'] = key + return super().validate(attrs) \ No newline at end of file diff --git a/apps/enm/views.py b/apps/enm/views.py index 698d606a..32d2cc1f 100644 --- a/apps/enm/views.py +++ b/apps/enm/views.py @@ -2,6 +2,7 @@ from django.shortcuts import render from apps.enm.models import Mpoint, MpLog, MpointStat from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet from rest_framework.mixins import ListModelMixin +from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin from apps.enm.serializers import (MpointSerializer, MpLogSerializer, MpointStatSerializer) @@ -28,16 +29,16 @@ class MpLogViewSet(ListModelMixin, CustomGenericViewSet): queryset = MpLog.objects.all() serializer_class = MpLogSerializer select_related_fields = ['mpoint'] - filterset_fields = ['mpoint'] + filterset_fields = ['mpoint', 'mpoint__mgroup', 'mpoint__mgroup__belong_dept'] -class MpointStatViewSet(ListModelMixin, CustomGenericViewSet): +class MpointStatViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, ListModelMixin, CustomGenericViewSet): """ list:测点统计记录 测点统计记录 """ - perms_map = {'get': '*'} + perms_map = {'get': '*', 'post': 'mpointstat.create', 'delete': 'mpointstat.delete'} queryset = MpointStat.objects.all() serializer_class = MpointStatSerializer select_related_fields = ['mpoint']