""" Printing API 序列化器 """ from rest_framework import serializers from printing import models from .services import PrintingOrderService, PrintingJobService from basic_info.models import Customer, Employee class PrintingOrderListSerializer(serializers.ModelSerializer): """印染订单列表序列化器""" customer_name = serializers.CharField(source='customer.name', read_only=True) customer_phone = serializers.CharField(source='customer.mobile', read_only=True) process_name = serializers.CharField(source='process.name', read_only=True) progress = serializers.IntegerField(read_only=True) class Meta: model = models.PrintingOrder fields = [ 'id', 'human_id', 'customer', 'customer_name', 'customer_phone', 'fabric', 'width', 'is_urgent', 'area', 'address', 'curve', 'is_fabric_received', 'outgoing_date', 'is_invalid', 'new_curve', 'process', 'process_name', 'progress', 'position', 'created_at', 'updated_at', ] read_only_fields = ['id', 'human_id', 'created_at', 'updated_at', 'progress'] class PrintingOrderDetailSerializer(serializers.ModelSerializer): """印染订单详情序列化器""" customer_name = serializers.CharField(source='customer.name', read_only=True) customer_phone = serializers.CharField(source='customer.mobile', read_only=True) customer_area = serializers.CharField(source='customer.area', read_only=True) process_name = serializers.CharField(source='process.name', read_only=True) progress = serializers.IntegerField(read_only=True) class Meta: model = models.PrintingOrder fields = [ 'id', 'human_id', 'customer', 'customer_name', 'customer_phone', 'customer_area', 'fabric', 'width', 'is_urgent', 'area', 'address', 'fabric_source', 'is_fabric_received', 'craft', 'description', 'outgoing_date', 'curve', 'new_curve', 'position', 'printing_warn', 'rolling_warn', 'production_warn', 'is_invalid', 'process', 'process_name', 'progress', 'created_at', 'updated_at' ] read_only_fields = ['id', 'human_id', 'created_at', 'updated_at', 'progress'] class PrintingOrderCreateUpdateSerializer(serializers.ModelSerializer): """印染订单创建/更新序列化器""" class Meta: model = models.PrintingOrder fields = [ 'id', 'customer', 'fabric', 'width', 'is_urgent', 'area', 'address', 'fabric_source', 'is_fabric_received', 'craft', 'description', 'outgoing_date', 'curve', 'new_curve', 'position', 'printing_warn', 'rolling_warn', 'production_warn', 'is_invalid', 'process' ] read_only_fields = ['id'] def validate_customer(self, value): """验证客户是否存在""" if not value: raise serializers.ValidationError("客户不能为空") return value def validate(self, attrs): """验证流程修改权限""" # 更新时验证 process 修改权限 if self.instance and 'process' in attrs: new_process = attrs['process'] old_process = self.instance.process if new_process != old_process: if not PrintingOrderService.can_change_process(self.instance): raise serializers.ValidationError({ 'process': '存在已开始的印染任务,无法修改流程' }) return attrs def create(self, validated_data): """创建订单,使用 service 层""" user = self.context['request'].user return PrintingOrderService.create_printing_order(validated_data, user) def update(self, instance, validated_data): """更新订单,使用 service 层""" user = self.context['request'].user success, message, updated_instance = PrintingOrderService.update_printing_order( instance, validated_data, user ) if not success: raise serializers.ValidationError(message) return updated_instance class PrintingJobListSerializer(serializers.ModelSerializer): """印染款式明细列表序列化器""" printing_order_id = serializers.CharField(source='printing_order.human_id', read_only=True) product_name = serializers.CharField(source='product.name', read_only=True) status = serializers.CharField(read_only=True) is_completed = serializers.BooleanField(read_only=True) business_object_id = serializers.SerializerMethodField() class Meta: model = models.PrintingJob fields = [ 'id', 'printing_order', 'printing_order_id', 'product', 'product_name', 'quantity', 'unit', 'size', 'pieces', 'description', 'status', 'is_completed', 'business_object_id', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at', 'status', 'is_completed', 'business_object_id'] def get_business_object_id(self, obj): """安全地获取 business_object_id""" return obj.business_object.id if obj.business_object else None class PrintingJobDetailSerializer(serializers.ModelSerializer): """印染款式明细详情序列化器""" printing_order_id = serializers.CharField(source='printing_order.human_id', read_only=True) product_name = serializers.CharField(source='product.name', read_only=True) product_code = serializers.CharField(source='product.human_id', read_only=True) status = serializers.CharField(read_only=True) status_id = serializers.IntegerField(read_only=True) is_completed = serializers.BooleanField(read_only=True) has_started = serializers.BooleanField(read_only=True) business_object_id = serializers.SerializerMethodField() class Meta: model = models.PrintingJob fields = [ 'id', 'printing_order', 'printing_order_id', 'product', 'product_name', 'product_code', 'quantity', 'unit', 'size', 'pieces', 'description', 'status', 'status_id', 'is_completed', 'has_started', 'business_object_id', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'created_at', 'updated_at', 'status', 'status_id', 'is_completed', 'has_started', 'business_object_id' ] def get_business_object_id(self, obj): """安全地获取 business_object_id""" return obj.business_object.id if obj.business_object else None class PrintingJobCreateUpdateSerializer(serializers.ModelSerializer): """印染款式明细创建/更新序列化器""" class Meta: model = models.PrintingJob fields = [ 'id', 'printing_order', 'product', 'quantity', 'unit', 'size', 'pieces', 'description' ] read_only_fields = ['id'] extra_kwargs = { 'size': {'required': False, 'allow_null': True, 'allow_blank': True}, 'pieces': {'required': False, 'allow_null': True}, 'description': {'required': False, 'allow_null': True, 'allow_blank': True}, } def validate_printing_order(self, value): """验证印染订单是否存在""" if not value: raise serializers.ValidationError("印染订单不能为空") return value def validate_product(self, value): """验证产品是否存在""" if not value: raise serializers.ValidationError("产品不能为空") return value def validate_quantity(self, value): """验证数量""" if value <= 0: raise serializers.ValidationError("数量必须大于0") return value def create(self, validated_data): """创建任务,使用 service 层""" user = self.context['request'].user return PrintingJobService.create_printing_job(validated_data, user) def update(self, instance, validated_data): """更新任务,使用 service 层""" user = self.context['request'].user success, message, updated_instance = PrintingJobService.update_printing_job( instance, validated_data, user ) if not success: raise serializers.ValidationError(message) return updated_instance class PlateOrderDesignCodeMixin: """确保 design_code 为空时使用主键""" @staticmethod def _normalize_design_code(design_code: str | None, instance_id: int | None) -> str | None: if design_code: return design_code if instance_id: return str(instance_id) return design_code def to_representation(self, instance): data = super().to_representation(instance) data['design_code'] = self._normalize_design_code(data.get('design_code'), instance.id) return data class PlateOrderListSerializer(PlateOrderDesignCodeMixin, serializers.ModelSerializer): """开版订单列表序列化器""" customer_name = serializers.CharField(source="customer.name", read_only=True) salesperson_name = serializers.CharField(source="salesperson.name", read_only=True) merchandiser_name = serializers.CharField(source="merchandiser.name", read_only=True) designer_name = serializers.CharField(source="designer.name", read_only=True) status = serializers.CharField(read_only=True) progress_percentage = serializers.IntegerField(read_only=True) process_name = serializers.SerializerMethodField() plate_image_url = serializers.SerializerMethodField() class Meta: model = models.PlateOrder fields = [ 'id', 'design_code', 'plate_type', 'plate_date', 'plate_method', 'plate_image', 'plate_image_url', 'image_name', 'plate_notes', 'reprint_reason', 'urgency_level', 'is_invalid', 'customer', 'customer_name', 'area', 'default_address', 'salesperson', 'salesperson_name', 'merchandiser', 'merchandiser_name', 'designer', 'designer_name', 'style_name', 'fabric', 'fabric_source', 'width', 'production_method', 'is_mark_frame', 'drawing_rating', 'color_matching_rating', 'sample_rating', 'difficulty_rating', 'sample_meter', 'required_sample_meters', 'required_completion_date', 'completion_date', 'approval_result', 'is_ordered', 'customer_feedback', 'process', 'process_name', 'status', 'status_id', 'is_completed', 'has_started', 'progress_percentage', 'business_object_id', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'status', 'progress_percentage', 'created_at', 'updated_at' ] def get_plate_image_url(self, obj): """获取图片完整URL""" if obj.plate_image: request = self.context.get("request") if request: return request.build_absolute_uri(obj.plate_image.url) return obj.plate_image.url return None def get_process_name(self, obj) ->str | None: """获取流程名称""" if obj.process: try: from stateflow.models import Process process = Process.objects.get(id=obj.process) return process.name except Process.DoesNotExist: return None return None class PlateOrderDetailSerializer(PlateOrderDesignCodeMixin, serializers.ModelSerializer): """开版订单详情序列化器""" customer_name = serializers.CharField(source="customer.name", read_only=True) customer_phone = serializers.CharField(source="customer.mobile", read_only=True) salesperson_name = serializers.CharField(source="salesperson.name", read_only=True) merchandiser_name = serializers.CharField(source="merchandiser.name", read_only=True) designer_name = serializers.CharField(source="designer.name", read_only=True) status = serializers.CharField(read_only=True) status_id = serializers.IntegerField(read_only=True) is_completed = serializers.BooleanField(read_only=True) has_started = serializers.BooleanField(read_only=True) progress_percentage = serializers.IntegerField(read_only=True) business_object_id = serializers.SerializerMethodField() plate_image_url = serializers.SerializerMethodField() process_name = serializers.SerializerMethodField() class Meta: model = models.PlateOrder fields = [ 'id', 'design_code', 'plate_type', 'plate_date', 'plate_method', 'plate_image', 'plate_image_url', 'image_name', 'plate_notes', 'reprint_reason', 'urgency_level', 'is_invalid', 'customer', 'customer_name', 'customer_phone', 'area', 'default_address', 'salesperson', 'salesperson_name', 'merchandiser', 'merchandiser_name', 'designer', 'designer_name', 'style_name', 'fabric', 'fabric_source', 'width', 'production_method', 'is_mark_frame', 'drawing_rating', 'color_matching_rating', 'sample_rating', 'difficulty_rating', 'sample_meter', 'required_sample_meters', 'required_completion_date', 'completion_date', 'approval_result', 'is_ordered', 'customer_feedback', 'process', 'process_name', 'status', 'status_id', 'is_completed', 'has_started', 'progress_percentage', 'business_object_id', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'status', 'status_id', 'is_completed', 'has_started', 'progress_percentage', 'business_object_id', 'created_at', 'updated_at' ] def get_business_object_id(self, obj): """安全地获取 business_object_id""" return obj.business_object.id if obj.business_object else None def get_plate_image_url(self, obj): """获取图片完整URL""" if obj.plate_image: request = self.context.get("request") if request: return request.build_absolute_uri(obj.plate_image.url) return obj.plate_image.url return None def get_process_name(self, obj): """获取流程名称""" if obj.process: try: from stateflow.models import Process process = Process.objects.get(id=obj.process) return process.name except Process.DoesNotExist: return None return None class PlateOrderCreateUpdateSerializer(serializers.ModelSerializer): """开版订单创建/更新序列化器""" class Meta: model = models.PlateOrder fields = [ "id", "design_code", "plate_type", "plate_date", "plate_method", "plate_image", "image_name", "plate_notes", "reprint_reason", "urgency_level", "is_invalid", "customer", "area", "default_address", "salesperson", "merchandiser", "designer", "style_name", "fabric", "fabric_source", "width", "production_method", "is_mark_frame", "drawing_rating", "color_matching_rating", "sample_rating", "difficulty_rating", "sample_meter", "required_sample_meters", "required_completion_date", "completion_date", "approval_result", "is_ordered", "customer_feedback", "process" ] read_only_fields = ["id"] def validate_customer(self, value): """验证客户是否存在""" if not value: raise serializers.ValidationError("客户不能为空") return value def validate_salesperson(self, value): """验证业务员是否存在""" if value and not Employee.objects.filter(id=value.id).exists(): raise serializers.ValidationError("业务员不存在") return value def validate_merchandiser(self, value): """验证跟单员是否存在""" if value and not Employee.objects.filter(id=value.id).exists(): raise serializers.ValidationError("跟单员不存在") return value def validate_designer(self, value): """验证设计师是否存在""" if value and not Employee.objects.filter(id=value.id).exists(): raise serializers.ValidationError("设计师不存在") return value def validate_sample_meter(self, value): """验证样品米数""" if value is not None and value < 0: raise serializers.ValidationError("样品米数不能为负数") return value def validate_required_sample_meters(self, value): """验证所需样品米数""" if value is not None and value < 0: raise serializers.ValidationError("所需样品米数不能为负数") return value def validate_process(self, value): """验证流程是否存在""" if value: from stateflow.models import Process if not Process.objects.filter(id=value).exists(): raise serializers.ValidationError("流程不存在") return value def validate(self, attrs): """交叉验证""" return attrs def create(self, validated_data): """创建开版订单""" user = self.context["request"].user # 创建 PlateOrder,save 方法会自动创建 BusinessObject plate_order = models.PlateOrder.objects.create(**validated_data) return plate_order def update(self, instance, validated_data): """更新开版订单""" # 直接更新字段,save 方法会自动处理 BusinessObject 的创建 for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() return instance