Example #1
0
class ShopProductSerializer(TranslatableModelSerializer):
    orderable = serializers.SerializerMethodField()
    visibility = EnumField(enum=ShopProductVisibility)
    visibility_limit = EnumField(enum=ProductVisibility)
    translations = TranslatedFieldsField(shared_model=ShopProduct, required=False)

    class Meta:
        model = ShopProduct
        fields = "__all__"
        extra_kwargs = {
            "visibility_groups": {"required": False},
            "shipping_methods": {"required": False},
            "suppliers": {"required": False},
            "payment_methods": {"required": False},
            "categories": {"required": False},
        }

    def get_orderable(self, shop_product):
        customer = self.context["request"].customer
        quantity = shop_product.minimum_purchase_quantity
        supplier = shop_product.get_supplier(customer, quantity)
        try:
            return shop_product.is_orderable(supplier=supplier, customer=customer, quantity=quantity)
        except:
            return False
Example #2
0
class SavedAddressSerializer(serializers.ModelSerializer):
    role = EnumField(SavedAddressRole)
    status = EnumField(SavedAddressStatus)
    address = AddressSerializer()

    class Meta:
        model = SavedAddress
        exclude = ()
Example #3
0
class AttributeSerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Attribute)
    type = EnumField(enum=AttributeType)
    visibility_mode = EnumField(enum=AttributeVisibility)

    class Meta:
        fields = "__all__"
        model = Attribute
Example #4
0
class CategorySerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Category)
    status = EnumField(CategoryStatus)
    visibility = EnumField(CategoryVisibility)

    class Meta:
        model = Category
        exclude = ("image", )
Example #5
0
class OrderSerializer(serializers.ModelSerializer):
    payment_status = EnumField(PaymentStatus)
    shipping_status = EnumField(ShippingStatus)
    billing_address = AddressSerializer()
    shipping_address = AddressSerializer()
    lines = OrderLineSerializer(many=True)

    class Meta:
        model = Order
        exclude = ()
Example #6
0
class CategorySerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Category)
    status = EnumField(CategoryStatus)
    visibility = EnumField(CategoryVisibility)
    image = serializers.SerializerMethodField()

    class Meta:
        model = Category
        exclude = ("shops",)

    def get_image(self, category):
        if category.image:
            return self.context["request"].build_absolute_uri(category.image.url)
Example #7
0
class ShopSerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Shop)
    status = EnumField(ShopStatus)

    class Meta:
        model = Shop
        exclude = ("logo", "favicon")
Example #8
0
class ShopSerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Shop)
    status = EnumField(ShopStatus)
    logo = serializers.SerializerMethodField()
    favicon = serializers.SerializerMethodField()
    contact_address = AddressSerializer(read_only=True)
    distance = serializers.SerializerMethodField()
    options = serializers.JSONField(binary=False, required=False)

    class Meta:
        model = Shop
        kwargs = {
            "modified_on": {"read_only": True},
            "created_on": {"read_only": True},
        }
        exclude = ("identifier",)

    def to_representation(self, instance):
        data = super(ShopSerializer, self).to_representation(instance)
        data["currency"] = CurrencySerializer(Currency.objects.get(code=instance.currency), context=self.context).data
        return data

    def get_logo(self, shop):
        if shop.logo:
            return self.context["request"].build_absolute_uri(shop.logo.url)

    def get_favicon(self, shop):
        if shop.favicon:
            return self.context["request"].build_absolute_uri(shop.favicon.url)

    def get_distance(self, shop):
        return getattr(shop, 'distance', 0)
Example #9
0
class PersonContactSerializer(ContactSerializer):
    gender = EnumField(Gender, required=False)

    class Meta(ContactSerializer.Meta):
        model = PersonContact
        extra_kwargs = {
            "created_on": {"read_only": True}
        }
Example #10
0
class GDPRPersonContactSerializer(ContactSerializer):
    gender = EnumField(Gender)
    user = UserSerializer()
    log_entries = PersonContactLogEntrySerializer(many=True)
    company_memberships = GDPRCompanyContactSerializer(many=True)

    class Meta:
        model = PersonContact
        exclude = ("polymorphic_ctype", )
