diff --git a/lib/simpleshop_theme/providers/printful.ex b/lib/simpleshop_theme/providers/printful.ex index 142c516..353fbf4 100644 --- a/lib/simpleshop_theme/providers/printful.ex +++ b/lib/simpleshop_theme/providers/printful.ex @@ -198,8 +198,9 @@ defmodule SimpleshopTheme.Providers.Printful do defp fetch_rate_for_product(catalog_product_id, variant_id, country_code) do items = [%{source: "catalog", catalog_variant_id: variant_id, quantity: 1}] + recipient = build_recipient(country_code) - case Client.calculate_shipping(%{country_code: country_code}, items) do + case Client.calculate_shipping(recipient, items) do {:ok, rates} when is_list(rates) -> standard = Enum.find(rates, &(&1["shipping"] == "STANDARD")) || List.first(rates) @@ -228,6 +229,18 @@ defmodule SimpleshopTheme.Providers.Printful do end end + # Printful requires state_code for US, CA, and AU + @default_state_codes %{"US" => "NY", "CA" => "ON", "AU" => "NSW"} + + defp build_recipient(country_code) do + base = %{country_code: country_code} + + case @default_state_codes[country_code] do + nil -> base + state -> Map.put(base, :state_code, state) + end + end + # Returns {catalog_product_id, first_catalog_variant_id} per product defp extract_per_product_items(products) do products diff --git a/lib/simpleshop_theme_web/live/admin/providers/form.ex b/lib/simpleshop_theme_web/live/admin/providers/form.ex index 626b24e..5b0c33e 100644 --- a/lib/simpleshop_theme_web/live/admin/providers/form.ex +++ b/lib/simpleshop_theme_web/live/admin/providers/form.ex @@ -5,15 +5,20 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do alias SimpleshopTheme.Products.ProviderConnection alias SimpleshopTheme.Providers + @supported_types ~w(printify printful) + @impl true def mount(params, _session, socket) do {:ok, apply_action(socket, socket.assigns.live_action, params)} end - defp apply_action(socket, :new, _params) do + defp apply_action(socket, :new, params) do + provider_type = validated_type(params["type"]) + socket - |> assign(:page_title, "Connect to Printify") - |> assign(:connection, %ProviderConnection{provider_type: "printify"}) + |> assign(:page_title, "Connect to #{provider_label(provider_type)}") + |> assign(:provider_type, provider_type) + |> assign(:connection, %ProviderConnection{provider_type: provider_type}) |> assign(:form, to_form(ProviderConnection.changeset(%ProviderConnection{}, %{}))) |> assign(:testing, false) |> assign(:test_result, nil) @@ -24,7 +29,8 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do connection = Products.get_provider_connection!(id) socket - |> assign(:page_title, "Printify settings") + |> assign(:page_title, "#{provider_label(connection.provider_type)} settings") + |> assign(:provider_type, connection.provider_type) |> assign(:connection, connection) |> assign(:form, to_form(ProviderConnection.changeset(connection, %{}))) |> assign(:testing, false) @@ -48,14 +54,13 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do def handle_event("test_connection", _params, socket) do socket = assign(socket, testing: true, test_result: nil) - # Use pending_api_key from validation, or fall back to existing encrypted key api_key = socket.assigns[:pending_api_key] || ProviderConnection.get_api_key(socket.assigns.connection) if api_key && api_key != "" do temp_conn = %ProviderConnection{ - provider_type: "printify", + provider_type: socket.assigns.provider_type, api_key_encrypted: encrypt_api_key(api_key) } @@ -72,17 +77,19 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do end defp save_connection(socket, :new, params) do + provider_type = socket.assigns.provider_type + params = params - |> Map.put("provider_type", "printify") - |> maybe_add_shop_config(socket.assigns.test_result) - |> maybe_add_name(socket.assigns.test_result) + |> Map.put("provider_type", provider_type) + |> maybe_add_config(provider_type, socket.assigns.test_result) + |> maybe_add_name(provider_type, socket.assigns.test_result) case Products.create_provider_connection(params) do {:ok, _connection} -> {:noreply, socket - |> put_flash(:info, "Connected to Printify!") + |> put_flash(:info, "Connected to #{provider_label(provider_type)}!") |> push_navigate(to: ~p"/admin/settings")} {:error, %Ecto.Changeset{} = changeset} -> @@ -103,19 +110,29 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do end end - defp maybe_add_shop_config(params, {:ok, %{shop_id: shop_id}}) do + # Printify returns shop_id, Printful returns store_id + defp maybe_add_config(params, "printify", {:ok, %{shop_id: shop_id}}) do config = Map.get(params, "config", %{}) |> Map.put("shop_id", to_string(shop_id)) Map.put(params, "config", config) end - defp maybe_add_shop_config(params, _), do: params - - defp maybe_add_name(params, {:ok, %{shop_name: shop_name}}) when is_binary(shop_name) do - Map.put_new(params, "name", shop_name) + defp maybe_add_config(params, "printful", {:ok, %{store_id: store_id}}) do + config = Map.get(params, "config", %{}) |> Map.put("store_id", to_string(store_id)) + Map.put(params, "config", config) end - defp maybe_add_name(params, _) do - Map.put_new(params, "name", "Printify") + defp maybe_add_config(params, _type, _result), do: params + + defp maybe_add_name(params, "printify", {:ok, %{shop_name: name}}) when is_binary(name) do + Map.put_new(params, "name", name) + end + + defp maybe_add_name(params, "printful", {:ok, %{store_name: name}}) when is_binary(name) do + Map.put_new(params, "name", name) + end + + defp maybe_add_name(params, type, _result) do + Map.put_new(params, "name", provider_label(type)) end defp encrypt_api_key(api_key) do @@ -125,9 +142,21 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do end end - defp format_error(:no_api_key), do: "Please enter your connection key" + defp validated_type(type) when type in @supported_types, do: type + defp validated_type(_), do: "printify" + + # Shared helpers used by the template + + defp provider_label("printful"), do: "Printful" + defp provider_label(_), do: "Printify" + + defp connection_name({:ok, %{shop_name: name}}), do: name + defp connection_name({:ok, %{store_name: name}}), do: name + defp connection_name(_), do: nil + + defp format_error(:no_api_key), do: "Please enter your API key" defp format_error(:unauthorized), do: "That key doesn't seem to be valid" - defp format_error(:timeout), do: "Couldn't reach Printify - try again" + defp format_error(:timeout), do: "Couldn't reach the provider - try again" defp format_error({:http_error, _code}), do: "Something went wrong - try again" defp format_error(error) when is_binary(error), do: error defp format_error(_), do: "Connection failed - check your key and try again" diff --git a/lib/simpleshop_theme_web/live/admin/providers/form.html.heex b/lib/simpleshop_theme_web/live/admin/providers/form.html.heex index d163bcc..3dd0c5d 100644 --- a/lib/simpleshop_theme_web/live/admin/providers/form.html.heex +++ b/lib/simpleshop_theme_web/live/admin/providers/form.html.heex @@ -1,54 +1,84 @@ <.header> - {if @live_action == :new, do: "Connect to Printify", else: "Printify settings"} + {if @live_action == :new, + do: "Connect to #{provider_label(@provider_type)}", + else: "#{provider_label(@provider_type)} settings"}
- Printify is a print-on-demand service that prints and ships products for you. + {provider_label(@provider_type)} is a print-on-demand service that prints and ships products for you. Connect your account to automatically import your products into your shop.
Get your connection key from Printify:
-Get your API key from Printify:
+Get your API key from Printful:
+- Printify handles printing and shipping for you. Connect your account - to import your products and start selling. + Connect your Printify or Printful account to import products + and start selling.
- <.button navigate={~p"/admin/providers/new"} class="mt-6"> - Connect to Printify - +@@ -357,10 +357,10 @@ defmodule SimpleshopThemeWeb.Admin.Settings do