from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, NotOkOption from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.serializers import CustomModelSerializer from rest_framework import serializers from rest_framework.exceptions import ValidationError from apps.system.models import Dept, Dictionary from apps.wpm.models import SfLog, WMaterial from django.db import transaction from apps.inm.serializers import MaterialBatchDetailSerializer class TestItemSerializer(CustomModelSerializer): class Meta: model = TestItem fields = '__all__' read_only_fields = EXCLUDE_FIELDS class QuaStatSerializer(CustomModelSerializer): sflog = serializers.PrimaryKeyRelatedField( label="值班记录", queryset=SfLog.objects.all(), required=True) belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) material_name = serializers.CharField( source='material.name', read_only=True) testitem_name = serializers.CharField( source='testitem.name', read_only=True) class Meta: model = QuaStat fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['belong_dept'] extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': { 'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}} def validate(self, attrs): attrs['rate_pass'] = attrs['num_ok']/attrs['num_test'] attrs['belong_dept'] = attrs['sflog'].mgroup.belong_dept return attrs class QuaStatUpdateSerializer(CustomModelSerializer): belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) material_name = serializers.CharField( source='material.name', read_only=True) testitem_name = serializers.CharField( source='testitem.name', read_only=True) class Meta: model = QuaStat fields = '__all__' read_only_fields = EXCLUDE_FIELDS + \ ['belong_dept', 'sflog', 'material', 'testitem'] extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': { 'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}} def validate(self, attrs): attrs['rate_pass'] = attrs['num_ok']/attrs['num_test'] return super().validate(attrs) class FtestWorkCreateUpdateSerializer(CustomModelSerializer): class Meta: model = FtestWork fields = ['id', 'wm', 'mb', 'type', 'type2', 'test_date', 'count', 'count_sampling', 'count_ok', 'count_notok', 'count_notok_json', 'test_user'] extra_kwargs = {'test_user': {'required': True}, 'type': {'required': True}} def validate(self, attrs): type2 = attrs.get('type2', 20) if type2 == 20: # 如果是全检 attrs['count_sampling'] = attrs['count'] if 'wm' in attrs and attrs['wm']: attrs['mb'] = None wm:WMaterial = attrs['wm'] if wm.state not in [WMaterial.WM_OK, WMaterial.WM_TEST]: raise ValidationError('不支持对该物料检验') attrs['material'] = wm.material attrs['batch'] = wm.batch count_notok_json = attrs.get('count_notok_json', None) if count_notok_json is None: raise ValidationError('不合格项不能为空') count_notok = 0 for k, v in count_notok_json.items(): k_2 = k.replace('count_n_', '') if k_2 not in NotOkOption.values: raise ValidationError(f'不支持的不合格项{k_2}') if isinstance(v, int) and v >= 0: count_notok = count_notok + v else: raise ValidationError(f'不合格项{k_2}必须为非负整数') attrs['count_notok'] = count_notok elif 'mb' in attrs and attrs['mb']: attrs['wm'] = None attrs['material'] = attrs['mb'].material attrs['batch'] = attrs['mb'].batch else: raise ValidationError('请选择车间/仓库库存') return attrs class FtestWorkSerializer(CustomModelSerializer): material_name = serializers.StringRelatedField( source='material', read_only=True) material_cate = serializers.CharField(source='material.cate', read_only=True) mb_ = MaterialBatchDetailSerializer(source='mb', read_only=True) class Meta: model = FtestWork fields = "__all__" class FtestItemSerializer(CustomModelSerializer): testitem_name = serializers.CharField( source='testitem.name', read_only=True) testitem_description = serializers.CharField( source='testitem.description', read_only=True) class Meta: model = FtestItem fields = '__all__' read_only_fields = EXCLUDE_FIELDS_BASE + ['ftest'] class FtestSerializer(CustomModelSerializer): test_user_name = serializers.CharField( source='test_user.name', read_only=True) check_user_name = serializers.CharField( source='check_user.name', read_only=True) ftestitems = FtestItemSerializer(label='检验明细', many=True) class Meta: model = Ftest fields = '__all__' read_only_fields = EXCLUDE_FIELDS def validate(self, attrs): ftest_work: FtestWork = attrs.get('ftest_work', None) if ftest_work: test_user = attrs.get('test_user', None) attrs['type'] = ftest_work.type if test_user is None: attrs['test_user'] = ftest_work.test_user return attrs def create(self, validated_data): ftestitems = validated_data.pop('ftestitems', []) with transaction.atomic(): instance = super().create(validated_data) for item in ftestitems: FtestItem.objects.create(ftest=instance, **item) return instance def update(self, instance, validated_data): validated_data.pop('ftest_work', None) ftestitems = validated_data.pop('ftestitems', []) with transaction.atomic(): instance = super().update(instance, validated_data) for item in ftestitems: id = item.get('id', None) if id: ftestitem = FtestItem.objects.get(id=id) ftestitem.test_val = item['test_val'] ftestitem.check_val = item['check_val'] ftestitem.save() return instance class PtestSerializer(CustomModelSerializer): testitem_name = serializers.CharField( source='testitem.name', read_only=True) test_user_name = serializers.CharField(source='test_user', read_only=True) class Meta: model = Ptest fields = '__all__'