All modules, configs, paths, and references updated. 836 tests pass, zero warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
57 lines
1.7 KiB
Elixir
57 lines
1.7 KiB
Elixir
defmodule Berrypod.Orders.OrderSubmissionWorker do
|
|
@moduledoc """
|
|
Oban worker for submitting paid orders to the fulfilment provider.
|
|
|
|
Enqueued after Stripe webhook confirms payment. Guards against
|
|
missing orders, unpaid orders, and already-submitted orders.
|
|
Retries up to 3 times with backoff for transient failures.
|
|
"""
|
|
|
|
use Oban.Worker, queue: :checkout, max_attempts: 3
|
|
|
|
alias Berrypod.Orders
|
|
|
|
require Logger
|
|
|
|
@impl Oban.Worker
|
|
def perform(%Oban.Job{args: %{"order_id" => order_id}}) do
|
|
case Orders.get_order(order_id) do
|
|
nil ->
|
|
Logger.warning("Order submission: order #{order_id} not found")
|
|
{:cancel, :order_not_found}
|
|
|
|
%{payment_status: status} when status != "paid" ->
|
|
Logger.warning("Order submission: order #{order_id} not paid (#{status})")
|
|
{:cancel, :not_paid}
|
|
|
|
%{provider_order_id: pid} when not is_nil(pid) ->
|
|
Logger.info("Order submission: order #{order_id} already submitted")
|
|
:ok
|
|
|
|
%{shipping_address: addr} when addr == %{} or is_nil(addr) ->
|
|
Logger.warning("Order submission: order #{order_id} has no shipping address, will retry")
|
|
{:error, :no_shipping_address}
|
|
|
|
order ->
|
|
case Orders.submit_to_provider(order) do
|
|
{:ok, updated} ->
|
|
Logger.info(
|
|
"Order #{updated.order_number} submitted to provider (#{updated.provider_order_id})"
|
|
)
|
|
|
|
:ok
|
|
|
|
{:error, reason} ->
|
|
Logger.error("Order #{order.order_number} submission failed: #{inspect(reason)}")
|
|
{:error, reason}
|
|
end
|
|
end
|
|
end
|
|
|
|
def enqueue(order_id) do
|
|
%{order_id: order_id}
|
|
|> new()
|
|
|> Oban.insert()
|
|
end
|
|
end
|