We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tickets can be created with end date greater than event end date
**Describe the bug**
Tickets can be created with end date greater than event end date.


**Expected behavior**
There should be a server-side check to check that this doesn't happen


**Additional context**
- [x]  Taking this up

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `app/api/tickets.py`
Content:
```
1 from flask import request, current_app
2 from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
3 from flask_rest_jsonapi.exceptions import ObjectNotFound
4 from flask_jwt_extended import current_user, verify_jwt_in_request
5 from sqlalchemy.orm.exc import NoResultFound
6 
7 from app.api.bootstrap import api
8 from app.api.helpers.db import safe_query
9 from app.api.helpers.permission_manager import has_access
10 from app.api.helpers.query import event_query
11 from app.api.helpers.utilities import require_relationship
12 from app.api.schema.tickets import TicketSchema, TicketSchemaPublic
13 from app.models import db
14 from app.models.access_code import AccessCode
15 from app.models.discount_code import DiscountCode
16 from app.models.order import Order
17 from app.models.ticket import Ticket, TicketTag, ticket_tags_table
18 from app.models.event import Event
19 from app.models.ticket_holder import TicketHolder
20 from app.api.helpers.exceptions import ConflictException, MethodNotAllowed, UnprocessableEntity
21 from app.api.helpers.db import get_count
22 
23 class TicketListPost(ResourceList):
24     """
25     Create and List Tickets
26     """
27     def before_post(self, args, kwargs, data):
28         """
29         before post method to check for required relationship and proper permission
30         :param args:
31         :param kwargs:
32         :param data:
33         :return:
34         """
35         require_relationship(['event'], data)
36         if not has_access('is_coorganizer', event_id=data['event']):
37             raise ObjectNotFound({'parameter': 'event_id'},
38                                  "Event: {} not found".format(data['event']))
39 
40         if get_count(db.session.query(Ticket.id).filter_by(name=data['name'], event_id=int(data['event']),
41                                                            deleted_at=None)) > 0:
42             raise ConflictException({'pointer': '/data/attributes/name'}, "Ticket already exists")
43 
44     def before_create_object(self, data, view_kwargs):
45         """
46         before create method to check if paid ticket has a paymentMethod enabled
47         :param data:
48         :param view_kwargs:
49         :return:
50         """
51         if data.get('type') == 'paid' and data.get('event'):
52             try:
53                 event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()
54             except NoResultFound:
55                 raise UnprocessableEntity({'event_id': data['event']}, "Event does not exist")
56             if not event.is_payment_enabled():
57                 raise UnprocessableEntity(
58                     {'event_id': data['event']}, "Event having paid ticket must have a payment method")
59 
60     schema = TicketSchema
61     methods = ['POST', ]
62     data_layer = {'session': db.session,
63                   'model': Ticket,
64                   'methods': {
65                       'before_create_object': before_create_object,
66                       'before_post': before_post
67                   }}
68 
69 
70 class TicketList(ResourceList):
71     """
72     List Tickets based on different params
73     """
74     def before_get(self, args, view_kwargs):
75         """
76         before get method to get the resource id for assigning schema
77         :param args:
78         :param view_kwargs:
79         :return:
80         """
81         if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'):
82             self.schema = TicketSchemaPublic
83 
84     def query(self, view_kwargs):
85         """
86         query method for resource list
87         :param view_kwargs:
88         :return:
89         """
90 
91         if 'Authorization' in request.headers:
92             verify_jwt_in_request()
93             if current_user.is_super_admin or current_user.is_admin:
94                 query_ = self.session.query(Ticket)
95             elif view_kwargs.get('event_id') and has_access('is_organizer', event_id=view_kwargs['event_id']):
96                 query_ = self.session.query(Ticket)
97             else:
98                 query_ = self.session.query(Ticket).filter_by(is_hidden=False)
99         else:
100             query_ = self.session.query(Ticket).filter_by(is_hidden=False)
101 
102         if view_kwargs.get('ticket_tag_id'):
103             ticket_tag = safe_query(self, TicketTag, 'id', view_kwargs['ticket_tag_id'], 'ticket_tag_id')
104             query_ = query_.join(ticket_tags_table).filter_by(ticket_tag_id=ticket_tag.id)
105         query_ = event_query(self, query_, view_kwargs)
106         if view_kwargs.get('access_code_id'):
107             access_code = safe_query(self, AccessCode, 'id', view_kwargs['access_code_id'], 'access_code_id')
108             # access_code - ticket :: many-to-many relationship
109             query_ = Ticket.query.filter(Ticket.access_codes.any(id=access_code.id))
110 
111         if view_kwargs.get('discount_code_id'):
112             discount_code = safe_query(self, DiscountCode, 'id', view_kwargs['discount_code_id'], 'discount_code_id')
113             # discount_code - ticket :: many-to-many relationship
114             query_ = Ticket.query.filter(Ticket.discount_codes.any(id=discount_code.id))
115 
116         if view_kwargs.get('order_identifier'):
117             order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')
118             ticket_ids = []
119             for ticket in order.tickets:
120                 ticket_ids.append(ticket.id)
121             query_ = query_.filter(Ticket.id.in_(tuple(ticket_ids)))
122 
123         return query_
124 
125     view_kwargs = True
126     methods = ['GET', ]
127     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
128                   fetch_as="event_id", model=Ticket, methods="POST",
129                   check=lambda a: a.get('event_id') or a.get('event_identifier')),)
130     schema = TicketSchema
131     data_layer = {'session': db.session,
132                   'model': Ticket,
133                   'methods': {
134                       'query': query,
135                   }}
136 
137 
138 class TicketDetail(ResourceDetail):
139     """
140     Ticket Resource
141     """
142     def before_get(self, args, view_kwargs):
143         """
144         before get method to get the resource id for assigning schema
145         :param args:
146         :param view_kwargs:
147         :return:
148         """
149         if view_kwargs.get('attendee_id'):
150             self.schema = TicketSchemaPublic
151 
152     def before_get_object(self, view_kwargs):
153         """
154         before get object method to get the resource id for fetching details
155         :param view_kwargs:
156         :return:
157         """
158         if view_kwargs.get('attendee_id') is not None:
159             attendee = safe_query(self, TicketHolder, 'id', view_kwargs['attendee_id'], 'attendee_id')
160             if attendee.ticket_id is not None:
161                 view_kwargs['id'] = attendee.ticket_id
162             else:
163                 view_kwargs['id'] = None
164 
165     def before_update_object(self, ticket, data, view_kwargs):
166         """
167         method to check if paid ticket has payment method before updating ticket object
168         :param ticket:
169         :param data:
170         :param view_kwargs:
171         :return:
172         """
173         if ticket.type == 'paid':
174             try:
175                 event = db.session.query(Event).filter_by(id=ticket.event.id, deleted_at=None).one()
176             except NoResultFound:
177                 raise UnprocessableEntity({'event_id': ticket.event.id}, "Event does not exist")
178             if not event.is_payment_enabled():
179                 raise UnprocessableEntity(
180                     {'event_id': ticket.event.id}, "Event having paid ticket must have a payment method")
181 
182     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
183                   fetch_as="event_id", model=Ticket, methods="PATCH,DELETE"),)
184     schema = TicketSchema
185     data_layer = {'session': db.session,
186                   'model': Ticket,
187                   'methods': {
188                       'before_get_object': before_get_object,
189                       'before_update_object': before_update_object
190                   }}
191 
192 
193 class TicketRelationshipRequired(ResourceRelationship):
194     """
195     Tickets Relationship (Required)
196     """
197     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
198                                      fetch_as="event_id", model=Ticket, methods="PATCH"),)
199     methods = ['GET', 'PATCH']
200     schema = TicketSchema
201     data_layer = {'session': db.session,
202                   'model': Ticket}
203 
204 
205 class TicketRelationshipOptional(ResourceRelationship):
206     """
207     Tickets Relationship (Optional)
208     """
209     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
210                                      fetch_as="event_id", model=Ticket, methods="PATCH,DELETE"),)
211     schema = TicketSchema
212     data_layer = {'session': db.session,
213                   'model': Ticket}
214
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/app/api/tickets.py b/app/api/tickets.py
--- a/app/api/tickets.py
+++ b/app/api/tickets.py
@@ -48,14 +48,20 @@
         :param view_kwargs:
         :return:
         """
-        if data.get('type') == 'paid' and data.get('event'):
+        if data.get('event'):
             try:
                 event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()
             except NoResultFound:
                 raise UnprocessableEntity({'event_id': data['event']}, "Event does not exist")
-            if not event.is_payment_enabled():
-                raise UnprocessableEntity(
-                    {'event_id': data['event']}, "Event having paid ticket must have a payment method")
+
+            if data.get('type') == 'paid':
+                if not event.is_payment_enabled():
+                    raise UnprocessableEntity(
+                        {'event_id': data['event']}, "Event having paid ticket must have a payment method")
+
+            if data.get('sales_ends_at') > event.ends_at:
+                raise UnprocessableEntity({'sales_ends_at': '/data/attributes/sales-ends-at'},
+                                          "Ticket end date cannot be greater than event end date")
 
     schema = TicketSchema
     methods = ['POST', ]

{"golden_diff": "diff --git a/app/api/tickets.py b/app/api/tickets.py\n--- a/app/api/tickets.py\n+++ b/app/api/tickets.py\n@@ -48,14 +48,20 @@\n         :param view_kwargs:\n         :return:\n         \"\"\"\n-        if data.get('type') == 'paid' and data.get('event'):\n+        if data.get('event'):\n             try:\n                 event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()\n             except NoResultFound:\n                 raise UnprocessableEntity({'event_id': data['event']}, \"Event does not exist\")\n-            if not event.is_payment_enabled():\n-                raise UnprocessableEntity(\n-                    {'event_id': data['event']}, \"Event having paid ticket must have a payment method\")\n+\n+            if data.get('type') == 'paid':\n+                if not event.is_payment_enabled():\n+                    raise UnprocessableEntity(\n+                        {'event_id': data['event']}, \"Event having paid ticket must have a payment method\")\n+\n+            if data.get('sales_ends_at') > event.ends_at:\n+                raise UnprocessableEntity({'sales_ends_at': '/data/attributes/sales-ends-at'},\n+                                          \"Ticket end date cannot be greater than event end date\")\n \n     schema = TicketSchema\n     methods = ['POST', ]\n", "issue": "Tickets can be created with end date greater than event end date\n**Describe the bug**\r\nTickets can be created with end date greater than event end date.\r\n\r\n\r\n**Expected behavior**\r\nThere should be a server-side check to check that this doesn't happen\r\n\r\n\r\n**Additional context**\r\n- [x]  Taking this up\n", "before_files": [{"content": "from flask import request, current_app\nfrom flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship\nfrom flask_rest_jsonapi.exceptions import ObjectNotFound\nfrom flask_jwt_extended import current_user, verify_jwt_in_request\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom app.api.bootstrap import api\nfrom app.api.helpers.db import safe_query\nfrom app.api.helpers.permission_manager import has_access\nfrom app.api.helpers.query import event_query\nfrom app.api.helpers.utilities import require_relationship\nfrom app.api.schema.tickets import TicketSchema, TicketSchemaPublic\nfrom app.models import db\nfrom app.models.access_code import AccessCode\nfrom app.models.discount_code import DiscountCode\nfrom app.models.order import Order\nfrom app.models.ticket import Ticket, TicketTag, ticket_tags_table\nfrom app.models.event import Event\nfrom app.models.ticket_holder import TicketHolder\nfrom app.api.helpers.exceptions import ConflictException, MethodNotAllowed, UnprocessableEntity\nfrom app.api.helpers.db import get_count\n\nclass TicketListPost(ResourceList):\n    \"\"\"\n    Create and List Tickets\n    \"\"\"\n    def before_post(self, args, kwargs, data):\n        \"\"\"\n        before post method to check for required relationship and proper permission\n        :param args:\n        :param kwargs:\n        :param data:\n        :return:\n        \"\"\"\n        require_relationship(['event'], data)\n        if not has_access('is_coorganizer', event_id=data['event']):\n            raise ObjectNotFound({'parameter': 'event_id'},\n                                 \"Event: {} not found\".format(data['event']))\n\n        if get_count(db.session.query(Ticket.id).filter_by(name=data['name'], event_id=int(data['event']),\n                                                           deleted_at=None)) > 0:\n            raise ConflictException({'pointer': '/data/attributes/name'}, \"Ticket already exists\")\n\n    def before_create_object(self, data, view_kwargs):\n        \"\"\"\n        before create method to check if paid ticket has a paymentMethod enabled\n        :param data:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if data.get('type') == 'paid' and data.get('event'):\n            try:\n                event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()\n            except NoResultFound:\n                raise UnprocessableEntity({'event_id': data['event']}, \"Event does not exist\")\n            if not event.is_payment_enabled():\n                raise UnprocessableEntity(\n                    {'event_id': data['event']}, \"Event having paid ticket must have a payment method\")\n\n    schema = TicketSchema\n    methods = ['POST', ]\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'before_create_object': before_create_object,\n                      'before_post': before_post\n                  }}\n\n\nclass TicketList(ResourceList):\n    \"\"\"\n    List Tickets based on different params\n    \"\"\"\n    def before_get(self, args, view_kwargs):\n        \"\"\"\n        before get method to get the resource id for assigning schema\n        :param args:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'):\n            self.schema = TicketSchemaPublic\n\n    def query(self, view_kwargs):\n        \"\"\"\n        query method for resource list\n        :param view_kwargs:\n        :return:\n        \"\"\"\n\n        if 'Authorization' in request.headers:\n            verify_jwt_in_request()\n            if current_user.is_super_admin or current_user.is_admin:\n                query_ = self.session.query(Ticket)\n            elif view_kwargs.get('event_id') and has_access('is_organizer', event_id=view_kwargs['event_id']):\n                query_ = self.session.query(Ticket)\n            else:\n                query_ = self.session.query(Ticket).filter_by(is_hidden=False)\n        else:\n            query_ = self.session.query(Ticket).filter_by(is_hidden=False)\n\n        if view_kwargs.get('ticket_tag_id'):\n            ticket_tag = safe_query(self, TicketTag, 'id', view_kwargs['ticket_tag_id'], 'ticket_tag_id')\n            query_ = query_.join(ticket_tags_table).filter_by(ticket_tag_id=ticket_tag.id)\n        query_ = event_query(self, query_, view_kwargs)\n        if view_kwargs.get('access_code_id'):\n            access_code = safe_query(self, AccessCode, 'id', view_kwargs['access_code_id'], 'access_code_id')\n            # access_code - ticket :: many-to-many relationship\n            query_ = Ticket.query.filter(Ticket.access_codes.any(id=access_code.id))\n\n        if view_kwargs.get('discount_code_id'):\n            discount_code = safe_query(self, DiscountCode, 'id', view_kwargs['discount_code_id'], 'discount_code_id')\n            # discount_code - ticket :: many-to-many relationship\n            query_ = Ticket.query.filter(Ticket.discount_codes.any(id=discount_code.id))\n\n        if view_kwargs.get('order_identifier'):\n            order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')\n            ticket_ids = []\n            for ticket in order.tickets:\n                ticket_ids.append(ticket.id)\n            query_ = query_.filter(Ticket.id.in_(tuple(ticket_ids)))\n\n        return query_\n\n    view_kwargs = True\n    methods = ['GET', ]\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                  fetch_as=\"event_id\", model=Ticket, methods=\"POST\",\n                  check=lambda a: a.get('event_id') or a.get('event_identifier')),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'query': query,\n                  }}\n\n\nclass TicketDetail(ResourceDetail):\n    \"\"\"\n    Ticket Resource\n    \"\"\"\n    def before_get(self, args, view_kwargs):\n        \"\"\"\n        before get method to get the resource id for assigning schema\n        :param args:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('attendee_id'):\n            self.schema = TicketSchemaPublic\n\n    def before_get_object(self, view_kwargs):\n        \"\"\"\n        before get object method to get the resource id for fetching details\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('attendee_id') is not None:\n            attendee = safe_query(self, TicketHolder, 'id', view_kwargs['attendee_id'], 'attendee_id')\n            if attendee.ticket_id is not None:\n                view_kwargs['id'] = attendee.ticket_id\n            else:\n                view_kwargs['id'] = None\n\n    def before_update_object(self, ticket, data, view_kwargs):\n        \"\"\"\n        method to check if paid ticket has payment method before updating ticket object\n        :param ticket:\n        :param data:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if ticket.type == 'paid':\n            try:\n                event = db.session.query(Event).filter_by(id=ticket.event.id, deleted_at=None).one()\n            except NoResultFound:\n                raise UnprocessableEntity({'event_id': ticket.event.id}, \"Event does not exist\")\n            if not event.is_payment_enabled():\n                raise UnprocessableEntity(\n                    {'event_id': ticket.event.id}, \"Event having paid ticket must have a payment method\")\n\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                  fetch_as=\"event_id\", model=Ticket, methods=\"PATCH,DELETE\"),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'before_get_object': before_get_object,\n                      'before_update_object': before_update_object\n                  }}\n\n\nclass TicketRelationshipRequired(ResourceRelationship):\n    \"\"\"\n    Tickets Relationship (Required)\n    \"\"\"\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                                     fetch_as=\"event_id\", model=Ticket, methods=\"PATCH\"),)\n    methods = ['GET', 'PATCH']\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket}\n\n\nclass TicketRelationshipOptional(ResourceRelationship):\n    \"\"\"\n    Tickets Relationship (Optional)\n    \"\"\"\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                                     fetch_as=\"event_id\", model=Ticket, methods=\"PATCH,DELETE\"),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket}\n", "path": "app/api/tickets.py"}], "after_files": [{"content": "from flask import request, current_app\nfrom flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship\nfrom flask_rest_jsonapi.exceptions import ObjectNotFound\nfrom flask_jwt_extended import current_user, verify_jwt_in_request\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom app.api.bootstrap import api\nfrom app.api.helpers.db import safe_query\nfrom app.api.helpers.permission_manager import has_access\nfrom app.api.helpers.query import event_query\nfrom app.api.helpers.utilities import require_relationship\nfrom app.api.schema.tickets import TicketSchema, TicketSchemaPublic\nfrom app.models import db\nfrom app.models.access_code import AccessCode\nfrom app.models.discount_code import DiscountCode\nfrom app.models.order import Order\nfrom app.models.ticket import Ticket, TicketTag, ticket_tags_table\nfrom app.models.event import Event\nfrom app.models.ticket_holder import TicketHolder\nfrom app.api.helpers.exceptions import ConflictException, MethodNotAllowed, UnprocessableEntity\nfrom app.api.helpers.db import get_count\n\nclass TicketListPost(ResourceList):\n    \"\"\"\n    Create and List Tickets\n    \"\"\"\n    def before_post(self, args, kwargs, data):\n        \"\"\"\n        before post method to check for required relationship and proper permission\n        :param args:\n        :param kwargs:\n        :param data:\n        :return:\n        \"\"\"\n        require_relationship(['event'], data)\n        if not has_access('is_coorganizer', event_id=data['event']):\n            raise ObjectNotFound({'parameter': 'event_id'},\n                                 \"Event: {} not found\".format(data['event']))\n\n        if get_count(db.session.query(Ticket.id).filter_by(name=data['name'], event_id=int(data['event']),\n                                                           deleted_at=None)) > 0:\n            raise ConflictException({'pointer': '/data/attributes/name'}, \"Ticket already exists\")\n\n    def before_create_object(self, data, view_kwargs):\n        \"\"\"\n        before create method to check if paid ticket has a paymentMethod enabled\n        :param data:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if data.get('event'):\n            try:\n                event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()\n            except NoResultFound:\n                raise UnprocessableEntity({'event_id': data['event']}, \"Event does not exist\")\n\n            if data.get('type') == 'paid':\n                if not event.is_payment_enabled():\n                    raise UnprocessableEntity(\n                        {'event_id': data['event']}, \"Event having paid ticket must have a payment method\")\n\n            if data.get('sales_ends_at') > event.ends_at:\n                raise UnprocessableEntity({'sales_ends_at': '/data/attributes/sales-ends-at'},\n                                          \"Ticket end date cannot be greater than event end date\")\n\n    schema = TicketSchema\n    methods = ['POST', ]\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'before_create_object': before_create_object,\n                      'before_post': before_post\n                  }}\n\n\nclass TicketList(ResourceList):\n    \"\"\"\n    List Tickets based on different params\n    \"\"\"\n    def before_get(self, args, view_kwargs):\n        \"\"\"\n        before get method to get the resource id for assigning schema\n        :param args:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'):\n            self.schema = TicketSchemaPublic\n\n    def query(self, view_kwargs):\n        \"\"\"\n        query method for resource list\n        :param view_kwargs:\n        :return:\n        \"\"\"\n\n        if 'Authorization' in request.headers:\n            verify_jwt_in_request()\n            if current_user.is_super_admin or current_user.is_admin:\n                query_ = self.session.query(Ticket)\n            elif view_kwargs.get('event_id') and has_access('is_organizer', event_id=view_kwargs['event_id']):\n                query_ = self.session.query(Ticket)\n            else:\n                query_ = self.session.query(Ticket).filter_by(is_hidden=False)\n        else:\n            query_ = self.session.query(Ticket).filter_by(is_hidden=False)\n\n        if view_kwargs.get('ticket_tag_id'):\n            ticket_tag = safe_query(self, TicketTag, 'id', view_kwargs['ticket_tag_id'], 'ticket_tag_id')\n            query_ = query_.join(ticket_tags_table).filter_by(ticket_tag_id=ticket_tag.id)\n        query_ = event_query(self, query_, view_kwargs)\n        if view_kwargs.get('access_code_id'):\n            access_code = safe_query(self, AccessCode, 'id', view_kwargs['access_code_id'], 'access_code_id')\n            # access_code - ticket :: many-to-many relationship\n            query_ = Ticket.query.filter(Ticket.access_codes.any(id=access_code.id))\n\n        if view_kwargs.get('discount_code_id'):\n            discount_code = safe_query(self, DiscountCode, 'id', view_kwargs['discount_code_id'], 'discount_code_id')\n            # discount_code - ticket :: many-to-many relationship\n            query_ = Ticket.query.filter(Ticket.discount_codes.any(id=discount_code.id))\n\n        if view_kwargs.get('order_identifier'):\n            order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')\n            ticket_ids = []\n            for ticket in order.tickets:\n                ticket_ids.append(ticket.id)\n            query_ = query_.filter(Ticket.id.in_(tuple(ticket_ids)))\n\n        return query_\n\n    view_kwargs = True\n    methods = ['GET', ]\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                  fetch_as=\"event_id\", model=Ticket, methods=\"POST\",\n                  check=lambda a: a.get('event_id') or a.get('event_identifier')),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'query': query,\n                  }}\n\n\nclass TicketDetail(ResourceDetail):\n    \"\"\"\n    Ticket Resource\n    \"\"\"\n    def before_get(self, args, view_kwargs):\n        \"\"\"\n        before get method to get the resource id for assigning schema\n        :param args:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('attendee_id'):\n            self.schema = TicketSchemaPublic\n\n    def before_get_object(self, view_kwargs):\n        \"\"\"\n        before get object method to get the resource id for fetching details\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if view_kwargs.get('attendee_id') is not None:\n            attendee = safe_query(self, TicketHolder, 'id', view_kwargs['attendee_id'], 'attendee_id')\n            if attendee.ticket_id is not None:\n                view_kwargs['id'] = attendee.ticket_id\n            else:\n                view_kwargs['id'] = None\n\n    def before_update_object(self, ticket, data, view_kwargs):\n        \"\"\"\n        method to check if paid ticket has payment method before updating ticket object\n        :param ticket:\n        :param data:\n        :param view_kwargs:\n        :return:\n        \"\"\"\n        if ticket.type == 'paid':\n            try:\n                event = db.session.query(Event).filter_by(id=ticket.event.id, deleted_at=None).one()\n            except NoResultFound:\n                raise UnprocessableEntity({'event_id': ticket.event.id}, \"Event does not exist\")\n            if not event.is_payment_enabled():\n                raise UnprocessableEntity(\n                    {'event_id': ticket.event.id}, \"Event having paid ticket must have a payment method\")\n\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                  fetch_as=\"event_id\", model=Ticket, methods=\"PATCH,DELETE\"),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket,\n                  'methods': {\n                      'before_get_object': before_get_object,\n                      'before_update_object': before_update_object\n                  }}\n\n\nclass TicketRelationshipRequired(ResourceRelationship):\n    \"\"\"\n    Tickets Relationship (Required)\n    \"\"\"\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                                     fetch_as=\"event_id\", model=Ticket, methods=\"PATCH\"),)\n    methods = ['GET', 'PATCH']\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket}\n\n\nclass TicketRelationshipOptional(ResourceRelationship):\n    \"\"\"\n    Tickets Relationship (Optional)\n    \"\"\"\n    decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                                     fetch_as=\"event_id\", model=Ticket, methods=\"PATCH,DELETE\"),)\n    schema = TicketSchema\n    data_layer = {'session': db.session,\n                  'model': Ticket}\n", "path": "app/api/tickets.py"}]}