Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use scopes in lottery division #1352

Merged
merged 3 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/models/lotteries/division_ranking.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Lotteries::DivisionRanking < ApplicationRecord
waitlisted: 1,
drawn_beyond_waitlist: 2,
not_drawn: 3,
withdrawn: 4,
}

end
10 changes: 3 additions & 7 deletions app/models/lottery_division.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion app/views/lotteries/_results.csv.ruby
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions app/views/lotteries/_results.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<p>No entrants have been drawn yet</p>
<% end %>

<% if division.wait_list_entrants.present? %>
<% if division.waitlisted_entrants.present? %>
<h5>Wait List</h5>
<ol>
<%= render partial: "entrant_for_results", collection: division.wait_list_entrants, as: :entrant %>
<%= render partial: "entrant_for_results", collection: division.waitlisted_entrants, as: :entrant %>
</ol>
<% end %>

Expand Down
4 changes: 2 additions & 2 deletions app/views/lotteries/manage_entrants.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<h5>Accepted</h5>
<%= render partial: "manage_entrants_table", locals: { entrants: division.accepted_entrants } %>

<% if division.wait_list_entrants.present? %>
<% if division.waitlisted_entrants.present? %>
<h5>Wait List</h5>
<%= 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? %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/lottery_divisions/_tickets_progress_bars.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
<h6 class="fw-bold">Wait List</h6>
</div>
<div class="col-4">
<h6 class="text-end"><%= "(#{division.wait_list_entrants.count}/#{division.maximum_wait_list})" %></h6>
<h6 class="text-end"><%= "(#{division.waitlisted_entrants.count}/#{division.maximum_wait_list})" %></h6>
</div>
</div>
<div class="progress">
<%= 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") %>
</div>
<% if show_pre_selected %>
<div class="row mt-2">
Expand Down
Original file line number Diff line number Diff line change
@@ -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
10 changes: 8 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions db/views/lotteries_division_rankings_v02.sql
Original file line number Diff line number Diff line change
@@ -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
;
Binary file modified erd.pdf
Binary file not shown.
13 changes: 11 additions & 2 deletions spec/models/lottery_division_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down Expand Up @@ -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
Expand Down
Loading