-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathtask.ex
More file actions
139 lines (118 loc) · 3.85 KB
/
task.ex
File metadata and controls
139 lines (118 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
defmodule CodeCorps.Task do
use CodeCorps.Model
import EctoOrdered
alias CodeCorps.{Services.MarkdownRendererService, Task}
alias Ecto.Changeset
@type t :: %__MODULE__{}
schema "tasks" do
field :archived, :boolean, default: false
field :body, :string
field :closed_at, :utc_datetime
field :created_at, :utc_datetime
field :created_from, :string, default: "code_corps"
field :markdown, :string
field :modified_at, :utc_datetime
field :modified_from, :string, default: "code_corps"
field :number, :integer, read_after_writes: true
field :order, :integer
field :status, :string, default: "open"
field :title, :string
field :position, :integer, virtual: true
belongs_to :github_issue, CodeCorps.GithubIssue
belongs_to :github_repo, CodeCorps.GithubRepo
belongs_to :project, CodeCorps.Project
belongs_to :task_list, CodeCorps.TaskList
belongs_to :user, CodeCorps.User
has_one :github_pull_request, through: [:github_issue, :github_pull_request]
has_one :user_task, CodeCorps.UserTask
has_many :comments, CodeCorps.Comment
has_many :task_skills, CodeCorps.TaskSkill
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:archived, :title, :markdown, :task_list_id, :position])
|> validate_required([:title])
|> assoc_constraint(:task_list)
|> handle_archived()
|> MarkdownRendererService.render_markdown_to_html(:markdown, :body)
end
def handle_archived(changeset) do
case get_field(changeset, :archived) do
true ->
changeset
|> put_change(:task_list_id, nil)
|> put_change(:order, nil)
_ ->
order_task(changeset)
end
end
def order_task(changeset) do
changeset
|> validate_required([:task_list_id])
|> apply_position()
|> set_order(:position, :order, :task_list_id)
end
@spec create_changeset(struct, map) :: Ecto.Changeset.t
def create_changeset(struct, %{} = params) do
struct
|> changeset(params)
|> cast(params, [:github_repo_id, :project_id, :user_id])
|> set_created_and_modified_at()
|> validate_required([:project_id, :user_id])
|> assoc_constraint(:github_repo)
|> assoc_constraint(:project)
|> assoc_constraint(:user)
|> put_change(:status, "open")
|> put_change(:modified_from, "code_corps")
end
@spec update_changeset(struct, map) :: Ecto.Changeset.t
def update_changeset(struct, %{} = params) do
struct
|> changeset(params)
|> cast(params, [:status])
|> validate_inclusion(:status, statuses())
|> set_closed_at()
|> update_modified_at()
|> maybe_assoc_with_repo(params)
|> put_change(:modified_from, "code_corps")
end
def apply_position(changeset) do
case get_field(changeset, :position) do
nil ->
put_change(changeset, :position, 0)
_ -> changeset
end
end
defp statuses do
~w{ open closed }
end
defp set_closed_at(changeset) do
case changeset do
%Changeset{valid?: true, changes: %{status: "closed"}} ->
put_change(changeset, :closed_at, DateTime.utc_now)
%Changeset{valid?: true, changes: %{status: "open"}} ->
put_change(changeset, :closed_at, nil)
_ ->
changeset
end
end
defp set_created_and_modified_at(changeset) do
now = DateTime.utc_now
changeset
|> put_change(:created_at, now)
|> put_change(:modified_at, now)
end
defp update_modified_at(changeset) do
put_change(changeset, :modified_at, DateTime.utc_now)
end
@spec maybe_assoc_with_repo(Changeset.t, map) :: Changeset.t
defp maybe_assoc_with_repo(
%Changeset{data: %Task{github_repo_id: nil}} = changeset,
%{} = params) do
changeset
|> cast(params, [:github_repo_id])
|> assoc_constraint(:github_repo)
end
defp maybe_assoc_with_repo(%Changeset{} = changeset, %{}), do: changeset
end