We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Server checks for ticket prices are missing
**Describe the bug**
Server checks are required for ticket prices. This would also allow decimal values greater than zero to pass through [similar to eventbrite]

**Additional context**
Corresponding FE PR which requires these checks : https://github.com/fossasia/open-event-frontend/pull/3341

--- 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         if get_count(db.session.query(Event).filter_by(id=int(data['event']), is_ticketing_enabled=False)) > 0:
45             raise MethodNotAllowed({'parameter': 'event_id'}, "Ticketing is disabled for this Event")
46 
47     def before_create_object(self, data, view_kwargs):
48         """
49         before create method to check if paid ticket has a paymentMethod enabled
50         :param data:
51         :param view_kwargs:
52         :return:
53         """
54         if data.get('type') == 'paid' and data.get('event'):
55             try:
56                 event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()
57             except NoResultFound:
58                 raise UnprocessableEntity({'event_id': data['event']}, "Event does not exist")
59             if not event.is_payment_enabled():
60                 raise UnprocessableEntity(
61                     {'event_id': data['event']}, "Event having paid ticket must have a payment method")
62 
63     schema = TicketSchema
64     methods = ['POST', ]
65     data_layer = {'session': db.session,
66                   'model': Ticket,
67                   'methods': {
68                       'before_create_object': before_create_object,
69                       'before_post': before_post
70                   }}
71 
72 
73 class TicketList(ResourceList):
74     """
75     List Tickets based on different params
76     """
77     def before_get(self, args, view_kwargs):
78         """
79         before get method to get the resource id for assigning schema
80         :param args:
81         :param view_kwargs:
82         :return:
83         """
84         if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'):
85             self.schema = TicketSchemaPublic
86 
87     def query(self, view_kwargs):
88         """
89         query method for resource list
90         :param view_kwargs:
91         :return:
92         """
93 
94         if 'Authorization' in request.headers:
95             verify_jwt_in_request()
96             if current_user.is_super_admin or current_user.is_admin:
97                 query_ = self.session.query(Ticket)
98             elif view_kwargs.get('event_id') and has_access('is_organizer', event_id=view_kwargs['event_id']):
99                 query_ = self.session.query(Ticket)
100             else:
101                 query_ = self.session.query(Ticket).filter_by(is_hidden=False)
102         else:
103             query_ = self.session.query(Ticket).filter_by(is_hidden=False)
104 
105         if view_kwargs.get('ticket_tag_id'):
106             ticket_tag = safe_query(self, TicketTag, 'id', view_kwargs['ticket_tag_id'], 'ticket_tag_id')
107             query_ = query_.join(ticket_tags_table).filter_by(ticket_tag_id=ticket_tag.id)
108         query_ = event_query(self, query_, view_kwargs)
109         if view_kwargs.get('access_code_id'):
110             access_code = safe_query(self, AccessCode, 'id', view_kwargs['access_code_id'], 'access_code_id')
111             # access_code - ticket :: many-to-many relationship
112             query_ = Ticket.query.filter(Ticket.access_codes.any(id=access_code.id))
113 
114         if view_kwargs.get('discount_code_id'):
115             discount_code = safe_query(self, DiscountCode, 'id', view_kwargs['discount_code_id'], 'discount_code_id')
116             # discount_code - ticket :: many-to-many relationship
117             query_ = Ticket.query.filter(Ticket.discount_codes.any(id=discount_code.id))
118 
119         if view_kwargs.get('order_identifier'):
120             order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')
121             ticket_ids = []
122             for ticket in order.tickets:
123                 ticket_ids.append(ticket.id)
124             query_ = query_.filter(Ticket.id.in_(tuple(ticket_ids)))
125 
126         return query_
127 
128     view_kwargs = True
129     methods = ['GET', ]
130     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
131                   fetch_as="event_id", model=Ticket, methods="POST",
132                   check=lambda a: a.get('event_id') or a.get('event_identifier')),)
133     schema = TicketSchema
134     data_layer = {'session': db.session,
135                   'model': Ticket,
136                   'methods': {
137                       'query': query,
138                   }}
139 
140 
141 class TicketDetail(ResourceDetail):
142     """
143     Ticket Resource
144     """
145     def before_get(self, args, view_kwargs):
146         """
147         before get method to get the resource id for assigning schema
148         :param args:
149         :param view_kwargs:
150         :return:
151         """
152         if view_kwargs.get('attendee_id'):
153             self.schema = TicketSchemaPublic
154 
155     def before_get_object(self, view_kwargs):
156         """
157         before get object method to get the resource id for fetching details
158         :param view_kwargs:
159         :return:
160         """
161         if view_kwargs.get('attendee_id') is not None:
162             attendee = safe_query(self, TicketHolder, 'id', view_kwargs['attendee_id'], 'attendee_id')
163             if attendee.ticket_id is not None:
164                 view_kwargs['id'] = attendee.ticket_id
165             else:
166                 view_kwargs['id'] = None
167 
168     def before_update_object(self, ticket, data, view_kwargs):
169         """
170         method to check if paid ticket has payment method before updating ticket object
171         :param ticket:
172         :param data:
173         :param view_kwargs:
174         :return:
175         """
176         if ticket.type == 'paid':
177             try:
178                 event = db.session.query(Event).filter_by(id=ticket.event.id, deleted_at=None).one()
179             except NoResultFound:
180                 raise UnprocessableEntity({'event_id': ticket.event.id}, "Event does not exist")
181             if not event.is_payment_enabled():
182                 raise UnprocessableEntity(
183                     {'event_id': ticket.event.id}, "Event having paid ticket must have a payment method")
184 
185     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
186                   fetch_as="event_id", model=Ticket, methods="PATCH,DELETE"),)
187     schema = TicketSchema
188     data_layer = {'session': db.session,
189                   'model': Ticket,
190                   'methods': {
191                       'before_get_object': before_get_object,
192                       'before_update_object': before_update_object
193                   }}
194 
195 
196 class TicketRelationshipRequired(ResourceRelationship):
197     """
198     Tickets Relationship (Required)
199     """
200     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
201                                      fetch_as="event_id", model=Ticket, methods="PATCH"),)
202     methods = ['GET', 'PATCH']
203     schema = TicketSchema
204     data_layer = {'session': db.session,
205                   'model': Ticket}
206 
207 
208 class TicketRelationshipOptional(ResourceRelationship):
209     """
210     Tickets Relationship (Optional)
211     """
212     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
213                                      fetch_as="event_id", model=Ticket, methods="PATCH,DELETE"),)
214     schema = TicketSchema
215     data_layer = {'session': db.session,
216                   'model': Ticket}
217
```
--- 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
@@ -20,6 +20,13 @@
 from app.api.helpers.exceptions import ConflictException, MethodNotAllowed, UnprocessableEntity
 from app.api.helpers.db import get_count
 
+
+def validate_ticket_price(data):
+    if data.get('type') != 'free' and int(data.get('price')) <= 0:
+        raise UnprocessableEntity(
+            {'price': data.get('price')}, "Price of a paid/donation ticket must be greater than zero")
+
+
 class TicketListPost(ResourceList):
     """
     Create and List Tickets
@@ -51,6 +58,8 @@
         :param view_kwargs:
         :return:
         """
+        if not data.get('price') or not data.get('type'):
+            raise UnprocessableEntity({}, "Type/price of ticket is missing")
         if data.get('type') == 'paid' and data.get('event'):
             try:
                 event = db.session.query(Event).filter_by(id=data['event'], deleted_at=None).one()
@@ -59,6 +68,7 @@
             if not event.is_payment_enabled():
                 raise UnprocessableEntity(
                     {'event_id': data['event']}, "Event having paid ticket must have a payment method")
+        validate_ticket_price(data)
 
     schema = TicketSchema
     methods = ['POST', ]
@@ -181,7 +191,8 @@
             if not event.is_payment_enabled():
                 raise UnprocessableEntity(
                     {'event_id': ticket.event.id}, "Event having paid ticket must have a payment method")
-
+        if data.get('type') and data.get('price'):
+            validate_ticket_price(data)
     decorators = (api.has_permission('is_coorganizer', fetch='event_id',
                   fetch_as="event_id", model=Ticket, methods="PATCH,DELETE"),)
     schema = TicketSchema

{"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@@ -20,6 +20,13 @@\n from app.api.helpers.exceptions import ConflictException, MethodNotAllowed, UnprocessableEntity\n from app.api.helpers.db import get_count\n \n+\n+def validate_ticket_price(data):\n+    if data.get('type') != 'free' and int(data.get('price')) <= 0:\n+        raise UnprocessableEntity(\n+            {'price': data.get('price')}, \"Price of a paid/donation ticket must be greater than zero\")\n+\n+\n class TicketListPost(ResourceList):\n     \"\"\"\n     Create and List Tickets\n@@ -51,6 +58,8 @@\n         :param view_kwargs:\n         :return:\n         \"\"\"\n+        if not data.get('price') or not data.get('type'):\n+            raise UnprocessableEntity({}, \"Type/price of ticket is missing\")\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@@ -59,6 +68,7 @@\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+        validate_ticket_price(data)\n \n     schema = TicketSchema\n     methods = ['POST', ]\n@@ -181,7 +191,8 @@\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+        if data.get('type') and data.get('price'):\n+            validate_ticket_price(data)\n     decorators = (api.has_permission('is_coorganizer', fetch='event_id',\n                   fetch_as=\"event_id\", model=Ticket, methods=\"PATCH,DELETE\"),)\n     schema = TicketSchema\n", "issue": "Server checks for ticket prices are missing\n**Describe the bug**\r\nServer checks are required for ticket prices. This would also allow decimal values greater than zero to pass through [similar to eventbrite]\r\n\r\n**Additional context**\r\nCorresponding FE PR which requires these checks : https://github.com/fossasia/open-event-frontend/pull/3341\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        if get_count(db.session.query(Event).filter_by(id=int(data['event']), is_ticketing_enabled=False)) > 0:\n            raise MethodNotAllowed({'parameter': 'event_id'}, \"Ticketing is disabled for this Event\")\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\n\ndef validate_ticket_price(data):\n    if data.get('type') != 'free' and int(data.get('price')) <= 0:\n        raise UnprocessableEntity(\n            {'price': data.get('price')}, \"Price of a paid/donation ticket must be greater than zero\")\n\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        if get_count(db.session.query(Event).filter_by(id=int(data['event']), is_ticketing_enabled=False)) > 0:\n            raise MethodNotAllowed({'parameter': 'event_id'}, \"Ticketing is disabled for this Event\")\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 not data.get('price') or not data.get('type'):\n            raise UnprocessableEntity({}, \"Type/price of ticket is missing\")\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        validate_ticket_price(data)\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        if data.get('type') and data.get('price'):\n            validate_ticket_price(data)\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"}]}