auction_fun_core 0.8.5 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.standard.yml +2 -0
- data/CHANGELOG.md +48 -0
- data/Procfile +1 -0
- data/README.md +34 -32
- data/Rakefile +1 -1
- data/auction_fun_core.gemspec +1 -0
- data/db/migrate/20240229143000_create_auctions.rb +1 -0
- data/db/seeds.rb +87 -36
- data/i18n/en-US/contracts/contracts.en-US.yml +12 -0
- data/i18n/en-US/mail/application.en-US.yml +66 -0
- data/i18n/en-US/mail/auction_context/post_auction/participant.en-US.yml +13 -0
- data/i18n/en-US/mail/auction_context/post_auction/winner.en-US.yml +13 -0
- data/i18n/en-US/mail/auction_context/pre_auction/auction_start_reminder.en-US.yml +11 -0
- data/i18n/pt-BR/contracts/contracts.pt-BR.yml +12 -0
- data/i18n/pt-BR/mail/application.pt-BR.yml +66 -0
- data/i18n/pt-BR/mail/auction_context/post_auction/participant.pt-BR.yml +13 -0
- data/i18n/pt-BR/mail/auction_context/post_auction/winner.pt-BR.yml +13 -0
- data/i18n/pt-BR/mail/auction_context/pre_auction/auction_start_reminder.pt-BR.yml +11 -0
- data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +0 -4
- data/lib/auction_fun_core/business/configuration.rb +31 -0
- data/lib/auction_fun_core/business/token_generator.rb +19 -1
- data/lib/auction_fun_core/contracts/application_contract.rb +9 -1
- data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +35 -20
- data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +64 -0
- data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +62 -0
- data/lib/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract.rb +48 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +59 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +60 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +60 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +16 -4
- data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +17 -5
- data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +16 -4
- data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +20 -11
- data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +18 -9
- data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +19 -10
- data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +18 -4
- data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +20 -8
- data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +18 -4
- data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +17 -2
- data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +17 -2
- data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +26 -8
- data/lib/auction_fun_core/entities/auction.rb +52 -2
- data/lib/auction_fun_core/entities/bid.rb +3 -2
- data/lib/auction_fun_core/entities/staff.rb +15 -2
- data/lib/auction_fun_core/entities/user.rb +31 -2
- data/lib/auction_fun_core/events/app.rb +8 -2
- data/lib/auction_fun_core/events/listener.rb +19 -16
- data/lib/auction_fun_core/operations/auction_context/create_operation.rb +37 -11
- data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +85 -0
- data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +85 -0
- data/lib/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation.rb +96 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +172 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +171 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +171 -0
- data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +36 -1
- data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +23 -11
- data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +36 -1
- data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +57 -7
- data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +10 -0
- data/lib/auction_fun_core/relations/auctions.rb +252 -30
- data/lib/auction_fun_core/relations/bids.rb +18 -0
- data/lib/auction_fun_core/relations/staffs.rb +1 -1
- data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +40 -11
- data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -5
- data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +63 -21
- data/lib/auction_fun_core/repos/user_context/user_repository.rb +69 -25
- data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +37 -0
- data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +37 -0
- data/lib/auction_fun_core/services/mail/auction_context/pre_auction/auction_start_reminder_mailer.rb +35 -0
- data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +173 -0
- data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +174 -0
- data/lib/auction_fun_core/services/mail/templates/auction_context/pre_auction/auction_start_reminder.html.erb +192 -0
- data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +2 -2
- data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +6 -0
- data/lib/auction_fun_core/version.rb +1 -1
- data/lib/auction_fun_core/workers/application_job.rb +12 -0
- data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +38 -0
- data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +37 -0
- data/lib/auction_fun_core/workers/operations/auction_context/pre_auction/auction_start_reminder_operation_job.rb +44 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +37 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +40 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +38 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +6 -3
- data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +56 -0
- data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +57 -0
- data/lib/auction_fun_core/workers/services/mail/auction_context/pre_auction/auction_start_reminder_mailer_job.rb +48 -0
- data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +8 -6
- data/system/providers/background_job.rb +25 -0
- metadata +51 -5
- data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +0 -27
- data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +0 -61
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +0 -32
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
module AuctionFunCore
|
4
4
|
module Entities
|
5
|
-
|
6
|
-
# to
|
5
|
+
##
|
6
|
+
# Defines the Bid class as Entity. It appears to be a simple data structure
|
7
|
+
# class representing bid-related information.
|
7
8
|
class Bid < ROM::Struct
|
8
9
|
end
|
9
10
|
end
|
@@ -2,17 +2,30 @@
|
|
2
2
|
|
3
3
|
module AuctionFunCore
|
4
4
|
module Entities
|
5
|
-
|
6
|
-
# to
|
5
|
+
##
|
6
|
+
# Defines the Staff class as Entity. It appears to be a simple data structure
|
7
|
+
# class representing staff-related information.
|
7
8
|
class Staff < ROM::Struct
|
9
|
+
##
|
10
|
+
# Checks if the staff is active.
|
11
|
+
#
|
12
|
+
# @return [Boolean] True if the staff is active, otherwise false.
|
8
13
|
def active?
|
9
14
|
active
|
10
15
|
end
|
11
16
|
|
17
|
+
##
|
18
|
+
# Checks if the staff is inactive.
|
19
|
+
#
|
20
|
+
# @return [Boolean] True if the staff is inactive, otherwise false.
|
12
21
|
def inactive?
|
13
22
|
!active
|
14
23
|
end
|
15
24
|
|
25
|
+
##
|
26
|
+
# Returns staff information excluding password digest.
|
27
|
+
#
|
28
|
+
# @return [Hash] Staff information.
|
16
29
|
def info
|
17
30
|
attributes.except(:password_digest)
|
18
31
|
end
|
@@ -2,33 +2,62 @@
|
|
2
2
|
|
3
3
|
module AuctionFunCore
|
4
4
|
module Entities
|
5
|
-
|
6
|
-
# to
|
5
|
+
##
|
6
|
+
# Defines the User class as Entity. It appears to be a simple data structure
|
7
|
+
# class representing user-related information.
|
7
8
|
class User < ROM::Struct
|
9
|
+
##
|
10
|
+
# Checks if the user is active.
|
11
|
+
#
|
12
|
+
# @return [Boolean] True if the user is active, otherwise false.
|
8
13
|
def active?
|
9
14
|
active
|
10
15
|
end
|
11
16
|
|
17
|
+
##
|
18
|
+
# Checks if the user is inactive.
|
19
|
+
#
|
20
|
+
# @return [Boolean] True if the user is inactive, otherwise false.
|
12
21
|
def inactive?
|
13
22
|
!active
|
14
23
|
end
|
15
24
|
|
25
|
+
##
|
26
|
+
# Checks if the user has been confirmed.
|
27
|
+
#
|
28
|
+
# @return [Boolean] True if the user is confirmed, otherwise false.
|
16
29
|
def confirmed?
|
17
30
|
confirmed_at.present?
|
18
31
|
end
|
19
32
|
|
33
|
+
##
|
34
|
+
# Checks if the user's email has been confirmed.
|
35
|
+
#
|
36
|
+
# @return [Boolean] True if the email is confirmed, otherwise false.
|
20
37
|
def email_confirmed?
|
21
38
|
email_confirmation_at.present?
|
22
39
|
end
|
23
40
|
|
41
|
+
##
|
42
|
+
# Checks if the user's phone has been confirmed.
|
43
|
+
#
|
44
|
+
# @return [Boolean] True if the phone is confirmed, otherwise false.
|
24
45
|
def phone_confirmed?
|
25
46
|
phone_confirmation_at.present?
|
26
47
|
end
|
27
48
|
|
49
|
+
##
|
50
|
+
# Returns user information excluding password digest.
|
51
|
+
#
|
52
|
+
# @return [Hash] User information.
|
28
53
|
def info
|
29
54
|
attributes.except(:password_digest)
|
30
55
|
end
|
31
56
|
|
57
|
+
##
|
58
|
+
# Returns the user's balance as a Money object.
|
59
|
+
#
|
60
|
+
# @return [Money] User's balance.
|
32
61
|
def balance
|
33
62
|
Money.new(balance_cents, balance_currency)
|
34
63
|
end
|
@@ -2,23 +2,29 @@
|
|
2
2
|
|
3
3
|
module AuctionFunCore
|
4
4
|
module Events
|
5
|
-
|
5
|
+
##
|
6
|
+
# Represents the main application class for registering business events in the system.
|
7
|
+
#
|
8
|
+
# This class includes Dry::Events::Publisher[:app] to enable event publishing functionality.
|
6
9
|
# @see https://dry-rb.org/gems/dry-events/main/
|
7
10
|
class App
|
8
|
-
# @!parser include Dry::Events::Publisher[:app]
|
9
11
|
include Dry::Events::Publisher[:app]
|
10
12
|
|
13
|
+
# Registers events related to auctions.
|
11
14
|
register_event("auctions.created")
|
12
15
|
register_event("auctions.started")
|
13
16
|
register_event("auctions.finished")
|
14
17
|
register_event("auctions.paused")
|
15
18
|
register_event("auctions.unpaused")
|
16
19
|
|
20
|
+
# Registers events related to bids.
|
17
21
|
register_event("bids.created")
|
18
22
|
|
23
|
+
# Registers events related to staffs.
|
19
24
|
register_event("staffs.authentication")
|
20
25
|
register_event("staffs.registration")
|
21
26
|
|
27
|
+
# Registers events related to users.
|
22
28
|
register_event("users.authentication")
|
23
29
|
register_event("users.registration")
|
24
30
|
register_event("users.confirmation")
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
module AuctionFunCore
|
4
4
|
module Events
|
5
|
-
|
5
|
+
##
|
6
|
+
# Represents a class that listens to business events and performs actions accordingly.
|
7
|
+
#
|
8
|
+
# This class defines methods to handle various events related to auctions, bids, staff, and users.
|
6
9
|
# @see https://dry-rb.org/gems/dry-events/main/#event-listeners
|
7
10
|
class Listener
|
8
11
|
# Listener for to *auctions.created* event.
|
@@ -36,15 +39,15 @@ module AuctionFunCore
|
|
36
39
|
end
|
37
40
|
|
38
41
|
# Listener for to *bids.created* event.
|
39
|
-
# @param event [
|
42
|
+
# @param event [ROM::Struct::Bid] Auction ID
|
40
43
|
def on_bids_created(bid)
|
41
44
|
logger("Create bid with: #{bid.to_h}")
|
42
45
|
end
|
43
46
|
|
44
|
-
# Listener for
|
45
|
-
# @param attributes [Hash] Authentication attributes
|
46
|
-
# @option staff_id [Integer] Staff ID
|
47
|
-
# @option time [DateTime] Authentication time
|
47
|
+
# Listener for the *staffs.authentication* event.
|
48
|
+
# @param attributes [Hash] Authentication attributes.
|
49
|
+
# @option attributes staff_id [Integer] Staff ID.
|
50
|
+
# @option attributes time [DateTime] Authentication time.
|
48
51
|
def on_staffs_authentication(attributes)
|
49
52
|
logger("Staff #{attributes[:staff_id]} authenticated on: #{attributes[:time].iso8601}")
|
50
53
|
end
|
@@ -61,26 +64,26 @@ module AuctionFunCore
|
|
61
64
|
logger("New registered user: #{user.to_h}")
|
62
65
|
end
|
63
66
|
|
64
|
-
# Listener for
|
65
|
-
# @param attributes [Hash] Authentication attributes
|
66
|
-
# @option user_id [Integer] User ID
|
67
|
-
# @option time [DateTime] Authentication time
|
67
|
+
# Listener for the *users.authentication* event.
|
68
|
+
# @param attributes [Hash] Authentication attributes.
|
69
|
+
# @option attributes user_id [Integer] User ID.
|
70
|
+
# @option attributes time [DateTime] Authentication time.
|
68
71
|
def on_users_authentication(attributes)
|
69
72
|
logger("User #{attributes[:user_id]} authenticated on: #{attributes[:time].iso8601}")
|
70
73
|
end
|
71
74
|
|
72
|
-
# Listener for
|
73
|
-
# @param attributes [Hash] Confirmation attributes
|
74
|
-
# @option user_id [Integer] User ID
|
75
|
-
# @option time [DateTime] Authentication time
|
75
|
+
# Listener for the *users.confirmation* event.
|
76
|
+
# @param attributes [Hash] Confirmation attributes.
|
77
|
+
# @option user_id [Integer] User ID.
|
78
|
+
# @option time [DateTime] Authentication time.
|
76
79
|
def on_users_confirmation(attributes)
|
77
80
|
logger("User #{attributes[:user_id]} confirmed at: #{attributes[:time].iso8601}")
|
78
81
|
end
|
79
82
|
|
80
83
|
private
|
81
84
|
|
82
|
-
#
|
83
|
-
# @param message [String]
|
85
|
+
# Appends a message to the system log.
|
86
|
+
# @param message [String] The message.
|
84
87
|
def logger(message)
|
85
88
|
Application[:logger].info(message)
|
86
89
|
end
|
@@ -10,6 +10,7 @@ module AuctionFunCore
|
|
10
10
|
include Import["repos.auction_context.auction_repository"]
|
11
11
|
include Import["contracts.auction_context.create_contract"]
|
12
12
|
include Import["workers.operations.auction_context.processor.start_operation_job"]
|
13
|
+
include Import["workers.operations.auction_context.pre_auction.auction_start_reminder_operation_job"]
|
13
14
|
|
14
15
|
# @todo Add custom doc
|
15
16
|
def self.call(attributes, &block)
|
@@ -21,11 +22,13 @@ module AuctionFunCore
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def call(attributes)
|
24
|
-
values = yield
|
25
|
+
values = yield validate_contract(attributes)
|
26
|
+
values = yield assign_default_values(values)
|
25
27
|
|
26
28
|
auction_repository.transaction do |_t|
|
27
29
|
@auction = yield persist(values)
|
28
30
|
yield scheduled_start_auction(@auction)
|
31
|
+
yield schedule_auction_notification(@auction)
|
29
32
|
yield publish_auctions_created(@auction)
|
30
33
|
end
|
31
34
|
|
@@ -38,7 +41,7 @@ module AuctionFunCore
|
|
38
41
|
# of the informed attributes.
|
39
42
|
# @param attrs [Hash] auction attributes
|
40
43
|
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
41
|
-
def
|
44
|
+
def validate_contract(attrs)
|
42
45
|
contract = create_contract.call(attrs)
|
43
46
|
|
44
47
|
return Failure(contract.errors.to_h) if contract.failure?
|
@@ -46,6 +49,15 @@ module AuctionFunCore
|
|
46
49
|
Success(contract.to_h)
|
47
50
|
end
|
48
51
|
|
52
|
+
# By default, the auction status is set to 'scheduled'.
|
53
|
+
# @todo Refactor this method in the future to consider the status as of the auction start date.
|
54
|
+
# @param attrs [Hash] auction attributes
|
55
|
+
# @return [Dry::Monads::Result::Success]
|
56
|
+
def assign_default_values(attrs)
|
57
|
+
attrs[:status] = "scheduled"
|
58
|
+
Success(attrs)
|
59
|
+
end
|
60
|
+
|
49
61
|
# Calls the auction repository class to persist the attributes in the database.
|
50
62
|
# @param result [Hash] Auction validated attributes
|
51
63
|
# @return [ROM::Struct::Auction]
|
@@ -53,15 +65,6 @@ module AuctionFunCore
|
|
53
65
|
Success(auction_repository.create(result))
|
54
66
|
end
|
55
67
|
|
56
|
-
# Triggers the publication of event *auctions.created*.
|
57
|
-
# @param auction [Hash] Auction persisted attributes
|
58
|
-
# @return [Dry::Monads::Result::Success]
|
59
|
-
def publish_auctions_created(auction)
|
60
|
-
Application[:event].publish("auctions.created", auction.to_h)
|
61
|
-
|
62
|
-
Success()
|
63
|
-
end
|
64
|
-
|
65
68
|
# Calls the background job class that will schedule the start of the auction.
|
66
69
|
# Added a small delay to perform operations (such as sending broadcasts and/or other operations).
|
67
70
|
# @param auction [ROM::Struct::Auction]
|
@@ -71,6 +74,29 @@ module AuctionFunCore
|
|
71
74
|
|
72
75
|
Success(start_operation_job.class.perform_at(perform_at, auction.id))
|
73
76
|
end
|
77
|
+
|
78
|
+
# Schedules a notification to be sent to users one hour before the auction starts.
|
79
|
+
# The scheduling is only done if the start of the auction is more than one hour ahead of the current time,
|
80
|
+
# ensuring that there is sufficient time for the notification to be sent.
|
81
|
+
#
|
82
|
+
# @param auction [ROM::Struct::Auction]
|
83
|
+
# @return [String] sidekiq jid
|
84
|
+
def schedule_auction_notification(auction)
|
85
|
+
perform_time = auction.started_at - 1.hour
|
86
|
+
|
87
|
+
return Success() if perform_time <= Time.current
|
88
|
+
|
89
|
+
Success(auction_start_reminder_operation_job.class.perform_at(perform_time, auction.id))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Triggers the publication of event *auctions.created*.
|
93
|
+
# @param auction [ROM::Struct::Auction]
|
94
|
+
# @return [Dry::Monads::Result::Success]
|
95
|
+
def publish_auctions_created(auction)
|
96
|
+
Application[:event].publish("auctions.created", auction.to_h)
|
97
|
+
|
98
|
+
Success()
|
99
|
+
end
|
74
100
|
end
|
75
101
|
end
|
76
102
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Operations
|
5
|
+
module AuctionContext
|
6
|
+
module PostAuction
|
7
|
+
##
|
8
|
+
# Operation class for managing participants in auctions.
|
9
|
+
#
|
10
|
+
class ParticipantOperation < AuctionFunCore::Operations::Base
|
11
|
+
include Import["repos.user_context.user_repository"]
|
12
|
+
include Import["contracts.auction_context.post_auction.participant_contract"]
|
13
|
+
include Import["workers.services.mail.auction_context.post_auction.participant_mailer_job"]
|
14
|
+
|
15
|
+
##
|
16
|
+
# Executes the participant operation with the provided attributes.
|
17
|
+
#
|
18
|
+
# @param attributes [Hash] The attributes for the winner operation.
|
19
|
+
# @option attributes auction_id [Integer] The ID of the auction.
|
20
|
+
# @option attributes participant_id [Integer] The participating user ID.
|
21
|
+
# @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
|
22
|
+
# @return [Dry::Matcher::Evaluator] The result of the operation.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# attributes = { auction_id: 123, participant_id: 123 }
|
26
|
+
#
|
27
|
+
# AuctionFunCore::Operations::AuctionContext::PostAuction::ParticipantOperation.call(attributes) do |result|
|
28
|
+
# result.success { |auction| puts "Participation operation completed successfully! #{auction.to_h}" }
|
29
|
+
# result.failure { |failure| puts "Failed auction participation operation: #{failure.errors.to_h}"}
|
30
|
+
# end
|
31
|
+
def self.call(attributes, &block)
|
32
|
+
operation = new.call(attributes)
|
33
|
+
|
34
|
+
return operation unless block
|
35
|
+
|
36
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Executes the participant operation.
|
41
|
+
#
|
42
|
+
# @param attributes [Hash] The attributes for the participant operation.
|
43
|
+
# @return [Dry::Monads::Result] The result of the operation.
|
44
|
+
#
|
45
|
+
def call(attributes)
|
46
|
+
auction, participant = yield validate_contract(attributes)
|
47
|
+
|
48
|
+
user_repository.transaction do |_t|
|
49
|
+
yield send_participant_email_with_statistics_and_payment_instructions(auction.id, participant.id)
|
50
|
+
end
|
51
|
+
|
52
|
+
Success([auction, participant])
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
##
|
58
|
+
# Validates the contract with the provided attributes.
|
59
|
+
#
|
60
|
+
# @param attributes [Hash] The attributes to validate.
|
61
|
+
# @return [Dry::Monads::Result] The result of the validation.
|
62
|
+
#
|
63
|
+
def validate_contract(attributes)
|
64
|
+
contract = participant_contract.call(attributes)
|
65
|
+
|
66
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
67
|
+
|
68
|
+
Success([contract.context[:auction], contract.context[:participant]])
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Sends participant email with auction statistics and payment instructions.
|
73
|
+
#
|
74
|
+
# @param auction_id [Integer] The ID of the auction.
|
75
|
+
# @param participant_id [Integer] The ID of the participant.
|
76
|
+
# @return [Dry::Monads::Result] The result of sending the email.
|
77
|
+
#
|
78
|
+
def send_participant_email_with_statistics_and_payment_instructions(auction_id, participant_id)
|
79
|
+
Success(participant_mailer_job.class.perform_async(auction_id, participant_id))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Operations
|
5
|
+
module AuctionContext
|
6
|
+
module PostAuction
|
7
|
+
##
|
8
|
+
# Operation class for managing winners in auctions.
|
9
|
+
#
|
10
|
+
class WinnerOperation < AuctionFunCore::Operations::Base
|
11
|
+
include Import["repos.user_context.user_repository"]
|
12
|
+
include Import["contracts.auction_context.post_auction.winner_contract"]
|
13
|
+
include Import["workers.services.mail.auction_context.post_auction.winner_mailer_job"]
|
14
|
+
|
15
|
+
##
|
16
|
+
# Executes the winner operation with the provided attributes.
|
17
|
+
#
|
18
|
+
# @param attributes [Hash] The attributes for the winner operation.
|
19
|
+
# @option attributes auction_id [Integer] The ID of the auction.
|
20
|
+
# @option attributes winner_id [Integer] The winning user ID
|
21
|
+
# @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
|
22
|
+
# @return [Dry::Matcher::Evaluator] The result of the operation.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# attributes = { auction_id: 123, winner_id: 123 }
|
26
|
+
#
|
27
|
+
# AuctionFunCore::Operations::AuctionContext::PostAuction::WinnerOperation.call(attributes) do |result|
|
28
|
+
# result.success { |auction| puts "Winner operation completed successfully! #{auction.to_h}" }
|
29
|
+
# result.failure { |failure| puts "Failed auction winner operation: #{failure.errors.to_h}"}
|
30
|
+
# end
|
31
|
+
def self.call(attributes, &block)
|
32
|
+
operation = new.call(attributes)
|
33
|
+
|
34
|
+
return operation unless block
|
35
|
+
|
36
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Executes the winner operation.
|
41
|
+
#
|
42
|
+
# @param attributes [Hash] The attributes for the winner operation.
|
43
|
+
# @return [Dry::Monads::Result] The result of the operation.
|
44
|
+
#
|
45
|
+
def call(attributes)
|
46
|
+
auction, winner = yield validate_contract(attributes)
|
47
|
+
|
48
|
+
user_repository.transaction do |_t|
|
49
|
+
send_winner_email_with_statistics_and_payment_instructions(auction.id, winner.id)
|
50
|
+
end
|
51
|
+
|
52
|
+
Success([auction, winner])
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
##
|
58
|
+
# Validates the contract with the provided attributes.
|
59
|
+
#
|
60
|
+
# @param attributes [Hash] The attributes to validate.
|
61
|
+
# @return [Dry::Monads::Result] The result of the validation.
|
62
|
+
#
|
63
|
+
def validate_contract(attributes)
|
64
|
+
contract = winner_contract.call(attributes)
|
65
|
+
|
66
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
67
|
+
|
68
|
+
Success([contract.context[:auction], contract.context[:winner]])
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Sends winner email with auction statistics and payment instructions.
|
73
|
+
#
|
74
|
+
# @param auction_id [Integer] The ID of the auction.
|
75
|
+
# @param winner_id [Integer] The ID of the winner.
|
76
|
+
# @return [Dry::Monads::Result] The result of sending the email.
|
77
|
+
#
|
78
|
+
def send_winner_email_with_statistics_and_payment_instructions(auction_id, winner_id)
|
79
|
+
Success(winner_mailer_job.class.perform_async(auction_id, winner_id))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Operations
|
5
|
+
module AuctionContext
|
6
|
+
module PreAuction
|
7
|
+
##
|
8
|
+
# Operation class for sending a reminder email to a participant about the start of an auction.
|
9
|
+
#
|
10
|
+
class AuctionStartReminderOperation < AuctionFunCore::Operations::Base
|
11
|
+
include Import["repos.bid_context.bid_repository"]
|
12
|
+
include Import["contracts.auction_context.pre_auction.auction_start_reminder_contract"]
|
13
|
+
include Import["workers.services.mail.auction_context.pre_auction.auction_start_reminder_mailer_job"]
|
14
|
+
|
15
|
+
##
|
16
|
+
# Executes the auction start reminder operation with the provided attributes.
|
17
|
+
#
|
18
|
+
# @param attributes [Hash] The attributes for the auction start reminder operation.
|
19
|
+
# @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
|
20
|
+
# @return [Dry::Matcher::Evaluator] The result of the operation.
|
21
|
+
#
|
22
|
+
def self.call(attributes, &block)
|
23
|
+
operation = new.call(attributes)
|
24
|
+
|
25
|
+
return operation unless block
|
26
|
+
|
27
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Executes the auction start reminder operation.
|
32
|
+
#
|
33
|
+
# @param attributes [Hash] The attributes for the auction start reminder operation.
|
34
|
+
# @return [Dry::Monads::Result] The result of the operation.
|
35
|
+
#
|
36
|
+
def call(attributes)
|
37
|
+
auction = yield validate_contract(attributes)
|
38
|
+
participant_ids = yield collect_current_auction_participants(auction.id)
|
39
|
+
|
40
|
+
bid_repository.transaction do |_t|
|
41
|
+
participant_ids.each do |participant_id|
|
42
|
+
yield send_auction_start_reminder_mailer_job(auction.id, participant_id)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Success([auction, participant_ids])
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
##
|
52
|
+
# Validates the contract with the provided attributes.
|
53
|
+
#
|
54
|
+
# @param attributes [Hash] The attributes to validate.
|
55
|
+
# @option auction_id [Integer] The ID of the auction.
|
56
|
+
# @return [Dry::Monads::Result] The result of the validation.
|
57
|
+
#
|
58
|
+
def validate_contract(attributes)
|
59
|
+
contract = auction_start_reminder_contract.call(attributes)
|
60
|
+
|
61
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
62
|
+
|
63
|
+
Success(contract.context[:auction])
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Collects the participant IDs for the current auction.
|
68
|
+
#
|
69
|
+
# @param auction_id [Integer] The ID of the auction.
|
70
|
+
# @return [Dry::Monads::Result] The result of collecting the participant IDs.
|
71
|
+
#
|
72
|
+
def collect_current_auction_participants(auction_id)
|
73
|
+
Success(
|
74
|
+
AuctionFunCore::Application[:container]
|
75
|
+
.relations[:bids]
|
76
|
+
.participants(auction_id)
|
77
|
+
.one
|
78
|
+
.participant_ids.to_a
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Sends the auction start reminder email to a participant.
|
84
|
+
#
|
85
|
+
# @param auction_id [Integer] The ID of the auction.
|
86
|
+
# @param participant_id [Integer] The ID of the participant.
|
87
|
+
# @return [Dry::Monads::Result] The result of sending the email.
|
88
|
+
#
|
89
|
+
def send_auction_start_reminder_mailer_job(auction_id, participant_id)
|
90
|
+
Success(auction_start_reminder_mailer_job.class.perform_async(auction_id, participant_id))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|