from rest_framework import serializers from apps.shop.models import Product, ProductCategory class CategoryManagementSerializer(serializers.ModelSerializer): order_cat = serializers.IntegerField(required=False, allow_null=True, min_value=0, max_value=2147483647) excel_order = serializers.IntegerField(required=False, allow_null=True, min_value=0, max_value=2147483647) product_count = serializers.IntegerField(read_only=True) child_count = serializers.IntegerField(read_only=True) parent = serializers.PrimaryKeyRelatedField(queryset=ProductCategory.objects.all(), allow_null=True, required=False) class Meta: model = ProductCategory fields = ('id', 'name', 'parent', 'image', 'order_cat', 'excel_order', 'product_count', 'child_count') def validate(self, attrs): workspace = self.context['workspace'] parent = attrs.get('parent', self.instance.parent if self.instance else None) if parent and parent.sys_ws_id != workspace.pk: raise serializers.ValidationError({'parent': 'دسته والد متعلق به فضای کاری دیگری است.'}) visited = set() cursor = parent while cursor: if cursor.pk in visited or self.instance and cursor.pk == self.instance.pk: raise serializers.ValidationError({'parent': 'انتخاب این والد باعث چرخه در دسته‌ها می‌شود.'}) visited.add(cursor.pk) cursor = cursor.parent name = attrs.get('name', self.instance.name if self.instance else '') matches = ProductCategory.objects.filter(sys_ws=workspace, name=name, parent=parent) if self.instance: matches = matches.exclude(pk=self.instance.pk) if matches.exists(): raise serializers.ValidationError({'name': 'این نام در همین دسته والد قبلاً ثبت شده است.'}) return attrs class ProductManagementSerializer(serializers.ModelSerializer): order_prd = serializers.IntegerField(required=False, allow_null=True, min_value=0, max_value=2147483647) excel_order = serializers.IntegerField(required=False, allow_null=True, min_value=0, max_value=2147483647) category_name = serializers.CharField(source='category.name', read_only=True) price = serializers.IntegerField(min_value=0, max_value=9223372036854775807) category = serializers.PrimaryKeyRelatedField(queryset=ProductCategory.objects.all()) acc_code = serializers.CharField(required=False, allow_blank=True, allow_null=True) class Meta: model = Product fields = ('id', 'name', 'price', 'category', 'category_name', 'acc_code', 'attr', 'view_only', 'order_prd', 'excel_order', 'created_at', 'updated_at') read_only_fields = ('id', 'created_at', 'updated_at') def validate_category(self, category): if category.sys_ws_id != self.context['workspace'].pk: raise serializers.ValidationError('دسته متعلق به فضای کاری دیگری است.') return category def validate_acc_code(self, code): if code: matches = Product.objects.filter(sys_ws=self.context['workspace'], acc_code=code) if self.instance: matches = matches.exclude(pk=self.instance.pk) if matches.exists(): raise serializers.ValidationError('کد محصول در این فضای کاری تکراری است.') return code def validate_attr(self, value): if value is not None and not isinstance(value, dict): raise serializers.ValidationError('ویژگی‌ها باید یک شیء JSON باشد.') return value def to_representation(self, instance): data = super().to_representation(instance) data['price'] = str(instance.price) return data class ImportOptionsSerializer(serializers.Serializer): file = serializers.FileField() sheet = serializers.CharField(required=False, allow_blank=True, default='') header_row = serializers.IntegerField(min_value=1, max_value=100, default=1) mode = serializers.ChoiceField(choices=('create', 'upsert', 'update'), default='create') create_categories = serializers.BooleanField(default=True) errors = serializers.ChoiceField(choices=('atomic', 'skip'), default='atomic') ordering = serializers.ChoiceField(choices=('preserve', 'rows', 'append'), default='preserve') mapping = serializers.JSONField(default=dict) def validate_mapping(self, value): if not isinstance(value, dict) or not all(isinstance(key, str) and isinstance(item, str) for key, item in value.items()): raise serializers.ValidationError('نگاشت ستون‌ها باید شیء JSON با مقدارهای متنی باشد.') return value