diff --git a/Dockerfile b/Dockerfile index 7bb4b07..e6bf857 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,10 @@ # # - https://hub.docker.com/r/hexpm/elixir/tags - for the build image # - https://hub.docker.com/_/debian/tags?name=trixie-20251229-slim - for the release image -# - Ex: docker.io/hexpm/elixir:1.19.5-erlang-28.3-debian-trixie-20251229-slim +# - Ex: docker.io/hexpm/elixir:1.19.5-erlang-28.5-debian-trixie-20251229-slim # ARG ELIXIR_VERSION=1.19.5 -ARG OTP_VERSION=28.3 +ARG OTP_VERSION=28.5 ARG DEBIAN_VERSION=trixie-20251229-slim ARG BUILDER_IMAGE="docker.io/hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" diff --git a/lib/ammoprices/prices.ex b/lib/ammoprices/prices.ex index 653a997..ad54563 100644 --- a/lib/ammoprices/prices.ex +++ b/lib/ammoprices/prices.ex @@ -83,6 +83,7 @@ defmodule Ammoprices.Prices do join: p in assoc(ps, :product), where: p.caliber_id == ^caliber_id, where: ps.recorded_at >= ^since, + where: ps.in_stock == true, group_by: fragment("date_trunc('day', ?)", ps.recorded_at), order_by: [asc: fragment("date_trunc('day', ?)", ps.recorded_at)], select: %{ @@ -145,12 +146,15 @@ defmodule Ammoprices.Prices do from(ps in PriceSnapshot, join: p in assoc(ps, :product), where: p.caliber_id == ^caliber_id, - where: ps.in_stock == true, distinct: ps.product_id, order_by: [asc: ps.product_id, desc: ps.recorded_at], - select: ps.price_per_round_cents + select: %{ + price_per_round_cents: ps.price_per_round_cents, + in_stock: ps.in_stock + } ) |> subquery() + |> where([s], s.in_stock == true) |> select([s], min(s.price_per_round_cents)) |> Repo.one() @@ -170,19 +174,20 @@ defmodule Ammoprices.Prices do latest = from(ps in PriceSnapshot, join: p in assoc(ps, :product), - where: ps.in_stock == true, - where: p.in_stock == true, distinct: ps.product_id, order_by: [asc: ps.product_id, desc: ps.recorded_at], select: %{ product_id: ps.product_id, caliber_id: p.caliber_id, - price_per_round_cents: ps.price_per_round_cents + price_per_round_cents: ps.price_per_round_cents, + in_stock: ps.in_stock, + product_in_stock: p.in_stock } ) Repo.all( from(s in subquery(latest), + where: s.in_stock == true and s.product_in_stock == true, group_by: s.caliber_id, select: %{caliber_id: s.caliber_id, min_ppr: min(s.price_per_round_cents)} ) diff --git a/lib/ammoprices/scraping/retailers/natchez.ex b/lib/ammoprices/scraping/retailers/natchez.ex index 8d883d8..54f19a2 100644 --- a/lib/ammoprices/scraping/retailers/natchez.ex +++ b/lib/ammoprices/scraping/retailers/natchez.ex @@ -123,15 +123,25 @@ defmodule Ammoprices.Scraping.Retailers.Natchez do end defp extract_price(%{"price_range" => %{"minimum_price" => %{"final_price" => %{"value" => value}}}}) do - {:ok, - value - |> String.to_float() - |> Kernel.*(100) - |> round()} + case parse_price(value) do + nil -> :error + price_cents -> {:ok, price_cents} + end end defp extract_price(_), do: :error + defp parse_price(value) when is_number(value), do: round(value * 100) + + defp parse_price(value) when is_binary(value) do + case Float.parse(value) do + {amount, ""} -> round(amount * 100) + _ -> nil + end + end + + defp parse_price(_), do: nil + defp parse_integer(nil), do: nil defp parse_integer(str) when is_binary(str) do diff --git a/lib/ammoprices_web/controllers/page_html/home.html.heex b/lib/ammoprices_web/controllers/page_html/home.html.heex index b107fd0..7c49a7d 100644 --- a/lib/ammoprices_web/controllers/page_html/home.html.heex +++ b/lib/ammoprices_web/controllers/page_html/home.html.heex @@ -69,8 +69,7 @@ href="https://hexdocs.pm/phoenix/overview.html" class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6" > - - + - + - +