class ProductLinkVariationVariableSerializer(serializers.Serializer):
    product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), required=False)
    hash = serializers.CharField(max_length=40, min_length=40, required=True)
    status = EnumField(enum=ProductVariationLinkStatus, required=False)

    def validate(self, data):
        if self.context["request"].method in ("PUT", "POST") and not data.get("product"):
            raise serializers.ValidationError("`product` is required for this method.")
        return data
Example #12
0
class ProductSerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Product)
    shop_products = ShopProductSubsetSerializer(many=True, read_only=True)
    primary_image = ProductMediaSerializer(read_only=True)
    media = ProductMediaSerializer(read_only=True, many=True)
    stock_behavior = EnumField(enum=StockBehavior)
    shipping_mode = EnumField(enum=ShippingMode)
    attributes = ProductAttributeSerializer(many=True, read_only=True)
    package_content = serializers.SerializerMethodField()
    variation_children = serializers.PrimaryKeyRelatedField(many=True,
                                                            read_only=True)
    variation_variables = serializers.PrimaryKeyRelatedField(many=True,
                                                             read_only=True)
    variation_results = serializers.SerializerMethodField()

    class Meta:
        fields = "__all__"
        model = Product
        extra_kwargs = {
            "mode": {
                "read_only": True
            },
            "variation_parent": {
                "read_only": True
            },
            "created_on": {
                "read_only": True
            },
            "modified_on": {
                "read_only": True
            },
            "deleted_on": {
                "read_only": True
            }
        }

    def get_package_content(self, product):
        return ProductPackageLinkSerializer(
            ProductPackageLink.objects.filter(parent=product), many=True).data

    def get_variation_results(self, product):
        return ProductVariationVariableResultSerializer(
            product).data["combinations"]
Example #13
0
class CategorySerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Category)
    status = EnumField(CategoryStatus)
    visibility = EnumField(CategoryVisibility)
    image = serializers.SerializerMethodField()

    def __init__(self, *args, **kwargs):
        super(CategorySerializer, self).__init__(*args, **kwargs)
        request = self.context.get("request")
        if request.method == "POST":
            self.fields["image"] = Base64FileField(required=False,
                                                   write_only=True)
            self.fields["image_path"] = serializers.CharField(required=False,
                                                              write_only=True)
        elif request.method == "GET":
            self.fields["image"] = serializers.SerializerMethodField()

    def create(self, validated_data):
        if "image_path" in validated_data:
            validated_data.pop("image_path")
        return super(CategorySerializer, self).create(validated_data)

    def validate(self, data):
        if data.get("image") and data.get("image_path"):
            data["image"] = filer_image_from_upload(self.context["request"],
                                                    path=data["image_path"],
                                                    upload_data=data["image"])
        elif data.get("image"):
            raise serializers.ValidationError(
                "Path is required when sending a Category image.")
        return data

    def get_image(self, category):
        if category.image:
            return self.context["request"].build_absolute_uri(
                category.image.url)

    class Meta:
        model = Category
        fields = '__all__'
Example #14
0
class ProductMediaSerializer(TranslatableModelSerializer):
    kind = EnumField(enum=ProductMediaKind)
    translations = TranslatedFieldsField(shared_model=ProductMedia)
    file = serializers.SerializerMethodField()

    class Meta:
        model = ProductMedia
        extra_kwargs = {"product": {"read_only": True}}
        exclude = ("identifier", )

    def get_file(self, product_media):
        if product_media.file:
            return self.context["request"].build_absolute_uri(
                product_media.file.url)
