Skip to content

Commit

Permalink
⛁ Create budget plan model
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-sidorov committed Jan 15, 2025
1 parent 035f9ce commit 6951cff
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/budget_tracker/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule BudgetTracker.Accounts.User do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
alias BudgetTracker.{DebitAccounts.DebitAccount, Operations.Operation}
alias BudgetTracker.{DebitAccounts.DebitAccount, Operations.Operation, BudgetPlans.BudgetPlan}

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
Expand All @@ -19,6 +19,7 @@ defmodule BudgetTracker.Accounts.User do
field :role, Ecto.Enum, values: [:admin, :member], default: :member
has_many :debit_accounts, DebitAccount
has_many :operations, Operation
has_many :budget_plans, BudgetPlan

timestamps(type: :utc_datetime)
end
Expand Down
104 changes: 104 additions & 0 deletions lib/budget_tracker/budget_plans.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
defmodule BudgetTracker.BudgetPlans do
@moduledoc """
The BudgetPlans context.
"""

import Ecto.Query, warn: false
alias BudgetTracker.Repo

alias BudgetTracker.BudgetPlans.BudgetPlan

@doc """
Returns the list of budget_plans.
## Examples
iex> list_budget_plans()
[%BudgetPlan{}, ...]
"""
def list_budget_plans do
Repo.all(BudgetPlan)
end

@doc """
Gets a single budget_plan.
Raises `Ecto.NoResultsError` if the Budget plan does not exist.
## Examples
iex> get_budget_plan!(123)
%BudgetPlan{}
iex> get_budget_plan!(456)
** (Ecto.NoResultsError)
"""
def get_budget_plan!(id), do: Repo.get!(BudgetPlan, id)

@doc """
Creates a budget_plan.
## Examples
iex> create_budget_plan(%{field: value})
{:ok, %BudgetPlan{}}
iex> create_budget_plan(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_budget_plan(attrs \\ %{}) do
%BudgetPlan{}
|> BudgetPlan.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a budget_plan.
## Examples
iex> update_budget_plan(budget_plan, %{field: new_value})
{:ok, %BudgetPlan{}}
iex> update_budget_plan(budget_plan, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_budget_plan(%BudgetPlan{} = budget_plan, attrs) do
budget_plan
|> BudgetPlan.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a budget_plan.
## Examples
iex> delete_budget_plan(budget_plan)
{:ok, %BudgetPlan{}}
iex> delete_budget_plan(budget_plan)
{:error, %Ecto.Changeset{}}
"""
def delete_budget_plan(%BudgetPlan{} = budget_plan) do
Repo.delete(budget_plan)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking budget_plan changes.
## Examples
iex> change_budget_plan(budget_plan)
%Ecto.Changeset{data: %BudgetPlan{}}
"""
def change_budget_plan(%BudgetPlan{} = budget_plan, attrs \\ %{}) do
BudgetPlan.changeset(budget_plan, attrs)
end
end
23 changes: 23 additions & 0 deletions lib/budget_tracker/budget_plans/budget_plan.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule BudgetTracker.BudgetPlans.BudgetPlan do
alias BudgetTracker.Accounts.User
use Ecto.Schema
import Ecto.Changeset

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "budget_plans" do
field :description, :string
field :started_form, :naive_datetime
field :duration_in_days, :integer
belongs_to :users, User

timestamps(type: :utc_datetime)
end

@doc false
def changeset(budget_plan, attrs) do
budget_plan
|> cast(attrs, [:started_form, :duration_in_days, :description])
|> validate_required([:started_form, :duration_in_days, :description])
end
end
17 changes: 17 additions & 0 deletions priv/repo/migrations/20250115123800_create_budget_plans.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule BudgetTracker.Repo.Migrations.CreateBudgetPlans do
use Ecto.Migration

def change do
create table(:budget_plans, primary_key: false) do
add :id, :binary_id, primary_key: true
add :started_form, :naive_datetime
add :duration_in_days, :integer
add :description, :text
add :user_id, references(:users, on_delete: :nothing, type: :binary_id)

timestamps(type: :utc_datetime)
end

create index(:budget_plans, [:user_id])
end
end
63 changes: 63 additions & 0 deletions test/budget_tracker/budget_plans_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
defmodule BudgetTracker.BudgetPlansTest do
use BudgetTracker.DataCase

alias BudgetTracker.BudgetPlans

describe "budget_plans" do
alias BudgetTracker.BudgetPlans.BudgetPlan

import BudgetTracker.BudgetPlansFixtures

@invalid_attrs %{description: nil, started_form: nil, duration_in_days: nil}

test "list_budget_plans/0 returns all budget_plans" do
budget_plan = budget_plan_fixture()
assert BudgetPlans.list_budget_plans() == [budget_plan]
end

test "get_budget_plan!/1 returns the budget_plan with given id" do
budget_plan = budget_plan_fixture()
assert BudgetPlans.get_budget_plan!(budget_plan.id) == budget_plan
end

test "create_budget_plan/1 with valid data creates a budget_plan" do
valid_attrs = %{description: "some description", started_form: ~N[2025-01-14 12:38:00], duration_in_days: 42}

assert {:ok, %BudgetPlan{} = budget_plan} = BudgetPlans.create_budget_plan(valid_attrs)
assert budget_plan.description == "some description"
assert budget_plan.started_form == ~N[2025-01-14 12:38:00]
assert budget_plan.duration_in_days == 42
end

test "create_budget_plan/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = BudgetPlans.create_budget_plan(@invalid_attrs)
end

test "update_budget_plan/2 with valid data updates the budget_plan" do
budget_plan = budget_plan_fixture()
update_attrs = %{description: "some updated description", started_form: ~N[2025-01-15 12:38:00], duration_in_days: 43}

assert {:ok, %BudgetPlan{} = budget_plan} = BudgetPlans.update_budget_plan(budget_plan, update_attrs)
assert budget_plan.description == "some updated description"
assert budget_plan.started_form == ~N[2025-01-15 12:38:00]
assert budget_plan.duration_in_days == 43
end

test "update_budget_plan/2 with invalid data returns error changeset" do
budget_plan = budget_plan_fixture()
assert {:error, %Ecto.Changeset{}} = BudgetPlans.update_budget_plan(budget_plan, @invalid_attrs)
assert budget_plan == BudgetPlans.get_budget_plan!(budget_plan.id)
end

test "delete_budget_plan/1 deletes the budget_plan" do
budget_plan = budget_plan_fixture()
assert {:ok, %BudgetPlan{}} = BudgetPlans.delete_budget_plan(budget_plan)
assert_raise Ecto.NoResultsError, fn -> BudgetPlans.get_budget_plan!(budget_plan.id) end
end

test "change_budget_plan/1 returns a budget_plan changeset" do
budget_plan = budget_plan_fixture()
assert %Ecto.Changeset{} = BudgetPlans.change_budget_plan(budget_plan)
end
end
end
22 changes: 22 additions & 0 deletions test/support/fixtures/budget_plans_fixtures.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule BudgetTracker.BudgetPlansFixtures do
@moduledoc """
This module defines test helpers for creating
entities via the `BudgetTracker.BudgetPlans` context.
"""

@doc """
Generate a budget_plan.
"""
def budget_plan_fixture(attrs \\ %{}) do
{:ok, budget_plan} =
attrs
|> Enum.into(%{
description: "some description",
duration_in_days: 42,
started_form: ~N[2025-01-14 12:38:00]
})
|> BudgetTracker.BudgetPlans.create_budget_plan()

budget_plan
end
end

0 comments on commit 6951cff

Please sign in to comment.