73 lines
1.8 KiB
Ruby
73 lines
1.8 KiB
Ruby
class Captain::Reservations::RevenueSummaryService
|
|
def initialize(scope:)
|
|
@scope = scope
|
|
end
|
|
|
|
def perform
|
|
{
|
|
summary: {
|
|
total_revenue: total_revenue,
|
|
confirmed_count: confirmed_count,
|
|
average_ticket: average_ticket
|
|
},
|
|
by_unit: grouped_revenue_by_unit,
|
|
by_suite: grouped_revenue_by_suite
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :scope
|
|
|
|
def total_revenue
|
|
scope.sum(:total_amount).to_f
|
|
end
|
|
|
|
def confirmed_count
|
|
scope.count
|
|
end
|
|
|
|
def average_ticket
|
|
return 0.0 unless confirmed_count.positive?
|
|
|
|
total_revenue / confirmed_count
|
|
end
|
|
|
|
def grouped_revenue_by_unit
|
|
scope.left_joins(:unit)
|
|
.group('captain_units.id', 'captain_units.name')
|
|
.order(Arel.sql('COALESCE(SUM(captain_reservations.total_amount), 0) DESC'))
|
|
.pluck(
|
|
'captain_units.id',
|
|
'captain_units.name',
|
|
Arel.sql('COUNT(captain_reservations.id)'),
|
|
Arel.sql('COALESCE(SUM(captain_reservations.total_amount), 0)')
|
|
)
|
|
.map do |unit_id, unit_name, count, amount|
|
|
{
|
|
unit_id: unit_id,
|
|
unit_name: unit_name,
|
|
reservations_count: count.to_i,
|
|
total_revenue: amount.to_f
|
|
}
|
|
end
|
|
end
|
|
|
|
def grouped_revenue_by_suite
|
|
scope.group(:suite_identifier)
|
|
.order(Arel.sql('COALESCE(SUM(captain_reservations.total_amount), 0) DESC'))
|
|
.pluck(
|
|
:suite_identifier,
|
|
Arel.sql('COUNT(captain_reservations.id)'),
|
|
Arel.sql('COALESCE(SUM(captain_reservations.total_amount), 0)')
|
|
)
|
|
.map do |suite_identifier, count, amount|
|
|
{
|
|
suite_identifier: suite_identifier,
|
|
reservations_count: count.to_i,
|
|
total_revenue: amount.to_f
|
|
}
|
|
end
|
|
end
|
|
end
|