Repository: fossasia/open-event-server

Issue:
Add endpoint for list of orders under a user. 
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
The FE needs this endpoint in the My Tickets tab. It should accept the user_id as the URL parameter and send the orders under that user in the response.

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
Parent #4852 


Discussion:

Resolving patch:
diff --git a/app/api/__init__.py b/app/api/__init__.py
--- a/app/api/__init__.py
+++ b/app/api/__init__.py
@@ -502,7 +502,7 @@
 # Orders API
 api.route(OrdersListPost, 'order_list_post', '/orders')
 api.route(OrdersList, 'orders_list', '/orders', '/events/<int:event_id>/orders',
-          '/events/<event_identifier>/orders')
+          '/events/<event_identifier>/orders', '/users/<int:user_id>/orders')
 api.route(OrderDetail, 'order_detail', '/orders/<order_identifier>',
           '/attendees/<int:attendee_id>/order')
 
diff --git a/app/api/orders.py b/app/api/orders.py
--- a/app/api/orders.py
+++ b/app/api/orders.py
@@ -7,7 +7,6 @@
 from marshmallow_jsonapi.flask import Schema
 from sqlalchemy.orm.exc import NoResultFound
 
-from app.api.helpers.storage import UPLOAD_PATHS
 from app.api.data_layers.ChargesLayer import ChargesLayer
 from app.api.helpers.db import save_to_db, safe_query, safe_query_without_soft_deleted_entries
 from app.api.helpers.exceptions import ForbiddenException, UnprocessableEntity, ConflictException
@@ -17,10 +16,11 @@
 from app.api.helpers.mail import send_order_cancel_email
 from app.api.helpers.notification import send_notif_to_attendees, send_notif_ticket_purchase_organizer, \
     send_notif_ticket_cancel
+from app.api.helpers.order import delete_related_attendees_for_order
 from app.api.helpers.permission_manager import has_access
 from app.api.helpers.permissions import jwt_required
 from app.api.helpers.query import event_query
-from app.api.helpers.order import delete_related_attendees_for_order
+from app.api.helpers.storage import UPLOAD_PATHS
 from app.api.helpers.ticketing import TicketingManager
 from app.api.helpers.utilities import dasherize, require_relationship
 from app.api.schema.orders import OrderSchema
@@ -28,6 +28,7 @@
 from app.models.discount_code import DiscountCode, TICKET
 from app.models.order import Order, OrderTicket
 from app.models.ticket_holder import TicketHolder
+from app.models.user import User
 
 
 class OrdersListPost(ResourceList):
@@ -163,7 +164,15 @@ def before_get(self, args, kwargs):
 
     def query(self, view_kwargs):
         query_ = self.session.query(Order)
-        query_ = event_query(self, query_, view_kwargs)
+        if view_kwargs.get('user_id'):
+            # orders under a user
+            user = safe_query(self, User, 'id', view_kwargs['user_id'], 'user_id')
+            if not has_access('is_user_itself', user_id=user.id):
+                raise ForbiddenException({'source': ''}, 'Access Forbidden')
+            query_ = query_.join(User, User.id == Order.user_id).filter(User.id == user.id)
+        else:
+            # orders under an event
+            query_ = event_query(self, query_, view_kwargs)
 
         return query_
 


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -3762,6 +3762,16 @@ def delete_order(transaction):
     transaction['skip'] = True
 
 
+@hooks.before("Orders > Orders under a User > List all Orders under a User")
+def orders_get_collection_under_user(transaction):
+    """
+    GET /users/1/orders
+    :param transaction:
+    :return:
+    """
+    transaction['skip'] = True
+
+
 @hooks.before("Event Copy > Create Event Copy > Create Copy")
 def create_event_copy(transaction):
     """