diff --git a/lib/shift73k/repo.ex b/lib/shift73k/repo.ex index 24add415..c817bf41 100644 --- a/lib/shift73k/repo.ex +++ b/lib/shift73k/repo.ex @@ -4,4 +4,9 @@ defmodule Shift73k.Repo do adapter: Ecto.Adapters.Postgres use Scrivener, page_size: 10 + + def timestamp(%{} = attrs) do + now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) + Map.merge(attrs, %{inserted_at: now, updated_at: now}) + end end diff --git a/lib/shift73k/shifts.ex b/lib/shift73k/shifts.ex index 8d6253d7..8d9c363b 100644 --- a/lib/shift73k/shifts.ex +++ b/lib/shift73k/shifts.ex @@ -87,6 +87,14 @@ defmodule Shift73k.Shifts do |> Repo.insert() end + def create_multiple(shift_attrs) when is_list(shift_attrs) do + try do + Repo.insert_all(Shift, shift_attrs) + rescue + e in Postgrex.Error -> {:error, e.message} + end + end + @doc """ Updates a shift. diff --git a/lib/shift73k/shifts/shift.ex b/lib/shift73k/shifts/shift.ex index dfc00279..0e7b7481 100644 --- a/lib/shift73k/shifts/shift.ex +++ b/lib/shift73k/shifts/shift.ex @@ -2,6 +2,8 @@ defmodule Shift73k.Shifts.Shift do use Ecto.Schema import Ecto.Changeset + alias Shift73k.Shifts.Templates.ShiftTemplate + @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "shifts" do @@ -31,14 +33,13 @@ defmodule Shift73k.Shifts.Shift do :time_end, :user_id ]) - - # |> validate_required([ - # :subject, - # :date, - # :time_zone, - # :time_start, - # :time_end, - # :user_id - # ]) + |> validate_required([ + :subject, + :date, + :time_zone, + :time_start, + :time_end, + :user_id + ]) end end diff --git a/lib/shift73k/shifts/templates.ex b/lib/shift73k/shifts/templates.ex index 6530802f..b5cac767 100644 --- a/lib/shift73k/shifts/templates.ex +++ b/lib/shift73k/shifts/templates.ex @@ -21,13 +21,11 @@ defmodule Shift73k.Shifts.Templates do Repo.all(ShiftTemplate) end - def list_shift_templates_by_user_id(user_id) do - q = - from s in ShiftTemplate, - where: s.user_id == ^user_id, - order_by: [fragment("lower(?)", s.subject), s.time_start] - - Repo.all(q) + def list_shift_templates_by_user(user_id) do + from(s in ShiftTemplate) + |> where([s], s.user_id == ^user_id) + |> order_by([s], [fragment("lower(?)", s.subject), s.time_start]) + |> Repo.all() end @doc """ diff --git a/lib/shift73k/shifts/templates/shift_template.ex b/lib/shift73k/shifts/templates/shift_template.ex index bfa64d62..b44c64dc 100644 --- a/lib/shift73k/shifts/templates/shift_template.ex +++ b/lib/shift73k/shifts/templates/shift_template.ex @@ -77,6 +77,14 @@ defmodule Shift73k.Shifts.Templates.ShiftTemplate do def shift_length(len_min) when is_integer(len_min) and len_min >= 0, do: len_min def shift_length(len_min) when is_integer(len_min) and len_min < 0, do: 1440 + len_min - def shift_length(time_end, time_start), - do: shift_length(%ShiftTemplate{time_end: time_end, time_start: time_start}) + def shift_length(time_end, time_start) do + shift_length(%ShiftTemplate{time_end: time_end, time_start: time_start}) + end + + # Get shift attrs from shift template + def attrs(%ShiftTemplate{} = shift_template) do + shift_template + |> Map.from_struct() + |> Map.drop([:__meta__, :id, :inserted_at, :updated_at, :user, :is_fave_of_user]) + end end diff --git a/lib/shift73k_web/live/shift_assign_live/index.ex b/lib/shift73k_web/live/shift_assign_live/index.ex index 0b5ccb0b..5e8e08ab 100644 --- a/lib/shift73k_web/live/shift_assign_live/index.ex +++ b/lib/shift73k_web/live/shift_assign_live/index.ex @@ -81,7 +81,7 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do defp init_shift_templates(%{assigns: %{current_user: user}} = socket) do shift_templates = - Templates.list_shift_templates_by_user_id(user.id) + Templates.list_shift_templates_by_user(user.id) |> Stream.map(fn t -> shift_template_option(t, user.fave_shift_template_id) end) |> Enum.concat([@custom_shift_opt]) @@ -252,12 +252,7 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do @impl true def handle_event("select-day", %{"day" => day}, socket) do - selected_days = - case Enum.member?(socket.assigns.selected_days, day) do - false -> [day | socket.assigns.selected_days] - true -> Enum.reject(socket.assigns.selected_days, fn d -> d == day end) - end - + selected_days = update_selected_days(socket.assigns.selected_days, day) {:noreply, assign(socket, :selected_days, selected_days)} end @@ -277,17 +272,15 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do @impl true def handle_event("save-days", _params, socket) do # 1. collect attrs from loaded shift template - shift_data = shift_data_from_template(socket.assigns.shift_template) + shift_data = ShiftTemplate.attrs(socket.assigns.shift_template) - # 2. create list of shift attrs to insert - to_insert = - Enum.map(socket.assigns.selected_days, &shift_from_day_and_shift_data(&1, shift_data)) - - # 3. insert the data - {status, msg} = insert_shifts(to_insert, length(socket.assigns.selected_days)) - - socket - |> put_flash(status, msg) + # 2. fashion list of shift attrs and insert + socket.assigns.selected_days + |> Stream.map(&Date.from_iso8601!/1) + |> Stream.map(&Map.put(shift_data, :date, &1)) + |> Enum.map(&Repo.timestamp/1) + |> Shifts.create_multiple() + |> handle_create_multiple_result(socket) |> assign(:selected_days, []) |> assign_known_shifts() |> live_noreply() @@ -320,35 +313,25 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do |> live_noreply() end - defp shift_data_from_template(shift_template) do - shift_template - |> Map.from_struct() - |> Map.drop([:__meta__, :id, :inserted_at, :updated_at, :user, :is_fave_of_user]) - end + defp handle_create_multiple_result(result, socket) do + day_count = length(socket.assigns.selected_days) - defp shift_from_day_and_shift_data(day, shift_data) do - now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) - date_data = %{date: Date.from_iso8601!(day), inserted_at: now, updated_at: now} - Map.merge(shift_data, date_data) - end + {status, msg} = + case result do + {:error, errmsg} -> + {:error, "Ope, problem error inserting shifts, page the dev! Message: #{errmsg}"} - defp insert_shifts(to_insert, day_count) do - Multi.new() - |> Multi.insert_all(:insert_all, Shift, to_insert) - |> Repo.transaction() - |> case do - {:ok, %{insert_all: {n, _}}} -> - s = (n > 1 && "s") || "" + {n, _} -> + s = (n > 1 && "s") || "" - if n == day_count do - {:success, "Successfully assigned shift to #{n} day#{s}"} - else - {:warning, "Some error, only #{n} day#{s} inserted but #{day_count} were selected"} - end + if n == day_count do + {:success, "Successfully assigned shift to #{n} day#{s}"} + else + {:warning, "Some error, only #{n} day#{s} inserted but #{day_count} were selected"} + end + end - _ -> - {:error, "Ope, unknown error inserting shifts, page the dev"} - end + put_flash(socket, status, msg) end def shifts_to_show(day_shifts) do @@ -356,4 +339,11 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do do: Enum.take(day_shifts, 1), else: day_shifts end + + defp update_selected_days(selected_days, day) do + case Enum.member?(selected_days, day) do + false -> [day | selected_days] + true -> Enum.reject(selected_days, fn d -> d == day end) + end + end end diff --git a/lib/shift73k_web/live/shift_template_live/index.ex b/lib/shift73k_web/live/shift_template_live/index.ex index aafc8332..8cea1922 100644 --- a/lib/shift73k_web/live/shift_template_live/index.ex +++ b/lib/shift73k_web/live/shift_template_live/index.ex @@ -65,7 +65,7 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do defp assign_shift_templates(socket) do %User{id: uid} = socket.assigns.current_user - user_shifts = Templates.list_shift_templates_by_user_id(uid) + user_shifts = Templates.list_shift_templates_by_user(uid) assign(socket, :shift_templates, user_shifts) end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 916f876e..d99cbe5e 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -121,3 +121,27 @@ for user <- Accounts.list_users() do Repo.insert_all(ShiftTemplate, user_shifts) end + +##### +# insert shifts for each user? +alias Shift73k.Shifts +alias Shift73k.Shifts.Templates + +for user <- Accounts.list_users() do + # build a date range for the time from 120 days ago to 120 days from now + today = Date.utc_today() + date_range = Date.range(Date.add(today, -120), Date.add(today, 120)) + + # get 3 random shift templates for user + st_list = Templates.list_shift_templates_by_user(user.id) |> Enum.take_random(3) + + for st <- st_list do + days_to_schedule = Enum.take_random(date_range, 47) + shift_data = ShiftTemplate.attrs(st) + + days_to_schedule + |> Stream.map(&Map.put(shift_data, :date, &1)) + |> Enum.map(&Repo.timestamp/1) + |> Shifts.create_multiple() + end +end