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"] || []
|
options = raw["options"] || []
|
||||||
raw_variants = raw["variants"] || []
|
raw_variants = raw["variants"] || []
|
||||||
color_lookup = build_image_color_lookup(raw_variants, options)
|
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"]),
|
provider_product_id: to_string(raw["id"]),
|
||||||
@ -350,7 +351,7 @@ defmodule SimpleshopTheme.Providers.Printify do
|
|||||||
blueprint_id: raw["blueprint_id"],
|
blueprint_id: raw["blueprint_id"],
|
||||||
print_provider_id: raw["print_provider_id"],
|
print_provider_id: raw["print_provider_id"],
|
||||||
tags: raw["tags"] || [],
|
tags: raw["tags"] || [],
|
||||||
options: options,
|
options: filtered_options,
|
||||||
raw: raw
|
raw: raw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,6 +383,59 @@ defmodule SimpleshopTheme.Providers.Printify do
|
|||||||
end)
|
end)
|
||||||
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
|
defp build_image_color_lookup(raw_variants, options) do
|
||||||
option_names = Enum.map(options, & &1["name"])
|
option_names = Enum.map(options, & &1["name"])
|
||||||
color_index = Enum.find_index(option_names, &(&1 in ["Colors", "Color"]))
|
color_index = Enum.find_index(option_names, &(&1 in ["Colors", "Color"]))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user