diff --git a/app/api/admin_sales/events.py b/app/api/admin_sales/events.py index 125b94a9c2..fad635508e 100644 --- a/app/api/admin_sales/events.py +++ b/app/api/admin_sales/events.py @@ -26,10 +26,13 @@ class Meta: inflect = dasherize id = fields.String() + identifier = fields.String() name = fields.String() + created_at = fields.DateTime() starts_at = fields.DateTime() ends_at = fields.DateTime() payment_currency = fields.String() + payment_country = fields.String() sales = fields.Method('calc_sales') @staticmethod @@ -38,7 +41,7 @@ def calc_sales(obj): Returns sales (dictionary with total sales and ticket count) for placed, completed and pending orders """ - return summary(obj.orders) + return summary(obj) class AdminSalesByEventsList(ResourceList): @@ -48,7 +51,7 @@ class AdminSalesByEventsList(ResourceList): """ def query(self, _): - return self.session.query(Event).outerjoin(Order).outerjoin(OrderTicket) + return Event.query methods = ['GET'] decorators = (api.has_permission('is_admin'),) diff --git a/app/api/admin_sales/marketer.py b/app/api/admin_sales/marketer.py index b4888fa818..6b6ef1664d 100644 --- a/app/api/admin_sales/marketer.py +++ b/app/api/admin_sales/marketer.py @@ -33,7 +33,7 @@ def calc_sales(obj): Returns sales (dictionary with total sales and ticket count) for placed, completed and pending orders """ - return summary(obj.orders) + return summary(obj) class AdminSalesByMarketerList(ResourceList): diff --git a/app/api/admin_sales/organizer.py b/app/api/admin_sales/organizer.py index e80673cb15..007c43f3ef 100644 --- a/app/api/admin_sales/organizer.py +++ b/app/api/admin_sales/organizer.py @@ -42,7 +42,7 @@ def calc_sales(obj): Returns sales (dictionary with total sales and ticket count) for placed, completed and pending orders """ - return summary(obj.orders) + return summary(obj) class AdminSalesByOrganizersList(ResourceList): diff --git a/app/api/admin_sales/utils.py b/app/api/admin_sales/utils.py index 2a70b8fdae..c74a460295 100644 --- a/app/api/admin_sales/utils.py +++ b/app/api/admin_sales/utils.py @@ -2,22 +2,50 @@ This module contains common sales calculations that are used throughout the admin section """ +from sqlalchemy import func +from app.models.order import Order +from app.models.ticket_holder import TicketHolder -def status_summary(orders, status): + +def status_summary(sales_summary, tickets_summary, status): """ Groups orders by status and returns the total sales and ticket count as a dictionary """ + sales = 0 + tickets = 0 + + for sale_status, sale in sales_summary: + if sale_status == status: + sales = sale + + for ticket_status, ticket in tickets_summary: + if ticket_status == status: + tickets = ticket + return { - 'sales_total': sum(o.amount for o in orders if o.status == status), - 'ticket_count': sum(o.tickets_count for o in orders if o.status == status), + 'sales_total': sales, + 'ticket_count': tickets, } -def summary(orders): +def summary(event): """ Returns sales as dictionary for all status codes """ + sales_summary = ( + Order.query.filter_by(event_id=event.id) + .with_entities(Order.status, func.sum(Order.amount)) + .group_by(Order.status) + .all() + ) + tickets_summary = ( + TicketHolder.query.join(Order) + .filter(Order.event_id == event.id) + .with_entities(Order.status, func.count()) + .group_by(Order.status) + .all() + ) status_codes = ['placed', 'completed', 'pending'] - return {s: status_summary(orders, s) for s in status_codes} + return {s: status_summary(sales_summary, tickets_summary, s) for s in status_codes}