# DO NOT EDIT! This file is automatically generated
import re
import typing

import marshmallow
import marshmallow_enum

from commercetools import helpers, types
from commercetools._schemas._common import (
    BaseResourceSchema,
    LocalizedStringField,
    ReferenceSchema,
    ResourceIdentifierSchema,
)
from commercetools._schemas._type import FieldContainerField

__all__ = [
    "AttributeSchema",
    "CustomTokenizerSchema",
    "FacetResultRangeSchema",
    "FacetResultSchema",
    "FacetResultTermSchema",
    "FacetResultsSchema",
    "FilteredFacetResultSchema",
    "ProductAddAssetActionSchema",
    "ProductAddExternalImageActionSchema",
    "ProductAddPriceActionSchema",
    "ProductAddToCategoryActionSchema",
    "ProductAddVariantActionSchema",
    "ProductCatalogDataSchema",
    "ProductChangeAssetNameActionSchema",
    "ProductChangeAssetOrderActionSchema",
    "ProductChangeMasterVariantActionSchema",
    "ProductChangeNameActionSchema",
    "ProductChangePriceActionSchema",
    "ProductChangeSlugActionSchema",
    "ProductDataSchema",
    "ProductDraftSchema",
    "ProductLegacySetSkuActionSchema",
    "ProductMoveImageToPositionActionSchema",
    "ProductPagedQueryResponseSchema",
    "ProductProjectionPagedQueryResponseSchema",
    "ProductProjectionPagedSearchResponseSchema",
    "ProductProjectionSchema",
    "ProductPublishActionSchema",
    "ProductReferenceSchema",
    "ProductRemoveAssetActionSchema",
    "ProductRemoveFromCategoryActionSchema",
    "ProductRemoveImageActionSchema",
    "ProductRemovePriceActionSchema",
    "ProductRemoveVariantActionSchema",
    "ProductResourceIdentifierSchema",
    "ProductRevertStagedChangesActionSchema",
    "ProductRevertStagedVariantChangesActionSchema",
    "ProductSchema",
    "ProductSetAssetCustomFieldActionSchema",
    "ProductSetAssetCustomTypeActionSchema",
    "ProductSetAssetDescriptionActionSchema",
    "ProductSetAssetKeyActionSchema",
    "ProductSetAssetSourcesActionSchema",
    "ProductSetAssetTagsActionSchema",
    "ProductSetAttributeActionSchema",
    "ProductSetAttributeInAllVariantsActionSchema",
    "ProductSetCategoryOrderHintActionSchema",
    "ProductSetDescriptionActionSchema",
    "ProductSetDiscountedPriceActionSchema",
    "ProductSetImageLabelActionSchema",
    "ProductSetKeyActionSchema",
    "ProductSetMetaDescriptionActionSchema",
    "ProductSetMetaKeywordsActionSchema",
    "ProductSetMetaTitleActionSchema",
    "ProductSetPricesActionSchema",
    "ProductSetProductPriceCustomFieldActionSchema",
    "ProductSetProductPriceCustomTypeActionSchema",
    "ProductSetProductVariantKeyActionSchema",
    "ProductSetSearchKeywordsActionSchema",
    "ProductSetSkuActionSchema",
    "ProductSetTaxCategoryActionSchema",
    "ProductTransitionStateActionSchema",
    "ProductUnpublishActionSchema",
    "ProductUpdateActionSchema",
    "ProductUpdateSchema",
    "ProductVariantAvailabilitySchema",
    "ProductVariantChannelAvailabilityMapSchema",
    "ProductVariantChannelAvailabilitySchema",
    "ProductVariantDraftSchema",
    "ProductVariantSchema",
    "RangeFacetResultSchema",
    "SearchKeywordSchema",
    "SearchKeywordsSchema",
    "SuggestTokenizerSchema",
    "SuggestionResultSchema",
    "SuggestionSchema",
    "TermFacetResultSchema",
    "WhitespaceTokenizerSchema",
]


class CategoryOrderHintsField(marshmallow.fields.Dict):
    def _deserialize(self, value, attr, data, **kwargs):
        result = super()._deserialize(value, attr, data)
        return types.CategoryOrderHints(**result)


class AttributeSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.Attribute`."""

    name = marshmallow.fields.String(allow_none=True)
    value = marshmallow.fields.Raw(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.Attribute(**data)


class FacetResultRangeSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.FacetResultRange`."""

    from_ = marshmallow.fields.Integer(allow_none=True, data_key="from")
    from_str = marshmallow.fields.String(allow_none=True, data_key="fromStr")
    to = marshmallow.fields.Integer(allow_none=True)
    to_str = marshmallow.fields.String(allow_none=True, data_key="toStr")
    count = marshmallow.fields.Integer(allow_none=True)
    product_count = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="productCount"
    )
    total = marshmallow.fields.Integer(allow_none=True)
    min = marshmallow.fields.Integer(allow_none=True)
    max = marshmallow.fields.Integer(allow_none=True)
    mean = marshmallow.fields.Integer(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.FacetResultRange(**data)


class FacetResultSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.FacetResult`."""

    type = marshmallow_enum.EnumField(types.FacetTypes, by_value=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.FacetResult(**data)


class FacetResultTermSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.FacetResultTerm`."""

    term = marshmallow.fields.Raw(allow_none=True)
    count = marshmallow.fields.Integer(allow_none=True)
    product_count = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="productCount"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.FacetResultTerm(**data)


class FacetResultsSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.FacetResults`."""

    _regex = helpers.RegexField(
        unknown=marshmallow.EXCLUDE,
        pattern=re.compile("^[a-z].*$"),
        type=helpers.Discriminator(
            discriminator_field=("type", "type"),
            discriminator_schemas={
                "filter": "commercetools._schemas._product.FilteredFacetResultSchema",
                "range": "commercetools._schemas._product.RangeFacetResultSchema",
                "terms": "commercetools._schemas._product.TermFacetResultSchema",
            },
            unknown=marshmallow.EXCLUDE,
            allow_none=True,
        ),
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return types.FacetResults(**data)

    @marshmallow.pre_load
    def pre_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.pre_dump
    def pre_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.post_dump
    def post_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return data


class ProductCatalogDataSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductCatalogData`."""

    published = marshmallow.fields.Bool(allow_none=True)
    current = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductDataSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    staged = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductDataSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    has_staged_changes = marshmallow.fields.Bool(
        allow_none=True, data_key="hasStagedChanges"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductCatalogData(**data)


class ProductDataSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductData`."""

    name = LocalizedStringField(allow_none=True)
    categories = helpers.LazyNestedField(
        nested="commercetools._schemas._category.CategoryReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    category_order_hints = CategoryOrderHintsField(
        allow_none=True, missing=None, data_key="categoryOrderHints"
    )
    description = LocalizedStringField(allow_none=True, missing=None)
    slug = LocalizedStringField(allow_none=True)
    meta_title = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaTitle"
    )
    meta_description = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaDescription"
    )
    meta_keywords = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaKeywords"
    )
    master_variant = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="masterVariant",
    )
    variants = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    search_keywords = helpers.LazyNestedField(
        nested="commercetools._schemas._product.SearchKeywordsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="searchKeywords",
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductData(**data)


class ProductDraftSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductDraft`."""

    product_type = helpers.LazyNestedField(
        nested="commercetools._schemas._product_type.ProductTypeResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="productType",
    )
    name = LocalizedStringField(allow_none=True)
    slug = LocalizedStringField(allow_none=True)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    description = LocalizedStringField(allow_none=True, missing=None)
    categories = helpers.LazyNestedField(
        nested="commercetools._schemas._category.CategoryResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    category_order_hints = CategoryOrderHintsField(
        allow_none=True, missing=None, data_key="categoryOrderHints"
    )
    meta_title = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaTitle"
    )
    meta_description = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaDescription"
    )
    meta_keywords = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaKeywords"
    )
    master_variant = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="masterVariant",
    )
    variants = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    tax_category = helpers.LazyNestedField(
        nested="commercetools._schemas._tax_category.TaxCategoryResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="taxCategory",
    )
    search_keywords = helpers.LazyNestedField(
        nested="commercetools._schemas._product.SearchKeywordsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="searchKeywords",
    )
    state = helpers.LazyNestedField(
        nested="commercetools._schemas._state.StateResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    publish = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductDraft(**data)


class ProductPagedQueryResponseSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductPagedQueryResponse`."""

    limit = marshmallow.fields.Integer(allow_none=True)
    count = marshmallow.fields.Integer(allow_none=True)
    total = marshmallow.fields.Integer(allow_none=True, missing=None)
    offset = marshmallow.fields.Integer(allow_none=True)
    results = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductPagedQueryResponse(**data)


class ProductProjectionPagedQueryResponseSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductProjectionPagedQueryResponse`."""

    limit = marshmallow.fields.Integer(allow_none=True)
    count = marshmallow.fields.Integer(allow_none=True)
    total = marshmallow.fields.Integer(allow_none=True, missing=None)
    offset = marshmallow.fields.Integer(allow_none=True)
    results = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductProjectionSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductProjectionPagedQueryResponse(**data)


class ProductProjectionPagedSearchResponseSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductProjectionPagedSearchResponse`."""

    count = marshmallow.fields.Integer(allow_none=True)
    total = marshmallow.fields.Integer(allow_none=True, missing=None)
    offset = marshmallow.fields.Integer(allow_none=True)
    results = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductProjectionSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    facets = helpers.LazyNestedField(
        nested="commercetools._schemas._product.FacetResultsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductProjectionPagedSearchResponse(**data)


class ProductProjectionSchema(BaseResourceSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductProjection`."""

    id = marshmallow.fields.String(allow_none=True)
    version = marshmallow.fields.Integer(allow_none=True)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    product_type = helpers.LazyNestedField(
        nested="commercetools._schemas._product_type.ProductTypeReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="productType",
    )
    name = LocalizedStringField(allow_none=True)
    description = LocalizedStringField(allow_none=True, missing=None)
    slug = LocalizedStringField(allow_none=True)
    categories = helpers.LazyNestedField(
        nested="commercetools._schemas._category.CategoryReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    category_order_hints = CategoryOrderHintsField(
        allow_none=True, missing=None, data_key="categoryOrderHints"
    )
    meta_title = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaTitle"
    )
    meta_description = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaDescription"
    )
    meta_keywords = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaKeywords"
    )
    search_keywords = helpers.LazyNestedField(
        nested="commercetools._schemas._product.SearchKeywordsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="searchKeywords",
    )
    has_staged_changes = marshmallow.fields.Bool(
        allow_none=True, missing=None, data_key="hasStagedChanges"
    )
    published = marshmallow.fields.Bool(allow_none=True, missing=None)
    master_variant = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="masterVariant",
    )
    variants = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    tax_category = helpers.LazyNestedField(
        nested="commercetools._schemas._tax_category.TaxCategoryReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="taxCategory",
    )
    state = helpers.LazyNestedField(
        nested="commercetools._schemas._state.StateReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    review_rating_statistics = helpers.LazyNestedField(
        nested="commercetools._schemas._review.ReviewRatingStatisticsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="reviewRatingStatistics",
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductProjection(**data)


class ProductReferenceSchema(ReferenceSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductReference`."""

    obj = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type_id"]
        return types.ProductReference(**data)


class ProductResourceIdentifierSchema(ResourceIdentifierSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductResourceIdentifier`."""

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type_id"]
        return types.ProductResourceIdentifier(**data)


class ProductSchema(BaseResourceSchema):
    """Marshmallow schema for :class:`commercetools.types.Product`."""

    id = marshmallow.fields.String(allow_none=True)
    version = marshmallow.fields.Integer(allow_none=True)
    created_at = marshmallow.fields.DateTime(allow_none=True, data_key="createdAt")
    last_modified_at = marshmallow.fields.DateTime(
        allow_none=True, data_key="lastModifiedAt"
    )
    last_modified_by = helpers.LazyNestedField(
        nested="commercetools._schemas._common.LastModifiedBySchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="lastModifiedBy",
    )
    created_by = helpers.LazyNestedField(
        nested="commercetools._schemas._common.CreatedBySchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="createdBy",
    )
    key = marshmallow.fields.String(allow_none=True, missing=None)
    product_type = helpers.LazyNestedField(
        nested="commercetools._schemas._product_type.ProductTypeReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="productType",
    )
    master_data = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductCatalogDataSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="masterData",
    )
    tax_category = helpers.LazyNestedField(
        nested="commercetools._schemas._tax_category.TaxCategoryReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="taxCategory",
    )
    state = helpers.LazyNestedField(
        nested="commercetools._schemas._state.StateReferenceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    review_rating_statistics = helpers.LazyNestedField(
        nested="commercetools._schemas._review.ReviewRatingStatisticsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="reviewRatingStatistics",
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.Product(**data)


class ProductUpdateActionSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductUpdateAction`."""

    action = marshmallow.fields.String(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductUpdateAction(**data)


class ProductUpdateSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductUpdate`."""

    version = marshmallow.fields.Integer(allow_none=True)
    actions = marshmallow.fields.List(
        helpers.Discriminator(
            discriminator_field=("action", "action"),
            discriminator_schemas={
                "addAsset": "commercetools._schemas._product.ProductAddAssetActionSchema",
                "addExternalImage": "commercetools._schemas._product.ProductAddExternalImageActionSchema",
                "addPrice": "commercetools._schemas._product.ProductAddPriceActionSchema",
                "addToCategory": "commercetools._schemas._product.ProductAddToCategoryActionSchema",
                "addVariant": "commercetools._schemas._product.ProductAddVariantActionSchema",
                "changeAssetName": "commercetools._schemas._product.ProductChangeAssetNameActionSchema",
                "changeAssetOrder": "commercetools._schemas._product.ProductChangeAssetOrderActionSchema",
                "changeMasterVariant": "commercetools._schemas._product.ProductChangeMasterVariantActionSchema",
                "changeName": "commercetools._schemas._product.ProductChangeNameActionSchema",
                "changePrice": "commercetools._schemas._product.ProductChangePriceActionSchema",
                "changeSlug": "commercetools._schemas._product.ProductChangeSlugActionSchema",
                "legacySetSku": "commercetools._schemas._product.ProductLegacySetSkuActionSchema",
                "moveImageToPosition": "commercetools._schemas._product.ProductMoveImageToPositionActionSchema",
                "publish": "commercetools._schemas._product.ProductPublishActionSchema",
                "removeAsset": "commercetools._schemas._product.ProductRemoveAssetActionSchema",
                "removeFromCategory": "commercetools._schemas._product.ProductRemoveFromCategoryActionSchema",
                "removeImage": "commercetools._schemas._product.ProductRemoveImageActionSchema",
                "removePrice": "commercetools._schemas._product.ProductRemovePriceActionSchema",
                "removeVariant": "commercetools._schemas._product.ProductRemoveVariantActionSchema",
                "revertStagedChanges": "commercetools._schemas._product.ProductRevertStagedChangesActionSchema",
                "revertStagedVariantChanges": "commercetools._schemas._product.ProductRevertStagedVariantChangesActionSchema",
                "setAssetCustomField": "commercetools._schemas._product.ProductSetAssetCustomFieldActionSchema",
                "setAssetCustomType": "commercetools._schemas._product.ProductSetAssetCustomTypeActionSchema",
                "setAssetDescription": "commercetools._schemas._product.ProductSetAssetDescriptionActionSchema",
                "setAssetKey": "commercetools._schemas._product.ProductSetAssetKeyActionSchema",
                "setAssetSources": "commercetools._schemas._product.ProductSetAssetSourcesActionSchema",
                "setAssetTags": "commercetools._schemas._product.ProductSetAssetTagsActionSchema",
                "setAttribute": "commercetools._schemas._product.ProductSetAttributeActionSchema",
                "setAttributeInAllVariants": "commercetools._schemas._product.ProductSetAttributeInAllVariantsActionSchema",
                "setCategoryOrderHint": "commercetools._schemas._product.ProductSetCategoryOrderHintActionSchema",
                "setDescription": "commercetools._schemas._product.ProductSetDescriptionActionSchema",
                "setDiscountedPrice": "commercetools._schemas._product.ProductSetDiscountedPriceActionSchema",
                "setImageLabel": "commercetools._schemas._product.ProductSetImageLabelActionSchema",
                "setKey": "commercetools._schemas._product.ProductSetKeyActionSchema",
                "setMetaDescription": "commercetools._schemas._product.ProductSetMetaDescriptionActionSchema",
                "setMetaKeywords": "commercetools._schemas._product.ProductSetMetaKeywordsActionSchema",
                "setMetaTitle": "commercetools._schemas._product.ProductSetMetaTitleActionSchema",
                "setPrices": "commercetools._schemas._product.ProductSetPricesActionSchema",
                "setProductPriceCustomField": "commercetools._schemas._product.ProductSetProductPriceCustomFieldActionSchema",
                "setProductPriceCustomType": "commercetools._schemas._product.ProductSetProductPriceCustomTypeActionSchema",
                "setProductVariantKey": "commercetools._schemas._product.ProductSetProductVariantKeyActionSchema",
                "setSearchKeywords": "commercetools._schemas._product.ProductSetSearchKeywordsActionSchema",
                "setSku": "commercetools._schemas._product.ProductSetSkuActionSchema",
                "setTaxCategory": "commercetools._schemas._product.ProductSetTaxCategoryActionSchema",
                "transitionState": "commercetools._schemas._product.ProductTransitionStateActionSchema",
                "unpublish": "commercetools._schemas._product.ProductUnpublishActionSchema",
            },
            unknown=marshmallow.EXCLUDE,
            allow_none=True,
        ),
        allow_none=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductUpdate(**data)


class ProductVariantAvailabilitySchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductVariantAvailability`."""

    is_on_stock = marshmallow.fields.Bool(
        allow_none=True, missing=None, data_key="isOnStock"
    )
    restockable_in_days = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="restockableInDays"
    )
    available_quantity = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="availableQuantity"
    )
    channels = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantChannelAvailabilityMapSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductVariantAvailability(**data)


class ProductVariantChannelAvailabilityMapSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductVariantChannelAvailabilityMap`."""

    _regex = helpers.RegexField(
        unknown=marshmallow.EXCLUDE,
        pattern=re.compile(""),
        type=helpers.LazyNestedField(
            nested="commercetools._schemas._product.ProductVariantChannelAvailabilitySchema",
            unknown=marshmallow.EXCLUDE,
            allow_none=True,
        ),
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return types.ProductVariantChannelAvailabilityMap(**data)

    @marshmallow.pre_load
    def pre_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.pre_dump
    def pre_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.post_dump
    def post_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return data


class ProductVariantChannelAvailabilitySchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductVariantChannelAvailability`."""

    is_on_stock = marshmallow.fields.Bool(
        allow_none=True, missing=None, data_key="isOnStock"
    )
    restockable_in_days = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="restockableInDays"
    )
    available_quantity = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="availableQuantity"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductVariantChannelAvailability(**data)


class ProductVariantDraftSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductVariantDraft`."""

    sku = marshmallow.fields.String(allow_none=True, missing=None)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    prices = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    attributes = helpers.LazyNestedField(
        nested="commercetools._schemas._product.AttributeSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    images = helpers.LazyNestedField(
        nested="commercetools._schemas._common.ImageSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    assets = helpers.LazyNestedField(
        nested="commercetools._schemas._common.AssetDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductVariantDraft(**data)


class ProductVariantSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.ProductVariant`."""

    id = marshmallow.fields.Integer(allow_none=True)
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    prices = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    attributes = helpers.LazyNestedField(
        nested="commercetools._schemas._product.AttributeSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    price = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    images = helpers.LazyNestedField(
        nested="commercetools._schemas._common.ImageSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    assets = helpers.LazyNestedField(
        nested="commercetools._schemas._common.AssetSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    availability = helpers.LazyNestedField(
        nested="commercetools._schemas._product.ProductVariantAvailabilitySchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    is_matching_variant = marshmallow.fields.Bool(
        allow_none=True, missing=None, data_key="isMatchingVariant"
    )
    scoped_price = helpers.LazyNestedField(
        nested="commercetools._schemas._common.ScopedPriceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="scopedPrice",
    )
    scoped_price_discounted = marshmallow.fields.Bool(
        allow_none=True, missing=None, data_key="scopedPriceDiscounted"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.ProductVariant(**data)


class SearchKeywordSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.SearchKeyword`."""

    text = marshmallow.fields.String(allow_none=True)
    suggest_tokenizer = helpers.Discriminator(
        discriminator_field=("type", "type"),
        discriminator_schemas={
            "custom": "commercetools._schemas._product.CustomTokenizerSchema",
            "whitespace": "commercetools._schemas._product.WhitespaceTokenizerSchema",
        },
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="suggestTokenizer",
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.SearchKeyword(**data)


class SearchKeywordsSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.SearchKeywords`."""

    _regex = helpers.RegexField(
        unknown=marshmallow.EXCLUDE,
        pattern=re.compile("^[a-z]{2}(-[A-Z]{2})?$"),
        type=helpers.LazyNestedField(
            nested="commercetools._schemas._product.SearchKeywordSchema",
            unknown=marshmallow.EXCLUDE,
            allow_none=True,
            many=True,
        ),
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return types.SearchKeywords(**data)

    @marshmallow.pre_load
    def pre_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.pre_dump
    def pre_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.post_dump
    def post_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return data


class SuggestTokenizerSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.SuggestTokenizer`."""

    type = marshmallow.fields.String(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.SuggestTokenizer(**data)


class SuggestionResultSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.SuggestionResult`."""

    _regex = helpers.RegexField(
        unknown=marshmallow.EXCLUDE,
        pattern=re.compile("searchKeywords.[a-z]{2}(-[A-Z]{2})?"),
        type=marshmallow.fields.List(
            helpers.LazyNestedField(
                nested="commercetools._schemas._product.SuggestionSchema",
                unknown=marshmallow.EXCLUDE,
                allow_none=True,
            ),
            allow_none=True,
        ),
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return types.SuggestionResult(**data)

    @marshmallow.pre_load
    def pre_load(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.pre_dump
    def pre_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).preprocess(data)
        return data

    @marshmallow.post_dump
    def post_dump(self, data, **kwargs):
        data = typing.cast(helpers.RegexField, self.fields["_regex"]).postprocess(data)
        return data


class SuggestionSchema(marshmallow.Schema):
    """Marshmallow schema for :class:`commercetools.types.Suggestion`."""

    text = marshmallow.fields.String(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        return types.Suggestion(**data)


class CustomTokenizerSchema(SuggestTokenizerSchema):
    """Marshmallow schema for :class:`commercetools.types.CustomTokenizer`."""

    inputs = marshmallow.fields.List(marshmallow.fields.String(allow_none=True))

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.CustomTokenizer(**data)


class FilteredFacetResultSchema(FacetResultSchema):
    """Marshmallow schema for :class:`commercetools.types.FilteredFacetResult`."""

    count = marshmallow.fields.Integer(allow_none=True)
    product_count = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="productCount"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.FilteredFacetResult(**data)


class ProductAddAssetActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductAddAssetAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset = helpers.LazyNestedField(
        nested="commercetools._schemas._common.AssetDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    position = marshmallow.fields.Integer(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductAddAssetAction(**data)


class ProductAddExternalImageActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductAddExternalImageAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    image = helpers.LazyNestedField(
        nested="commercetools._schemas._common.ImageSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductAddExternalImageAction(**data)


class ProductAddPriceActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductAddPriceAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    price = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductAddPriceAction(**data)


class ProductAddToCategoryActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductAddToCategoryAction`."""

    category = helpers.LazyNestedField(
        nested="commercetools._schemas._category.CategoryResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    order_hint = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="orderHint"
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductAddToCategoryAction(**data)


class ProductAddVariantActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductAddVariantAction`."""

    sku = marshmallow.fields.String(allow_none=True, missing=None)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    prices = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    images = helpers.LazyNestedField(
        nested="commercetools._schemas._common.ImageSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    attributes = helpers.LazyNestedField(
        nested="commercetools._schemas._product.AttributeSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    assets = helpers.LazyNestedField(
        nested="commercetools._schemas._common.AssetSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
        missing=None,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductAddVariantAction(**data)


class ProductChangeAssetNameActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangeAssetNameAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    name = LocalizedStringField(allow_none=True)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangeAssetNameAction(**data)


class ProductChangeAssetOrderActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangeAssetOrderAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_order = marshmallow.fields.List(
        marshmallow.fields.String(allow_none=True), data_key="assetOrder"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangeAssetOrderAction(**data)


class ProductChangeMasterVariantActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangeMasterVariantAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangeMasterVariantAction(**data)


class ProductChangeNameActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangeNameAction`."""

    name = LocalizedStringField(allow_none=True)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangeNameAction(**data)


class ProductChangePriceActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangePriceAction`."""

    price_id = marshmallow.fields.String(allow_none=True, data_key="priceId")
    price = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangePriceAction(**data)


class ProductChangeSlugActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductChangeSlugAction`."""

    slug = LocalizedStringField(allow_none=True)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductChangeSlugAction(**data)


class ProductLegacySetSkuActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductLegacySetSkuAction`."""

    sku = marshmallow.fields.String(allow_none=True, missing=None)
    variant_id = marshmallow.fields.Integer(allow_none=True, data_key="variantId")

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductLegacySetSkuAction(**data)


class ProductMoveImageToPositionActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductMoveImageToPositionAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    image_url = marshmallow.fields.String(allow_none=True, data_key="imageUrl")
    position = marshmallow.fields.Integer(allow_none=True)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductMoveImageToPositionAction(**data)


class ProductPublishActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductPublishAction`."""

    scope = marshmallow_enum.EnumField(
        types.ProductPublishScope, by_value=True, missing=None
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductPublishAction(**data)


class ProductRemoveAssetActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRemoveAssetAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRemoveAssetAction(**data)


class ProductRemoveFromCategoryActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRemoveFromCategoryAction`."""

    category = helpers.LazyNestedField(
        nested="commercetools._schemas._category.CategoryResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRemoveFromCategoryAction(**data)


class ProductRemoveImageActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRemoveImageAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    image_url = marshmallow.fields.String(allow_none=True, data_key="imageUrl")
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRemoveImageAction(**data)


class ProductRemovePriceActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRemovePriceAction`."""

    price_id = marshmallow.fields.String(allow_none=True, data_key="priceId")
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRemovePriceAction(**data)


class ProductRemoveVariantActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRemoveVariantAction`."""

    id = marshmallow.fields.Integer(allow_none=True, missing=None)
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRemoveVariantAction(**data)


class ProductRevertStagedChangesActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRevertStagedChangesAction`."""

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRevertStagedChangesAction()


class ProductRevertStagedVariantChangesActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductRevertStagedVariantChangesAction`."""

    variant_id = marshmallow.fields.Integer(allow_none=True, data_key="variantId")

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductRevertStagedVariantChangesAction(**data)


class ProductSetAssetCustomFieldActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetCustomFieldAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    name = marshmallow.fields.String(allow_none=True)
    value = marshmallow.fields.Raw(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetCustomFieldAction(**data)


class ProductSetAssetCustomTypeActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetCustomTypeAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    type = helpers.LazyNestedField(
        nested="commercetools._schemas._type.TypeResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    fields = marshmallow.fields.Dict(allow_none=True, missing=None)  # type: ignore

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetCustomTypeAction(**data)


class ProductSetAssetDescriptionActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetDescriptionAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    description = LocalizedStringField(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetDescriptionAction(**data)


class ProductSetAssetKeyActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetKeyAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(allow_none=True, data_key="assetId")
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetKeyAction(**data)


class ProductSetAssetSourcesActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetSourcesAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    sources = helpers.LazyNestedField(
        nested="commercetools._schemas._common.AssetSourceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetSourcesAction(**data)


class ProductSetAssetTagsActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAssetTagsAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    asset_id = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetId"
    )
    asset_key = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="assetKey"
    )
    tags = marshmallow.fields.List(
        marshmallow.fields.String(allow_none=True), missing=None
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAssetTagsAction(**data)


class ProductSetAttributeActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAttributeAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    name = marshmallow.fields.String(allow_none=True)
    value = marshmallow.fields.Raw(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAttributeAction(**data)


class ProductSetAttributeInAllVariantsActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetAttributeInAllVariantsAction`."""

    name = marshmallow.fields.String(allow_none=True)
    value = marshmallow.fields.Raw(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetAttributeInAllVariantsAction(**data)


class ProductSetCategoryOrderHintActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetCategoryOrderHintAction`."""

    category_id = marshmallow.fields.String(allow_none=True, data_key="categoryId")
    order_hint = marshmallow.fields.String(
        allow_none=True, missing=None, data_key="orderHint"
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetCategoryOrderHintAction(**data)


class ProductSetDescriptionActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetDescriptionAction`."""

    description = LocalizedStringField(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetDescriptionAction(**data)


class ProductSetDiscountedPriceActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetDiscountedPriceAction`."""

    price_id = marshmallow.fields.String(allow_none=True, data_key="priceId")
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    discounted = helpers.LazyNestedField(
        nested="commercetools._schemas._common.DiscountedPriceSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetDiscountedPriceAction(**data)


class ProductSetImageLabelActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetImageLabelAction`."""

    sku = marshmallow.fields.String(allow_none=True, missing=None)
    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    image_url = marshmallow.fields.String(allow_none=True, data_key="imageUrl")
    label = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetImageLabelAction(**data)


class ProductSetKeyActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetKeyAction`."""

    key = marshmallow.fields.String(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetKeyAction(**data)


class ProductSetMetaDescriptionActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetMetaDescriptionAction`."""

    meta_description = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaDescription"
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetMetaDescriptionAction(**data)


class ProductSetMetaKeywordsActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetMetaKeywordsAction`."""

    meta_keywords = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaKeywords"
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetMetaKeywordsAction(**data)


class ProductSetMetaTitleActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetMetaTitleAction`."""

    meta_title = LocalizedStringField(
        allow_none=True, missing=None, data_key="metaTitle"
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetMetaTitleAction(**data)


class ProductSetPricesActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetPricesAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    prices = helpers.LazyNestedField(
        nested="commercetools._schemas._common.PriceDraftSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetPricesAction(**data)


class ProductSetProductPriceCustomFieldActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetProductPriceCustomFieldAction`."""

    price_id = marshmallow.fields.String(allow_none=True, data_key="priceId")
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    name = marshmallow.fields.String(allow_none=True)
    value = marshmallow.fields.Raw(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetProductPriceCustomFieldAction(**data)


class ProductSetProductPriceCustomTypeActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetProductPriceCustomTypeAction`."""

    price_id = marshmallow.fields.String(allow_none=True, data_key="priceId")
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)
    type = helpers.LazyNestedField(
        nested="commercetools._schemas._type.TypeResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    fields = FieldContainerField(allow_none=True, missing=None)  # type: ignore

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetProductPriceCustomTypeAction(**data)


class ProductSetProductVariantKeyActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetProductVariantKeyAction`."""

    variant_id = marshmallow.fields.Integer(
        allow_none=True, missing=None, data_key="variantId"
    )
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    key = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetProductVariantKeyAction(**data)


class ProductSetSearchKeywordsActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetSearchKeywordsAction`."""

    search_keywords = helpers.LazyNestedField(
        nested="commercetools._schemas._product.SearchKeywordsSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        data_key="searchKeywords",
    )
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetSearchKeywordsAction(**data)


class ProductSetSkuActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetSkuAction`."""

    variant_id = marshmallow.fields.Integer(allow_none=True, data_key="variantId")
    sku = marshmallow.fields.String(allow_none=True, missing=None)
    staged = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetSkuAction(**data)


class ProductSetTaxCategoryActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductSetTaxCategoryAction`."""

    tax_category = helpers.LazyNestedField(
        nested="commercetools._schemas._tax_category.TaxCategoryResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
        data_key="taxCategory",
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductSetTaxCategoryAction(**data)


class ProductTransitionStateActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductTransitionStateAction`."""

    state = helpers.LazyNestedField(
        nested="commercetools._schemas._state.StateResourceIdentifierSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        missing=None,
    )
    force = marshmallow.fields.Bool(allow_none=True, missing=None)

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductTransitionStateAction(**data)


class ProductUnpublishActionSchema(ProductUpdateActionSchema):
    """Marshmallow schema for :class:`commercetools.types.ProductUnpublishAction`."""

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["action"]
        return types.ProductUnpublishAction()


class RangeFacetResultSchema(FacetResultSchema):
    """Marshmallow schema for :class:`commercetools.types.RangeFacetResult`."""

    ranges = helpers.LazyNestedField(
        nested="commercetools._schemas._product.FacetResultRangeSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.RangeFacetResult(**data)


class TermFacetResultSchema(FacetResultSchema):
    """Marshmallow schema for :class:`commercetools.types.TermFacetResult`."""

    data_type = marshmallow_enum.EnumField(
        types.TermFacetResultType, by_value=True, data_key="dataType"
    )
    missing = marshmallow.fields.Integer(allow_none=True)
    total = marshmallow.fields.Integer(allow_none=True)
    other = marshmallow.fields.Integer(allow_none=True)
    terms = helpers.LazyNestedField(
        nested="commercetools._schemas._product.FacetResultTermSchema",
        unknown=marshmallow.EXCLUDE,
        allow_none=True,
        many=True,
    )

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.TermFacetResult(**data)


class WhitespaceTokenizerSchema(SuggestTokenizerSchema):
    """Marshmallow schema for :class:`commercetools.types.WhitespaceTokenizer`."""

    class Meta:
        unknown = marshmallow.EXCLUDE

    @marshmallow.post_load
    def post_load(self, data, **kwargs):
        del data["type"]
        return types.WhitespaceTokenizer()
