auction_fun_core 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/auction_fun_core.gemspec +1 -0
  4. data/db/migrate/20240229143000_create_auctions.rb +1 -0
  5. data/db/seeds.rb +87 -36
  6. data/i18n/en-US/contracts/contracts.en-US.yml +9 -0
  7. data/i18n/en-US/mail/application.en-US.yml +59 -0
  8. data/i18n/en-US/mail/auction_context/post_auction/participant.en-US.yml +13 -0
  9. data/i18n/en-US/mail/auction_context/post_auction/winner.en-US.yml +13 -0
  10. data/i18n/pt-BR/contracts/contracts.pt-BR.yml +9 -0
  11. data/i18n/pt-BR/mail/application.pt-BR.yml +59 -0
  12. data/i18n/pt-BR/mail/auction_context/post_auction/participant.pt-BR.yml +13 -0
  13. data/i18n/pt-BR/mail/auction_context/post_auction/winner.pt-BR.yml +13 -0
  14. data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +0 -4
  15. data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +42 -0
  16. data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +41 -0
  17. data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +47 -0
  18. data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +48 -0
  19. data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +48 -0
  20. data/lib/auction_fun_core/entities/auction.rb +6 -0
  21. data/lib/auction_fun_core/operations/auction_context/create_operation.rb +12 -2
  22. data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +52 -0
  23. data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +51 -0
  24. data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +100 -0
  25. data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +100 -0
  26. data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +102 -0
  27. data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +23 -11
  28. data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +57 -7
  29. data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +10 -0
  30. data/lib/auction_fun_core/relations/auctions.rb +167 -26
  31. data/lib/auction_fun_core/relations/staffs.rb +1 -1
  32. data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +31 -0
  33. data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +31 -0
  34. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +173 -0
  35. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +174 -0
  36. data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +2 -2
  37. data/lib/auction_fun_core/version.rb +1 -1
  38. data/lib/auction_fun_core/workers/application_job.rb +2 -0
  39. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +33 -0
  40. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +33 -0
  41. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +34 -0
  42. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +37 -0
  43. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +34 -0
  44. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +51 -0
  45. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +51 -0
  46. data/system/providers/background_job.rb +19 -0
  47. metadata +43 -5
  48. data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +0 -27
  49. data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +0 -61
  50. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b42434481eccb486a4e38674f4219b1969e8951bd0a06430066a2ca9e9c9931d
4
- data.tar.gz: a243a07a6b63c1e9a10f17a616290b1eea8c825af4a5e1a47e7f4f3515e192c6
3
+ metadata.gz: 3dc7fade29c1849f1e1c8d9a67cd060e0ceeac555290cf9cc3588a27eab72ee0
4
+ data.tar.gz: 7995c3ca65daa279c8e989771f7989e06695fcbdef4d7472c4f5aee0c02048f1
5
5
  SHA512:
6
- metadata.gz: 6a3d12e06b32f527e2744f996b14716e32e6f496a5367452eeeae62425a34c7a90878c2f256e901a9a165b00325838f0bba29526580d02dc65d0240c4444d2f8
7
- data.tar.gz: 4dcaa1d26811cdab77368cc5eb5567b83a5cf647e9f123ecaed217e41e908e7f1ea6e56a5fcfccc6410f04e9ba91b054fe282c41a7c7b1b5806556006f76e703
6
+ metadata.gz: ddfa76b5f57846ed62986520b98c367f46490c6d74aebd55b45ff033f84ddfb31f95dc370afec5159b49e93bdf678b4d63437b58bcc47e63c6461b5963aa6d31
7
+ data.tar.gz: eddbd9f79955aed50f5ac48605a16454bb93329e3e87fb21eb8437c0af43291b0ec84f3b29099635fa7cb89cab0e4cd0cdc8cfec433b3e003d1b69a94ace1f4a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.8.7] - 2024-04-23
4
+
5
+ ### Added
6
+
7
+ - Removing default values from relations;
8
+ - Rebuild factories to not contain default values;
9
+ - Add automated tests for auction relations;
10
+
11
+ ## [0.8.6] - 2024-04-23
12
+
13
+ ### Added
14
+
15
+ - Auction finalization configured for each type of auction;
16
+ - Add operations for winner and participant of an auction;
17
+ - Configure background job to work with unique jobs;
18
+ - Add 'sidekiq-unique-jobs' to be responsible for finishing penny auctions;
19
+
20
+ ### Changed:
21
+
22
+ - General improvements on seed data;
23
+
24
+ ### Fixed:
25
+
26
+ - NameError: uninitialized constant AuctionFunCore::Workers::ApplicationJob::Sidekiq (NameError)
27
+
3
28
  ## [0.8.5] - 2024-04-03
