diff --git a/lib/simpleshop_theme/providers/printful.ex b/lib/simpleshop_theme/providers/printful.ex index 338675f..b938470 100644 --- a/lib/simpleshop_theme/providers/printful.ex +++ b/lib/simpleshop_theme/providers/printful.ex @@ -76,7 +76,9 @@ defmodule SimpleshopTheme.Providers.Printful do case Client.get_sync_product(product["id"]) do {:ok, detail} -> - normalize_product(detail["sync_product"], detail["sync_variants"] || []) + sync_variants = detail["sync_variants"] || [] + catalog_colors = fetch_catalog_colors(sync_variants) + normalize_product(detail["sync_product"], sync_variants, catalog_colors) {:error, reason} -> Logger.warning( @@ -106,6 +108,42 @@ defmodule SimpleshopTheme.Providers.Printful do end end + # Fetch catalog color hex codes for a product's catalog type. + # Caches per catalog_product_id in the process dictionary to avoid duplicate calls. + defp fetch_catalog_colors(sync_variants) do + catalog_product_id = extract_catalog_product_id_from_variants(sync_variants) + cache_key = {:catalog_colors, catalog_product_id} + + case Process.get(cache_key) do + nil -> + colors = do_fetch_catalog_colors(catalog_product_id) + Process.put(cache_key, colors) + colors + + cached -> + cached + end + end + + defp do_fetch_catalog_colors(0), do: %{} + + defp do_fetch_catalog_colors(catalog_product_id) do + Process.sleep(100) + + case Client.get_catalog_product(catalog_product_id) do + {:ok, catalog} -> + (catalog["colors"] || []) + |> Map.new(fn c -> {c["name"], c["value"]} end) + + {:error, reason} -> + Logger.warning( + "Failed to fetch catalog colors for product #{catalog_product_id}: #{inspect(reason)}" + ) + + %{} + end + end + # ============================================================================= # Orders # ============================================================================= @@ -295,7 +333,7 @@ defmodule SimpleshopTheme.Providers.Printful do # Data Normalization # ============================================================================= - defp normalize_product(sync_product, sync_variants) do + defp normalize_product(sync_product, sync_variants, catalog_colors) do images = extract_preview_images(sync_variants) catalog_product_id = extract_catalog_product_id_from_variants(sync_variants) catalog_variant_ids = Enum.map(sync_variants, & &1["variant_id"]) |> Enum.reject(&is_nil/1) @@ -322,7 +360,7 @@ defmodule SimpleshopTheme.Providers.Printful do print_provider_id: 0, thumbnail_url: sync_product["thumbnail_url"], artwork_url: extract_artwork_url(sync_variants), - options: build_option_types(sync_variants), + options: build_option_types(sync_variants, catalog_colors), raw: %{sync_product: sync_product} } } @@ -395,16 +433,18 @@ defmodule SimpleshopTheme.Providers.Printful do end) || 0 end - # Build option types from variants for frontend display - defp build_option_types(sync_variants) do - # Build colour values with hex codes from sync variant data + # Build option types from variants for frontend display. + # catalog_colors is a %{"Black" => "#0b0b0b", ...} map from the catalog API. + defp build_option_types(sync_variants, catalog_colors) do colors = sync_variants |> Enum.reject(fn sv -> is_nil(sv["color"]) end) |> Enum.uniq_by(fn sv -> sv["color"] end) |> Enum.map(fn sv -> - base = %{"title" => normalize_text(sv["color"])} - if sv["color_code"], do: Map.put(base, "hex", sv["color_code"]), else: base + title = normalize_text(sv["color"]) + base = %{"title" => title} + hex = Map.get(catalog_colors, sv["color"]) + if hex, do: Map.put(base, "colors", [hex]), else: base end) sizes =