<commit_before>_ = require 'underscore'
_.mixin require('underscore.string').exports()
CONS = require './constants'
GLOBALS = require './globals'

# TODO:
# - JSDoc
# - no services!!!
# - utils only
class ExportMapping

  constructor: (options = {}) ->
    @typesService = options.typesService
    @categoryService = options.categoryService
    @channelService = options.channelService
    @customerGroupService = options.customerGroupService
    @taxService = options.taxService
    @header = options.header

  mapProduct: (product, productTypes) ->
    productType = productTypes[@typesService.id2index[product.productType.id]]

    rows = []
    rows.push @_mapBaseProduct product, productType

    if product.variants
      for variant in product.variants
        rows.push @_mapVariant variant, productType

    rows

  createTemplate: (productType, languages = [GLOBALS.DEFAULT_LANGUAGE]) ->
    header = [ CONS.HEADER_PUBLISHED, CONS.HEADER_HAS_STAGED_CHANGES ].concat(CONS.BASE_HEADERS.concat(CONS.SPECIAL_HEADERS))
    _.each CONS.BASE_LOCALIZED_HEADERS, (locBaseAttrib) ->
      header = header.concat _.map languages, (lang) ->
        "#{locBaseAttrib}#{GLOBALS.DELIM_HEADER_LANGUAGE}#{lang}"
    _.each productType.attributes, (attribute) =>
      switch attribute.type.name
        when CONS.ATTRIBUTE_TYPE_SET then header = header.concat @_mapAttributeTypeDef attribute.type.elementType, attribute, languages
        else header = header.concat @_mapAttributeTypeDef attribute.type, attribute, languages
    header

  _mapAttributeTypeDef: (attributeTypeDef, attribute, languages) ->
    switch attributeTypeDef.name
      when CONS.ATTRIBUTE_TYPE_LTEXT then _.map languages, (lang) -> "#{attribute.name}#{GLOBALS.DELIM_HEADER_LANGUAGE}#{lang}"
      else [ attribute.name ]

  _mapBaseProduct: (product, productType) ->
    row = @_mapVariant product.masterVariant, productType

    if @header.has(CONS.HEADER_PUBLISHED)
      row[@header.toIndex CONS.HEADER_PUBLISHED] = "#{product.published}"

    if @header.has(CONS.HEADER_HAS_STAGED_CHANGES)
      row[@header.toIndex CONS.HEADER_HAS_STAGED_CHANGES] = "#{product.hasStagedChanges}"

    if @header.has(CONS.HEADER_ID)
      row[@header.toIndex CONS.HEADER_ID] = product.id

    if @header.has(CONS.HEADER_PRODUCT_TYPE)
      row[@header.toIndex CONS.HEADER_PRODUCT_TYPE] = productType.name

    if @header.has(CONS.HEADER_TAX) and _.has(product, 'taxCategory')
      if _.has @taxService.id2name, product.taxCategory.id
        row[@header.toIndex CONS.HEADER_TAX] = @taxService.id2name[product.taxCategory.id]

    if @header.has(CONS.HEADER_CATEGORIES)
      row[@header.toIndex CONS.HEADER_CATEGORIES] = _.reduce(product.categories or [], (memo, category, index) =>
        memo += GLOBALS.DELIM_MULTI_VALUE unless index is 0
        memo + @categoryService.id2fqName[category.id]
      , '')

    if @header.has(CONS.HEADER_CREATED_AT)
      row[@header.toIndex CONS.HEADER_CREATED_AT] = product.createdAt

    if @header.has(CONS.HEADER_LAST_MODIFIED_AT)
      row[@header.toIndex CONS.HEADER_LAST_MODIFIED_AT] = product.lastModifiedAt

    for attribName, h2i of @header.toLanguageIndex()
      for lang, index of h2i
        if product[attribName]
          row[index] = product[attribName][lang]

    row

  _mapVariant: (variant, productType) ->
    row = []
    if @header.has(CONS.HEADER_VARIANT_ID)
      row[@header.toIndex CONS.HEADER_VARIANT_ID] = variant.id

    if @header.has(CONS.HEADER_SKU)
      row[@header.toIndex CONS.HEADER_SKU] = variant.sku

    if @header.has(CONS.HEADER_PRICES)
      row[@header.toIndex CONS.HEADER_PRICES] = @_mapPrices(variant.prices)

    if @header.has(CONS.HEADER_IMAGES)
      row[@header.toIndex CONS.HEADER_IMAGES] = @_mapImages(variant.images)

    if variant.attributes
      for attribute in variant.attributes
        attributeTypeDef = @typesService.id2nameAttributeDefMap[productType.id][attribute.name].type
        if attributeTypeDef.name is CONS.ATTRIBUTE_TYPE_LTEXT
          row = @_mapLocalizedAttribute attribute, productType, row
        else if @header.has attribute.name
          row[@header.toIndex attribute.name] = @_mapAttribute(attribute, attributeTypeDef)

    row

  _mapPrices: (prices) ->
    _.reduce(prices, (acc, price, index) =>
      acc += GLOBALS.DELIM_MULTI_VALUE unless index is 0
      countryPart = ''
      if price.country
        countryPart = "#{price.country}-"
      customerGroupPart = ''
      if price.customerGroup and _.has(@customerGroupService.id2name, price.customerGroup.id)
        customerGroupPart = " #{@customerGroupService.id2name[price.customerGroup.id]}"<commit_msg>Fill variant rows with product base attribtues.<commit_after>_ = require 'underscore'
_.mixin require('underscore.string').exports()
CONS = require './constants'
GLOBALS = require './globals'

# TODO:
# - JSDoc
# - no services!!!
# - utils only
class ExportMapping

  constructor: (options = {}) ->
    @typesService = options.typesService
    @categoryService = options.categoryService
    @channelService = options.channelService
    @customerGroupService = options.customerGroupService
    @taxService = options.taxService
    @header = options.header
    @fillAllRows = false

  mapProduct: (product, productTypes) ->
    productType = productTypes[@typesService.id2index[product.productType.id]]

    rows = []
    productRow = @_mapBaseProduct product, productType
    rows.push productRow

    if product.variants
      for variant in product.variants
        variantRow = if @fillAllRows
          _.deepClone productRow
        else
          []
        rows.push @_mapVariant variant, productType, variantRow

    rows

  createTemplate: (productType, languages = [GLOBALS.DEFAULT_LANGUAGE]) ->
    header = [ CONS.HEADER_PUBLISHED, CONS.HEADER_HAS_STAGED_CHANGES ].concat(CONS.BASE_HEADERS.concat(CONS.SPECIAL_HEADERS))
    _.each CONS.BASE_LOCALIZED_HEADERS, (locBaseAttrib) ->
      header = header.concat _.map languages, (lang) ->
        "#{locBaseAttrib}#{GLOBALS.DELIM_HEADER_LANGUAGE}#{lang}"
    _.each productType.attributes, (attribute) =>
      switch attribute.type.name
        when CONS.ATTRIBUTE_TYPE_SET then header = header.concat @_mapAttributeTypeDef attribute.type.elementType, attribute, languages
        else header = header.concat @_mapAttributeTypeDef attribute.type, attribute, languages
    header

  _mapAttributeTypeDef: (attributeTypeDef, attribute, languages) ->
    switch attributeTypeDef.name
      when CONS.ATTRIBUTE_TYPE_LTEXT then _.map languages, (lang) -> "#{attribute.name}#{GLOBALS.DELIM_HEADER_LANGUAGE}#{lang}"
      else [ attribute.name ]

  _mapBaseProduct: (product, productType) ->
    row = @_mapVariant product.masterVariant, productType

    if @header.has(CONS.HEADER_PUBLISHED)
      row[@header.toIndex CONS.HEADER_PUBLISHED] = "#{product.published}"

    if @header.has(CONS.HEADER_HAS_STAGED_CHANGES)
      row[@header.toIndex CONS.HEADER_HAS_STAGED_CHANGES] = "#{product.hasStagedChanges}"

    if @header.has(CONS.HEADER_ID)
      row[@header.toIndex CONS.HEADER_ID] = product.id

    if @header.has(CONS.HEADER_PRODUCT_TYPE)
      row[@header.toIndex CONS.HEADER_PRODUCT_TYPE] = productType.name

    if @header.has(CONS.HEADER_TAX) and _.has(product, 'taxCategory')
      if _.has @taxService.id2name, product.taxCategory.id
        row[@header.toIndex CONS.HEADER_TAX] = @taxService.id2name[product.taxCategory.id]

    if @header.has(CONS.HEADER_CATEGORIES)
      row[@header.toIndex CONS.HEADER_CATEGORIES] = _.reduce(product.categories or [], (memo, category, index) =>
        memo += GLOBALS.DELIM_MULTI_VALUE unless index is 0
        memo + @categoryService.id2fqName[category.id]
      , '')

    if @header.has(CONS.HEADER_CREATED_AT)
      row[@header.toIndex CONS.HEADER_CREATED_AT] = product.createdAt

    if @header.has(CONS.HEADER_LAST_MODIFIED_AT)
      row[@header.toIndex CONS.HEADER_LAST_MODIFIED_AT] = product.lastModifiedAt

    for attribName, h2i of @header.toLanguageIndex()
      for lang, index of h2i
        if product[attribName]
          row[index] = product[attribName][lang]

    row

  _mapVariant: (variant, productType, row = []) ->
    if @header.has(CONS.HEADER_VARIANT_ID)
      row[@header.toIndex CONS.HEADER_VARIANT_ID] = variant.id

    if @header.has(CONS.HEADER_SKU)
      row[@header.toIndex CONS.HEADER_SKU] = variant.sku

    if @header.has(CONS.HEADER_PRICES)
      row[@header.toIndex CONS.HEADER_PRICES] = @_mapPrices(variant.prices)

    if @header.has(CONS.HEADER_IMAGES)
      row[@header.toIndex CONS.HEADER_IMAGES] = @_mapImages(variant.images)

    if variant.attributes
      for attribute in variant.attributes
        attributeTypeDef = @typesService.id2nameAttributeDefMap[productType.id][attribute.name].type
        if attributeTypeDef.name is CONS.ATTRIBUTE_TYPE_LTEXT
          row = @_mapLocalizedAttribute attribute, productType, row
        else if @header.has attribute.name
          row[@header.toIndex attribute.name] = @_mapAttribute(attribute, attributeTypeDef)

    row

  _mapPrices: (prices) ->
    _.reduce(prices, (acc, price, index) =>
      acc += GLOBALS.DELIM_MULTI_VALUE unless index is 0
      countryPart = ''
      if price.country
        countryPart = "#{price.country}-"
      customerGroupPart = ''
      if price.customerGroup and _.has(@customerGroupService.id2name, price.customerGroup.id)
        customerGroupPart = " #{@customerGroupService.id2name[price.customerGroup.id]}"
{'fraction_non_alphanumeric': 0.10897030953885029, 'fraction_numerical': 0.0023162771109707307, 'mean_word_length': 3.7878024193548385, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7368280', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2984, 'n_words': 544}