产品生产分解

This commit is contained in:
caoqianming 2021-10-12 10:45:14 +08:00
parent bbba12ed6c
commit 1e7ebd672a
6 changed files with 183 additions and 84 deletions

View File

@ -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=[

View File

@ -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,
),
]

View File

@ -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:

View File

@ -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:

View File

@ -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')

View File

@ -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']