auction_fun_core 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +12 -0
- data/.env.development.template +7 -0
- data/.env.test.template +7 -0
- data/.rspec +3 -0
- data/.standard.yml +3 -0
- data/.tool-versions +5 -0
- data/CHANGELOG.md +145 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/Procfile +4 -0
- data/README.md +141 -0
- data/Rakefile +13 -0
- data/auction_fun_core.gemspec +57 -0
- data/config/app.rb +5 -0
- data/config/application.rb +37 -0
- data/config/boot.rb +15 -0
- data/db/migrate/20240216200926_enable_postgres_extensions.rb +13 -0
- data/db/migrate/20240217115734_create_users.rb +28 -0
- data/db/migrate/20240220140151_create_custom_types.rb +11 -0
- data/db/migrate/20240220140254_create_staffs.rb +20 -0
- data/db/migrate/20240229142933_create_custom_types.rb +13 -0
- data/db/migrate/20240229143000_create_auctions.rb +29 -0
- data/db/migrate/20240304144422_create_bids.rb +19 -0
- data/db/seeds.rb +116 -0
- data/i18n/en-US/contracts/contracts.en-US.yml +72 -0
- data/i18n/en-US/mail/user_context/registration.en-US.yml +11 -0
- data/i18n/pt-BR/contracts/contracts.pt-BR.yml +72 -0
- data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +12 -0
- data/lib/auction_fun_core/business/configuration.rb +18 -0
- data/lib/auction_fun_core/business/token_generator.rb +17 -0
- data/lib/auction_fun_core/commands/auction_context/create_auction.rb +19 -0
- data/lib/auction_fun_core/commands/auction_context/delete_auction.rb +15 -0
- data/lib/auction_fun_core/commands/auction_context/update_auction.rb +18 -0
- data/lib/auction_fun_core/commands/bid_context/create_bid.rb +19 -0
- data/lib/auction_fun_core/commands/bid_context/delete_bid.rb +15 -0
- data/lib/auction_fun_core/commands/bid_context/update_bid.rb +18 -0
- data/lib/auction_fun_core/commands/staff_context/create_staff.rb +19 -0
- data/lib/auction_fun_core/commands/user_context/create_user.rb +19 -0
- data/lib/auction_fun_core/contracts/application_contract.rb +55 -0
- data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +101 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +27 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +46 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +79 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +69 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +68 -0
- data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +52 -0
- data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +63 -0
- data/lib/auction_fun_core/entities/auction.rb +17 -0
- data/lib/auction_fun_core/entities/bid.rb +10 -0
- data/lib/auction_fun_core/entities/staff.rb +21 -0
- data/lib/auction_fun_core/entities/user.rb +37 -0
- data/lib/auction_fun_core/events/app.rb +27 -0
- data/lib/auction_fun_core/events/listener.rb +89 -0
- data/lib/auction_fun_core/operations/auction_context/create_operation.rb +77 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +61 -0
- data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +84 -0
- data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/base.rb +11 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_closed_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_standard_operation.rb +74 -0
- data/lib/auction_fun_core/operations/staff_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +76 -0
- data/lib/auction_fun_core/operations/user_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/user_context/email_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/phone_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/registration_operation.rb +105 -0
- data/lib/auction_fun_core/relations/auctions.rb +119 -0
- data/lib/auction_fun_core/relations/bids.rb +28 -0
- data/lib/auction_fun_core/relations/staffs.rb +27 -0
- data/lib/auction_fun_core/relations/users.rb +26 -0
- data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +42 -0
- data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -0
- data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +64 -0
- data/lib/auction_fun_core/repos/user_context/user_repository.rb +78 -0
- data/lib/auction_fun_core/services/mail/templates/layout.html.erb +72 -0
- data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +170 -0
- data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +25 -0
- data/lib/auction_fun_core/version.rb +8 -0
- data/lib/auction_fun_core/workers/application_job.rb +22 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +40 -0
- data/lib/auction_fun_core.rb +21 -0
- data/lib/tasks/database.rake +87 -0
- data/system/providers/background_job.rb +15 -0
- data/system/providers/core.rb +35 -0
- data/system/providers/db.rb +26 -0
- data/system/providers/events.rb +13 -0
- data/system/providers/logger.rb +11 -0
- data/system/providers/mail.rb +25 -0
- data/system/providers/persistence.rb +18 -0
- data/system/providers/settings.rb +26 -0
- metadata +400 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Relations
|
5
|
+
# SQL relation for auctions.
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
7
|
+
class Auctions < ROM::Relation[:sql]
|
8
|
+
use :pagination, per_page: 10
|
9
|
+
|
10
|
+
KINDS = Types::Coercible::String.default("standard").enum("standard", "penny", "closed")
|
11
|
+
STATUSES = Types::Coercible::String.default("scheduled")
|
12
|
+
.enum("scheduled", "running", "paused", "canceled", "finished")
|
13
|
+
|
14
|
+
schema(:auctions, infer: true) do
|
15
|
+
attribute :id, Types::Integer
|
16
|
+
attribute :staff_id, Types::ForeignKey(:staffs)
|
17
|
+
attribute :title, Types::String
|
18
|
+
attribute :description, Types::String
|
19
|
+
attribute :kind, KINDS
|
20
|
+
attribute :status, STATUSES
|
21
|
+
attribute :started_at, Types::DateTime
|
22
|
+
attribute :finished_at, Types::DateTime
|
23
|
+
attribute :stopwatch, Types::Integer
|
24
|
+
attribute :initial_bid_cents, Types::Integer
|
25
|
+
attribute :initial_bid_currency, Types::String
|
26
|
+
attribute :minimal_bid_cents, Types::Integer
|
27
|
+
attribute :minimal_bid_currency, Types::String
|
28
|
+
|
29
|
+
attribute :metadata, Types::PG::JSONB
|
30
|
+
attribute :statistics, Types::PG::JSONB
|
31
|
+
primary_key :id
|
32
|
+
|
33
|
+
associations do
|
34
|
+
belongs_to :staff, as: :staff, relation: :staffs
|
35
|
+
has_many :bids, as: :bids, relation: :bids
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
struct_namespace Entities
|
40
|
+
auto_struct(true)
|
41
|
+
|
42
|
+
def all(page = 1, per_page = 10, options = {bidders_count: 3})
|
43
|
+
offset = ((page - 1) * per_page)
|
44
|
+
|
45
|
+
read(all_auctions_with_bid_info(per_page, offset, options))
|
46
|
+
end
|
47
|
+
|
48
|
+
def info(auction_id, options = {bidders_count: 3})
|
49
|
+
raise "Invalid argument" unless auction_id.is_a?(Integer)
|
50
|
+
|
51
|
+
read(auction_with_bid_info(auction_id, options))
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def auction_with_bid_info(auction_id, options = {bidders_count: 3})
|
57
|
+
"SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
|
58
|
+
(SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = #{auction_id}) dt) AS total_bids,
|
59
|
+
CASE
|
60
|
+
WHEN a.kind = 'standard' THEN
|
61
|
+
json_build_object(
|
62
|
+
'current', a.minimal_bid_cents,
|
63
|
+
'minimal', a.minimal_bid_cents,
|
64
|
+
'bidders', COALESCE(
|
65
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
66
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
67
|
+
)
|
68
|
+
)
|
69
|
+
WHEN a.kind = 'penny' THEN
|
70
|
+
json_build_object(
|
71
|
+
'value', a.initial_bid_cents,
|
72
|
+
'bidders', COALESCE(
|
73
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
74
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
75
|
+
)
|
76
|
+
)
|
77
|
+
WHEN a.kind = 'closed' THEN
|
78
|
+
json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
|
79
|
+
END as bids
|
80
|
+
FROM auctions as a
|
81
|
+
LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id AND a.id = #{auction_id}
|
82
|
+
LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
|
83
|
+
WHERE a.id = #{auction_id}
|
84
|
+
GROUP BY a.id"
|
85
|
+
end
|
86
|
+
|
87
|
+
def all_auctions_with_bid_info(per_page, offset, options = {bidders_count: 3})
|
88
|
+
"SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
|
89
|
+
(SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = a.id) dt) AS total_bids,
|
90
|
+
CASE
|
91
|
+
WHEN a.kind = 'standard' THEN
|
92
|
+
json_build_object(
|
93
|
+
'current', a.minimal_bid_cents,
|
94
|
+
'minimal', a.minimal_bid_cents,
|
95
|
+
'bidders', COALESCE(
|
96
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
97
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
98
|
+
)
|
99
|
+
)
|
100
|
+
WHEN a.kind = 'penny' THEN
|
101
|
+
json_build_object(
|
102
|
+
'value', a.initial_bid_cents,
|
103
|
+
'bidders', COALESCE(
|
104
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
105
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
106
|
+
)
|
107
|
+
)
|
108
|
+
WHEN a.kind = 'closed' THEN
|
109
|
+
json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
|
110
|
+
END as bids
|
111
|
+
FROM auctions as a
|
112
|
+
LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id
|
113
|
+
LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
|
114
|
+
GROUP BY a.id
|
115
|
+
LIMIT #{per_page} OFFSET #{offset}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Relations
|
5
|
+
# SQL relation for bids
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
7
|
+
class Bids < ROM::Relation[:sql]
|
8
|
+
use :pagination, per_page: 3
|
9
|
+
|
10
|
+
schema(:bids, infer: true) do
|
11
|
+
attribute :id, Types::Integer
|
12
|
+
|
13
|
+
attribute :auction_id, Types::ForeignKey(:auctions)
|
14
|
+
attribute :user_id, Types::ForeignKey(:users)
|
15
|
+
|
16
|
+
associations do
|
17
|
+
belongs_to :auction
|
18
|
+
belongs_to :user
|
19
|
+
end
|
20
|
+
|
21
|
+
primary_key :id
|
22
|
+
end
|
23
|
+
|
24
|
+
struct_namespace Entities
|
25
|
+
auto_struct(true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Relations
|
5
|
+
# SQL relation for staffs.
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
7
|
+
class Staffs < ROM::Relation[:sql]
|
8
|
+
use :pagination, per_page: 10
|
9
|
+
|
10
|
+
STAFF_KINDS = Types::Coercible::String.default("common").enum("root", "common")
|
11
|
+
|
12
|
+
schema(:staffs, infer: true) do
|
13
|
+
attribute :id, Types::Integer
|
14
|
+
attribute :name, Types::String
|
15
|
+
attribute :email, Types::String
|
16
|
+
attribute :phone, Types::String
|
17
|
+
attribute :kind, STAFF_KINDS
|
18
|
+
attribute :active, Types::Bool
|
19
|
+
|
20
|
+
primary_key :id
|
21
|
+
end
|
22
|
+
|
23
|
+
struct_namespace Entities
|
24
|
+
auto_struct(true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Relations
|
5
|
+
# SQL relation for users.
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
7
|
+
class Users < ROM::Relation[:sql]
|
8
|
+
use :pagination, per_page: 10
|
9
|
+
|
10
|
+
schema(:users, infer: true) do
|
11
|
+
attribute :id, Types::Integer
|
12
|
+
attribute :name, Types::String
|
13
|
+
attribute :email, Types::String
|
14
|
+
attribute :phone, Types::String
|
15
|
+
attribute :active, Types::Bool
|
16
|
+
attribute :balance_cents, Types::Integer
|
17
|
+
attribute :balance_currency, Types::String
|
18
|
+
|
19
|
+
primary_key :id
|
20
|
+
end
|
21
|
+
|
22
|
+
struct_namespace Entities
|
23
|
+
auto_struct(true)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Repos
|
5
|
+
module AuctionContext
|
6
|
+
# SQL repository for auctions.
|
7
|
+
class AuctionRepository < ROM::Repository[:auctions]
|
8
|
+
include Import["container"]
|
9
|
+
|
10
|
+
struct_namespace Entities
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
12
|
+
|
13
|
+
# Returns all auctions in the database.
|
14
|
+
# @return [Array<ROM::Struct::Auction>, []]
|
15
|
+
def all
|
16
|
+
auctions.to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the total number of auctions in database.
|
20
|
+
# @return [Integer]
|
21
|
+
def count
|
22
|
+
auctions.count
|
23
|
+
end
|
24
|
+
|
25
|
+
# Search auction in database by primary key.
|
26
|
+
# @param id [Integer] Auction ID
|
27
|
+
# @return [ROM::Struct::Auction, nil]
|
28
|
+
def by_id(id)
|
29
|
+
auctions.by_pk(id).one
|
30
|
+
end
|
31
|
+
|
32
|
+
# Search auction in database by primary key.
|
33
|
+
# @param id [Integer] Auction ID
|
34
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
35
|
+
# @return [ROM::Struct::Auction]
|
36
|
+
def by_id!(id)
|
37
|
+
auctions.by_pk(id).one!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Repos
|
5
|
+
module BidContext
|
6
|
+
# SQL repository for bids.
|
7
|
+
class BidRepository < ROM::Repository[:bids]
|
8
|
+
include Import["container"]
|
9
|
+
|
10
|
+
struct_namespace Entities
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
12
|
+
|
13
|
+
# Returns the total number of bids in database.
|
14
|
+
# @return [Integer]
|
15
|
+
def count
|
16
|
+
bids.count
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param conditions [Hash] DSL Dataset
|
20
|
+
# @return [Boolean]
|
21
|
+
def exists?(conditions)
|
22
|
+
bids.exist?(conditions)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Repos
|
5
|
+
module StaffContext
|
6
|
+
# SQL repository for staffs.
|
7
|
+
class StaffRepository < ROM::Repository[:staffs]
|
8
|
+
include Import["container"]
|
9
|
+
|
10
|
+
struct_namespace Entities
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
12
|
+
|
13
|
+
# Returns all staffs in database.
|
14
|
+
# @return [Array<ROM::Struct::Staff>, []]
|
15
|
+
def all
|
16
|
+
staffs.to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the total number of staffs in database.
|
20
|
+
# @return [Integer]
|
21
|
+
def count
|
22
|
+
staffs.count
|
23
|
+
end
|
24
|
+
|
25
|
+
# Mount SQL conditions in query for search in database.
|
26
|
+
# @param conditions [Hash] DSL Dataset
|
27
|
+
# @return [AuctionFunCore::Relations::Staffs]
|
28
|
+
def query(conditions)
|
29
|
+
staffs.where(conditions)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Search staff in database by primary key.
|
33
|
+
# @param id [Integer] Staff ID
|
34
|
+
# @return [ROM::Struct::Staff, nil]
|
35
|
+
def by_id(id)
|
36
|
+
staffs.by_pk(id).one
|
37
|
+
end
|
38
|
+
|
39
|
+
# Search staffs in database by primary key.
|
40
|
+
# @param id [Integer] Staff ID
|
41
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
42
|
+
# @return [ROM::Struct::Auction]
|
43
|
+
def by_id!(id)
|
44
|
+
staffs.by_pk(id).one!
|
45
|
+
end
|
46
|
+
|
47
|
+
# Search staff in database by email of phone keys.
|
48
|
+
# @param login [String] Staff email or phone
|
49
|
+
# @return [ROM::Struct::Staff, nil]
|
50
|
+
def by_login(login)
|
51
|
+
staffs.where(Sequel[email: login] | Sequel[phone: login]).one
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks if it returns any staff given one or more conditions.
|
55
|
+
# @param conditions [Hash] DSL Dataset
|
56
|
+
# @return [true] when some staff is returned from the given condition.
|
57
|
+
# @return [false] when no staff is returned from the given condition.
|
58
|
+
def exists?(conditions)
|
59
|
+
staffs.exist?(conditions)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuctionFunCore
|
4
|
+
module Repos
|
5
|
+
module UserContext
|
6
|
+
# SQL repository for users.
|
7
|
+
class UserRepository < ROM::Repository[:users]
|
8
|
+
include Import["container"]
|
9
|
+
|
10
|
+
struct_namespace Entities
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
12
|
+
|
13
|
+
# Returns all users in database.
|
14
|
+
# @return [Array<ROM::Struct::User>, []]
|
15
|
+
def all
|
16
|
+
users.to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the total number of users in database.
|
20
|
+
# @return [Integer]
|
21
|
+
def count
|
22
|
+
users.count
|
23
|
+
end
|
24
|
+
|
25
|
+
# Mount SQL conditions in query for search in database.
|
26
|
+
# @param conditions [Hash] DSL Dataset
|
27
|
+
# @return [AuctionFunCore::Relations::Users]
|
28
|
+
def query(conditions)
|
29
|
+
users.where(conditions)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Search user in database by primary key.
|
33
|
+
# @param id [Integer] User ID
|
34
|
+
# @return [ROM::Struct::User, nil]
|
35
|
+
def by_id(id)
|
36
|
+
users.by_pk(id).one
|
37
|
+
end
|
38
|
+
|
39
|
+
# Search user in database by primary key.
|
40
|
+
# @param id [Integer] User ID
|
41
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
42
|
+
# @return [ROM::Struct::Auction]
|
43
|
+
def by_id!(id)
|
44
|
+
users.by_pk(id).one!
|
45
|
+
end
|
46
|
+
|
47
|
+
# Search user in database by email of phone keys.
|
48
|
+
# @param login [String] User email or phone
|
49
|
+
# @return [ROM::Struct::User, nil]
|
50
|
+
def by_login(login)
|
51
|
+
users.where(Sequel[email: login] | Sequel[phone: login]).one
|
52
|
+
end
|
53
|
+
|
54
|
+
# Search user in database by email_confirmation_token key.
|
55
|
+
# @param email_confirmation_token [String] User email confirmation token
|
56
|
+
# @return [ROM::Struct::User, nil]
|
57
|
+
def by_email_confirmation_token(email_confirmation_token)
|
58
|
+
users.where(Sequel[email_confirmation_token: email_confirmation_token]).one
|
59
|
+
end
|
60
|
+
|
61
|
+
# Search user in database by phone_confirmation_token of phone keys.
|
62
|
+
# @param phone [String] User phone confirmation token
|
63
|
+
# @return [ROM::Struct::User, nil]
|
64
|
+
def by_phone_confirmation_token(phone_confirmation_token)
|
65
|
+
users.where(Sequel[phone_confirmation_token: phone_confirmation_token]).one
|
66
|
+
end
|
67
|
+
|
68
|
+
# Checks if it returns any user given one or more conditions.
|
69
|
+
# @param conditions [Hash] DSL Dataset
|
70
|
+
# @return [true] when some user is returned from the given condition.
|
71
|
+
# @return [false] when no user is returned from the given condition.
|
72
|
+
def exists?(conditions)
|
73
|
+
users.exist?(conditions)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
3
|
+
<head>
|
4
|
+
<title>AuctionFun</title>
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
8
|
+
<style type="text/css">
|
9
|
+
#outlook a {
|
10
|
+
padding: 0;
|
11
|
+
}
|
12
|
+
body {
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
-webkit-text-size-adjust: 100%;
|
16
|
+
-ms-text-size-adjust: 100%;
|
17
|
+
}
|
18
|
+
table,
|
19
|
+
td {
|
20
|
+
border-collapse: collapse;
|
21
|
+
mso-table-lspace: 0pt;
|
22
|
+
mso-table-rspace: 0pt;
|
23
|
+
}
|
24
|
+
img {
|
25
|
+
border: 0;
|
26
|
+
height: auto;
|
27
|
+
line-height: 100%;
|
28
|
+
outline: none;
|
29
|
+
text-decoration: none;
|
30
|
+
-ms-interpolation-mode: bicubic;
|
31
|
+
}
|
32
|
+
p {
|
33
|
+
display: block;
|
34
|
+
margin: 13px 0;
|
35
|
+
}
|
36
|
+
</style>
|
37
|
+
<style type="text/css">
|
38
|
+
.mj-outlook-group-fix { width:100% !important; }
|
39
|
+
</style>
|
40
|
+
<style type="text/css">
|
41
|
+
@media only screen and (min-width:480px) {
|
42
|
+
.mj-column-per-100 {
|
43
|
+
width: 100% !important;
|
44
|
+
max-width: 100%;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
<style type="text/css">
|
49
|
+
@media only screen and (max-width:480px) {
|
50
|
+
table.mj-full-width-mobile {
|
51
|
+
width: 100% !important;
|
52
|
+
}
|
53
|
+
td.mj-full-width-mobile {
|
54
|
+
width: auto !important;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
</style>
|
58
|
+
<style type="text/css">
|
59
|
+
a,
|
60
|
+
span,
|
61
|
+
td,
|
62
|
+
th {
|
63
|
+
-webkit-font-smoothing: antialiased !important;
|
64
|
+
-moz-osx-font-smoothing: grayscale !important;
|
65
|
+
}
|
66
|
+
</style>
|
67
|
+
</head>
|
68
|
+
<body style="background-color:#ffffff;">
|
69
|
+
<%= yield %>
|
70
|
+
</div>
|
71
|
+
</body>
|
72
|
+
</html>
|
@@ -0,0 +1,170 @@
|
|
1
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" style="width:600px;" width="600">
|
2
|
+
<tr>
|
3
|
+
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
|
4
|
+
<div style="margin:0px auto;max-width:600px;">
|
5
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
6
|
+
<tbody>
|
7
|
+
<tr>
|
8
|
+
<td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;text-align:center;">
|
9
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
10
|
+
<tr>
|
11
|
+
<td style="vertical-align:top;width:600px;">
|
12
|
+
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
13
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
14
|
+
<tbody>
|
15
|
+
<tr>
|
16
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
17
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;">
|
18
|
+
<tbody>
|
19
|
+
<tr>
|
20
|
+
<td style="width:50px;">
|
21
|
+
<img alt="image description" height="auto" src="https://codedmails.com/images/logo-circle.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:14px;" width="50" />
|
22
|
+
</td>
|
23
|
+
</tr>
|
24
|
+
</tbody>
|
25
|
+
</table>
|
26
|
+
</td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
30
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
31
|
+
<h1 style="margin: 0; font-size: 24px; line-height: normal; font-weight: bold;">
|
32
|
+
<%= I18n.t("mail.general.hello", name: @user.name) %>,
|
33
|
+
</h1>
|
34
|
+
</div>
|
35
|
+
</td>
|
36
|
+
</tr>
|
37
|
+
</tbody>
|
38
|
+
</table>
|
39
|
+
</div>
|
40
|
+
</td>
|
41
|
+
</tr>
|
42
|
+
</table>
|
43
|
+
</td>
|
44
|
+
</tr>
|
45
|
+
</tbody>
|
46
|
+
</table>
|
47
|
+
</div>
|
48
|
+
</td>
|
49
|
+
</tr>
|
50
|
+
</table>
|
51
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" style="width:600px;" width="600">
|
52
|
+
<tr>
|
53
|
+
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
|
54
|
+
<div style="margin:0px auto;max-width:600px;">
|
55
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
56
|
+
<tbody>
|
57
|
+
<tr>
|
58
|
+
<td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;">
|
59
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
60
|
+
<tr>
|
61
|
+
<td style="vertical-align:top;width:600px;">
|
62
|
+
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
63
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
64
|
+
<tbody>
|
65
|
+
<tr>
|
66
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
67
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
68
|
+
<%= I18n.t("mail.user_context.registration.body.description") %>
|
69
|
+
</div>
|
70
|
+
</td>
|
71
|
+
</tr>
|
72
|
+
<tr>
|
73
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
74
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
75
|
+
<%= raw I18n.t("mail.user_context.registration.body.email_confirmation_token", token: @user.email_confirmation_token) %>
|
76
|
+
</div>
|
77
|
+
</td>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
81
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:bold;line-height:24px;text-align:left;color:#434245;">
|
82
|
+
<%= I18n.t("mail.general.team") %>
|
83
|
+
</div>
|
84
|
+
</td>
|
85
|
+
</tr>
|
86
|
+
<tr>
|
87
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
88
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
89
|
+
<tr>
|
90
|
+
<td>
|
91
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
92
|
+
<tbody>
|
93
|
+
<tr>
|
94
|
+
<td style="padding:4px;">
|
95
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
96
|
+
<tbody>
|
97
|
+
<tr>
|
98
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
99
|
+
<a href="https://twitter.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
100
|
+
<img alt="twitter-logo" height="18" src="https://codedmails.com/images/social/black/twitter-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
101
|
+
</a>
|
102
|
+
</td>
|
103
|
+
</tr>
|
104
|
+
</tbody>
|
105
|
+
</table>
|
106
|
+
</td>
|
107
|
+
</tr>
|
108
|
+
</tbody>
|
109
|
+
</table>
|
110
|
+
</td>
|
111
|
+
<td>
|
112
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
113
|
+
<tbody>
|
114
|
+
<tr>
|
115
|
+
<td style="padding:4px;">
|
116
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
117
|
+
<tbody>
|
118
|
+
<tr>
|
119
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
120
|
+
<a href="https://facebook.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
121
|
+
<img alt="facebook-logo" height="18" src="https://codedmails.com/images/social/black/facebook-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
122
|
+
</a>
|
123
|
+
</td>
|
124
|
+
</tr>
|
125
|
+
</tbody>
|
126
|
+
</table>
|
127
|
+
</td>
|
128
|
+
</tr>
|
129
|
+
</tbody>
|
130
|
+
</table>
|
131
|
+
</td>
|
132
|
+
<td>
|
133
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
134
|
+
<tbody>
|
135
|
+
<tr>
|
136
|
+
<td style="padding:4px;">
|
137
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
138
|
+
<tbody>
|
139
|
+
<tr>
|
140
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
141
|
+
<a href="https://instagram.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
142
|
+
<img alt="instagram-logo" height="18" src="https://codedmails.com/images/social/black/instagram-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
143
|
+
</a>
|
144
|
+
</td>
|
145
|
+
</tr>
|
146
|
+
</tbody>
|
147
|
+
</table>
|
148
|
+
</td>
|
149
|
+
</tr>
|
150
|
+
</tbody>
|
151
|
+
</table>
|
152
|
+
</td>
|
153
|
+
</tr>
|
154
|
+
</table>
|
155
|
+
</td>
|
156
|
+
</tr>
|
157
|
+
</tbody>
|
158
|
+
</table>
|
159
|
+
</div>
|
160
|
+
</td>
|
161
|
+
</tr>
|
162
|
+
</table>
|
163
|
+
</td>
|
164
|
+
</tr>
|
165
|
+
</tbody>
|
166
|
+
</table>
|
167
|
+
</div>
|
168
|
+
</td>
|
169
|
+
</tr>
|
170
|
+
</table>
|