flamingo.me/flamingo-commerce/v3@v3.11.0/product/domain/productTypeConfigurables.go (about)

     1  package domain
     2  
     3  import (
     4  	"errors"
     5  )
     6  
     7  const (
     8  	// TypeConfigurable denotes configurable products
     9  	TypeConfigurable = "configurable"
    10  
    11  	// TypeConfigurableWithActiveVariant denotes configurable products that has a variant selected
    12  	TypeConfigurableWithActiveVariant = "configurable_with_activevariant"
    13  )
    14  
    15  type (
    16  
    17  	// Configurable - interface that is implemented by ConfigurableProduct and ConfigurableProductWithActiveVariant
    18  	Configurable interface {
    19  		GetConfigurableWithActiveVariant(variantMarketplaceCode string) (ConfigurableProductWithActiveVariant, error)
    20  		Variant(variantMarketplaceCode string) (*Variant, error)
    21  		GetDefaultVariant() (*Variant, error)
    22  		HasVariant(variantMarketplaceCode string) bool
    23  	}
    24  
    25  	// ConfigurableProduct - A product that can be teasered and that has Sellable Variants Aggregated
    26  	ConfigurableProduct struct {
    27  		Identifier string
    28  		BasicProductData
    29  		Teaser                            TeaserData
    30  		VariantVariationAttributes        []string
    31  		Variants                          []Variant
    32  		VariantVariationAttributesSorting map[string][]string
    33  	}
    34  
    35  	// ConfigurableProductWithActiveVariant - A product that can be teasered and that has Sellable Variants Aggregated, One Variant is Active
    36  	ConfigurableProductWithActiveVariant struct {
    37  		Identifier string
    38  		BasicProductData
    39  		Teaser                            TeaserData
    40  		VariantVariationAttributes        []string
    41  		Variants                          []Variant
    42  		VariantVariationAttributesSorting map[string][]string
    43  		ActiveVariant                     Variant
    44  	}
    45  
    46  	// Variant is a concrete kind of a product
    47  	Variant struct {
    48  		BasicProductData
    49  		Saleable
    50  	}
    51  )
    52  
    53  var _ BasicProduct = ConfigurableProduct{}
    54  var _ BasicProduct = ConfigurableProductWithActiveVariant{}
    55  var _ Configurable = ConfigurableProduct{}
    56  var _ Configurable = ConfigurableProductWithActiveVariant{}
    57  
    58  // Type interface implementation for SimpleProduct
    59  func (p ConfigurableProduct) Type() string {
    60  	return TypeConfigurable
    61  }
    62  
    63  // IsSaleable defaults to false
    64  func (p ConfigurableProduct) IsSaleable() bool {
    65  	return false
    66  }
    67  
    68  // SaleableData getter for ConfigurableProduct - Configurable is NOT Salable
    69  func (p ConfigurableProduct) SaleableData() Saleable {
    70  	return Saleable{}
    71  }
    72  
    73  // GetConfigurableWithActiveVariant getter
    74  func (p ConfigurableProduct) GetConfigurableWithActiveVariant(variantMarketplaceCode string) (ConfigurableProductWithActiveVariant, error) {
    75  	variant, err := p.Variant(variantMarketplaceCode)
    76  	if err != nil {
    77  		return ConfigurableProductWithActiveVariant{}, err
    78  	}
    79  	return ConfigurableProductWithActiveVariant{
    80  		Identifier:                        p.Identifier,
    81  		BasicProductData:                  p.BasicProductData,
    82  		Teaser:                            p.Teaser,
    83  		VariantVariationAttributes:        p.VariantVariationAttributes,
    84  		VariantVariationAttributesSorting: p.VariantVariationAttributesSorting,
    85  		Variants:                          p.Variants,
    86  		ActiveVariant:                     *variant,
    87  	}, nil
    88  }
    89  
    90  // GetIdentifier interface implementation for SimpleProduct
    91  func (p ConfigurableProduct) GetIdentifier() string {
    92  	return p.Identifier
    93  }
    94  
    95  // BaseData interface implementation for ConfigurableProduct
    96  func (p ConfigurableProduct) BaseData() BasicProductData {
    97  	return p.BasicProductData
    98  }
    99  
   100  // TeaserData interface implementation for SimpleProduct
   101  func (p ConfigurableProduct) TeaserData() TeaserData {
   102  	return p.Teaser
   103  }
   104  
   105  // Variant getter for ConfigurableProduct
   106  // Variant is retrieved via marketplaceCode of the variant
   107  func (p ConfigurableProduct) Variant(variantMarketplaceCode string) (*Variant, error) {
   108  	for _, variant := range p.Variants {
   109  		if variant.BasicProductData.MarketPlaceCode == variantMarketplaceCode {
   110  			return &variant, nil
   111  		}
   112  	}
   113  	return nil, errors.New("No Variant with code " + variantMarketplaceCode + " found ")
   114  }
   115  
   116  // GetDefaultVariant getter
   117  func (p ConfigurableProduct) GetDefaultVariant() (*Variant, error) {
   118  	if len(p.Variants) > 0 {
   119  		return &p.Variants[0], nil
   120  	}
   121  	return nil, errors.New("there is no variant. ")
   122  }
   123  
   124  // HasMedia for ConfigurableProduct
   125  func (p ConfigurableProduct) HasMedia(group string, usage string) bool {
   126  	media := findMediaInProduct(BasicProduct(p), group, usage)
   127  	return media != nil
   128  }
   129  
   130  // GetMedia  for ConfigurableProduct
   131  func (p ConfigurableProduct) GetMedia(group string, usage string) Media {
   132  	return *findMediaInProduct(BasicProduct(p), group, usage)
   133  }
   134  
   135  // HasVariant  for ConfigurableProduct
   136  func (p ConfigurableProduct) HasVariant(variantMarketplaceCode string) bool {
   137  	for _, variant := range p.Variants {
   138  		if variant.BasicProductData.MarketPlaceCode == variantMarketplaceCode {
   139  			return true
   140  		}
   141  	}
   142  	return false
   143  }
   144  
   145  // BaseData getter for BasicProductData
   146  func (v Variant) BaseData() BasicProductData {
   147  	return v.BasicProductData
   148  }
   149  
   150  // SaleableData getter for Saleable
   151  func (v Variant) SaleableData() Saleable {
   152  	return v.Saleable
   153  }
   154  
   155  // ********CONFIGURABLE WITH ACTIVE VARIANT
   156  
   157  // Type getter
   158  func (p ConfigurableProductWithActiveVariant) Type() string {
   159  	return TypeConfigurableWithActiveVariant
   160  }
   161  
   162  // IsSaleable is true
   163  func (p ConfigurableProductWithActiveVariant) IsSaleable() bool {
   164  	return true
   165  }
   166  
   167  // GetIdentifier getter
   168  func (p ConfigurableProductWithActiveVariant) GetIdentifier() string {
   169  	return p.Identifier
   170  }
   171  
   172  // BaseData returns only BaseData for Active Variant. If you need the BaseData of the Configurable - use ConfigurableBaseData()
   173  func (p ConfigurableProductWithActiveVariant) BaseData() BasicProductData {
   174  	return p.ActiveVariant.BasicProductData
   175  }
   176  
   177  // ConfigurableBaseData getter
   178  func (p ConfigurableProductWithActiveVariant) ConfigurableBaseData() BasicProductData {
   179  	return p.BasicProductData
   180  }
   181  
   182  // TeaserData interface implementation for SimpleProduct
   183  func (p ConfigurableProductWithActiveVariant) TeaserData() TeaserData {
   184  	return p.Teaser
   185  }
   186  
   187  // Variant getter for ConfigurableProduct
   188  // Variant is retrieved via marketplaceCode of the variant
   189  func (p ConfigurableProductWithActiveVariant) Variant(variantMarketplaceCode string) (*Variant, error) {
   190  	for _, variant := range p.Variants {
   191  		if variant.BasicProductData.MarketPlaceCode == variantMarketplaceCode {
   192  			return &variant, nil
   193  		}
   194  	}
   195  	return nil, errors.New("No Variant with code " + variantMarketplaceCode + " found ")
   196  }
   197  
   198  // GetDefaultVariant getter
   199  func (p ConfigurableProductWithActiveVariant) GetDefaultVariant() (*Variant, error) {
   200  	if len(p.Variants) > 0 {
   201  		return &p.Variants[0], nil
   202  	}
   203  	return nil, errors.New("there is no variant. ")
   204  }
   205  
   206  // SaleableData getter for ConfigurableProduct
   207  // Gets either the first or the active variants saleableData
   208  func (p ConfigurableProductWithActiveVariant) SaleableData() Saleable {
   209  	return p.ActiveVariant.Saleable
   210  }
   211  
   212  // HasMedia  for ConfigurableProduct
   213  func (p ConfigurableProductWithActiveVariant) HasMedia(group string, usage string) bool {
   214  	media := findMediaInProduct(BasicProduct(p), group, usage)
   215  	return media != nil
   216  }
   217  
   218  // GetMedia  for ConfigurableProduct
   219  func (p ConfigurableProductWithActiveVariant) GetMedia(group string, usage string) Media {
   220  	return *findMediaInProduct(BasicProduct(p), group, usage)
   221  }
   222  
   223  // HasVariant  for ConfigurableProduct
   224  func (p ConfigurableProductWithActiveVariant) HasVariant(variantMarketplaceCode string) bool {
   225  	for _, variant := range p.Variants {
   226  		if variant.BasicProductData.MarketPlaceCode == variantMarketplaceCode {
   227  			return true
   228  		}
   229  	}
   230  	return false
   231  }
   232  
   233  // GetConfigurableWithActiveVariant getter
   234  func (p ConfigurableProductWithActiveVariant) GetConfigurableWithActiveVariant(variantMarketplaceCode string) (ConfigurableProductWithActiveVariant, error) {
   235  	variant, err := p.Variant(variantMarketplaceCode)
   236  	if err != nil {
   237  		return ConfigurableProductWithActiveVariant{}, err
   238  	}
   239  	return ConfigurableProductWithActiveVariant{
   240  		Identifier:                 p.Identifier,
   241  		BasicProductData:           p.BasicProductData,
   242  		Teaser:                     p.Teaser,
   243  		VariantVariationAttributes: p.VariantVariationAttributes,
   244  		Variants:                   p.Variants,
   245  		ActiveVariant:              *variant,
   246  	}, nil
   247  }