Maps file columns to catalogue fields and transforms row data into validated item attribute maps ready for insertion.
Summary
Functions
Auto-detects column mappings by matching headers against known patterns. Uses score-based matching — normalizes headers (lowercase, strip diacritics/whitespace).
Returns available mapping targets with display labels.
Builds an import plan from column mappings and parsed rows.
Checks how many items from the import plan already exist in the catalogue with identical field values, category, and language.
Checks for duplicate rows within the import file. Returns the count of rows that are exact duplicates of another row.
Checks if an import item matches an existing item on all mapped fields, including category and language.
Normalizes a price string to a Decimal. Handles comma-as-decimal ("4,88"), currency symbols, whitespace.
Normalizes a unit value using the user-provided unit map and built-in aliases.
Extracts unique values from a specific column across all rows. Useful for showing unit mapping UI or category preview.
Types
@type column_mapping() :: %{ column_index: non_neg_integer(), header: String.t(), target: target() }
@type import_plan() :: %{ items: [map()], categories_to_create: [String.t()], manufacturers_to_create: [String.t()], suppliers_to_create: [String.t()], custom_fields: [String.t()], errors: [{non_neg_integer(), String.t()}], stats: %{ total: non_neg_integer(), valid: non_neg_integer(), invalid: non_neg_integer() } }
@type target() :: :name | :description | :sku | :base_price | :markup_percentage | :unit | :category | :manufacturer | :supplier | :skip | {:data, String.t()}
Functions
@spec auto_detect_mappings([String.t()]) :: [column_mapping()]
Auto-detects column mappings by matching headers against known patterns. Uses score-based matching — normalizes headers (lowercase, strip diacritics/whitespace).
Returns available mapping targets with display labels.
@spec build_import_plan([column_mapping()], [[String.t()]], keyword()) :: import_plan()
Builds an import plan from column mappings and parsed rows.
Validates all rows, normalizes units and prices, collects errors.
The unit_map option allows custom unit value mappings from the UI.
@spec detect_existing_duplicates(import_plan(), String.t(), keyword()) :: non_neg_integer()
Checks how many items from the import plan already exist in the catalogue with identical field values, category, and language.
Options
:category_uuid— the target category UUID (nil = uncategorized):language— the import language code (nil = no multilang)
@spec detect_file_duplicates([[String.t()]]) :: non_neg_integer()
Checks for duplicate rows within the import file. Returns the count of rows that are exact duplicates of another row.
Checks if an import item matches an existing item on all mapped fields, including category and language.
Options
:category_uuid— the target category UUID (nil = uncategorized):language— the import language code (nil = no multilang)
Normalizes a price string to a Decimal. Handles comma-as-decimal ("4,88"), currency symbols, whitespace.
Normalizes a unit value using the user-provided unit map and built-in aliases.
@spec unique_column_values([[String.t()]], non_neg_integer()) :: [String.t()]
Extracts unique values from a specific column across all rows. Useful for showing unit mapping UI or category preview.