入厂检查

This commit is contained in:
caoqianming 2021-11-02 15:51:22 +08:00
parent 1bec31257e
commit 0f38d31883
13 changed files with 180 additions and 40 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.6 on 2021-11-02 03:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inm', '0008_auto_20211102_0935'),
]
operations = [
migrations.AddField(
model_name='fifo',
name='is_audited',
field=models.BooleanField(default=False, verbose_name='是否审核'),
),
migrations.AddField(
model_name='fifodetail',
name='is_tested',
field=models.BooleanField(default=False, verbose_name='是否检测'),
),
]

View File

@ -72,7 +72,8 @@ class FIFODetail(BaseModel):
""" """
出入库详细记录 出入库详细记录
""" """
is_tested = models.BooleanField('是否检测', default=False) is_tested = models.BooleanField('是否已检测', default=False)
is_testok = models.BooleanField('是否检测合格', default=False)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
count = models.IntegerField('数量', default=0) count = models.IntegerField('数量', default=0)
batch = models.CharField('批次号', max_length=100, null=True, blank=True) batch = models.CharField('批次号', max_length=100, null=True, blank=True)

View File

@ -8,32 +8,31 @@ def update_inm(instance:FIFO, type:int):
""" """
更新库存(正反) 更新库存(正反)
""" """
if instance.is_audited: warehouse = instance.warehouse
warehouse = instance.warehouse if instance.type in [3]: # 采购入库
if instance.type in [3]: # 采购入库 # 更新相关表
# 更新相关表 for i in FIFODetail.objects.filter(fifo=instance):
for i in FIFODetail.objects.filter(fifo=instance): material = i.material
material = i.material o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \
o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \ defaults={'material':material, 'warehouse':warehouse, 'count':0})
defaults={'material':material, 'warehouse':warehouse, 'count':0}) o1.count = o1.count + i.count
o1.count = o1.count + i.count o1.save()
o1.save() o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\ defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch}) o2.count = o2.count + i.count
o2.count = o2.count + i.count o2.save()
o2.save() material.count = material.count + i.count
material.count = material.count + i.count material.save()
material.save() elif instance.type in [1]: # 生产领料
elif instance.type in [1]: # 生产领料 # 更新相关表
# 更新相关表 for i in FIFODetail.objects.filter(fifo=instance):
for i in FIFODetail.objects.filter(fifo=instance): material = i.material
material = i.material o1 = Inventory.objects.get(material=material, warehouse=warehouse)
o1 = Inventory.objects.get(material=material, warehouse=warehouse) o1.count = o1.count - i.count
o1.count = o1.count - i.count o1.save()
o1.save() o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch)
o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch) o2.count = o2.count - i.count
o2.count = o2.count - i.count o2.save()
o2.save() material.count = material.count - i.count
material.count = material.count - i.count material.save()
material.save()

View File

@ -82,7 +82,10 @@ class FIFOViewSet(ListModelMixin, GenericViewSet):
perms_map = {'*': '*'} perms_map = {'*': '*'}
queryset = FIFO.objects.select_related('warehouse', 'operator') queryset = FIFO.objects.select_related('warehouse', 'operator')
serializer_class = FIFOListSerializer serializer_class = FIFOListSerializer
filterset_fields = ['warehouse', 'type'] filterset_fields = '__all__'
ordering_fields = '__all__'
search_fields = ['warehouse__name', 'warehouse__number']
ordering = ['-pk']
def get_serializer_class(self): def get_serializer_class(self):
if self.action == 'list': if self.action == 'list':
@ -106,7 +109,7 @@ class FIFOViewSet(ListModelMixin, GenericViewSet):
""" """
obj = self.get_object() obj = self.get_object()
for i in FIFODetail.objects.filter(fifo=obj): for i in FIFODetail.objects.filter(fifo=obj):
if not i.is_tested: if not i.is_testok:
raise APIException('未检验通过, 不可审核') raise APIException('未检验通过, 不可审核')
obj.is_audited = True obj.is_audited = True
obj.save() obj.save()

View File

