iachat/enterprise/app/services/captain/reservations/revenue_summary_service.rb

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