It was simpler than I thought! I followed the contract of extracting a calculation in its module and it worked.
# MyApp.Sales.Sale resource
calculations do
calculate :sub_total, :decimal, MyApp.Sales.Sale.Calculations.SubTotal
end
Calculation Module
defmodule MyApp.Sales.Sale.Calculations.SubTotal do
use Ash.Resource.Calculation
def description, do: "Calculates the sub total of a sale."
def public?, do: true
@impl true
def load(_query, opts, _context) do
[line_items: [:line_total, :quantity, :price]]
end
@impl true
def calculate(sales, _opts, _arguments) do
Enum.map(sales, &calculate_sub_total/1)
end
defp calculate_sub_total(%{line_items: line_items}) do
line_items
|> Enum.map(& &1.line_total)
|> Enum.reduce(Decimal.new(0), &Decimal.add/2)
end
end
Now I am able to successful calculate subtotal without hitting the DB
sale_attrs = %{line_items: [%{line_total: 12}, %{line_total: 15}]}
Ash.calculate!(Zippiker.Sales.Sale, :sub_total, refs: sale_attrs)
# Decimal.new("27")






