@ -88,6 +88,7 @@ class RecordForm(CommonAModel):
type = models.IntegerField('表格类型', choices=type_choices, default=1) type = models.IntegerField('表格类型', choices=type_choices, default=1)
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True) step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True)
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True) material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
class Meta: class Meta:
verbose_name = '记录表格' verbose_name = '记录表格'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
@ -130,7 +131,7 @@ class RecordFormField(CommonAModel):
field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True, null=True, field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True, null=True,
help_text='radio,checkbox,select,multiselect类型可供选择的选项格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号') help_text='radio,checkbox,select,multiselect类型可供选择的选项格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
need_judge = models.BooleanField('需要判定', default=False) need_judge = models.BooleanField('需要判定项目', default=False)
high_limit = models.FloatField('上限值', null=True, blank=True) high_limit = models.FloatField('上限值', null=True, blank=True)
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True) high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True)
low_limit = models.FloatField('下限值', null=True, blank=True) low_limit = models.FloatField('下限值', null=True, blank=True)

View File

@ -151,6 +151,11 @@ class UsedStepListSerializer(serializers.ModelSerializer):
queryset = queryset.select_related('step') queryset = queryset.select_related('step')
return queryset return queryset
class RecordFormSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = RecordForm
fields = ['id', 'name']
class RecordFormSerializer(serializers.ModelSerializer): class RecordFormSerializer(serializers.ModelSerializer):
step_ = StepSimpleSerializer(source='step', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
@ -182,6 +187,26 @@ class RecordFormFieldSerializer(serializers.ModelSerializer):
model = RecordFormField model = RecordFormField
fields = '__all__' fields = '__all__'
class RecordFormDetailSerializer(serializers.ModelSerializer):
step_ = StepSimpleSerializer(source='step', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True)
form_fields = serializers.SerializerMethodField()
class Meta:
model = RecordForm
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('step', 'material')
return queryset
def get_form_fields(self, obj):
serializer = RecordFormFieldSerializer(instance=RecordFormField.objects.filter(form=obj, is_deleted=False), many=True)
return serializer.data
class RecordFormFieldCreateSerializer(serializers.ModelSerializer): class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordFormField model = RecordFormField

View File

@ -3,7 +3,7 @@ from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubplanMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubplanMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
@ -159,6 +159,8 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
return RecordFormCreateSerializer return RecordFormCreateSerializer
elif self.action == 'update': elif self.action == 'update':
return RecordFormUpdateSerializer return RecordFormUpdateSerializer
elif self.action == 'retrieve':
return RecordFormDetailSerializer
return RecordFormSerializer return RecordFormSerializer
@action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=RecordFormFieldSerializer) @action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=RecordFormFieldSerializer)
@ -171,6 +173,8 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
return Response(serializer.data) return Response(serializer.data)
class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet): class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
""" """
表格字段表 增删改查 表格字段表 增删改查

View File

@ -44,3 +44,9 @@ class TestRecord(CommonAModel):
""" """
检验记录 检验记录
""" """
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
record_data = models.JSONField('记录数据', default=dict, blank=True)
is_testok = models.BooleanField('是否合格', default=True)
fifo_detail = models.ForeignKey('inm.fifodetail', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)

View File

@ -1,6 +1,8 @@
from rest_framework import serializers from rest_framework import serializers
from apps.mtm.models import RecordForm, RecordFormField
from apps.mtm.serializers import RecordFormFieldSerializer, RecordFormSimpleSerializer
from apps.system.serializers import FileSimpleSerializer from apps.system.serializers import FileSimpleSerializer
from .models import Standard, TestItem from .models import Standard, TestItem, TestRecord
class StandardCreateUpdateSerializer(serializers.ModelSerializer): class StandardCreateUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -31,3 +33,41 @@ class TestItemSerializer(serializers.ModelSerializer):
class AnalysisItemSerializer(serializers.ModelSerializer): class AnalysisItemSerializer(serializers.ModelSerializer):
pass pass
class TestRecordCreateSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'fifo_detail']
def create(self, validated_data):
if 'is_testok' not in validated_data:
raise serializers.ValidationError('未填写检测结论')
return super().create(validated_data)
class TestRecordListSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecord
fields = '__all__'
class TestRecordDetailSerializer(serializers.ModelSerializer):
form_ = RecordFormSimpleSerializer(source='form', read_only=True)
record_data_ = serializers.SerializerMethodField()
class Meta:
model = TestRecord
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('form','fifo_detail')
return queryset
def get_record_data_(self, obj):
record_data = obj.record_data
all_fields = RecordFormField.objects.filter(form=obj.form, is_deletd=False).order_by('sort')
all_fields_l = RecordFormFieldSerializer(instance=all_fields, many=True).data
for i in all_fields_l:
key = i['field_key']
i['field_value'] = record_data.get(key, None)
return all_fields_l

