diff --git a/app/jobs/active_auctions_ai_sorting_job.rb b/app/jobs/active_auctions_ai_sorting_job.rb
index fa92134bc..ac2c859c2 100644
--- a/app/jobs/active_auctions_ai_sorting_job.rb
+++ b/app/jobs/active_auctions_ai_sorting_job.rb
@@ -4,7 +4,7 @@ class ActiveAuctionsAiSortingJob < ApplicationJob
def perform
return unless self.class.needs_to_run?
- auctions_list = Auction.active
+ auctions_list = Auction.active_with_offers_count
ai_response = fetch_ai_response(auctions_list)
process_ai_response(ai_response)
rescue OpenAI::Error => e
@@ -51,12 +51,24 @@ def chat_parameters(auctions_list)
model: model,
messages: [
{ role: 'system', content: system_message },
- { role: 'user', content: auctions_list.pluck(:id, :domain_name).to_s },
+ { role: 'user', content: format(auctions_list) },
{ role: 'user', content: 'Response in JSON format: [{id:, domain_name:, ai_score:}]' }
]
}
end
+ def format(auctions_list)
+ auctions_list.map do |a|
+ sliced = a.attributes.slice('id', 'domain_name')
+ if a.platform != 'english'
+ sliced.merge!({ last_offer: 0, offers_count: 0 })
+ else
+ sliced.merge!({ last_offer: a.cents, offers_count: a.offers_count })
+ end
+ sliced
+ end.to_json
+ end
+
def update_auctions_with_ai_scores(ai_scores)
update_values = ai_scores.map { |score| "WHEN #{score[:id]} THEN #{score[:ai_score]}" }.join(' ')
update_ids = ai_scores.pluck(:id).join(',')
diff --git a/app/models/auction.rb b/app/models/auction.rb
index b9cbd08fc..fc20babdc 100644
--- a/app/models/auction.rb
+++ b/app/models/auction.rb
@@ -1,6 +1,6 @@
-# rubocop:disable Metrics
-class Auction < ApplicationRecord
+class Auction < ApplicationRecord # rubocop:disable Metrics
include Presentable
+ include SqlQueriable
include Searchable
include PgSearch::Model
@@ -227,58 +227,4 @@ def users_price
def maximum_bids
Money.new(offers.maximum(:cents), Setting.find_by(code: 'auction_currency').retrieve)
end
-
- def self.with_user_offers(user_id)
- Auction.from(with_user_offers_query(user_id))
- end
-
- def self.with_user_offers_query(user_id)
- sql = <<~SQL
- (WITH offers_subquery AS (
- SELECT *
- FROM offers
- WHERE user_id = ?
- )
- SELECT DISTINCT
- auctions.*,
- offers_subquery.cents AS users_offer_cents,
- offers_subquery.id AS users_offer_id,
- offers_subquery.uuid AS users_offer_uuid
- FROM auctions
- LEFT JOIN offers_subquery on auctions.id = offers_subquery.auction_id) AS auctions
- SQL
-
- ActiveRecord::Base.sanitize_sql([sql, user_id])
- end
-
- def self.with_highest_offers
- Auction.from(with_highest_offers_query)
- end
-
- def self.with_highest_offers_query
- sql = <<~SQL
- (WITH offers_subquery AS (
- SELECT DISTINCT on (uuid) offers.*
- FROM (SELECT auction_id,
- max(cents) over (PARTITION BY auction_id) as max_price,
- min(created_at) over (PARTITION BY auction_id, cents) as min_time
- FROM offers
- ) AS highest_offers
- INNER JOIN offers
- ON
- offers.cents = highest_offers.max_price AND
- offers.created_at = highest_offers.min_time AND
- offers.auction_id = highest_offers.auction_id)
- SELECT DISTINCT
- auctions.*,
- offers_subquery.cents AS highest_offer_cents,
- offers_subquery.id AS highest_offer_id,
- offers_subquery.uuid AS highest_offer_uuid,
- (SELECT COUNT(*) FROM offers where offers.auction_id = auctions.id) AS number_of_offers
- FROM auctions
- LEFT JOIN offers_subquery on auctions.id = offers_subquery.auction_id) AS auctions
- SQL
-
- sql
- end
end
diff --git a/app/models/auction/searchable.rb b/app/models/concerns/auction/searchable.rb
similarity index 72%
rename from app/models/auction/searchable.rb
rename to app/models/concerns/auction/searchable.rb
index b3b0a278f..4d1f8262a 100644
--- a/app/models/auction/searchable.rb
+++ b/app/models/concerns/auction/searchable.rb
@@ -1,9 +1,10 @@
-# rubocop:disable Metrics
+# frozen_string_literal: true
+
module Auction::Searchable
extend ActiveSupport::Concern
- BLIND = '0'.freeze
- ENGLISH = '1'.freeze
+ BLIND = '0'
+ ENGLISH = '1'
included do
scope :active, -> { where('starts_at <= ? AND ends_at >= ?', Time.now.utc, Time.now.utc) }
@@ -99,49 +100,5 @@ def search(params = {}, current_user = nil)
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
diff --git a/app/models/concerns/auction/sql_queriable.rb b/app/models/concerns/auction/sql_queriable.rb
new file mode 100644
index 000000000..63c049eb3
--- /dev/null
+++ b/app/models/concerns/auction/sql_queriable.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: true
+
+module Auction::SqlQueriable # rubocop:disable Metrics/ModuleLength
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def with_user_offers(user_id)
+ Auction.from(with_user_offers_query(user_id))
+ end
+
+ def with_user_offers_query(user_id)
+ sql = <<~SQL
+ (WITH offers_subquery AS (
+ SELECT *
+ FROM offers
+ WHERE user_id = ?
+ )
+ SELECT DISTINCT
+ auctions.*,
+ offers_subquery.cents AS users_offer_cents,
+ offers_subquery.id AS users_offer_id,
+ offers_subquery.uuid AS users_offer_uuid
+ FROM auctions
+ LEFT JOIN offers_subquery on auctions.id = offers_subquery.auction_id) AS auctions
+ SQL
+
+ ActiveRecord::Base.sanitize_sql([sql, user_id])
+ end
+
+ def with_highest_offers
+ Auction.from(with_highest_offers_query)
+ end
+
+ def with_highest_offers_query
+ <<~SQL
+ (WITH offers_subquery AS (
+ SELECT DISTINCT on (uuid) offers.*
+ FROM (SELECT auction_id,
+ max(cents) over (PARTITION BY auction_id) as max_price,
+ min(created_at) over (PARTITION BY auction_id, cents) as min_time
+ FROM offers
+ ) AS highest_offers
+ INNER JOIN offers
+ ON
+ offers.cents = highest_offers.max_price AND
+ offers.created_at = highest_offers.min_time AND
+ offers.auction_id = highest_offers.auction_id)
+ SELECT DISTINCT
+ auctions.*,
+ offers_subquery.cents AS highest_offer_cents,
+ offers_subquery.id AS highest_offer_id,
+ offers_subquery.uuid AS highest_offer_uuid,
+ (SELECT COUNT(*) FROM offers where offers.auction_id = auctions.id) AS number_of_offers
+ FROM auctions
+ LEFT JOIN offers_subquery on auctions.id = offers_subquery.auction_id) AS auctions
+ SQL
+ end
+
+ def active_with_offers_count
+ Auction.active.from(with_offers_count_query)
+ end
+
+ def with_offers_count_query
+ <<~SQL
+ (SELECT
+ auctions.*,
+ offers.cents,
+ recent_offers.offers_count
+ FROM auctions
+ LEFT JOIN (
+ SELECT auction_id,
+ MAX(updated_at) as last_updated_at,
+ COUNT(*) as offers_count
+ FROM offers
+ GROUP BY auction_id
+ ) AS recent_offers ON auctions.id = recent_offers.auction_id
+ LEFT JOIN offers ON auctions.id = offers.auction_id AND offers.updated_at = recent_offers.last_updated_at) AS auctions
+ SQL
+ 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
diff --git a/app/views/auctions/_auction.html.erb b/app/views/auctions/_auction.html.erb
index da47b39a7..de914cc42 100644
--- a/app/views/auctions/_auction.html.erb
+++ b/app/views/auctions/_auction.html.erb
@@ -17,7 +17,7 @@
<% if auction.platform == 'blind' || auction.platform.nil? %>
<%= t('auctions.your_current_price') %>: <%= number_with_precision(auction.users_price, precision: 2, separator: ",") %>
<% else %>
- <%= t('auctions.your_current_price') %>:
+ <%= t('auctions.current_price') %>:
<%= number_with_precision(english_auction_presenter.maximum_bids, precision: 2, separator: ",") %>
<% end %>