Example #15
0
class BasketLineSerializer(serializers.Serializer):
    product = BasketProductSerializer(required=False)
    image = serializers.SerializerMethodField()
    text = serializers.CharField()
    sku = serializers.CharField()
    quantity = serializers.DecimalField(
        max_digits=FORMATTED_DECIMAL_FIELD_MAX_DIGITS,
        decimal_places=FORMATTED_DECIMAL_FIELD_DECIMAL_PLACES)
    price = serializers.DecimalField(
        max_digits=FORMATTED_DECIMAL_FIELD_MAX_DIGITS,
        decimal_places=FORMATTED_DECIMAL_FIELD_DECIMAL_PLACES)
    base_price = serializers.DecimalField(
        max_digits=FORMATTED_DECIMAL_FIELD_MAX_DIGITS,
        decimal_places=FORMATTED_DECIMAL_FIELD_DECIMAL_PLACES)
    discount_amount = serializers.DecimalField(
        max_digits=FORMATTED_DECIMAL_FIELD_MAX_DIGITS,
        decimal_places=FORMATTED_DECIMAL_FIELD_DECIMAL_PLACES)
    type = EnumField(OrderLineType)
    shop = serializers.SerializerMethodField()
    shop_product = serializers.SerializerMethodField()
    line_id = serializers.CharField()

    def get_image(self, line):
        """ Return simply the primary image URL """

        if not line.product:
            return

        primary_image = line.product.primary_image

        # no image found
        if not primary_image:
            # check for variation parent image
            if not line.product.variation_parent or not line.product.variation_parent.primary_image:
                return

            primary_image = line.product.variation_parent.primary_image

        if primary_image.external_url:
            return primary_image.external_url
        else:
            return self.context["request"].build_absolute_uri(
                primary_image.file.url)

    def get_shop_product(self, line):
        return line.shop_product.id if line.product else None

    def get_shop(self, line):
        return line.shop.id if line.shop else None
Example #16
0
class BasketBaseLineSerializer(BaseLineSerializerMixin,
                               serializers.Serializer):
    product = BasketProductSerializer(required=False)
    image = serializers.SerializerMethodField()
    text = serializers.CharField()
    sku = serializers.CharField()
    can_delete = serializers.BooleanField()
    can_change_quantity = serializers.BooleanField()
    supplier = serializers.IntegerField(source="supplier.id")

    type = EnumField(OrderLineType)
    shop = serializers.SerializerMethodField()
    shop_product = serializers.SerializerMethodField()
    line_id = serializers.CharField()

    def get_image(self, line):
        """ Return simply the primary image URL """

        if not line.product:
            return

        primary_image = line.product.primary_image

        # no image found
        if not primary_image:
            # check for variation parent image
            if not line.product.variation_parent or not line.product.variation_parent.primary_image:
                return

            primary_image = line.product.variation_parent.primary_image

        if primary_image.external_url:
            return primary_image.external_url
        else:
            return self.context["request"].build_absolute_uri(
                primary_image.file.url)

    def get_shop_product(self, line):
        return line.shop_product.id if line.product else None

    def get_shop(self, line):
        return line.shop.id if line.shop else None
Example #17
0
class ContactSerializer(serializers.ModelSerializer):
    default_shipping_address = AddressSerializer(required=False)
    default_billing_address = AddressSerializer(required=False)
    gender = EnumField(Gender, required=False)
    name = serializers.CharField(required=False)

    class Meta:
        model = PersonContact
        exclude = [
            "identifier", "tax_group", "polymorphic_ctype", "account_manager"
        ]
        extra_kwargs = {"created_on": {"read_only": True}}

    def update_address(self, instance, field_name, validated_address_data):
        if not validated_address_data:
            return None
        contact_address = getattr(instance, field_name)
        if contact_address:
            MutableAddress.objects.filter(pk=contact_address.pk).update(
                **validated_address_data)
            contact_address.refresh_from_db()
        else:
            address = MutableAddress(**validated_address_data)
            address.save()
            setattr(instance, field_name, address)
            instance.save()

    def update(self, instance, validated_data):
        default_shipping_address = validated_data.pop(
            "default_shipping_address", None)
        default_billing_address = validated_data.pop("default_billing_address",
                                                     None)
        instance = super(ContactSerializer,
                         self).update(instance, validated_data)
        self.update_address(instance, "default_shipping_address",
                            default_shipping_address)
        self.update_address(instance, "default_billing_address",
                            default_billing_address)
        return instance
Example #18
0
class OrderLineSerializer(serializers.ModelSerializer):
    type = EnumField(OrderLineType)

    class Meta:
        model = OrderLine
        exclude = ()