View File

@ -1,4 +1,4 @@
from apps.qm.views import StandardViewSet, TestItemViewSet from apps.qm.views import StandardViewSet, TestItemViewSet, TestRecordViewSet
from django.db.models import base from django.db.models import base
from rest_framework import urlpatterns from rest_framework import urlpatterns
from django.urls import path, include from django.urls import path, include
@ -7,6 +7,7 @@ from rest_framework.routers import DefaultRouter
router = DefaultRouter() router = DefaultRouter()
router.register('standard', StandardViewSet, basename='standard') router.register('standard', StandardViewSet, basename='standard')
router.register('testitem', TestItemViewSet, basename='testitem') router.register('testitem', TestItemViewSet, basename='testitem')
router.register('testrecord', TestRecordViewSet, basename='testrecord')
urlpatterns = [ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),
] ]

View File

@ -1,5 +1,5 @@
from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer, TestRecordCreateSerializer, TestRecordDetailSerializer, TestRecordListSerializer
from apps.qm.models import Standard, TestItem from apps.qm.models import Standard, TestItem, TestRecord
from django.shortcuts import render from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from apps.system.mixins import CreateUpdateModelAMixin from apps.system.mixins import CreateUpdateModelAMixin
@ -37,3 +37,29 @@ class TestItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
if self.action in ['create', 'update']: if self.action in ['create', 'update']:
return TestItemCreateUpdateSerializer return TestItemCreateUpdateSerializer
return TestItemSerializer return TestItemSerializer
class TestRecordViewSet(ModelViewSet):
"""
检测记录
"""
perms_map = {'*': '*'}
queryset = TestRecord.objects.select_related('fifo_detail', 'form').all()
serializer_class = TestRecordListSerializer
ordering = ['-id']
def get_serializer_class(self):
if self.action == 'create':
return TestRecordCreateSerializer
elif self.action == 'list':
return TestRecordListSerializer
elif self.action == 'retrieve':
return TestRecordDetailSerializer
return super().get_serializer_class()
def perform_create(self, serializer):
obj = serializer.save(create_by = self.request.user)
# 如果检测合格
if obj.fifo_detail:
obj.fifo_detail.is_testok = True if obj.is_testok else False
obj.fifo_detail.is_tested = True
obj.fifo_detail.save()

View File

@ -1,6 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse
from apps.inm.signals import update_inm
from apps.mtm.models import Material from apps.mtm.models import Material
from apps.mtm.serializers import MaterialSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer
@ -53,12 +54,16 @@ class PickSerializer(serializers.Serializer):
}) })
wm.count = wm.count + i['pick_count'] wm.count = wm.count + i['pick_count']
wm.save() wm.save()
# 更新子计划进度 # 更新子计划物料情况
spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1) spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1)
spp.count_real = spp.count_real + i['pick_count'] spp.count_real = spp.count_real + i['pick_count']
spp.save() spp.save()
sp.is_picked=True sp.is_picked=True
sp.save() sp.save()
# 更新库存
fifo.is_audited = True
fifo.save()
update_inm(fifo)
return fifo return fifo
class WMaterialListSerializer(serializers.ModelSerializer): class WMaterialListSerializer(serializers.ModelSerializer):

View File

@ -0,0 +1,6 @@
from rest_framework.viewsets import GenericViewSet
class MyGenericViewSet(GenericViewSet):
filterset_fields = '__all__'
ordering_fields = '__all__'
ordering = ['-pk']