1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88# frozen_string_literal: true
class SubscriptionService
class << self
def create_subscription(work_email:, first_name:, last_name:, category_guids:)
return if category_guids.blank?
ActiveRecord::Base.transaction do
customer = Customer.find_or_create_by!(work_email: work_email) do |c|
c.first_name = first_name
c.last_name = last_name
c.guid = SecureRandom.uuid
end
subscriptions = prepare_subscription_data(customer, category_guids)
Subscription.insert_all!(subscriptions)
rescue StandardError
raise StandardError, I18n.t('services.subscription.errors.create_failed')
end
end
def get_subscriptions(category_guids: nil, pagination_id: nil, pagination_direction: 'forward', limit: 10)
subscriptions = fetch_subscriptions(
category_guids: category_guids,
limit: limit + 1,
pagination_id: pagination_id,
pagination_direction: pagination_direction
).to_a
subscription_list = build_subscription_list(subscriptions, limit, pagination_direction)
formatted_subscription_list = format_subscription_list(subscription_list)
{
subscriptions: formatted_subscription_list.as_json(except: [:id, :customer_id]),
previous_cursor: formatted_subscription_list.first&.customer_id,
next_cursor: formatted_subscription_list.last&.customer_id,
has_more: subscriptions.size > limit
}
end
private
def get_unsubscribed_category_ids(customer, category_guids)
subscribed_guids = customer.subscriptions.joins(:category).pluck('categories.guid')
unsubscribed_category_guids = category_guids - subscribed_guids
Category.where(guid: unsubscribed_category_guids).pluck(:id)
end
def prepare_subscription_data(customer, category_guids)
unsubscribed_category_ids = get_unsubscribed_category_ids(customer, category_guids)
raise ActiveRecord::Rollback if unsubscribed_category_ids.empty?
unsubscribed_category_ids.map do |category_id|
{
customer_id: customer.id,
category_id: category_id,
guid: SecureRandom.uuid,
created_at: Time.current,
updated_at: Time.current
}
end
end
def fetch_subscriptions(limit:, category_guids: nil, pagination_id: nil, pagination_direction: 'forward')
subscriptions = Subscription.fetch_subscriptions(
limit: limit,
category_guids: category_guids,
pagination_id: pagination_id,
pagination_direction: pagination_direction
)
pagination_direction == 'backward' ? subscriptions.reverse : subscriptions
end
def build_subscription_list(subscriptions, limit, pagination_direction)
return subscriptions.take(limit) if pagination_direction == 'forward'
return subscriptions.drop(1).take(limit) if subscriptions.size > limit
subscriptions.take(limit)
end
def format_subscription_list(subscription_list)
subscription_list.map do |subscription|
subscription.tap do |s|
s.category_names = s.category_names&.split(',') || []
end
end
end
end
end