filter Printify options to enabled variants and order by hero colour
Printify's API returns all blueprint option values (e.g. 21 colours) even when only a few are enabled as variants. This caused the PDP to show phantom colour swatches with no images or purchasable variants. Now filter_options_by_variants strips option values to only those with enabled variants, ordered by first appearance so the hero/default colour leads the swatch list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4e19d4c4a9
commit
0fe48baaa8
@ -338,6 +338,7 @@ defmodule SimpleshopTheme.Providers.Printify do
|
||||
options = raw["options"] || []
|
||||
raw_variants = raw["variants"] || []
|
||||
color_lookup = build_image_color_lookup(raw_variants, options)
|
||||
filtered_options = filter_options_by_variants(options, raw_variants)
|
||||
|
||||
%{
|
||||
provider_product_id: to_string(raw["id"]),
|
||||
@ -350,7 +351,7 @@ defmodule SimpleshopTheme.Providers.Printify do
|
||||
blueprint_id: raw["blueprint_id"],
|
||||
print_provider_id: raw["print_provider_id"],
|
||||
tags: raw["tags"] || [],
|
||||
options: options,
|
||||
options: filtered_options,
|
||||
raw: raw
|
||||
}
|
||||
}
|
||||
@ -382,6 +383,59 @@ defmodule SimpleshopTheme.Providers.Printify do
|
||||
end)
|
||||
end
|
||||
|
||||
# Filter blueprint options to only include values present in enabled variants,
|
||||
# ordered to match variant ordering (so the default variant's colour comes first).
|
||||
defp filter_options_by_variants(options, raw_variants) do
|
||||
enabled_order = enabled_option_value_order(options, raw_variants)
|
||||
|
||||
Enum.map(options, fn opt ->
|
||||
name = opt["name"]
|
||||
|
||||
case Map.get(enabled_order, name) do
|
||||
nil ->
|
||||
opt
|
||||
|
||||
ordered_values ->
|
||||
values_by_title = Map.new(opt["values"] || [], fn v -> {v["title"], v} end)
|
||||
|
||||
sorted =
|
||||
ordered_values
|
||||
|> Enum.map(&Map.get(values_by_title, &1))
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
Map.put(opt, "values", sorted)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
# Returns %{"Colors" => ["Dark Heather", "Navy", ...], "Sizes" => ["S", "2XL"]}
|
||||
# preserving first-seen order from enabled variants.
|
||||
defp enabled_option_value_order(options, raw_variants) do
|
||||
option_names = Enum.map(options, & &1["name"])
|
||||
|
||||
raw_variants
|
||||
|> Enum.filter(& &1["is_enabled"])
|
||||
|> Enum.reduce(%{}, fn var, acc ->
|
||||
parts = String.split(var["title"] || "", " / ")
|
||||
|
||||
option_names
|
||||
|> Enum.with_index()
|
||||
|> Enum.reduce(acc, fn {name, idx}, inner_acc ->
|
||||
case Enum.at(parts, idx) do
|
||||
nil ->
|
||||
inner_acc
|
||||
|
||||
val ->
|
||||
existing = Map.get(inner_acc, name, [])
|
||||
|
||||
if val in existing,
|
||||
do: inner_acc,
|
||||
else: Map.put(inner_acc, name, existing ++ [val])
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
defp build_image_color_lookup(raw_variants, options) do
|
||||
option_names = Enum.map(options, & &1["name"])
|
||||
color_index = Enum.find_index(option_names, &(&1 in ["Colors", "Color"]))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user