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

sort fixing #1124

Merged
merged 6 commits into from
Sep 18, 2023
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
21 changes: 7 additions & 14 deletions app/controllers/admin/invoices_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# rubocop:disable Metrics/ClassLength
# rubocop:disable Metrics
# require 'invoice_already_paid'

module Admin
Expand All @@ -15,23 +15,16 @@ def show

# GET /admin/invoices
def index
sort_column = params[:sort].presence_in(%w[paid_through
paid_amount
vat_rate
cents
notes
status
number
due_date
billing_profile_id]) || 'id'
sort_direction = params[:direction].presence_in(%w[asc desc]) || 'desc'

invoices = Invoice.accessible_by(current_ability)
.includes(:paid_with_payment_order)
.search(params)
.order("#{sort_column} #{sort_direction}")

@pagy, @invoices = pagy(invoices, items: params[:per_page] ||= 15)
if invoices.is_a?(Array)
@pagy, @invoices = pagy_array(invoices, items: params[:per_page] ||= 15)
else
@pagy, @invoices = pagy(invoices, items: params[:per_page] ||= 15)
end

end

# GET /admin/invoices/aa450f1a-45e2-4f22-b2c3-f5f46b5f906b/download
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/auctions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ def show

def fetch_auctions_list
if should_sort_auctions?
Auction.active.ai_score_order.search(params).with_user_offers(current_user&.id)
Auction.active.ai_score_order.search(params, current_user).with_user_offers(current_user&.id)
else
Auction.active.search(params).with_user_offers(current_user&.id)
Auction.active.search(params, current_user).with_user_offers(current_user&.id)
end
end

Expand Down
1 change: 0 additions & 1 deletion app/controllers/histories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ class HistoriesController < ApplicationController

def index
auctions = Auction.where('ends_at <= ?', Time.zone.now)
.order(ends_at: :desc, domain_name: :asc)
.search(params)

