fp/services/bright/lib/bright/orders.ex

232 lines
4.3 KiB
Elixir

defmodule Bright.Orders do
@moduledoc """
The Orders context.
"""
import Ecto.Query, warn: false
alias Bright.Repo
alias Bright.Orders.{Order,LineItem}
alias Bright.ShoppingCart
@doc """
Returns the list of orders.
## Examples
iex> list_orders()
[%Order{}, ...]
"""
def list_orders do
Repo.all(Order)
end
@doc """
Gets a single order.
Raises `Ecto.NoResultsError` if the Order does not exist.
## Examples
iex> get_order!(123)
%Order{}
iex> get_order!(456)
** (Ecto.NoResultsError)
"""
# def get_order!(id), do: Repo.get!(Order, id)
def get_order!(user_uuid, id) do
Order
|> Repo.get_by!(id: id, user_uuid: user_uuid)
|> Repo.preload([line_items: [:product]])
end
@doc """
Creates a order.
## Examples
iex> create_order(%{field: value})
{:ok, %Order{}}
iex> create_order(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_order(attrs \\ %{}) do
%Order{}
|> Order.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a order.
## Examples
iex> update_order(order, %{field: new_value})
{:ok, %Order{}}
iex> update_order(order, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_order(%Order{} = order, attrs) do
order
|> Order.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a order.
## Examples
iex> delete_order(order)
{:ok, %Order{}}
iex> delete_order(order)
{:error, %Ecto.Changeset{}}
"""
def delete_order(%Order{} = order) do
Repo.delete(order)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking order changes.
## Examples
iex> change_order(order)
%Ecto.Changeset{data: %Order{}}
"""
def change_order(%Order{} = order, attrs \\ %{}) do
Order.changeset(order, attrs)
end
alias Bright.Orders.LineItem
@doc """
Returns the list of order_line_items.
## Examples
iex> list_order_line_items()
[%LineItem{}, ...]
"""
def list_order_line_items do
Repo.all(LineItem)
end
@doc """
Gets a single line_item.
Raises `Ecto.NoResultsError` if the Line item does not exist.
## Examples
iex> get_line_item!(123)
%LineItem{}
iex> get_line_item!(456)
** (Ecto.NoResultsError)
"""
def get_line_item!(id), do: Repo.get!(LineItem, id)
@doc """
Creates a line_item.
## Examples
iex> create_line_item(%{field: value})
{:ok, %LineItem{}}
iex> create_line_item(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_line_item(attrs \\ %{}) do
%LineItem{}
|> LineItem.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a line_item.
## Examples
iex> update_line_item(line_item, %{field: new_value})
{:ok, %LineItem{}}
iex> update_line_item(line_item, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_line_item(%LineItem{} = line_item, attrs) do
line_item
|> LineItem.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a line_item.
## Examples
iex> delete_line_item(line_item)
{:ok, %LineItem{}}
iex> delete_line_item(line_item)
{:error, %Ecto.Changeset{}}
"""
def delete_line_item(%LineItem{} = line_item) do
Repo.delete(line_item)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking line_item changes.
## Examples
iex> change_line_item(line_item)
%Ecto.Changeset{data: %LineItem{}}
"""
def change_line_item(%LineItem{} = line_item, attrs \\ %{}) do
LineItem.changeset(line_item, attrs)
end
def complete_order(%ShoppingCart.Cart{} = cart) do
line_items =
Enum.map(cart.items, fn item ->
%{product_id: item.product_id, price: item.product.price, quantity: item.quantity}
end)
order =
Ecto.Changeset.change(%Order{},
user_uuid: cart.user_uuid,
total_price: ShoppingCart.total_cart_price(cart),
line_items: line_items
)
Ecto.Multi.new()
|> Ecto.Multi.insert(:order, order)
|> Ecto.Multi.run(:prune_cart, fn _repo, _changes ->
ShoppingCart.prune_cart_items(cart)
end)
|> Repo.transaction()
|> case do
{:ok, %{order: order}} -> {:ok, order}
{:error, name, value, _changes_so_far} -> {:error, {name, value}}
end
end
end