module Tournaments class SyncAssignments def self.call(invitation:) new(invitation).sync_invitation! end def self.sync_match!(match) return unless match.tournament_id.present? match.tournament.broadcast_invitations.accepted.find_each do |invitation| new(invitation).sync_invitation! end end def initialize(invitation) @invitation = invitation end def sync_invitation! return unless @invitation.accepted_at.present? return unless @invitation.accepted_by_id.present? desired_ids = resolve_match_ids existing = @invitation.assignments.index_by(&:match_id) desired_ids.each do |match_id| next if existing[match_id] TournamentBroadcastAssignment.find_or_create_by!( tournament_id: @invitation.tournament_id, match_id: match_id, user_id: @invitation.accepted_by_id ) do |row| row.invitation = @invitation end end stale = existing.keys - desired_ids @invitation.assignments.where(match_id: stale).delete_all if stale.any? end private def resolve_match_ids matches = @invitation.tournament.matches case @invitation.scope_kind when "court_day" matches .where(court: @invitation.court) .where("scheduled_at >= ? AND scheduled_at < ?", @invitation.on_date.beginning_of_day, @invitation.on_date.end_of_day) .pluck(:id) else Array(@invitation.match_ids).map(&:to_s).intersection(matches.pluck(:id).map(&:to_s)) end end end end