4
29
 
5
30
  ### Added
@@ -49,6 +49,7 @@ Gem::Specification.new do |spec|
49
49
  spec.add_dependency "rom", "5.3.0"
50
50
  spec.add_dependency "rom-sql", "3.6.2"
51
51
  spec.add_dependency "sidekiq", "7.2.2"
52
+ spec.add_dependency "sidekiq-unique-jobs", "8.0.10"
52
53
  spec.add_dependency "yard", "0.9.36"
53
54
  spec.add_dependency "zeitwerk", "2.6.13"
54
55
 
@@ -5,6 +5,7 @@ ROM::SQL.migration do
5
5
  create_table(:auctions) do
6
6
  primary_key :id
7
7
  foreign_key :staff_id, :staffs, null: false
8
+ foreign_key :winner_id, :users
8
9
  column :title, String, null: false
9
10
  column :description, :text
10
11
  column :kind, :auction_kinds, null: false
data/db/seeds.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pry"
4
3
  require "faker"
4
+ require "pry"
5
5
 
6
6
  I18n.enforce_available_locales = false
7
7
  Faker::Config.locale = "pt-BR"
@@ -13,7 +13,6 @@ STOPWATCH_OPTIONS = [15, 30, 45, 60].freeze
13
13
  AuctionFunCore::Application.start(:core)
14
14
 
15
15
  # Instantiate repos
16
- auction_repository = AuctionFunCore::Repos::AuctionContext::AuctionRepository.new
17
16
  staff_repository = AuctionFunCore::Repos::StaffContext::StaffRepository.new
18
17
 
19
18
  # Create root staff. Create as a regular user using the normal flow and after that
