Class ProductRowConverter

java.lang.Object
com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter<com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>>
com.broadleafcommerce.catalog.dataimport.converter.ProductRowConverter

public class ProductRowConverter extends com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter<com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>>
Row converter to convert a Map (or row from a CSV file) into a Product.
Author:
Kelly Tisdell (ktisdell)
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    Properties that can be provided in a product option column to configure an option.
    static final class 
     
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched business types by their type key.
    static final String
    In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched products by their external ID.
    static final String
    In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched products by their ID.

    Fields inherited from class com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter

    COMPLEX_COLUMN_HEADER_PREFIX_DELIMITER
  • Constructor Summary

    Constructors
    Constructor
    Description
    ProductRowConverter(com.fasterxml.jackson.databind.ObjectMapper mapper, com.broadleafcommerce.common.extension.TypeFactory typeFactory, com.broadleafcommerce.common.dataimport.util.IdResolver idResolver)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    canConvert(@NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>
    convert(Object parent, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected com.broadleafcommerce.data.tracking.core.type.OperationType
    determineOperationType(@NonNull Product product, boolean productAlreadyExistsInDatastore, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    Determine the effective operation type for the given batch record and product instance.
    protected Map<String,String>
    extractSpecialColumns(@NonNull Map<String,String> mutableRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected String
     
    protected String
    It's possible that a provided attribute choice type is the same as one of the defaults but doesn't have the same casing.
    protected com.broadleafcommerce.common.dataimport.util.IdResolver
     
    protected com.fasterxml.jackson.databind.ObjectMapper
     
    getPrefetchedBusinessTypesFromAdditionalContextMap(Map<String,Object> additionalContextMap, String keyForPrefetchedBusinessTypesMap, String keyForTypeInPrefetchedBusinessTypesProductsMap)
     
    protected Product
    getPrefetchedProduct(com.broadleafcommerce.common.dataimport.messaging.BatchRecord batchRecord, Map<String,String> batchRecordRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    Checks the BatchRequest.BatchContext.getAdditionalContextMap() to see if there is already a pre-fetched product matching the batchRecord.
    protected Optional<Product>
    getPrefetchedProductFromAdditionalContextMap(Map<String,Object> additionalContextMap, String keyForPrefetchedProductsMap, String keyForProductInPrefetchedProductsMap)
     
    protected com.broadleafcommerce.common.extension.TypeFactory
     
    Lazy injection to avoid circular dependency issues.
    protected void
    initializeAttributeChoiceType(String explicitlyProvidedAttributeChoiceType, @NonNull String attributeChoiceLabel, AttributeChoice initializationTarget)
     
    initializeAttributeChoiceValue(String label, String value, Integer displayOrder)
     
    protected void
    initializeData(@NonNull Product product, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> mutableRow, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operation, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    Initialize the data from the row onto the product.
    protected org.springframework.data.util.Pair<Boolean,Product>
    instantiateOrGetPrefetchedProduct(@NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord batchRecord, @NonNull Map<String,String> mutableRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    We expect the CompleteProductImportBatchHandler to have pre-fetched products by various identifier fields if supplied in the original rows.
    protected boolean
    isEligibleForPricingKeyAutoGeneration(Product product, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
     
    protected Product
    modifyProduct(@NonNull Product product, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    Hook point to allow implementers to modify the details of the product or return a different product instance.
    protected void
    parseAndSetAttributes(@NonNull Product product, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> specialColumns, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected void
    parseAndSetCurrency(@NonNull Product product, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> mutableRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    Currency is not complex but gets special treatment because we should not mix different currencies in a single Catalog without using the Pricing Service.
    protected void
    parseAndSetFulfillmentFlatRates(@NonNull Product product, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> mutableRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected void
    parseAndSetKeywords(@NonNull Product product, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> specialColumns, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected void
    parseAndSetOptions(@NonNull Product product, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull Map<String,String> mutableRow, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    The syntax we expect for the ProductRowConverter.ProductProperties.OPTIONS_HEADER column is a series of individual option values separated by RowUtils.VALUE_SEPARATOR.
    parseAttributeChoiceAllowedValuesForOption(Map<String,String> givenOptionPropertyMap, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
     
    protected Map<String,String>
     
    protected ProductOption
    parseIndividualOptionToken(String givenOptionToken, AtomicInteger displayOrderCounter, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
     
    protected boolean
    Product.getPricingKey() only makes sense for certain types of products, so this method checks those conditions.
    protected boolean
    productRecordHasAnyVariants(com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
     
    protected String
    resolveProductId(@NonNull Product product, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operation, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     
    protected void
    setProductPricingKeyIfNeeded(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
     
    protected void
    setProductTypeBasedOnRecord(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
    Set Product.getProductType() based on whether or not the given BatchRecord for product has any variants.
    protected void
    setProductUriIfNeeded(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
     
    void
    Lazy injection to avoid circular dependency issues.
    protected org.springframework.data.util.Pair<String,Attribute>
    toKeyAttributePair(String[] keyValueArray)
     
    protected org.springframework.data.util.Pair<String,FulfillmentFlatRate>
     
    protected void
    validateBusinessType(@NonNull Product product, @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • BATCH_CONTEXT_PREFETCHED_PRODUCTS_BY_ID_MAP

      public static final String BATCH_CONTEXT_PREFETCHED_PRODUCTS_BY_ID_MAP
      In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched products by their ID.
      See Also:
    • BATCH_CONTEXT_PREFETCHED_PRODUCTS_BY_EXTERNAL_ID_MAP

      public static final String BATCH_CONTEXT_PREFETCHED_PRODUCTS_BY_EXTERNAL_ID_MAP
      In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched products by their external ID.
      See Also:
    • BATCH_CONTEXT_PREFETCHED_BUSINESS_TYPES_BY_TYPE_KEY_MAP

      public static final String BATCH_CONTEXT_PREFETCHED_BUSINESS_TYPES_BY_TYPE_KEY_MAP
      In BatchRequest.BatchContext.getAdditionalContextMap(), we expect a nested map under this key to contain prefetched business types by their type key.
      See Also:
  • Constructor Details

    • ProductRowConverter

      public ProductRowConverter(com.fasterxml.jackson.databind.ObjectMapper mapper, com.broadleafcommerce.common.extension.TypeFactory typeFactory, com.broadleafcommerce.common.dataimport.util.IdResolver idResolver)
  • Method Details

    • convert

      @NonNull public com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product> convert(@Nullable Object parent, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Specified by:
      convert in class com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter<com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>>
    • canConvert

      public boolean canConvert(@NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Specified by:
      canConvert in class com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter<com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>>
    • determineOperationType

      protected com.broadleafcommerce.data.tracking.core.type.OperationType determineOperationType(@NonNull @NonNull Product product, boolean productAlreadyExistsInDatastore, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Determine the effective operation type for the given batch record and product instance. This can help inform decisions on how to instantiate/map fields.
      Parameters:
      product - the resolved product instance
      productAlreadyExistsInDatastore - whether the product was determined to already exist in the datastore. See instantiateOrGetPrefetchedProduct(BatchRecord, Map, BatchContext)
      record - the original batch record
      context - the batch context
      Returns:
      the effective operation type for the given batch record
    • resolveProductId

      protected String resolveProductId(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operation, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    • validateBusinessType

      protected void validateBusinessType(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    • parseAndSetKeywords

      protected void parseAndSetKeywords(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> specialColumns, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    • parseAndSetAttributes

      protected void parseAndSetAttributes(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> specialColumns, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    • toKeyAttributePair

      protected org.springframework.data.util.Pair<String,Attribute> toKeyAttributePair(String[] keyValueArray)
    • parseAndSetOptions

      protected void parseAndSetOptions(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> mutableRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      The syntax we expect for the ProductRowConverter.ProductProperties.OPTIONS_HEADER column is a series of individual option values separated by RowUtils.VALUE_SEPARATOR.

      Each option value consists of a few properties separated by RowUtils.PROPERTY_SEPARATOR. Assignment of property values is done with RowUtils.VALUE_ASSIGNMENT_SEPARATOR.

      For convenience, some properties can be omitted in certain scenarios with an implied default. Here are a few examples of option values:

      • label::Label for Option and Attribute Choice;required::true;type::Size
      • label::Label for Option and Attribute Choice;type::Size -> implies 'required' is false
      • label::Size -> implies 'required' is false, and 'type' will be set to match 'label' since it matches one of DefaultAttributeChoiceType
      • Size -> implies 'required' is false, and both 'label' and 'type' will be set to match the given value since it matches one of DefaultAttributeChoiceType

      Note that 'type' is only optional in situations where the given 'label' value matches (ignoring case) one of DefaultAttributeChoiceType. This prevents inadvertent creation/usage of random types. If custom types need to be used, they should be explicitly provided.

      Furthermore, AttributeChoice.getAllowedValues() are set on each option from the values found in CompleteProductImportBatchHandler.RecordTypes.VARIANT dependent records of the product record.

      Parameters:
      product - the product to set the parsed options on
      operationType - the determined operation type
      record - the original product batch record
      mutableRow - the row from which to obtain the options column
      context - the batch context
    • parseAndSetCurrency

      protected void parseAndSetCurrency(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> mutableRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Currency is not complex but gets special treatment because we should not mix different currencies in a single Catalog without using the Pricing Service. Therefore, this method will ensure that there is no currency mismatch issue. By default, this is actually a no-op because JpaProduct.preToMe(ContextInfo, Object) already handles setting the currency.
      Parameters:
      product - the product to set the parsed currency on
      operationType - the determined operation type
      record - the original product batch record
      mutableRow - the row from which to obtain the currency column
      context - the batch context
    • parseIndividualOptionToken

      protected ProductOption parseIndividualOptionToken(String givenOptionToken, AtomicInteger displayOrderCounter, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
    • parseGivenOptionProperties

      protected Map<String,String> parseGivenOptionProperties(String givenOptionToken)
    • initializeAttributeChoiceType

      protected void initializeAttributeChoiceType(@Nullable String explicitlyProvidedAttributeChoiceType, @NonNull @NonNull String attributeChoiceLabel, AttributeChoice initializationTarget)
    • getCaseCorrectedAttributeChoiceTypeIfMatchesDefault

      @Nullable protected String getCaseCorrectedAttributeChoiceTypeIfMatchesDefault(String attributeChoiceType)
      It's possible that a provided attribute choice type is the same as one of the defaults but doesn't have the same casing. To avoid a situation where there are, for example, both 'SIZE' and 'Size' types, we will force-set the value to match the enum.
      Parameters:
      attributeChoiceType - the attribute choice type value to compare
      Returns:
      the case-corrected attribute choice type if it matched a default, else null
    • parseAttributeChoiceAllowedValuesForOption

      protected List<AttributeChoiceValue> parseAttributeChoiceAllowedValuesForOption(Map<String,String> givenOptionPropertyMap, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
    • initializeAttributeChoiceValue

      protected AttributeChoiceValue initializeAttributeChoiceValue(String label, String value, Integer displayOrder)
    • parseAndSetFulfillmentFlatRates

      protected void parseAndSetFulfillmentFlatRates(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operationType, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> mutableRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
    • toKeyFulfillmentFlatRatePair

      protected org.springframework.data.util.Pair<String,FulfillmentFlatRate> toKeyFulfillmentFlatRatePair(String[] keyValueArray)
    • instantiateOrGetPrefetchedProduct

      protected org.springframework.data.util.Pair<Boolean,Product> instantiateOrGetPrefetchedProduct(@NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord batchRecord, @NonNull @NonNull Map<String,String> mutableRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      We expect the CompleteProductImportBatchHandler to have pre-fetched products by various identifier fields if supplied in the original rows. Any products that were found in the datastore should have been populated into BatchRequest.BatchContext.getAdditionalContextMap().

      If a product is present in this map, we will use this existing instance.

      If a product is not present in this map, we will simply instantiate a new instance.

      Parameters:
      batchRecord - the original BatchRecord
      mutableRow - the row from the batch record (usually with any special columns pre-removed via extractSpecialColumns(Map, BatchContext))
      context - the BatchRequest.BatchContext, which should have any pre-fetched products in BatchRequest.BatchContext.getAdditionalContextMap()
      Returns:
      a Pair containing a boolean describing whether the product was found in the pre-fetched map, as well as the product instance itself
    • getPrefetchedProduct

      @Nullable protected Product getPrefetchedProduct(com.broadleafcommerce.common.dataimport.messaging.BatchRecord batchRecord, Map<String,String> batchRecordRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Checks the BatchRequest.BatchContext.getAdditionalContextMap() to see if there is already a pre-fetched product matching the batchRecord.
      Parameters:
      batchRecord - the batch record for which to find the corresponding pre-fetched product instance (if exists)
      batchRecordRow - the row from the batch record (pre-processed if necessary)
      context - the batch context which should contain pre-fetched products set by CompleteProductImportBatchHandler
      Returns:
      the pre-fetched product instance if found, or null
    • getPrefetchedProductFromAdditionalContextMap

      protected Optional<Product> getPrefetchedProductFromAdditionalContextMap(Map<String,Object> additionalContextMap, String keyForPrefetchedProductsMap, String keyForProductInPrefetchedProductsMap)
      Parameters:
      additionalContextMap - the BatchRequest.BatchContext.getAdditionalContextMap()
      keyForPrefetchedProductsMap - the key in additionalContextMap where the value must be a nested Map<String, Product> of prefetched products by some key
      keyForProductInPrefetchedProductsMap - the key in the prefetched products map for which to find a given product
      Returns:
      an Optional containing the prefetched product if found in the given map
    • getPrefetchedBusinessTypesFromAdditionalContextMap

      protected Optional<BusinessType> getPrefetchedBusinessTypesFromAdditionalContextMap(Map<String,Object> additionalContextMap, String keyForPrefetchedBusinessTypesMap, String keyForTypeInPrefetchedBusinessTypesProductsMap)
      Parameters:
      additionalContextMap - the BatchRequest.BatchContext.getAdditionalContextMap()
      keyForPrefetchedBusinessTypesMap - the key in additionalContextMap where the value must be a nested Map<String, BusinessType> of prefetched business types by some key
      keyForTypeInPrefetchedBusinessTypesProductsMap - the key in the prefetched business types map for which to find a given type
      Returns:
      an Optional containing the prefetched business type if found in the given map
    • modifyProduct

      protected Product modifyProduct(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Hook point to allow implementers to modify the details of the product or return a different product instance.

      This MUST return a non-null value. By default, it returns the provided value.

      Parameters:
      product - the product that has been created populated with data from the row
      record - the record that represents the row that was mapped to the product
      context - the batch context
    • initializeData

      protected void initializeData(@NonNull @NonNull Product product, @NonNull @NonNull com.broadleafcommerce.common.dataimport.messaging.BatchRecord record, @NonNull @NonNull Map<String,String> mutableRow, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.type.OperationType operation, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Initialize the data from the row onto the product. Set additional data as needed. For example, set ID and activeStartDate.
      Parameters:
      product - the target product onto which we set data.
      record - the original BatchRecord
      mutableRow - the mutable row from the BatchRecord with entries removed that cannot be handled by reflection
      operation - the operation; typically CREATE or UPDATE
      context - the BatchContext
    • extractSpecialColumns

      protected Map<String,String> extractSpecialColumns(@NonNull @NonNull Map<String,String> mutableRow, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context)
      Overrides:
      extractSpecialColumns in class com.broadleafcommerce.common.dataimport.conversion.AbstractRowConverter<com.broadleafcommerce.common.dataimport.util.ConversionUtils.ConversionResponse<Product>>
    • setProductTypeBasedOnRecord

      protected void setProductTypeBasedOnRecord(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)

      Set Product.getProductType() based on whether or not the given BatchRecord for product has any variants. If it does, Product.getProductType() is set to VARIANT_BASED. Otherwise, STANDARD. This way, the Product.getProductType() wouldn't need to be explicitly declared.

      The Product.getProductType() should only be set if the BatchRecord.getOperation() is CREATE, since Product.getProductType() should never be changed once it's set.

      This method will set the product type to null if the operation is anything but create. This will cause the eventual update operation to skip updating the field.

      Parameters:
      product - product created from the BatchRecord
      productRecord - BatchRecord for the product
      context - BatchRequest.BatchContext
    • setProductUriIfNeeded

      protected void setProductUriIfNeeded(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
    • setProductPricingKeyIfNeeded

      protected void setProductPricingKeyIfNeeded(Product product, com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord, @Nullable com.broadleafcommerce.common.dataimport.messaging.BatchRequest.BatchContext context, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
    • isEligibleForPricingKeyAutoGeneration

      protected boolean isEligibleForPricingKeyAutoGeneration(Product product, com.broadleafcommerce.data.tracking.core.type.OperationType operationType)
    • pricingKeyConceptAppliesToProduct

      protected boolean pricingKeyConceptAppliesToProduct(Product product)
      Product.getPricingKey() only makes sense for certain types of products, so this method checks those conditions. Essentially, it only makes sense for products that don't have their own SKUs but could have a price.

      NOTE - this method would only work in OperationType.CREATE situations, where the provided product instance has all fields set. It would not work in an update scenario, where some fields may be null and thus fail to provide accurate data for the checks this method performs.

      NOTE - some of the checks in this method are likely not ever going to be hit, since setProductTypeBasedOnRecord(Product, BatchRecord, BatchContext, OperationType) is fairly restrictive in the types it sets. Nonetheless, we define all potentially relevant checks here.

      Parameters:
      product - the product instance to test
      Returns:
      whether the pricing key concept makes sense for this product
    • productRecordHasAnyVariants

      protected boolean productRecordHasAnyVariants(com.broadleafcommerce.common.dataimport.messaging.BatchRecord productRecord)
    • getAttributeName

      protected String getAttributeName(Map<String,String> propertyMap)
    • getMapper

      protected com.fasterxml.jackson.databind.ObjectMapper getMapper()
    • getTypeFactory

      protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory()
    • getIdResolver

      protected com.broadleafcommerce.common.dataimport.util.IdResolver getIdResolver()
    • getVariantRowConverter

      protected VariantRowConverter getVariantRowConverter()
      Lazy injection to avoid circular dependency issues.
    • setVariantRowConverter

      @Autowired @Lazy public void setVariantRowConverter(VariantRowConverter variantRowConverter)
      Lazy injection to avoid circular dependency issues.