@pagy, @auctions = pagy(auctions, items: params[:per_page] ||= 20,
Expand Down
84 changes: 3 additions & 81 deletions app/models/auction.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# rubocop:disable Metrics
class Auction < ApplicationRecord
include Presentable
include Searchable
include PgSearch::Model

BLIND = '0'.freeze
ENGLISH = '1'.freeze

after_create :find_auction_turns
validates :domain_name, presence: true
Expand All @@ -25,61 +28,6 @@ class Auction < ApplicationRecord
after_update_commit :update_list_broadcast, unless: :skip_broadcast
after_update_commit :update_offer_broadcast, unless: :skip_broadcast

scope :active, -> { where('starts_at <= ? AND ends_at >= ?', Time.now.utc, Time.now.utc) }
scope :without_result, lambda {
where('ends_at < ? and id NOT IN (SELECT results.auction_id FROM results)', Time.now.utc)
}

scope :for_period, lambda { |start_date, end_date|
where(ends_at: start_date.beginning_of_day..end_date.end_of_day)
}

scope :random_order, -> { order(Arel.sql('RANDOM()')) }
scope :ai_score_order, lambda {
order(Arel.sql('CASE WHEN ai_score > 0 THEN ai_score ELSE RANDOM() END DESC'))
}

scope :without_offers, -> { includes(:offers).where(offers: { auction_id: nil }) }
scope :with_offers, -> { includes(:offers).where.not(offers: { auction_id: nil }) }
scope :with_domain_name, (lambda do |domain_name|
return unless domain_name.present?

where('domain_name like ?', "%#{domain_name}%")
end)

scope :with_type, (lambda do |type|
if type.present?
return where(platform: [type, nil]) if type == BLIND

where(platform: type)
end
end)

scope :with_starts_at, (lambda do |starts_at|
where('starts_at >= ?', starts_at.to_date.beginning_of_day) if starts_at.present?
end)

scope :with_ends_at, (lambda do |ends_at|
where('ends_at <= ?', ends_at.to_date.end_of_day) if ends_at.present?
end)
scope :with_starts_at_nil, ->(state) { where(starts_at: nil) if state.present? }

scope :english, -> { where(platform: :english) }
scope :not_english, -> { where.not(platform: :english) }

scope :with_offers, (lambda do |auction_offer_type, type|
return if auction_offer_type.blank? || type == BLIND || type.empty?

case auction_offer_type
when 'with_offers'
auction_id_list = self.select { |a| a.offers.present? }.pluck(:id)
when 'without_offers'
auction_id_list = self.select { |a| a.offers.empty? }.pluck(:id)
end

where(id: auction_id_list)
end)

delegate :count, to: :offers, prefix: true
delegate :size, to: :offers, prefix: true

Expand All @@ -101,32 +49,6 @@ def deposit=(value)
self.requirement_deposit_in_cents = deposit.cents
end

def self.search(params = {})
param_list = %w[domain_name starts_at ends_at platform users_price]
sort_column = params[:sort].presence_in(param_list) || 'domain_name'
sort_admin_column = params[:sort].presence_in(%w[domain name
starts_at
ends_at
highest_offer_cents
number_of_offers
turns_count
starting_price
min_bids_step
slipping_end
platform]) || 'id'
sort_direction = params[:direction].presence_in(%w[asc desc]) || 'desc'
is_from_admin = params[:admin] == 'true'

with_highest_offers
.with_domain_name(params[:domain_name])
.with_type(params[:type])
.with_starts_at(params[:starts_at])
.with_ends_at(params[:ends_at])
.with_starts_at_nil(params[:starts_at_nil])
.with_offers(params[:auction_offer_type], params[:type])
.order("#{is_from_admin ? sort_admin_column : sort_column} #{sort_direction} NULLS LAST")
end

def deposit_and_enable_deposit_should_be_togeter
return unless english?
return if (requirement_deposit_in_cents.nil? || requirement_deposit_in_cents.zero?) && !enable_deposit
Expand Down
143 changes: 143 additions & 0 deletions app/models/auction/searchable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# rubocop:disable Metrics
module Auction::Searchable
extend ActiveSupport::Concern

included do
scope :active, -> { where('starts_at <= ? AND ends_at >= ?', Time.now.utc, Time.now.utc) }
scope :without_result, lambda {
where('ends_at < ? and id NOT IN (SELECT results.auction_id FROM results)', Time.now.utc)
}

scope :for_period, lambda { |start_date, end_date|
where(ends_at: start_date.beginning_of_day..end_date.end_of_day)
}

scope :random_order, -> { order(Arel.sql('RANDOM()')) }
scope :ai_score_order, lambda {
order(Arel.sql('CASE WHEN ai_score > 0 THEN ai_score ELSE RANDOM() END DESC'))
}

scope :without_offers, -> { includes(:offers).where(offers: { auction_id: nil }) }
scope :with_offers, -> { includes(:offers).where.not(offers: { auction_id: nil }) }
scope :with_domain_name, (lambda do |domain_name|
return unless domain_name.present?

where('domain_name like ?', "%#{domain_name}%")
end)

scope :with_type, (lambda do |type|
if type.present?
return where(platform: [type, nil]) if type == BLIND

where(platform: type)
end
end)

scope :with_starts_at, (lambda do |starts_at|
where('starts_at >= ?', starts_at.to_date.beginning_of_day) if starts_at.present?
end)

scope :with_ends_at, (lambda do |ends_at|
where('ends_at <= ?', ends_at.to_date.end_of_day) if ends_at.present?
end)
scope :with_starts_at_nil, ->(state) { where(starts_at: nil) if state.present? }

scope :english, -> { where(platform: :english) }
scope :not_english, -> { where.not(platform: :english) }

scope :with_offers, (lambda do |auction_offer_type, type|
return if auction_offer_type.blank? || type == BLIND || type.empty?

case auction_offer_type
when 'with_offers'
auction_id_list = self.select { |a| a.offers.present? }.pluck(:id)
when 'without_offers'
auction_id_list = self.select { |a| a.offers.empty? }.pluck(:id)
end

where(id: auction_id_list)
end)
end

class_methods do
def search(params = {}, current_user = nil)
param_list = %w[domain_name starts_at ends_at platform users_price]
sort_column = params[:sort].presence_in(param_list) || 'domain_name'
sort_admin_column = params[:sort].presence_in(%w[domain_name
starts_at
ends_at
highest_offer_cents
number_of_offers
turns_count
starting_price
min_bids_step
slipping_end
platform
requirement_deposit_in_cents
enable_deposit]) || 'id'
sort_direction = params[:direction].presence_in(%w[asc desc]) || 'desc'
is_from_admin = params[:admin] == 'true'

query =
with_highest_offers
.with_domain_name(params[:domain_name])
.with_type(params[:type])
.with_starts_at(params[:starts_at])
.with_ends_at(params[:ends_at])
.with_starts_at_nil(params[:starts_at_nil])
.with_offers(params[:auction_offer_type], params[:type])

if params[:sort] == 'users_price'
query.with_max_offer_cents_for_english_auction(current_user).order("offers_subquery.max_offer_cents #{sort_direction} NULLS LAST")
elsif params[:sort] == 'username'
query.sorted_by_winning_offer_username.order("offers_subquery.username #{sort_direction} NULLS LAST")
else
query.order("#{is_from_admin ? sort_admin_column : sort_column} #{sort_direction} NULLS LAST")
end
end

def with_max_offer_cents_for_english_auction(user = nil)
if user
joins(<<-SQL
LEFT JOIN (
SELECT auction_id, MAX(cents) AS max_offer_cents
FROM offers
WHERE auction_id IN (
SELECT id FROM auctions WHERE platform = 1
UNION
SELECT auction_id FROM offers WHERE user_id = #{user.id} AND auction_id IN (SELECT id FROM auctions WHERE platform IS NULL OR platform = 0)
)
GROUP BY auction_id
) AS offers_subquery ON auctions.id = offers_subquery.auction_id
SQL
)
else
joins(<<-SQL
LEFT JOIN (
SELECT auction_id, MAX(cents) AS max_offer_cents
FROM offers
WHERE auction_id IN (SELECT id FROM auctions WHERE platform = 1)
GROUP BY auction_id
) AS offers_subquery ON auctions.id = offers_subquery.auction_id
SQL
)
end
end

def sorted_by_winning_offer_username
joins(<<-SQL
LEFT JOIN (
SELECT offers.auction_id, offers.username
FROM offers
WHERE offers.cents = (
SELECT MAX(offers_inner.cents)
FROM offers AS offers_inner
WHERE offers_inner.auction_id = offers.auction_id
)
GROUP BY offers.auction_id, offers.username
) AS offers_subquery ON auctions.id = offers_subquery.auction_id
SQL
)
end
end
end
Loading
Loading