@@ -44,6 +43,19 @@ AuctionFunCore::Operations::StaffContext::RegistrationOperation.call(common_staf
44
43
  result.success { |staff| @staff = staff }
45
44
  end
46
45
 
46
+ # Add some users
47
+ 100.times do
48
+ attributes = {
49
+ name: Faker::Name.name, email: Faker::Internet.unique.email,
50
+ phone: Faker::PhoneNumber.unique.cell_phone_in_e164, password: "password",
51
+ password_confirmation: "password"
52
+ }
53
+ AuctionFunCore::Operations::UserContext::RegistrationOperation.call(attributes) do |result|
54
+ result.failure { |failure| raise "Error to create user: #{failure}" }
55
+ result.success { |user| puts "Create user with: #{user.to_h}" }
56
+ end
57
+ end
58
+
47
59
  # Create some standard auctions
48
60
  (1..15).each do |i|
49
61
  attributes = {
@@ -53,7 +65,31 @@ end
53
65
  }
54
66
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
55
67
  result.failure { |failure| raise "Error to create standard auction: #{failure}" }
56
- result.success { |auction| puts "Create standard auction with: #{auction.to_h}" }
68
+ result.success do |auction|
69
+ @auction = auction
70
+ puts "Create standard auction with: #{auction.to_h}"
71
+ end
72
+ end
73
+
74
+ # Create auctions that have no bid. Multiples if 7
75
+ next if (i % 7).zero?
76
+
77
+ # Increase the value of each new bid by 10%
78
+ @current_bid = @auction.minimal_bid_cents
79
+ @minimal_percentage = 0.1
80
+ # Create some bids for standard auctions based on total users
81
+ (2..100).to_a.sample(rand(1..100)).each_with_index do |user_id, index|
82
+ @current_bid = index.zero? ? @current_bid : (@current_bid + (@current_bid * @minimal_percentage)).round(half: :up)
83
+ bid_params = {
84
+ auction_id: @auction.id,
85
+ user_id: user_id,
86
+ value_cents: @current_bid
87
+ }
88
+
89
+ AuctionFunCore::Operations::BidContext::CreateBidStandardOperation.call(bid_params) do |result|
90
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
91
+ result.success { |bid| puts "Create standard bid with: #{bid.to_h}" }
92
+ end
57
93
  end
58
94
  end
59
95
 
@@ -65,52 +101,67 @@ end
65
101
 
66
102
  attributes = {
67
103
  staff_id: @staff.id, title: Faker::Commerce.product_name, description: Faker::Lorem.paragraph_by_chars,
68
- kind: "penny", started_at: started_at, finished_at: finished_at, stopwatch: stopwatch
104
+ kind: "penny", started_at: started_at, finished_at: finished_at, stopwatch: stopwatch,
105
+ initial_bid_cents: (i * 100), minimal_bid_cents: (i * 100)
69
106
  }
70
107
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
71
108
  result.failure { |failure| raise "Error to create penny auction: #{failure}" }
72
- result.success { |auction| puts "Create penny auction with: #{auction.to_h}" }
109
+ result.success do |auction|
110
+ @auction = auction
111
+ puts "Create penny auction with: #{auction.to_h}"
112
+ end
113
+ end
114
+
115
+ # Create auctions that have no bid. Multiples if 7
116
+ next if (i % 7).zero?
117
+
118
+ # Create some bids for penny auctions based on total users
119
+ (2..100).to_a.sample(rand(1..100)).each do |user_id|
120
+ bid_params = {
121
+ auction_id: @auction.id,
122
+ user_id: user_id,
123
+ value_cents: @auction.minimal_bid_cents
124
+ }
125
+
126
+ AuctionFunCore::Operations::BidContext::CreateBidPennyOperation.call(bid_params) do |result|
127
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
128
+ result.success { |bid| puts "Create penny bid with: #{bid.to_h}" }
129
+ end
73
130
  end
74
131
  end
75
132
 
76
133
  # Create some closed auctions
77
- (1..3).each do |i|
134
+ (1..5).each do |i|
78
135
  attributes = {
79
- staff_id: @staff.id, title: Faker::Commerce.product_name, kind: "closed",
80
- started_at: i.hour.from_now, finished_at: i.day.from_now.end_of_day,
136
+ staff_id: @staff.id, title: Faker::Commerce.product_name, description: Faker::Lorem.paragraph_by_chars,
137
+ kind: "closed", started_at: i.hour.from_now, finished_at: i.day.from_now.end_of_day,
81
138
  initial_bid_cents: (i * 1000)
82
139
  }
83
140
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
84
141
  result.failure { |failure| raise "Error to create closed auction: #{failure}" }
85
- result.success { |auction| puts "Create closed auction with: #{auction.to_h}" }
142
+ result.success do |auction|
143
+ @auction = auction
144
+ puts "Create closed auction with: #{auction.to_h}"
145
+ end
86
146
  end
87
- end
88
-
89
- # Add some users
90
- 100.times do
91
- attributes = {
92
- name: Faker::Name.name, email: Faker::Internet.unique.email,
93
- phone: Faker::PhoneNumber.unique.cell_phone_in_e164, password: "password",
94
- password_confirmation: "password"
95
- }
96
- AuctionFunCore::Operations::UserContext::RegistrationOperation.call(attributes) do |result|
97
- result.failure { |failure| raise "Error to create user: #{failure}" }
98
- result.success { |user| puts "Create user with: #{user.to_h}" }
99
- end
100
- end
101
-
102
- # Create some bids
103
- auction_repository.all.each do |auction|
104
- next if auction.id.even?
105
-
106
- bid_params = {
107
- auction_id: auction.id,
108
- user_id: rand(2..100),
109
- value_cents: auction.minimal_bid_cents + (auction.minimal_bid_cents * 0.10)
110
- }
111
147
 
112
- "AuctionFunCore::Operations::BidContext::CreateBid#{auction.kind.capitalize}Operation".constantize.call(bid_params) do |result|
113
- result.failure { |failure| raise "Error to create bid: #{failure}" }
114
- result.success { |bid| puts "Create bid with: #{bid.to_h}" }
148
+ # Create auctions that have no bid. Pair numbers
149
+ next if i.even?
150
+
151
+ @minimal_bid = @auction.minimal_bid_cents
152
+ # Create some bids for closed auctions based on total users
153
+ (2..100).to_a.sample(rand(1..100)).each_with_index do |user_id, index|
154
+ # Choosing a random value for the bid, obeying the rule that it has to be just greater than the minimum bid.
155
+ random_bid = index.zero? ? @minimal_bid : rand((@minimal_bid + 1)..10_000).round
156
+ bid_params = {
157
+ auction_id: @auction.id,
158
+ user_id: user_id,
159
+ value_cents: random_bid
160
+ }
161
+
162
+ AuctionFunCore::Operations::BidContext::CreateBidClosedOperation.call(bid_params) do |result|
163
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
164
+ result.success { |bid| puts "Create closed bid with: #{bid.to_h}" }
165
+ end
115
166
  end
116
167
  end
@@ -70,3 +70,12 @@ en-US:
70
70
  auction_context:
71
71
  create:
72
72
  finished_at: "must be after started time"
73
+ post_auction:
74
+ participant:
75
+ none: "there was no participation from this user in the auction reported"
76
+ winner:
77
+ wrong: "was not the winner of this auction"
78
+ processor:
79
+ finish:
80
+ invalid_kind: "auction with invalid type"
81
+ invalid_status: "auction with invalid status"
@@ -0,0 +1,59 @@
1
+ en-US:
2
+ date:
3
+ abbr_day_names:
4
+ - Sun
5
+ - Mon
6
+ - Tue
7
+ - Wed
8
+ - Thu
9
+ - Fri
10
+ - Sat
11
+ abbr_month_names:
12
+ -
13
+ - Jan
14
+ - Feb
15
+ - Mar
16
+ - Apr
17
+ - May
18
+ - Jun
19
+ - Jul
20
+ - Aug
21
+ - Sep
22
+ - Oct
23
+ - Nov
24
+ - Dec
25
+ day_names:
26
+ - Sunday
27
+ - Monday
28
+ - Tuesday
29
+ - Wednesday
30
+ - Thursday
31
+ - Friday
32
+ - Saturday
33
+ formats:
34
+ default: "%Y-%m-%d"
35
+ long: "%B %d, %Y"
36
+ short: "%b %d"
37
+ month_names:
38
+ -
39
+ - January
40
+ - February
41
+ - March
42
+ - April
43
+ - May
44
+ - June
45
+ - July
46
+ - August
47
+ - September
48
+ - October
49
+ - November
50
+ - December
51
+ order:
52
+ - :year
53
+ - :month
54
+ - :day
55
+ application:
56
+ general:
57
+ hello: "Hi %{name}"
58
+ app_name: "AuctionFun"
59
+ team: "Team AuctionFun"
@@ -0,0 +1,13 @@
1
+ en-US:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ participant_mailer:
6
+ subject: "Thank you for participating in the auction %{title}"
7
+ body:
8
+ description: "Thank you for participating in the auction <b>%{title}</b>! Although you weren't the winner this time, we would like to recognize your efforts and share some statistics on your performance:"
9
+ stats:
10
+ auction_total_bids: "Total auction bids: %{auction_total_bids}"
11
+ winner_bid: "Winner bid: %{winner_bid}"
12
+ auction_date: "Auction Date"
13
+ regards: "We hope you found the experience enriching and invite you to participate in our future auctions. Follow our website and social media to stay up to date with upcoming opportunities."
@@ -0,0 +1,13 @@
1
+ en-US:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ winner_mailer:
6
+ subject: "Congratulations! You are the winner of the auction %{title}!"
7
+ body:
8
+ description: "We are very happy to inform you that you were the winner of our auction <b>%{title}</b>! Your bid was the highest, and you are now the new owner of item. Below is some information and statistics about the auction:"
9
+ item:
10
+ title: "Auctioned item: <b>%{title}</b>"
11
+ winner_bid: "Your Winning Bid: %{winner_bid}"
12
+ auction_total_bids: "Total Number of Bids: %{auction_total_bids}"
13
+ auction_date: "Auction Date"
@@ -70,3 +70,12 @@ pt-BR:
70
70
  auction_context:
71
71
  create:
72
72
  finished_at: "deve ser depois da hora de início"
73
+ post_auction:
74
+ participant:
75
+ none: "não houve nenhuma participação deste usuário no leilão informado"
76
+ winner:
77
+ wrong: "não foi o vencedor deste leilão"
78
+ processor:
79
+ finish:
80
+ invalid_kind: "leilão com tipo inválido"
81
+ invalid_status: "leilão com status inválido"
@@ -0,0 +1,59 @@
1
+ pt-BR:
2
+ date:
3
+ abbr_day_names:
4
+ - Dom
5
+ - Seg
6
+ - Ter
7
+ - Qua
8
+ - Qui
9
+ - Sex
10
+ - Sáb
11
+ abbr_month_names:
12
+ -
13
+ - Jan
14
+ - Fev
15
+ - Mar
16
+ - Abr
17
+ - Mai
18
+ - Jun
19
+ - Jul
20
+ - Ago
21
+ - Set
22
+ - Out
23
+ - Nov
24
+ - Dez
25
+ day_names:
26
+ - Domingo
27
+ - Segunda-feira
28
+ - Terça-feira
29
+ - Quarta-feira
30
+ - Quinta-feira
31
+ - Sexta-feira
32
+ - Sábado
33
+ formats:
34
+ default: "%d/%m/%Y"
35
+ long: "%d de %B de %Y"
36
+ short: "%d de %B"
37
+ month_names:
38
+ -
39
+ - Janeiro
40
+ - Fevereiro
41
+ - Março
42
+ - Abril
43
+ - Maio
44
+ - Junho
45
+ - Julho
46
+ - Agosto
47
+ - Setembro
48
+ - Outubro
49
+ - Novembro
50
+ - Dezembro
51
+ order:
52
+ - :day
53
+ - :month
54
+ - :year
55
+ application:
56
+ general:
57
+ hello: "Olá %{name}"
58
+ app_name: "AuctionFun"
59
+ team: "Time AuctionFun"
@@ -0,0 +1,13 @@
1
+ pt-BR:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ participant_mailer:
6
+ subject: "Sua participação no leilão %{title}"
7
+ body:
8
+ description: "Agradecemos por participar do leilão <b>%{title}</b>! Embora você não tenha sido o vencedor desta vez, gostaríamos de reconhecer o seu empenho e compartilhar algumas estatísticas do seu desempenho:"
9
+ stats:
10
+ auction_total_bids: "Total de lances do leilão: %{auction_total_bids}"
11
+ winner_bid: "Lance vencedor: %{winner_bid}"
12
+ auction_date: "Data do Leilão"
13
+ regards: "Esperamos que você tenha encontrado a experiência enriquecedora e convidamos você a participar de nossos futuros leilões. Acompanhe nosso site e redes sociais para ficar por dentro das próximas oportunidades."
@@ -0,0 +1,13 @@
1
+ pt-BR:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ winner_mailer:
6
+ subject: "Parabéns! Você é o vencedor do leilão %{title}!"
7
+ body:
8
+ description: "Estamos muito felizes em informar que você foi o vencedor do leilão <b>%{title}</b>! Seu lance foi o maior, e agora você é o novo proprietário do item. Abaixo estão algumas informações e estatísticas sobre o leilão:"
9
+ item:
10
+ title: "Item Arrematado: <b>%{title}</b>"
11
+ winner_bid: "Seu Lance Vencedor: %{winner_bid}"
12
+ auction_total_bids: "Número Total de Lances: %{auction_total_bids}"
13
+ auction_date: "Data do Leilão"
@@ -1,9 +1,5 @@
1
1
  pt-BR:
2
2
  mail:
3
- general:
4
- hello: "Olá %{name}"
5
- app_name: "AuctionFun"
6
- team: "Time AuctionFun"
7
3
  user_context:
8
4
  registration:
9
5
  subject: "Bem vindo a AuctionFun"
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module PostAuction
7
+ ##
8
+ # Contract class for validate participation auction.
9
+ #
10
+ class ParticipantContract < Contracts::ApplicationContract
11
+ I18N_SCOPE = "contracts.errors.custom.auction_context.post_auction.participation"
12
+
13
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
14
+ option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
15
+ option :bid_repository, default: proc { Repos::BidContext::BidRepository.new }
16
+
17
+ params do
18
+ required(:auction_id).filled(:integer)
19
+ required(:participant_id).filled(:integer)
20
+ end
21
+
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
25
+ end
26
+
27
+ rule(:participant_id) do |context:|
28
+ context[:participant] ||= user_repository.by_id(value)
29
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:participant]
30
+ end
31
+
32
+ rule(:auction_id, :participant_id) do |context:|
33
+ next if (rule_error?(:auction_id) || schema_error?(:auction_id)) || (rule_error?(:winner_id) || schema_error?(:winner_id))
34
+ next if bid_repository.exists?(auction_id: values[:auction_id], user_id: values[:participant_id])
35
+
36
+ key(:participant_id).failure(I18n.t("none", scope: I18N_SCOPE))
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module PostAuction
7
+ ##
8
+ # Contract class for validate winner auction.
9
+ #
10
+ class WinnerContract < Contracts::ApplicationContract
11
+ I18N_SCOPE = "contracts.errors.custom.auction_context.post_auction.winner"
12
+
13
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
14
+ option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ required(:winner_id).filled(:integer)
19
+ end
20
+
21
+ rule(:auction_id) do |context:|
22
+ context[:auction] ||= auction_repository.by_id(value)
23
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
24
+ end
25
+
26
+ rule(:winner_id) do |context:|
27
+ context[:winner] ||= user_repository.by_id(value)
28
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:winner]
29
+ end
30
+
31
+ rule(:auction_id, :winner_id) do |context:|
32
+ next if (rule_error?(:auction_id) || schema_error?(:auction_id)) || (rule_error?(:winner_id) || schema_error?(:winner_id))
33
+ next if context[:auction].winner_id == values[:winner_id]
34
+
35
+ key(:winner_id).failure(I18n.t("wrong", scope: I18N_SCOPE))
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing closed auctions.
10
+ #
11
+ class ClosedContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
25
+ end
26
+
27
+ # Validation for kind.
28
+ #
29
+ rule do |context:|
30
+ next if context[:auction].present? && context[:auction].kind == "closed"
31
+
32
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
33
+ end
34
+
35
+ # Validation for status.
36
+ #
37
+ rule do |context:|
38
+ next if context[:auction].present? && context[:auction].status == "running"
39
+
40
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing penny auctions.
10
+ #
11
+ class PennyContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+
25
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
26
+ end
27
+
28
+ # Validation for kind.
29
+ #
30
+ rule do |context:|
31
+ next if context[:auction].present? && context[:auction].kind == "penny"
32
+
33
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
34
+ end
35
+
36
+ # Validation for status.
37
+ #
38
+ rule do |context:|
39
+ next if context[:auction].present? && context[:auction].status == "running"
40
+
41
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing standard auctions.
10
+ #
11
+ class StandardContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+
25
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
26
+ end
27
+
28
+ # Validation for kind.
29
+ #
30
+ rule do |context:|
31
+ next if context[:auction].present? && context[:auction].kind == "standard"
32
+
33
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
34
+ end
35
+
36
+ # Validation for status.
37
+ #
38
+ rule do |context:|
39
+ next if context[:auction].present? && context[:auction].status == "running"
40
+
41
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end