Example #19
0
class ProductSerializer(TranslatableModelSerializer):
    translations = TranslatedFieldsField(shared_model=Product)
    shop_products = ShopProductSubsetSerializer(many=True, required=False)
    primary_image = ProductMediaSerializer(read_only=True)
    media = ProductMediaSerializer(read_only=True, many=True)
    stock_behavior = EnumField(enum=StockBehavior)
    shipping_mode = EnumField(enum=ShippingMode)
    attributes = ProductAttributeSerializer(many=True, required=False)
    package_content = serializers.SerializerMethodField()
    variation_children = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    variation_variables = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    variation_results = serializers.SerializerMethodField()

    class Meta:
        fields = "__all__"
        model = Product
        extra_kwargs = {
            "mode": {"read_only": True},
            "variation_parent": {"read_only": True},
            "created_on": {"read_only": True},
            "modified_on": {"read_only": True},
            "deleted_on": {"read_only": True}
        }

    def get_package_content(self, product):
        return ProductPackageLinkSerializer(ProductPackageLink.objects.filter(parent=product), many=True).data

    def get_variation_results(self, product):
        return ProductVariationVariableResultSerializer(product).data["combinations"]

    def create(self, validated_data):
        nested = self._pop_nested_objects(validated_data)
        instance = super(ProductSerializer, self).create(validated_data)
        self._handle_nested_structures(instance, nested)
        return instance

    def update(self, instance, validated_data):
        nested = self._pop_nested_objects(validated_data)
        super(ProductSerializer, self).update(instance, validated_data)
        self._handle_nested_structures(instance, nested)
        return instance

    def _pop_nested_objects(self, validated_data):
        return {
            field: validated_data.pop(field, None)
            for field in ['attributes', 'shop_products']
        }

    def _handle_nested_structures(self, product, nested):
        attributes = nested['attributes']
        shop_products = nested['shop_products']

        if not self.partial:
            if attributes is not None:
                product.attributes.all().delete()
            if shop_products is not None:
                product.shop_products.all().delete()

        if attributes:
            for attribute_data in attributes:
                self._handle_attribute_value(product, attribute_data)

        if shop_products:
            for shop_product_data in shop_products:
                self._handle_shop_product(product, shop_product_data)

    def _handle_attribute_value(self, product, data):
        attr = data["attribute"]  # type: shuup.core.models.Attribute
        if attr.is_stringy and attr.is_translated:
            translations = data.get('translations')
            if not self.partial or translations is None:
                product.clear_attribute_value(attr.identifier)
            for (lang, lang_data) in (translations or {}).items():
                value = lang_data["translated_string_value"]
                product.set_attribute_value(attr.identifier, value, language=lang)
        elif attr.is_stringy:
            product.set_attribute_value(attr.identifier, data["untranslated_string_value"])
        elif attr.is_numeric:
            product.set_attribute_value(attr.identifier, data["numeric_value"])
        elif attr.is_temporal:
            product.set_attribute_value(attr.identifier, data["datetime_value"])

    def _handle_shop_product(self, product, data):
        shop = data.pop('shop')
        m2m_data = [
            (field, data.pop(field, None))
            for field in ['suppliers', 'categories', 'visibility_groups',
                          'shipping_methods', 'payment_methods']
        ]

        (shop_product, created) = ShopProduct.objects.get_or_create(
            product=product, shop=shop, defaults=data)

        if not created:
            for (field, value) in data.items():
                setattr(shop_product, field, value)
            shop_product.save()

        for (field, values) in m2m_data:
            if values is None:
                continue
            field_objects = getattr(shop_product, field)
            field_objects.clear()
            for value in values:
                field_objects.add(value)

        return shop_product
Example #20
0
class ContactLogEntrySerializer(serializers.ModelSerializer):
    kind = EnumField(LogEntryKind)

    class Meta:
        model = ContactGroupLogEntry
        exclude = ()
Example #21
0
class StockAdjustmentSerializer(serializers.Serializer):
    type = EnumField(StockAdjustmentType, default=StockAdjustmentType.INVENTORY)
    product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all_except_deleted())
    delta = FormattedDecimalField()