diff --git a/app/models/lotteries/division_ranking.rb b/app/models/lotteries/division_ranking.rb index 3c8e6dd63..bee45807f 100644 --- a/app/models/lotteries/division_ranking.rb +++ b/app/models/lotteries/division_ranking.rb @@ -12,6 +12,7 @@ class Lotteries::DivisionRanking < ApplicationRecord waitlisted: 1, drawn_beyond_waitlist: 2, not_drawn: 3, + withdrawn: 4, } end diff --git a/app/models/lottery_division.rb b/app/models/lottery_division.rb index 362c4e274..f0a4a998c 100644 --- a/app/models/lottery_division.rb +++ b/app/models/lottery_division.rb @@ -24,7 +24,7 @@ class LotteryDivision < ApplicationRecord delegate :organization, to: :lottery def accepted_entrants - ordered_drawn_entrants.limit(maximum_entries) + entrants.accepted.ordered end def all_entrants_drawn? @@ -52,8 +52,8 @@ def maximum_slots maximum_entries + maximum_wait_list end - def wait_list_entrants - ordered_drawn_entrants.offset(maximum_entries).limit(maximum_wait_list) + def waitlisted_entrants + entrants.waitlisted.ordered end def withdrawn_entrants @@ -66,8 +66,4 @@ def broadcast_lottery_draw_header broadcast_replace_to self, :lottery_draw_header, target: "draw_tickets_header_lottery_division_#{id}", partial: "lottery_divisions/draw_tickets_header", locals: { division: self } broadcast_replace_to self, :lottery_header, target: "lottery_header_lottery_division_#{id}", partial: "lottery_divisions/tickets_progress_bars", locals: { division: self, show_pre_selected: false } end - - def ordered_drawn_entrants - entrants.drawn.not_withdrawn.ordered - end end diff --git a/app/views/lotteries/_results.csv.ruby b/app/views/lotteries/_results.csv.ruby index 773b74f86..c0901dca0 100644 --- a/app/views/lotteries/_results.csv.ruby +++ b/app/views/lotteries/_results.csv.ruby @@ -24,7 +24,7 @@ if lottery.entrants.exists? end csv << ["Wait List"] - division.wait_list_entrants.each.with_index(1) do |entrant, i| + division.waitlisted_entrants.each.with_index(1) do |entrant, i| csv << [ i, entrant.first_name, diff --git a/app/views/lotteries/_results.html.erb b/app/views/lotteries/_results.html.erb index 8b9624735..55a73c6a8 100644 --- a/app/views/lotteries/_results.html.erb +++ b/app/views/lotteries/_results.html.erb @@ -15,10 +15,10 @@

No entrants have been drawn yet

<% end %> - <% if division.wait_list_entrants.present? %> + <% if division.waitlisted_entrants.present? %>
Wait List
    - <%= render partial: "entrant_for_results", collection: division.wait_list_entrants, as: :entrant %> + <%= render partial: "entrant_for_results", collection: division.waitlisted_entrants, as: :entrant %>
<% end %> diff --git a/app/views/lotteries/manage_entrants.html.erb b/app/views/lotteries/manage_entrants.html.erb index db5f7a4b5..281b7921b 100644 --- a/app/views/lotteries/manage_entrants.html.erb +++ b/app/views/lotteries/manage_entrants.html.erb @@ -13,9 +13,9 @@
Accepted
<%= render partial: "manage_entrants_table", locals: { entrants: division.accepted_entrants } %> - <% if division.wait_list_entrants.present? %> + <% if division.waitlisted_entrants.present? %>
Wait List
- <%= render partial: "manage_entrants_table", locals: { entrants: division.wait_list_entrants } %> + <%= render partial: "manage_entrants_table", locals: { entrants: division.waitlisted_entrants } %> <% end %> <% if division.withdrawn_entrants.present? %> diff --git a/app/views/lottery_divisions/_tickets_progress_bars.html.erb b/app/views/lottery_divisions/_tickets_progress_bars.html.erb index 5484cac28..13cc69c23 100644 --- a/app/views/lottery_divisions/_tickets_progress_bars.html.erb +++ b/app/views/lottery_divisions/_tickets_progress_bars.html.erb @@ -18,11 +18,11 @@
Wait List
-
<%= "(#{division.wait_list_entrants.count}/#{division.maximum_wait_list})" %>
+
<%= "(#{division.waitlisted_entrants.count}/#{division.maximum_wait_list})" %>
- <%= bootstrap_progress_bar(min_value: 0, max_value: division.maximum_wait_list, current_value: division.wait_list_entrants.count, color: "warning") %> + <%= bootstrap_progress_bar(min_value: 0, max_value: division.maximum_wait_list, current_value: division.waitlisted_entrants.count, color: "warning") %>
<% if show_pre_selected %>
diff --git a/db/migrate/20241220002632_update_lotteries_division_rankings_to_version_2.rb b/db/migrate/20241220002632_update_lotteries_division_rankings_to_version_2.rb new file mode 100644 index 000000000..453fd63bc --- /dev/null +++ b/db/migrate/20241220002632_update_lotteries_division_rankings_to_version_2.rb @@ -0,0 +1,5 @@ +class UpdateLotteriesDivisionRankingsToVersion2 < ActiveRecord::Migration[7.0] + def change + update_view :lotteries_division_rankings, version: 2, revert_to_version: 1 + end +end diff --git a/db/schema.rb b/db/schema.rb index 514175762..7e951d623 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_12_19_195819) do +ActiveRecord::Schema[7.0].define(version: 2024_12_20_002632) do # These are extensions that must be enabled in order to support this database enable_extension "fuzzystrmatch" enable_extension "pg_trgm" @@ -1041,12 +1041,18 @@ FROM ((lottery_tickets JOIN lottery_draws ON ((lottery_draws.lottery_ticket_id = lottery_tickets.id))) JOIN lottery_entrants lottery_entrants_1 ON ((lottery_entrants_1.id = lottery_tickets.lottery_entrant_id))) - WINDOW division_window AS (PARTITION BY lottery_entrants_1.lottery_division_id ORDER BY lottery_draws.created_at) + WINDOW division_window AS (PARTITION BY lottery_entrants_1.lottery_division_id ORDER BY + CASE + WHEN ((lottery_entrants_1.withdrawn IS FALSE) OR (lottery_entrants_1.withdrawn IS NULL)) THEN 0 + WHEN (lottery_entrants_1.withdrawn IS TRUE) THEN 1 + ELSE NULL::integer + END, lottery_draws.created_at) ) SELECT lottery_entrants.id AS lottery_entrant_id, lottery_divisions.name AS division_name, ranked_draws.division_rank, CASE + WHEN lottery_entrants.withdrawn THEN 4 WHEN (ranked_draws.division_rank <= lottery_divisions.maximum_entries) THEN 0 WHEN (ranked_draws.division_rank <= (lottery_divisions.maximum_entries + lottery_divisions.maximum_wait_list)) THEN 1 WHEN (ranked_draws.division_rank IS NOT NULL) THEN 2 diff --git a/db/views/lotteries_division_rankings_v02.sql b/db/views/lotteries_division_rankings_v02.sql new file mode 100644 index 000000000..203d5d89e --- /dev/null +++ b/db/views/lotteries_division_rankings_v02.sql @@ -0,0 +1,33 @@ +with ranked_draws as ( + select lottery_tickets.lottery_entrant_id, + rank() over division_window as division_rank + from lottery_tickets + join lottery_draws on lottery_draws.lottery_ticket_id = lottery_tickets.id + join lottery_entrants on lottery_entrants.id = lottery_tickets.lottery_entrant_id + window division_window as ( + partition by lottery_entrants.lottery_division_id + order by case + when withdrawn is false or withdrawn is null then 0 + when withdrawn is true then 1 end, + lottery_draws.created_at + ) + ) + +select lottery_entrants.id as lottery_entrant_id, + lottery_divisions.name as division_name, + division_rank, +-- accepted: 0 +-- waitlisted: 1 +-- drawn_beyond_waitlist: 2 +-- not_drawn: 3 +-- withdrawn: 4 + case + when lottery_entrants.withdrawn then 4 + when division_rank <= maximum_entries then 0 + when division_rank <= maximum_entries + maximum_wait_list then 1 + when division_rank is not null then 2 + else 3 end as draw_status +from lottery_entrants + left join ranked_draws on ranked_draws.lottery_entrant_id = lottery_entrants.id + join lottery_divisions on lottery_entrants.lottery_division_id = lottery_divisions.id +; diff --git a/erd.pdf b/erd.pdf index 0d1456085..bc193aed0 100644 Binary files a/erd.pdf and b/erd.pdf differ diff --git a/spec/models/lottery_division_spec.rb b/spec/models/lottery_division_spec.rb index 4f41539dc..582fa00a0 100644 --- a/spec/models/lottery_division_spec.rb +++ b/spec/models/lottery_division_spec.rb @@ -108,8 +108,8 @@ end end - describe "#wait_list_entrants" do - let(:result) { subject.wait_list_entrants } + describe "#waitlisted_entrants" do + let(:result) { subject.waitlisted_entrants } context "when draws have spilled over into the wait list" do let(:division_name) { "Never Ever Evers" } @@ -143,6 +143,15 @@ expect(result.count).to eq(subject.maximum_entries) expect(result).to all be_a(LotteryEntrant) end + + context "when one of the entrants has withdrawn" do + let(:withdrawn_entrant) { subject.entrants.accepted.first } + before { withdrawn_entrant.update(withdrawn: true) } + + it "does not include the withdrawn entrant" do + expect(result).not_to include(withdrawn_entrant) + end + end end context "when some accepted entrants have been drawn" do