diff --git a/hb_server/apps/mtm/migrations/0001_initial.py b/hb_server/apps/mtm/migrations/0001_initial.py index d44f801..654ed11 100644 --- a/hb_server/apps/mtm/migrations/0001_initial.py +++ b/hb_server/apps/mtm/migrations/0001_initial.py @@ -94,24 +94,6 @@ class Migration(migrations.Migration): 'verbose_name_plural': '操作记录条目', }, ), - migrations.CreateModel( - name='ProductProcess', - fields=[ - ('id', models.BigAutoField(auto_created=True, 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='删除标记')), - ('sort', models.IntegerField(default=1, verbose_name='排序号')), - ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productprocess_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), - ('process', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='工序')), - ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='产品')), - ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productprocess_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), - ], - options={ - 'verbose_name': '产品生产工序', - 'verbose_name_plural': '产品生产工序', - }, - ), migrations.CreateModel( name='OutputMaterial', fields=[ diff --git a/hb_server/apps/mtm/migrations/0019_auto_20211012_0901.py b/hb_server/apps/mtm/migrations/0019_auto_20211012_0901.py new file mode 100644 index 0000000..9cc24ed --- /dev/null +++ b/hb_server/apps/mtm/migrations/0019_auto_20211012_0901.py @@ -0,0 +1,137 @@ +# Generated by Django 3.2.6 on 2021-10-12 01:01 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0018_material_count'), + ] + + operations = [ + migrations.CreateModel( + name='SubProduction', + fields=[ + ('id', models.BigAutoField(auto_created=True, 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='删除标记')), + ('name', models.CharField(blank=True, max_length=50, null=True, verbose_name='命名')), + ('sort', models.IntegerField(default=1, verbose_name='排序号')), + ], + options={ + 'verbose_name': '产品生产工序', + 'verbose_name_plural': '产品生产工序', + }, + ), + migrations.RemoveField( + model_name='inputmaterial', + name='create_by', + ), + migrations.RemoveField( + model_name='inputmaterial', + name='process', + ), + migrations.RemoveField( + model_name='inputmaterial', + name='product', + ), + migrations.RemoveField( + model_name='inputmaterial', + name='update_by', + ), + migrations.RemoveField( + model_name='material', + name='processes', + ), + migrations.RemoveField( + model_name='outputmaterial', + name='create_by', + ), + migrations.RemoveField( + model_name='outputmaterial', + name='process', + ), + migrations.RemoveField( + model_name='outputmaterial', + name='product', + ), + migrations.RemoveField( + model_name='outputmaterial', + name='update_by', + ), + migrations.RemoveField( + model_name='techdoc', + name='create_by', + ), + migrations.RemoveField( + model_name='techdoc', + name='process', + ), + migrations.RemoveField( + model_name='techdoc', + name='product', + ), + migrations.RemoveField( + model_name='techdoc', + name='update_by', + ), + migrations.RemoveField( + model_name='usedstep', + name='create_by', + ), + migrations.RemoveField( + model_name='usedstep', + name='process', + ), + migrations.RemoveField( + model_name='usedstep', + name='product', + ), + migrations.RemoveField( + model_name='usedstep', + name='update_by', + ), + migrations.AddField( + model_name='usedstep', + name='remark', + field=models.TextField(blank=True, null=True, verbose_name='生产备注'), + ), + migrations.AlterField( + model_name='step', + name='process', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='step_process', to='mtm.process', verbose_name='所属工序'), + ), + migrations.AddField( + model_name='subproduction', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='产品'), + ), + migrations.AddField( + model_name='inputmaterial', + name='subproduction', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'), + preserve_default=False, + ), + migrations.AddField( + model_name='outputmaterial', + name='subproduction', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'), + preserve_default=False, + ), + migrations.AddField( + model_name='techdoc', + name='subproduction', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'), + preserve_default=False, + ), + migrations.AddField( + model_name='usedstep', + name='subproduction', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'), + preserve_default=False, + ), + ] diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 36f2c04..1037796 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -29,7 +29,6 @@ class Material(CommonAModel): specification = models.CharField('型号', max_length=100, null=True, blank=True) type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) - processes = models.JSONField('工艺流程', default=list, blank=True, null=True) unit = models.CharField('基准计量单位', choices=unit_choices, default='块', max_length=10) count = models.IntegerField('物料总数', default=0) class Meta: @@ -60,7 +59,7 @@ class Step(CommonAModel): """ 工序步骤 """ - process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序') + process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序', related_name='step_process') name = models.CharField('工序步骤名称', max_length=100) number = models.CharField('步骤编号', max_length=100, null=True, blank=True) instruction_content = models.TextField('相应操作指导', null=True, blank=True) @@ -127,26 +126,28 @@ class RecordFormField(CommonAModel): def __str__(self): return self.field_key + '-' + self.field_name -class ProductProcess(CommonAModel): + + +class SubProduction(BaseModel): """ - 产品生产工艺集 + 产品生产分解 """ + name = models.CharField('命名', max_length=50, null=True, blank=True) product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE) - process = models.ForeignKey(Process, verbose_name='工序', on_delete=models.CASCADE) sort = models.IntegerField('排序号', default=1) class Meta: verbose_name = '产品生产工序' verbose_name_plural = verbose_name -class InputMaterial(CommonAModel): + +class InputMaterial(BaseModel): """ 输入物料 """ material = models.ForeignKey(Material, verbose_name='输入物料', on_delete=models.CASCADE, related_name='inputmaterial') count = models.FloatField('消耗量', default=1) - product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE, related_name='inputmaterial_product') - process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) sort = models.IntegerField('排序号', default=1) class Meta: @@ -155,41 +156,39 @@ class InputMaterial(CommonAModel): -class OutputMaterial(CommonAModel): +class OutputMaterial(BaseModel): """ 输出物料 """ material = models.ForeignKey(Material, verbose_name='输出物料', on_delete=models.CASCADE, related_name='outputmaterial') count = models.FloatField('产出量', default=1) - product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE, related_name='outputmaterial_product') - process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) sort = models.IntegerField('排序号', default=1) class Meta: verbose_name = '输出物料' verbose_name_plural = verbose_name -class UsedStep(CommonAModel): +class UsedStep(BaseModel): """ - 产品生产子工序 + 涉及的生产子工序 """ step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedsteps') - product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE) - process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE) + remark = models.TextField('生产备注', null=True, blank=True) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) class Meta: verbose_name = '产品生产子工序' verbose_name_plural = verbose_name -class TechDoc(CommonAModel): +class TechDoc(BaseModel): """ 技术文件 """ name = models.CharField('名称', max_length=50) file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE) - product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE) - process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) content = models.TextField('内容', null=True, blank=True) class Meta: diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index 6a1dd98..e6ab035 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -1,7 +1,7 @@ from apps.em.serializers import EquipmentSimpleSerializer from rest_framework import serializers from rest_framework.exceptions import ParseError, ValidationError -from .models import InputMaterial, Material, OutputMaterial, Process, ProductProcess, RecordForm, RecordFormField, Step, TechDoc, UsedStep +from .models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer @@ -18,7 +18,8 @@ class MaterialDetailSerializer(serializers.ModelSerializer): fields = '__all__' def get_processes_(self, obj): - objs = Process.objects.filter(id__in=obj.processes).order_by('number') + steps = UsedStep.objects.filter(subproducation__product=obj) + objs = Process.objects.filter(step_process__in=steps).order_by('number') return ProcessSimpleSerializer(instance=objs, many=True).data @@ -60,18 +61,11 @@ class StepDetailSerializer(serializers.ModelSerializer): queryset = queryset.prefetch_related('equipments') return queryset -class ProductProcessListSerializer(serializers.ModelSerializer): - process_ = ProcessSimpleSerializer(source='process', read_only=True) - product_ = MaterialSimpleSerializer(source='product', read_only=True) +class SubProductionSerializer(serializers.ModelSerializer): class Meta: - model = ProductProcess + model = SubProduction fields = '__all__' -class ProductProcessUpdateSerializer(serializers.ModelSerializer): - class Meta: - model = ProductProcess - fields = ['sort'] - class InputMaterialListSerializer(serializers.ModelSerializer): material_ = MaterialSimpleSerializer(source='material', read_only=True) class Meta: @@ -88,10 +82,10 @@ class OutputMaterialListSerializer(serializers.ModelSerializer): class InputMaterialSerializer(serializers.ModelSerializer): class Meta: model = InputMaterial - fields = ['count', 'sort', 'material', 'product', 'process'] + fields = ['count', 'sort', 'material', 'subproduction'] def create(self, validated_data): - if InputMaterial.objects.filter(material=validated_data['material'], product=validated_data['product'], process=validated_data['process'], is_deleted=False).exists(): + if InputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists(): raise ValidationError('该物料已存在') return super().create(validated_data) @@ -103,10 +97,10 @@ class InputMaterialUpdateSerializer(serializers.ModelSerializer): class OutputMaterialSerializer(serializers.ModelSerializer): class Meta: model = OutputMaterial - fields = ['count', 'sort', 'material', 'product', 'process'] + fields = ['count', 'sort', 'material', 'subproduction'] def create(self, validated_data): - if OutputMaterial.objects.filter(material=validated_data['material'], product=validated_data['product'], process=validated_data['process'], is_deleted=False).exists(): + if OutputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists(): raise ValidationError('该物料已存在') return super().create(validated_data) @@ -121,7 +115,7 @@ class UsedStepCreateSerializer(serializers.ModelSerializer): """ class Meta: model = UsedStep - fields = ['step', 'product', 'process'] + fields = ['step', 'subproduction'] class UsedStepListSerializer(serializers.ModelSerializer): """ @@ -198,7 +192,7 @@ class TechDocListSerializer(serializers.ModelSerializer): class TechDocCreateSerializer(serializers.ModelSerializer): class Meta: model = TechDoc - fields = ['file', 'product', 'process', 'name', 'content'] + fields = ['file', 'subproduction', 'name', 'content'] class TechDocUpdateSerializer(serializers.ModelSerializer): class Meta: diff --git a/hb_server/apps/mtm/urls.py b/hb_server/apps/mtm/urls.py index 7048bc5..5c18f0c 100644 --- a/hb_server/apps/mtm/urls.py +++ b/hb_server/apps/mtm/urls.py @@ -1,14 +1,14 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, TechDocViewSet, UsedStepViewSet +from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, SubProductionViewSet, TechDocViewSet, UsedStepViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register('material', MaterialViewSet, basename='material') router.register('process', ProcessViewSet, basename='process') -# router.register('productprocess', ProductProcessViewSet, basename='productprocess') router.register('step', StepViewSet, basename='step') +router.register('subproducation', SubProductionViewSet, basename='subproducation') router.register('inputmaterial', InputMaterialViewSet, basename='inputmaterial') router.register('outputmaterial', OutputMaterialViewSet, basename='outputmaterial') router.register('usedstep', UsedStepViewSet, basename='usedstep') diff --git a/hb_server/apps/mtm/views.py b/hb_server/apps/mtm/views.py index 974bdba..96ecf06 100644 --- a/hb_server/apps/mtm/views.py +++ b/hb_server/apps/mtm/views.py @@ -2,8 +2,8 @@ from django.shortcuts import render from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin -from apps.mtm.models import InputMaterial, Material, OutputMaterial, Process, ProductProcess, RecordForm, RecordFormField, Step, TechDoc, UsedStep -from apps.mtm.serializers import InputMaterialListSerializer, InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OutputMaterialListSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProductProcessListSerializer, ProductProcessUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer +from apps.mtm.models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction +from apps.mtm.serializers import InputMaterialListSerializer, InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OutputMaterialListSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from rest_framework.decorators import action from rest_framework.response import Response @@ -30,15 +30,6 @@ class MaterialViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet): return MaterialDetailSerializer return MaterialSerializer - # @action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=MaterialSimpleSerializer) - # def processes(self, request, pk=None): - # """ - # 产品生产工艺流程 - # """ - # material = self.get_object() - # serializer = self.serializer_class(instance=Process.objects.filter(id__in=material.processes), many=True) - # return Response(serializer.data) - class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet): """ @@ -78,20 +69,16 @@ class StepViewSet(OptimizationMixin, CreateUpdateModelAMixin, CreateModelMixin, return StepDetailSerializer return StepSerializer -# class ProductProcessViewSet(PageOrNot, CreateModelMixin, UpdateModelMixin, ListModelMixin, DestroyModelMixin, GenericViewSet): -# """ -# 产品生产工艺流程增删改查 -# """ -# perms_map={'*':'*'} -# queryset = ProductProcess.objects.select_related('process', 'product').all() -# filterset_fields = ['process', 'product'] -# serializer_class = ProductProcessListSerializer -# ordering = ['sort'] - -# def get_serializer_class(self): -# if self.action == 'update': -# return ProductProcessUpdateSerializer -# return super().get_serializer_class() +class SubProductionViewSet(PageOrNot, CreateModelMixin, UpdateModelMixin, ListModelMixin, DestroyModelMixin, GenericViewSet): + """ + 产品生产分解增删改查 + """ + perms_map={'*':'*'} + queryset = SubProduction.objects.all() + filterset_fields = ['product'] + search_fields = ['name'] + serializer_class = SubProductionSerializer + ordering = ['sort'] class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet): """ @@ -100,7 +87,7 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet): perms_map = {'*':'*'} queryset = InputMaterial.objects.select_related('material').all() serializer_class = InputMaterialSerializer - filterset_fields = ['process', 'product'] + filterset_fields = ['subproduction'] ordering = ['sort', '-create_time'] def get_serializer_class(self): @@ -117,7 +104,7 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet): perms_map = {'*':'*'} queryset = OutputMaterial.objects.select_related('material').all() serializer_class = OutputMaterialSerializer - filterset_fields = ['process', 'product'] + filterset_fields = ['subproduction'] ordering = ['sort', '-create_time'] def get_serializer_class(self): @@ -133,7 +120,7 @@ class UsedStepViewSet(OptimizationMixin, CreateUpdateModelAMixin, CreateModelMix """ perms_map = {'*':'*'} queryset = UsedStep.objects.all() - filterset_fields = ['process', 'product', 'step'] + filterset_fields = ['subproduction', 'step'] ordering = ['step__sort', '-step__create_time'] def get_serializer_class(self): @@ -189,7 +176,7 @@ class TechDocViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet): """ perms_map = {'*':'*'} queryset = TechDoc.objects.select_related('file').all() - filterset_fields = ['process', 'product'] + filterset_fields = ['subproduction'] search_fields = ['name'] ordering = ['-id']