Skip to content

Commit

Permalink
##
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergei Tsoganov authored and Sergei Tsoganov committed Sep 22, 2023
1 parent 3c6fa98 commit 747245a
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 106 deletions.
16 changes: 14 additions & 2 deletions app/jobs/active_auctions_ai_sorting_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(',')
Expand Down
58 changes: 2 additions & 56 deletions app/models/auction.rb
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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) }
Expand Down Expand Up @@ -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
125 changes: 125 additions & 0 deletions app/models/concerns/auction/sql_queriable.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion app/views/auctions/_auction.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<% if auction.platform == 'blind' || auction.platform.nil? %>
<span class="auctions-table-mobile-infotainment"><%= t('auctions.your_current_price') %>: </span><%= number_with_precision(auction.users_price, precision: 2, separator: ",") %>
<% else %>
<span class="auctions-table-mobile-infotainment"><%= t('auctions.your_current_price') %>:</span>
<span class="auctions-table-mobile-infotainment"><%= t('auctions.current_price') %>:</span>
<span class="initial-color current_<%= auction.currently_winning_offer&.user_id %>_user"><%= number_with_precision(english_auction_presenter.maximum_bids, precision: 2, separator: ",") %></span>
<% end %>
</td>
Expand Down

0 comments on commit 747245a

Please sign in to comment.