Supported option types for product options.
Supported Types
text- Free-form text inputnumber- Numeric input (optional min/max/step validation)boolean- Checkbox/toggleselect- Single choice dropdown (requires options)multiselect- Multiple choice selection (requires options)
Option Schema Format (Simple)
%{
"key" => "material",
"label" => "Material",
"type" => "select",
"options" => ["PLA", "ABS", "PETG"],
"default" => "PLA",
"required" => false,
"unit" => nil,
"position" => 0,
"affects_price" => true,
"modifier_type" => "fixed",
"price_modifiers" => %{
"PLA" => "0",
"ABS" => "5.00",
"PETG" => "10.00"
}
}Option Schema Format (Enhanced with Localization)
%{
"key" => "color",
"label" => %{"en" => "Color", "ru" => "Цвет"},
"type" => "select",
"allow_multiple_slots" => true,
"options" => [
%{"value" => "red", "label" => %{"en" => "Red", "ru" => "Красный"}, "hex" => "#FF0000"},
%{"value" => "blue", "label" => %{"en" => "Blue", "ru" => "Синий"}, "hex" => "#0000FF"}
]
}Multiple Slots
When allow_multiple_slots: true, the same global option can be used
multiple times in a product with different slot names. For example:
- Global option "color" can be used as "cup_color" and "liquid_color"
- Slots are stored in product metadata["_option_slots"]
- Each slot references the source global option key
Price Modifiers
For select and multiselect types, you can enable price modifiers:
affects_price- Boolean indicating if this option affects product pricemodifier_type- "fixed" or "percent"price_modifiers- Map of option value to price delta (as string decimal)allow_override- Boolean, allows overriding price modifiers per-product
Modifier Types
fixed- Add exact amount to base price (e.g., +$10)percent- Add percentage of base price (e.g., +20% of $20 = +$4)
Allow Override
When allow_override: true, the price modifier values can be customized
for each individual product. The global values serve as defaults.
Overridden values are stored in product's metadata["_price_modifiers"].
Price Calculation Order
- Sum all fixed modifiers
- Add to base price (intermediate price)
- Sum all percent modifiers
- Apply percent to intermediate price
Example:
- Base price: $20
- Material: PETG (+$10 fixed)
- Finish: Premium (+20% percent)
- Final: ($20 + $10) * 1.20 = $36
Summary
Functions
Checks if option allows multiple slots.
Gets localized label for an option or option value.
Extracts option values from options list.
Returns list of supported modifier types.
Checks if a type requires options array.
Returns list of supported option types.
Checks if a type supports price modifiers.
Checks if a modifier type is valid.
Checks if a type is valid.
Validates an option definition map.
Validates a list of option definitions. Returns {:ok, options} or {:error, reason} on first failure.
Functions
Checks if option allows multiple slots.
Gets localized label for an option or option value.
Handles both string labels and localized map labels. Falls back to default language or first available.
Extracts option values from options list.
Works with both simple string format and enhanced map format:
- Simple: ["Red", "Blue"] -> ["Red", "Blue"]
- Enhanced: [%{"value" => "red", "label" => ...}] -> ["red"]
Returns list of supported modifier types.
Checks if a type requires options array.
Returns list of supported option types.
Checks if a type supports price modifiers.
Checks if a modifier type is valid.
Checks if a type is valid.
Validates an option definition map.
Required Keys
key- Unique identifier (string)label- Display label (string)type- One of supported types
Optional Keys
options- Required for select/multiselect typesdefault- Default valuerequired- Whether field is required (boolean)unit- Unit label (e.g., "cm", "kg")position- Sort order (integer)affects_price- Whether this option affects price (boolean)modifier_type- "fixed" or "percent" (defaults to "fixed")price_modifiers- Map of option value to price modifier
Examples
iex> OptionTypes.validate_option(%{"key" => "material", "label" => "Material", "type" => "text"})
{:ok, %{"key" => "material", "label" => "Material", "type" => "text"}}
iex> OptionTypes.validate_option(%{"key" => "color", "label" => "Color", "type" => "select", "options" => ["Red", "Blue"]})
{:ok, %{"key" => "color", "label" => "Color", "type" => "select", "options" => ["Red", "Blue"]}}
iex> OptionTypes.validate_option(%{"key" => "test"})
{:error, "Missing required keys: label, type"}
Validates a list of option definitions. Returns {:ok, options} or {:error, reason} on first failure.