Files
2026-07-17 23:22:13 +03:00

53 lines
1.7 KiB
Elixir

defmodule Bid do
use Ecto.Schema
import Ecto.Changeset
alias NeonVertigoService.Repo
import Ecto.Query, only: [from: 2]
@primary_key false
schema "bids" do
belongs_to :auction, Auction, foreign_key: :auction_gid, references: :gid, type: :string, primary_key: true
field :bid_timestamp, :utc_datetime_usec, primary_key: true
field :bidder_gid, :string, primary_key: true
field :bid, :decimal
end
def changeset(bid, params \\ %{}) do
bid
|> cast(params, [:auction_gid, :bidder_gid, :bid])
|> validate_required([:auction_gid, :bidder_gid, :bid])
|> validate_number(:bid, greater_than_or_equal_to: 0)
|> validate_bid_value_max
|> validate_bid_value_more_than_auction_starting_price
|> put_change(:bid_timestamp, DateTime.utc_now)
|> foreign_key_constraint(:auction_gid)
end
defp validate_bid_value_max(changeset) do
auction_gid = get_field(changeset, :auction_gid)
new_bid = get_field(changeset, :bid)
existing_bid = Repo.one(
from b in Bid, where: b.auction_gid == ^auction_gid,
order_by: [desc: :bid_timestamp],
limit: 1,
select: b.bid
)
if is_nil(existing_bid) or Decimal.compare(existing_bid, new_bid) == :lt do
changeset
else
add_error(changeset, :bid, "smaller than last bid")
end
end
defp validate_bid_value_more_than_auction_starting_price(changeset) do
auction_gid = get_field(changeset, :auction_gid)
auction = Repo.one!(from a in Auction, where: a.gid == ^auction_gid, select: a)
if Decimal.compare(auction.starting_price, get_field(changeset, :bid)) == :lt do
changeset
else
add_error(changeset, :bid, "smaller than auction's starting price")
end
end
end