from apps.utils.serializers import CustomModelSerializer from apps.mtm.models import Shift, Material, Mgroup, Team, Goal, Process, Route, TeamMember from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT from rest_framework import serializers from rest_framework.exceptions import ValidationError, ParseError from apps.system.models import Dept, UserPost from django.db import transaction class ShiftSerializer(CustomModelSerializer): class Meta: model = Shift fields = '__all__' read_only_fields = EXCLUDE_FIELDS class MaterialSimpleSerializer(CustomModelSerializer): full_name = serializers.SerializerMethodField() process_name = serializers.CharField(source='process.name', read_only=True) class Meta: model = Material fields = ['id', 'name', 'number', 'model', 'specification', 'type', 'cate', 'brothers', 'process_name', 'full_name'] def get_full_name(self, obj): return f'{obj.name}|{obj.specification if obj.specification else ""}|{obj.model if obj.model else ""}|{obj.process.name if obj.process else ""}' class MaterialSerializer(CustomModelSerializer): process_name = serializers.CharField(source='process.name', read_only=True) full_name = serializers.SerializerMethodField() class Meta: model = Material fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['count'] def get_full_name(self, obj): return f'{obj.name}|{obj.specification if obj.specification else ""}|{obj.model if obj.model else ""}|{obj.process.name if obj.process else ""}' def create(self, validated_data): if Material.objects.filter(name=validated_data['name'], specification=validated_data.get('specification', None), model=validated_data.get('model', None), process=validated_data.get('process', None)).exists(): raise serializers.ValidationError('物料已存在') return super().create(validated_data) def validate(self, attrs): type = attrs['type'] if type in [Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]: if attrs.get('process', None) is None: raise ValidationError('半成品/成品必须指定所到工序') return super().validate(attrs) class MgroupSerializer(CustomModelSerializer): belong_dept = serializers.PrimaryKeyRelatedField( label="所属部门", queryset=Dept.objects.all(), required=True) belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) process_name = serializers.CharField(source='process.name', read_only=True) process_cate = serializers.CharField(source='process.cate', read_only=True) class Meta: model = Mgroup fields = '__all__' read_only_fields = EXCLUDE_FIELDS class TeamMemberSerializer(CustomModelSerializer): user_name = serializers.CharField(source='user.name', read_only=True) mgroup_name = serializers.CharField(source='mgroup.name', read_only=True) post_name = serializers.CharField(source='post.name', read_only=True) class Meta: model = TeamMember fields = '__all__' read_only_fields = EXCLUDE_FIELDS_BASE def validate(self, attrs): user = attrs['user'] post = attrs.get('post', None) if post is None: userpost = UserPost.objects.filter( dept=attrs['mgroup'].belong_dept, user=user).first() if userpost: attrs['post'] = userpost.post else: raise ParseError(f'{user.name}未配置岗位') return super().validate(attrs) class TeamSerializer(CustomModelSerializer): belong_dept = serializers.PrimaryKeyRelatedField( label="所属部门", queryset=Dept.objects.all(), required=True) leader_name = serializers.CharField(source='leader.name', read_only=True) belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) class Meta: model = Team fields = '__all__' read_only_fields = EXCLUDE_FIELDS class GoalSerializer(CustomModelSerializer): goal_cate_name = serializers.CharField( source='goal_cate.name', read_only=True) mgroup_name = serializers.CharField(source='mgroup.name', read_only=True) class Meta: model = Goal fields = '__all__' read_only_fields = EXCLUDE_FIELDS class MgroupGoalYearSerializer(serializers.Serializer): mgroup = serializers.CharField(label='ID或名称') year = serializers.IntegerField(label='年') class ProcessSerializer(CustomModelSerializer): belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) class Meta: model = Process fields = '__all__' read_only_fields = EXCLUDE_FIELDS class RouteSerializer(CustomModelSerializer): material_ = MaterialSerializer(source='material', read_only=True) process_name = serializers.CharField(source='process.name', read_only=True) process_cate = serializers.CharField(source='process.cate', read_only=True) material_in_name = serializers.StringRelatedField( source='material_in', read_only=True) material_out_name = serializers.StringRelatedField( source='material_out', read_only=True) material_out_type = serializers.CharField( source='material_out.type', read_only=True) material_out_is_hidden = serializers.BooleanField( source='material_out.is_hidden', read_only=True) class Meta: model = Route fields = '__all__' read_only_fields = EXCLUDE_FIELDS def validate(self, attrs): if 'mgroup' in attrs and attrs['mgroup']: attrs['process'] = attrs['mgroup'].process if attrs.get('process', None) is None: raise ParseError('未提供操作工序') return super().validate(attrs) def gen_material_out(self, instance): """ 自动形成物料 """ name = f'{instance.material.name}' material_out, _ = Material.objects.get_queryset(all=True).get_or_create(type=Material.MA_TYPE_HALFGOOD, parent=instance.material, process=instance.process, defaults={'parent': instance.material, 'process': instance.process, 'is_hidden': True, 'name': name, 'number': instance.material.number, 'specification': instance.material.specification, 'model': instance.material.model, 'type': Material.MA_TYPE_HALFGOOD, 'create_by': self.request.user, 'update_by': self.request.user, }) if material_out.is_deleted: material_out.is_deleted = False material_out.save() instance.material_out = material_out instance.save() def create(self, validated_data): process = validated_data['process'] material = validated_data.get('material', None) if material and process and Route.objects.filter(material=material, process=process).exists(): raise ValidationError('已选择该工序') with transaction.atomic(): instance = super().create(validated_data) material_out = instance.material_out if material_out: if material_out.process is None: material_out.process = process if instance.material: material_out.parent = instance.material material_out.save() elif material_out.process != process: raise ParseError('物料工序错误!请重新选择') else: if instance.material: self.gen_material_out(instance) return instance def update(self, instance, validated_data): validated_data.pop('material', None) process = validated_data.pop('process', None) with transaction.atomic(): instance = super().update(instance, validated_data) material_out = instance.material_out if material_out: if material_out.process is None: material_out.process = process if instance.material: material_out.parent = instance.material material_out.save() elif material_out.process != process: raise ParseError('物料工序错误!请重新选择') else: if instance.material: self.gen_material_out(instance) return instance