Skip to content

Commit

Permalink
feat: add boosts (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
feliciofilipe authored Sep 3, 2023
1 parent 85d023f commit b72f208
Show file tree
Hide file tree
Showing 48 changed files with 1,607 additions and 128 deletions.
4 changes: 4 additions & 0 deletions lib/parzival/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ defmodule Parzival.Accounts do
User.changeset(user, attrs, generate_password: false)
end

def load_user_fields(user, preloads \\ []) do
Repo.preload(user, preloads)
end

@doc """
Creates a user.
## Examples
Expand Down
2 changes: 2 additions & 0 deletions lib/parzival/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Parzival.Accounts.User do
alias Parzival.Companies.Connection
alias Parzival.Gamification.Curriculum
alias Parzival.Gamification.Mission
alias Parzival.Store.Item
alias Parzival.Store.Order
alias Parzival.Uploaders

Expand Down Expand Up @@ -67,6 +68,7 @@ defmodule Parzival.Accounts.User do
belongs_to :qrcode, QRCode

has_many :orders, Order
has_many :inventory, Item

many_to_many :missions, Mission, join_through: "missions_users"

Expand Down
74 changes: 73 additions & 1 deletion lib/parzival/gamification.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ defmodule Parzival.Gamification do

alias Ecto.Multi

alias Parzival.Accounts
alias Parzival.Accounts.User
alias Parzival.Companies
alias Parzival.Gamification
alias Parzival.Gamification.Curriculum
alias Parzival.Gamification.Curriculum.Education
alias Parzival.Gamification.Curriculum.Experience
alias Parzival.Gamification.Curriculum.Language
alias Parzival.Gamification.Curriculum.Position
alias Parzival.Gamification.Curriculum.Skill
alias Parzival.Gamification.Curriculum.Volunteering
alias Parzival.Gamification.Mission.MissionUser
alias Parzival.Gamification.Mission.TaskUser
alias Parzival.Store

@doc """
Returns the list of curriculums.
Expand Down Expand Up @@ -438,6 +443,58 @@ defmodule Parzival.Gamification do
Task.changeset(task, attrs)
end

def skip_task(%User{} = user, %Task{} = task) do
Multi.new()
|> Multi.insert(
:task_user,
TaskUser.changeset(%TaskUser{}, %{
user_id: user.id,
task_id: task.id
})
)
|> Multi.update(
:update_user,
User.task_completion_changeset(user, %{
balance: user.balance + task.tokens,
exp: user.exp + task.exp
})
)
|> Multi.run(:mission, fn repo, _change ->
mission = Gamification.get_mission!(task.mission_id, tasks: [:users])

case Enum.all?(mission.tasks, fn task -> Enum.any?(task.users, &(&1.id == user.id)) end) do
true ->
%MissionUser{}
|> MissionUser.changeset(%{mission_id: mission.id, user_id: user.id})
|> repo.insert()

user
|> User.task_completion_changeset(%{
balance: user.balance + mission.tokens * get_tokens_multiplier(user),
exp: user.exp + mission.exp
})
|> repo.update()

{:ok, mission}

_ ->
{:ok, mission}
end
end)
|> Multi.delete(
:redeem_boost,
Store.get_skip_task_from_inventory(user.id)
)
|> Repo.transaction()
|> case do
{:ok, transaction} ->
broadcast({:ok, transaction}, :updated)

{:error, _transaction, changeset, _} ->
{:error, changeset}
end
end

alias Parzival.Gamification.Mission.Difficulty

@doc """
Expand Down Expand Up @@ -907,7 +964,7 @@ defmodule Parzival.Gamification do
TaskUser.changeset(%TaskUser{}, %{user_id: user.id, staff_id: staff.id, task_id: task.id})
)
|> Multi.run(:mission, fn repo, _change ->
mission = Parzival.Gamification.get_mission!(task.mission_id, tasks: [:users])
mission = Gamification.get_mission!(task.mission_id, tasks: [:users])

case Enum.all?(mission.tasks, fn task -> Enum.any?(task.users, &(&1.id == user.id)) end) do
true ->
Expand Down Expand Up @@ -948,6 +1005,21 @@ defmodule Parzival.Gamification do
end
end

defp get_tokens_multiplier(%User{} = user) do
user = Accounts.load_user_fields(user, inventory: [:boost])

user.inventory
|> Enum.find_value(
1.0,
fn item ->
if item.boost.type == :tokens &&
Timex.diff(DateTime.utc_now(), item.boost.expires_at, :minutes) <= 60 do
item.boost.multiplier
end
end
)
end

def is_task_completed?(task_id, user_id) do
from(t in TaskUser, where: t.task_id == ^task_id and t.user_id == ^user_id)
|> Repo.exists?()
Expand Down
Loading

0 comments on commit b72f208

Please sign in to comment.