We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Ordering new tickets gives IntegrityError
IntegrityError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely) (psycopg2.IntegrityError) null value in column "order_id" violates not-null constraint
DETAIL:  Failing row contains (null, 1, 4).
 [SQL: 'INSERT INTO orders_tickets (ticket_id, quantity) VALUES (%(ticket_id)s, %(quantity)s) RETURNING orders_tickets.order_id'] [parameters: {'ticket_id': 1, 'quantity': 4}]


--- 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/helpers/ticketing.py`
Content:
```
1 """Copyright 2016 Niranjan Rajendran"""
2 import binascii
3 import os
4 import uuid
5 
6 from datetime import timedelta, datetime
7 
8 from flask import url_for
9 
10 from flask.ext import login
11 
12 from app.helpers.cache import cache
13 from app.helpers.data import save_to_db
14 from app.helpers.helpers import string_empty, send_email_for_after_purchase, get_count
15 from app.models.order import Order
16 from app.models.ticket import Ticket
17 from app.helpers.data_getter import DataGetter
18 from app.helpers.data import DataManager
19 
20 from app.helpers.payment import StripePaymentsManager, represents_int, PayPalPaymentsManager
21 from app.models.ticket_holder import TicketHolder
22 from app.models.order import OrderTicket
23 from app.models.event import Event
24 from app.models.user_detail import UserDetail
25 from app.models.discount_code import DiscountCode
26 
27 from app.helpers.helpers import send_email_after_account_create_with_password
28 
29 
30 class TicketingManager(object):
31     """All ticketing and orders related functions"""
32 
33     @staticmethod
34     @cache.memoize(50)
35     def get_ticket(ticket_id):
36         return Ticket.query.get(ticket_id)
37 
38     @staticmethod
39     def get_orders_of_user(user_id=None, upcoming_events=True):
40         """
41         :return: Return all order objects with the current user
42         """
43         if not user_id:
44             user_id = login.current_user.id
45         query = Order.query.join(Order.event) \
46             .filter(Order.user_id == user_id) \
47             .filter(Order.status == 'completed')
48         if upcoming_events:
49             return query.filter(Event.start_time >= datetime.now())
50         else:
51             return query.filter(Event.end_time < datetime.now())
52 
53     @staticmethod
54     def get_orders(event_id=None, status=None, from_date=None, to_date=None):
55         if event_id:
56             if status:
57                 orders = Order.query.filter_by(event_id=event_id).filter_by(status=status) \
58                     .filter(Order.user_id.isnot(None))
59             else:
60                 orders = Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))
61         else:
62             if status:
63                 orders = Order.query.filter_by(status=status).filter(Order.user_id.isnot(None))
64             else:
65                 orders = Order.query.filter(Order.user_id.isnot(None))
66 
67         if from_date:
68             orders = orders.filter(Order.created_at >= from_date)
69         if to_date:
70             orders = orders.filter(Order.created_at <= to_date)
71         return orders.all()
72 
73     @staticmethod
74     def get_orders_count(event_id, status='completed'):
75         return get_count(Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))
76                          .filter_by(status=status))
77 
78     @staticmethod
79     def get_orders_count_by_type(event_id, type='free'):
80         return get_count(Order.query.filter_by(event_id=event_id).filter_by(status='completed')
81                          .filter(Ticket.type == type))
82 
83     @staticmethod
84     def get_all_orders_count_by_type(type='free'):
85         return get_count(Order.query.filter_by(status='completed').filter(Ticket.type == type))
86 
87     @staticmethod
88     def get_max_orders_count(event_id, type='free'):
89         ticket = Ticket.query.filter_by(event_id=event_id).filter_by(type=type).first()
90         if ticket:
91             return ticket.quantity
92         else:
93             return 0
94 
95     @staticmethod
96     def get_order_expiry():
97         return 10
98 
99     @staticmethod
100     def get_new_order_identifier():
101         identifier = str(uuid.uuid4())
102         count = get_count(Order.query.filter_by(identifier=identifier))
103         if count == 0:
104             return identifier
105         else:
106             return TicketingManager.get_new_order_identifier()
107 
108     @staticmethod
109     def get_order(order_id):
110         return Ticket.query.get(order_id)
111 
112     @staticmethod
113     def get_order_by_identifier(identifier):
114         return Order.query.filter_by(identifier=identifier).first()
115 
116     @staticmethod
117     def get_discount_codes(event_id):
118         return DiscountCode.query.filter_by(event_id=event_id).all()
119 
120     @staticmethod
121     def get_discount_code(event_id, discount_code):
122         if represents_int(discount_code):
123             return DiscountCode.query.get(discount_code)
124         else:
125             return DiscountCode.query.filter_by(code=discount_code).first()
126 
127     @staticmethod
128     def get_or_create_user_by_email(email, data=None):
129         user = DataGetter.get_user_by_email(email, False)
130         if not user:
131             password = binascii.b2a_hex(os.urandom(4))
132             user_data = [email, password]
133             user = DataManager.create_user(user_data)
134             send_email_after_account_create_with_password({
135                 'email': email,
136                 'password': password
137             })
138         if user.user_detail:
139             user.user_detail.firstname = data['firstname']
140             user.user_detail.lastname = data['lastname']
141         else:
142             user_detail = UserDetail(firstname=data['firstname'], lastname=data['lastname'])
143             user.user_detail = user_detail
144 
145         save_to_db(user)
146         return user
147 
148     @staticmethod
149     def get_and_set_expiry(identifier, override=False):
150         if type(identifier) is Order:
151             order = identifier
152         elif represents_int(identifier):
153             order = TicketingManager.get_order(identifier)
154         else:
155             order = TicketingManager.get_order_by_identifier(identifier)
156 
157         if order and not order.paid_via:
158             if override \
159                 or (order.status != 'completed' and
160                             (order.created_at + timedelta(
161                                 minutes=TicketingManager.get_order_expiry())) < datetime.utcnow()):
162                 order.status = 'expired'
163                 save_to_db(order)
164         return order
165 
166     @staticmethod
167     def create_order(form, from_organizer=False):
168         order = Order()
169         order.status = 'pending'
170         order.identifier = TicketingManager.get_new_order_identifier()
171         order.event_id = form.get('event_id')
172 
173         if from_organizer:
174             order.paid_via = form.get('payment_via')
175 
176         ticket_ids = form.getlist('ticket_ids[]')
177         ticket_quantity = form.getlist('ticket_quantities[]')
178 
179         ticket_subtotals = []
180         if from_organizer:
181             ticket_subtotals = form.getlist('ticket_subtotals[]')
182 
183         amount = 0
184         for index, id in enumerate(ticket_ids):
185             if not string_empty(id) and int(ticket_quantity[index]) > 0:
186                 order_ticket = OrderTicket()
187                 order_ticket.ticket = TicketingManager.get_ticket(id)
188                 order_ticket.quantity = int(ticket_quantity[index])
189                 order.tickets.append(order_ticket)
190 
191                 if from_organizer:
192                     amount += int(ticket_subtotals[index])
193                 else:
194                     amount += (order_ticket.ticket.price * order_ticket.quantity)
195 
196         order.amount = amount
197 
198         if login.current_user.is_authenticated:
199             order.user_id = login.current_user.id
200 
201         save_to_db(order)
202         return order
203 
204     @staticmethod
205     def initiate_order_payment(form):
206         identifier = form['identifier']
207         email = form['email']
208 
209         order = TicketingManager.get_and_set_expiry(identifier)
210 
211         if order:
212 
213             user = TicketingManager.get_or_create_user_by_email(email, form)
214             order.user_id = user.id
215 
216             if order.amount > 0 \
217                 and (not order.paid_via
218                      or (order.paid_via
219                          and (order.paid_via == 'stripe'
220                               or order.paid_via == 'paypal'))):
221 
222                 country = form['country']
223                 address = form['address']
224                 city = form['city']
225                 state = form['state']
226                 zipcode = form['zipcode']
227                 order.address = address
228                 order.city = city
229                 order.state = state
230                 order.country = country
231                 order.zipcode = zipcode
232                 order.status = 'initialized'
233                 ticket_holder = TicketHolder(name=user.user_detail.fullname,
234                                              email=email, address=address,
235                                              city=city, state=state, country=country, order_id=order.id)
236             else:
237                 order.status = 'completed'
238                 order.completed_at = datetime.utcnow()
239                 if not order.paid_via:
240                     order.paid_via = 'free'
241                 ticket_holder = TicketHolder(name=user.user_detail.fullname, email=email, order_id=order.id)
242             # add attendee role to user
243             DataManager.add_attendee_role_to_event(user, order.event_id)
244             # save items
245             save_to_db(order)
246             save_to_db(ticket_holder)
247 
248             return order
249         else:
250             return False
251 
252     @staticmethod
253     def charge_stripe_order_payment(form):
254         order = TicketingManager.get_and_set_expiry(form['identifier'])
255         order.stripe_token = form['stripe_token_id']
256         save_to_db(order)
257 
258         charge = StripePaymentsManager.capture_payment(order)
259         if charge:
260             order.paid_via = 'stripe'
261             order.payment_mode = charge.source.object
262             order.brand = charge.source.brand
263             order.exp_month = charge.source.exp_month
264             order.exp_year = charge.source.exp_year
265             order.last4 = charge.source.last4
266             order.transaction_id = charge.id
267             order.status = 'completed'
268             order.completed_at = datetime.utcnow()
269             save_to_db(order)
270 
271             send_email_for_after_purchase(order.user.email, order.get_invoice_number(),
272                                           url_for('ticketing.view_order_after_payment',
273                                                   order_identifier=order.identifier, _external=True))
274             return True, order
275         else:
276             return False, 'Error'
277 
278     @staticmethod
279     def charge_paypal_order_payment(order):
280         payment_details = PayPalPaymentsManager.get_approved_payment_details(order)
281         if 'PAYERID' in payment_details:
282             capture_result = PayPalPaymentsManager.capture_payment(order, payment_details['PAYERID'])
283             if capture_result['ACK'] == 'Success':
284                 order.paid_via = 'paypal'
285                 order.status = 'completed'
286                 order.transaction_id = capture_result['PAYMENTINFO_0_TRANSACTIONID']
287                 order.completed_at = datetime.utcnow()
288                 save_to_db(order)
289                 send_email_for_after_purchase(order.user.email, order.get_invoice_number(),
290                                               url_for('ticketing.view_order_after_payment',
291                                                       order_identifier=order.identifier, _external=True))
292                 return True, order
293             else:
294                 return False, capture_result['L_SHORTMESSAGE0']
295         else:
296             return False, 'Payer ID missing. Payment flow tampered.'
297 
298     @staticmethod
299     def create_edit_discount_code(form, event_id, discount_code_id=None):
300         if not discount_code_id:
301             discount_code = DiscountCode()
302         else:
303             discount_code = TicketingManager.get_discount_code(event_id, discount_code_id)
304         discount_code.code = form.get('code')
305         discount_code.value = form.get('value')
306         discount_code.type = form.get('value_type')
307         discount_code.min_quantity = form.get('min_quantity', None)
308         discount_code.max_quantity = form.get('max_quantity', None)
309         discount_code.tickets_number = form.get('tickets_number')
310         discount_code.event_id = event_id
311 
312         if discount_code.min_quantity == "":
313             discount_code.min_quantity = None
314         if discount_code.max_quantity == "":
315             discount_code.max_quantity = None
316         if discount_code.tickets_number == "":
317             discount_code.tickets_number = None
318 
319         try:
320             discount_code.valid_from = datetime.strptime(form.get('start_date', None) + ' ' +
321                                                          form.get('start_time', None), '%m/%d/%Y %H:%M')
322         except:
323             discount_code.valid_from = None
324 
325         try:
326             discount_code.valid_till = datetime.strptime(form.get('end_date', None) + ' ' +
327                                                          form.get('end_time', None), '%m/%d/%Y %H:%M')
328         except:
329             discount_code.valid_till = None
330 
331         discount_code.tickets = ",".join(form.getlist('tickets[]'))
332 
333         save_to_db(discount_code)
334 
335         return discount_code
336
```
--- 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/helpers/ticketing.py b/app/helpers/ticketing.py
--- a/app/helpers/ticketing.py
+++ b/app/helpers/ticketing.py
@@ -9,6 +9,7 @@
 
 from flask.ext import login
 
+from app.models import db
 from app.helpers.cache import cache
 from app.helpers.data import save_to_db
 from app.helpers.helpers import string_empty, send_email_for_after_purchase, get_count
@@ -183,15 +184,16 @@
         amount = 0
         for index, id in enumerate(ticket_ids):
             if not string_empty(id) and int(ticket_quantity[index]) > 0:
-                order_ticket = OrderTicket()
-                order_ticket.ticket = TicketingManager.get_ticket(id)
-                order_ticket.quantity = int(ticket_quantity[index])
-                order.tickets.append(order_ticket)
-
-                if from_organizer:
-                    amount += int(ticket_subtotals[index])
-                else:
-                    amount += (order_ticket.ticket.price * order_ticket.quantity)
+                with db.session.no_autoflush:
+                    order_ticket = OrderTicket()
+                    order_ticket.ticket = TicketingManager.get_ticket(id)
+                    order_ticket.quantity = int(ticket_quantity[index])
+                    order.tickets.append(order_ticket)
+
+                    if from_organizer:
+                        amount += int(ticket_subtotals[index])
+                    else:
+                        amount += (order_ticket.ticket.price * order_ticket.quantity)
 
         order.amount = amount

{"golden_diff": "diff --git a/app/helpers/ticketing.py b/app/helpers/ticketing.py\n--- a/app/helpers/ticketing.py\n+++ b/app/helpers/ticketing.py\n@@ -9,6 +9,7 @@\n \n from flask.ext import login\n \n+from app.models import db\n from app.helpers.cache import cache\n from app.helpers.data import save_to_db\n from app.helpers.helpers import string_empty, send_email_for_after_purchase, get_count\n@@ -183,15 +184,16 @@\n         amount = 0\n         for index, id in enumerate(ticket_ids):\n             if not string_empty(id) and int(ticket_quantity[index]) > 0:\n-                order_ticket = OrderTicket()\n-                order_ticket.ticket = TicketingManager.get_ticket(id)\n-                order_ticket.quantity = int(ticket_quantity[index])\n-                order.tickets.append(order_ticket)\n-\n-                if from_organizer:\n-                    amount += int(ticket_subtotals[index])\n-                else:\n-                    amount += (order_ticket.ticket.price * order_ticket.quantity)\n+                with db.session.no_autoflush:\n+                    order_ticket = OrderTicket()\n+                    order_ticket.ticket = TicketingManager.get_ticket(id)\n+                    order_ticket.quantity = int(ticket_quantity[index])\n+                    order.tickets.append(order_ticket)\n+\n+                    if from_organizer:\n+                        amount += int(ticket_subtotals[index])\n+                    else:\n+                        amount += (order_ticket.ticket.price * order_ticket.quantity)\n \n         order.amount = amount\n", "issue": "Ordering new tickets gives IntegrityError\nIntegrityError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely) (psycopg2.IntegrityError) null value in column \"order_id\" violates not-null constraint\nDETAIL:  Failing row contains (null, 1, 4).\n [SQL: 'INSERT INTO orders_tickets (ticket_id, quantity) VALUES (%(ticket_id)s, %(quantity)s) RETURNING orders_tickets.order_id'] [parameters: {'ticket_id': 1, 'quantity': 4}]\n\n", "before_files": [{"content": "\"\"\"Copyright 2016 Niranjan Rajendran\"\"\"\nimport binascii\nimport os\nimport uuid\n\nfrom datetime import timedelta, datetime\n\nfrom flask import url_for\n\nfrom flask.ext import login\n\nfrom app.helpers.cache import cache\nfrom app.helpers.data import save_to_db\nfrom app.helpers.helpers import string_empty, send_email_for_after_purchase, get_count\nfrom app.models.order import Order\nfrom app.models.ticket import Ticket\nfrom app.helpers.data_getter import DataGetter\nfrom app.helpers.data import DataManager\n\nfrom app.helpers.payment import StripePaymentsManager, represents_int, PayPalPaymentsManager\nfrom app.models.ticket_holder import TicketHolder\nfrom app.models.order import OrderTicket\nfrom app.models.event import Event\nfrom app.models.user_detail import UserDetail\nfrom app.models.discount_code import DiscountCode\n\nfrom app.helpers.helpers import send_email_after_account_create_with_password\n\n\nclass TicketingManager(object):\n    \"\"\"All ticketing and orders related functions\"\"\"\n\n    @staticmethod\n    @cache.memoize(50)\n    def get_ticket(ticket_id):\n        return Ticket.query.get(ticket_id)\n\n    @staticmethod\n    def get_orders_of_user(user_id=None, upcoming_events=True):\n        \"\"\"\n        :return: Return all order objects with the current user\n        \"\"\"\n        if not user_id:\n            user_id = login.current_user.id\n        query = Order.query.join(Order.event) \\\n            .filter(Order.user_id == user_id) \\\n            .filter(Order.status == 'completed')\n        if upcoming_events:\n            return query.filter(Event.start_time >= datetime.now())\n        else:\n            return query.filter(Event.end_time < datetime.now())\n\n    @staticmethod\n    def get_orders(event_id=None, status=None, from_date=None, to_date=None):\n        if event_id:\n            if status:\n                orders = Order.query.filter_by(event_id=event_id).filter_by(status=status) \\\n                    .filter(Order.user_id.isnot(None))\n            else:\n                orders = Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))\n        else:\n            if status:\n                orders = Order.query.filter_by(status=status).filter(Order.user_id.isnot(None))\n            else:\n                orders = Order.query.filter(Order.user_id.isnot(None))\n\n        if from_date:\n            orders = orders.filter(Order.created_at >= from_date)\n        if to_date:\n            orders = orders.filter(Order.created_at <= to_date)\n        return orders.all()\n\n    @staticmethod\n    def get_orders_count(event_id, status='completed'):\n        return get_count(Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))\n                         .filter_by(status=status))\n\n    @staticmethod\n    def get_orders_count_by_type(event_id, type='free'):\n        return get_count(Order.query.filter_by(event_id=event_id).filter_by(status='completed')\n                         .filter(Ticket.type == type))\n\n    @staticmethod\n    def get_all_orders_count_by_type(type='free'):\n        return get_count(Order.query.filter_by(status='completed').filter(Ticket.type == type))\n\n    @staticmethod\n    def get_max_orders_count(event_id, type='free'):\n        ticket = Ticket.query.filter_by(event_id=event_id).filter_by(type=type).first()\n        if ticket:\n            return ticket.quantity\n        else:\n            return 0\n\n    @staticmethod\n    def get_order_expiry():\n        return 10\n\n    @staticmethod\n    def get_new_order_identifier():\n        identifier = str(uuid.uuid4())\n        count = get_count(Order.query.filter_by(identifier=identifier))\n        if count == 0:\n            return identifier\n        else:\n            return TicketingManager.get_new_order_identifier()\n\n    @staticmethod\n    def get_order(order_id):\n        return Ticket.query.get(order_id)\n\n    @staticmethod\n    def get_order_by_identifier(identifier):\n        return Order.query.filter_by(identifier=identifier).first()\n\n    @staticmethod\n    def get_discount_codes(event_id):\n        return DiscountCode.query.filter_by(event_id=event_id).all()\n\n    @staticmethod\n    def get_discount_code(event_id, discount_code):\n        if represents_int(discount_code):\n            return DiscountCode.query.get(discount_code)\n        else:\n            return DiscountCode.query.filter_by(code=discount_code).first()\n\n    @staticmethod\n    def get_or_create_user_by_email(email, data=None):\n        user = DataGetter.get_user_by_email(email, False)\n        if not user:\n            password = binascii.b2a_hex(os.urandom(4))\n            user_data = [email, password]\n            user = DataManager.create_user(user_data)\n            send_email_after_account_create_with_password({\n                'email': email,\n                'password': password\n            })\n        if user.user_detail:\n            user.user_detail.firstname = data['firstname']\n            user.user_detail.lastname = data['lastname']\n        else:\n            user_detail = UserDetail(firstname=data['firstname'], lastname=data['lastname'])\n            user.user_detail = user_detail\n\n        save_to_db(user)\n        return user\n\n    @staticmethod\n    def get_and_set_expiry(identifier, override=False):\n        if type(identifier) is Order:\n            order = identifier\n        elif represents_int(identifier):\n            order = TicketingManager.get_order(identifier)\n        else:\n            order = TicketingManager.get_order_by_identifier(identifier)\n\n        if order and not order.paid_via:\n            if override \\\n                or (order.status != 'completed' and\n                            (order.created_at + timedelta(\n                                minutes=TicketingManager.get_order_expiry())) < datetime.utcnow()):\n                order.status = 'expired'\n                save_to_db(order)\n        return order\n\n    @staticmethod\n    def create_order(form, from_organizer=False):\n        order = Order()\n        order.status = 'pending'\n        order.identifier = TicketingManager.get_new_order_identifier()\n        order.event_id = form.get('event_id')\n\n        if from_organizer:\n            order.paid_via = form.get('payment_via')\n\n        ticket_ids = form.getlist('ticket_ids[]')\n        ticket_quantity = form.getlist('ticket_quantities[]')\n\n        ticket_subtotals = []\n        if from_organizer:\n            ticket_subtotals = form.getlist('ticket_subtotals[]')\n\n        amount = 0\n        for index, id in enumerate(ticket_ids):\n            if not string_empty(id) and int(ticket_quantity[index]) > 0:\n                order_ticket = OrderTicket()\n                order_ticket.ticket = TicketingManager.get_ticket(id)\n                order_ticket.quantity = int(ticket_quantity[index])\n                order.tickets.append(order_ticket)\n\n                if from_organizer:\n                    amount += int(ticket_subtotals[index])\n                else:\n                    amount += (order_ticket.ticket.price * order_ticket.quantity)\n\n        order.amount = amount\n\n        if login.current_user.is_authenticated:\n            order.user_id = login.current_user.id\n\n        save_to_db(order)\n        return order\n\n    @staticmethod\n    def initiate_order_payment(form):\n        identifier = form['identifier']\n        email = form['email']\n\n        order = TicketingManager.get_and_set_expiry(identifier)\n\n        if order:\n\n            user = TicketingManager.get_or_create_user_by_email(email, form)\n            order.user_id = user.id\n\n            if order.amount > 0 \\\n                and (not order.paid_via\n                     or (order.paid_via\n                         and (order.paid_via == 'stripe'\n                              or order.paid_via == 'paypal'))):\n\n                country = form['country']\n                address = form['address']\n                city = form['city']\n                state = form['state']\n                zipcode = form['zipcode']\n                order.address = address\n                order.city = city\n                order.state = state\n                order.country = country\n                order.zipcode = zipcode\n                order.status = 'initialized'\n                ticket_holder = TicketHolder(name=user.user_detail.fullname,\n                                             email=email, address=address,\n                                             city=city, state=state, country=country, order_id=order.id)\n            else:\n                order.status = 'completed'\n                order.completed_at = datetime.utcnow()\n                if not order.paid_via:\n                    order.paid_via = 'free'\n                ticket_holder = TicketHolder(name=user.user_detail.fullname, email=email, order_id=order.id)\n            # add attendee role to user\n            DataManager.add_attendee_role_to_event(user, order.event_id)\n            # save items\n            save_to_db(order)\n            save_to_db(ticket_holder)\n\n            return order\n        else:\n            return False\n\n    @staticmethod\n    def charge_stripe_order_payment(form):\n        order = TicketingManager.get_and_set_expiry(form['identifier'])\n        order.stripe_token = form['stripe_token_id']\n        save_to_db(order)\n\n        charge = StripePaymentsManager.capture_payment(order)\n        if charge:\n            order.paid_via = 'stripe'\n            order.payment_mode = charge.source.object\n            order.brand = charge.source.brand\n            order.exp_month = charge.source.exp_month\n            order.exp_year = charge.source.exp_year\n            order.last4 = charge.source.last4\n            order.transaction_id = charge.id\n            order.status = 'completed'\n            order.completed_at = datetime.utcnow()\n            save_to_db(order)\n\n            send_email_for_after_purchase(order.user.email, order.get_invoice_number(),\n                                          url_for('ticketing.view_order_after_payment',\n                                                  order_identifier=order.identifier, _external=True))\n            return True, order\n        else:\n            return False, 'Error'\n\n    @staticmethod\n    def charge_paypal_order_payment(order):\n        payment_details = PayPalPaymentsManager.get_approved_payment_details(order)\n        if 'PAYERID' in payment_details:\n            capture_result = PayPalPaymentsManager.capture_payment(order, payment_details['PAYERID'])\n            if capture_result['ACK'] == 'Success':\n                order.paid_via = 'paypal'\n                order.status = 'completed'\n                order.transaction_id = capture_result['PAYMENTINFO_0_TRANSACTIONID']\n                order.completed_at = datetime.utcnow()\n                save_to_db(order)\n                send_email_for_after_purchase(order.user.email, order.get_invoice_number(),\n                                              url_for('ticketing.view_order_after_payment',\n                                                      order_identifier=order.identifier, _external=True))\n                return True, order\n            else:\n                return False, capture_result['L_SHORTMESSAGE0']\n        else:\n            return False, 'Payer ID missing. Payment flow tampered.'\n\n    @staticmethod\n    def create_edit_discount_code(form, event_id, discount_code_id=None):\n        if not discount_code_id:\n            discount_code = DiscountCode()\n        else:\n            discount_code = TicketingManager.get_discount_code(event_id, discount_code_id)\n        discount_code.code = form.get('code')\n        discount_code.value = form.get('value')\n        discount_code.type = form.get('value_type')\n        discount_code.min_quantity = form.get('min_quantity', None)\n        discount_code.max_quantity = form.get('max_quantity', None)\n        discount_code.tickets_number = form.get('tickets_number')\n        discount_code.event_id = event_id\n\n        if discount_code.min_quantity == \"\":\n            discount_code.min_quantity = None\n        if discount_code.max_quantity == \"\":\n            discount_code.max_quantity = None\n        if discount_code.tickets_number == \"\":\n            discount_code.tickets_number = None\n\n        try:\n            discount_code.valid_from = datetime.strptime(form.get('start_date', None) + ' ' +\n                                                         form.get('start_time', None), '%m/%d/%Y %H:%M')\n        except:\n            discount_code.valid_from = None\n\n        try:\n            discount_code.valid_till = datetime.strptime(form.get('end_date', None) + ' ' +\n                                                         form.get('end_time', None), '%m/%d/%Y %H:%M')\n        except:\n            discount_code.valid_till = None\n\n        discount_code.tickets = \",\".join(form.getlist('tickets[]'))\n\n        save_to_db(discount_code)\n\n        return discount_code\n", "path": "app/helpers/ticketing.py"}], "after_files": [{"content": "\"\"\"Copyright 2016 Niranjan Rajendran\"\"\"\nimport binascii\nimport os\nimport uuid\n\nfrom datetime import timedelta, datetime\n\nfrom flask import url_for\n\nfrom flask.ext import login\n\nfrom app.models import db\nfrom app.helpers.cache import cache\nfrom app.helpers.data import save_to_db\nfrom app.helpers.helpers import string_empty, send_email_for_after_purchase, get_count\nfrom app.models.order import Order\nfrom app.models.ticket import Ticket\nfrom app.helpers.data_getter import DataGetter\nfrom app.helpers.data import DataManager\n\nfrom app.helpers.payment import StripePaymentsManager, represents_int, PayPalPaymentsManager\nfrom app.models.ticket_holder import TicketHolder\nfrom app.models.order import OrderTicket\nfrom app.models.event import Event\nfrom app.models.user_detail import UserDetail\nfrom app.models.discount_code import DiscountCode\n\nfrom app.helpers.helpers import send_email_after_account_create_with_password\n\n\nclass TicketingManager(object):\n    \"\"\"All ticketing and orders related functions\"\"\"\n\n    @staticmethod\n    @cache.memoize(50)\n    def get_ticket(ticket_id):\n        return Ticket.query.get(ticket_id)\n\n    @staticmethod\n    def get_orders_of_user(user_id=None, upcoming_events=True):\n        \"\"\"\n        :return: Return all order objects with the current user\n        \"\"\"\n        if not user_id:\n            user_id = login.current_user.id\n        query = Order.query.join(Order.event) \\\n            .filter(Order.user_id == user_id) \\\n            .filter(Order.status == 'completed')\n        if upcoming_events:\n            return query.filter(Event.start_time >= datetime.now())\n        else:\n            return query.filter(Event.end_time < datetime.now())\n\n    @staticmethod\n    def get_orders(event_id=None, status=None, from_date=None, to_date=None):\n        if event_id:\n            if status:\n                orders = Order.query.filter_by(event_id=event_id).filter_by(status=status) \\\n                    .filter(Order.user_id.isnot(None))\n            else:\n                orders = Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))\n        else:\n            if status:\n                orders = Order.query.filter_by(status=status).filter(Order.user_id.isnot(None))\n            else:\n                orders = Order.query.filter(Order.user_id.isnot(None))\n\n        if from_date:\n            orders = orders.filter(Order.created_at >= from_date)\n        if to_date:\n            orders = orders.filter(Order.created_at <= to_date)\n        return orders.all()\n\n    @staticmethod\n    def get_orders_count(event_id, status='completed'):\n        return get_count(Order.query.filter_by(event_id=event_id).filter(Order.user_id.isnot(None))\n                         .filter_by(status=status))\n\n    @staticmethod\n    def get_orders_count_by_type(event_id, type='free'):\n        return get_count(Order.query.filter_by(event_id=event_id).filter_by(status='completed')\n                         .filter(Ticket.type == type))\n\n    @staticmethod\n    def get_all_orders_count_by_type(type='free'):\n        return get_count(Order.query.filter_by(status='completed').filter(Ticket.type == type))\n\n    @staticmethod\n    def get_max_orders_count(event_id, type='free'):\n        ticket = Ticket.query.filter_by(event_id=event_id).filter_by(type=type).first()\n        if ticket:\n            return ticket.quantity\n        else:\n            return 0\n\n    @staticmethod\n    def get_order_expiry():\n        return 10\n\n    @staticmethod\n    def get_new_order_identifier():\n        identifier = str(uuid.uuid4())\n        count = get_count(Order.query.filter_by(identifier=identifier))\n        if count == 0:\n            return identifier\n        else:\n            return TicketingManager.get_new_order_identifier()\n\n    @staticmethod\n    def get_order(order_id):\n        return Ticket.query.get(order_id)\n\n    @staticmethod\n    def get_order_by_identifier(identifier):\n        return Order.query.filter_by(identifier=identifier).first()\n\n    @staticmethod\n    def get_discount_codes(event_id):\n        return DiscountCode.query.filter_by(event_id=event_id).all()\n\n    @staticmethod\n    def get_discount_code(event_id, discount_code):\n        if represents_int(discount_code):\n            return DiscountCode.query.get(discount_code)\n        else:\n            return DiscountCode.query.filter_by(code=discount_code).first()\n\n    @staticmethod\n    def get_or_create_user_by_email(email, data=None):\n        user = DataGetter.get_user_by_email(email, False)\n        if not user:\n            password = binascii.b2a_hex(os.urandom(4))\n            user_data = [email, password]\n            user = DataManager.create_user(user_data)\n            send_email_after_account_create_with_password({\n                'email': email,\n                'password': password\n            })\n        if user.user_detail:\n            user.user_detail.firstname = data['firstname']\n            user.user_detail.lastname = data['lastname']\n        else:\n            user_detail = UserDetail(firstname=data['firstname'], lastname=data['lastname'])\n            user.user_detail = user_detail\n\n        save_to_db(user)\n        return user\n\n    @staticmethod\n    def get_and_set_expiry(identifier, override=False):\n        if type(identifier) is Order:\n            order = identifier\n        elif represents_int(identifier):\n            order = TicketingManager.get_order(identifier)\n        else:\n            order = TicketingManager.get_order_by_identifier(identifier)\n\n        if order and not order.paid_via:\n            if override \\\n                or (order.status != 'completed' and\n                            (order.created_at + timedelta(\n                                minutes=TicketingManager.get_order_expiry())) < datetime.utcnow()):\n                order.status = 'expired'\n                save_to_db(order)\n        return order\n\n    @staticmethod\n    def create_order(form, from_organizer=False):\n        order = Order()\n        order.status = 'pending'\n        order.identifier = TicketingManager.get_new_order_identifier()\n        order.event_id = form.get('event_id')\n\n        if from_organizer:\n            order.paid_via = form.get('payment_via')\n\n        ticket_ids = form.getlist('ticket_ids[]')\n        ticket_quantity = form.getlist('ticket_quantities[]')\n\n        ticket_subtotals = []\n        if from_organizer:\n            ticket_subtotals = form.getlist('ticket_subtotals[]')\n\n        amount = 0\n        for index, id in enumerate(ticket_ids):\n            if not string_empty(id) and int(ticket_quantity[index]) > 0:\n                with db.session.no_autoflush:\n                    order_ticket = OrderTicket()\n                    order_ticket.ticket = TicketingManager.get_ticket(id)\n                    order_ticket.quantity = int(ticket_quantity[index])\n                    order.tickets.append(order_ticket)\n\n                    if from_organizer:\n                        amount += int(ticket_subtotals[index])\n                    else:\n                        amount += (order_ticket.ticket.price * order_ticket.quantity)\n\n        order.amount = amount\n\n        if login.current_user.is_authenticated:\n            order.user_id = login.current_user.id\n\n        save_to_db(order)\n        return order\n\n    @staticmethod\n    def initiate_order_payment(form):\n        identifier = form['identifier']\n        email = form['email']\n\n        order = TicketingManager.get_and_set_expiry(identifier)\n\n        if order:\n\n            user = TicketingManager.get_or_create_user_by_email(email, form)\n            order.user_id = user.id\n\n            if order.amount > 0 \\\n                and (not order.paid_via\n                     or (order.paid_via\n                         and (order.paid_via == 'stripe'\n                              or order.paid_via == 'paypal'))):\n\n                country = form['country']\n                address = form['address']\n                city = form['city']\n                state = form['state']\n                zipcode = form['zipcode']\n                order.address = address\n                order.city = city\n                order.state = state\n                order.country = country\n                order.zipcode = zipcode\n                order.status = 'initialized'\n                ticket_holder = TicketHolder(name=user.user_detail.fullname,\n                                             email=email, address=address,\n                                             city=city, state=state, country=country, order_id=order.id)\n            else:\n                order.status = 'completed'\n                order.completed_at = datetime.utcnow()\n                if not order.paid_via:\n                    order.paid_via = 'free'\n                ticket_holder = TicketHolder(name=user.user_detail.fullname, email=email, order_id=order.id)\n            # add attendee role to user\n            DataManager.add_attendee_role_to_event(user, order.event_id)\n            # save items\n            save_to_db(order)\n            save_to_db(ticket_holder)\n\n            return order\n        else:\n            return False\n\n    @staticmethod\n    def charge_stripe_order_payment(form):\n        order = TicketingManager.get_and_set_expiry(form['identifier'])\n        order.stripe_token = form['stripe_token_id']\n        save_to_db(order)\n\n        charge = StripePaymentsManager.capture_payment(order)\n        if charge:\n            order.paid_via = 'stripe'\n            order.payment_mode = charge.source.object\n            order.brand = charge.source.brand\n            order.exp_month = charge.source.exp_month\n            order.exp_year = charge.source.exp_year\n            order.last4 = charge.source.last4\n            order.transaction_id = charge.id\n            order.status = 'completed'\n            order.completed_at = datetime.utcnow()\n            save_to_db(order)\n\n            send_email_for_after_purchase(order.user.email, order.get_invoice_number(),\n                                          url_for('ticketing.view_order_after_payment',\n                                                  order_identifier=order.identifier, _external=True))\n            return True, order\n        else:\n            return False, 'Error'\n\n    @staticmethod\n    def charge_paypal_order_payment(order):\n        payment_details = PayPalPaymentsManager.get_approved_payment_details(order)\n        if 'PAYERID' in payment_details:\n            capture_result = PayPalPaymentsManager.capture_payment(order, payment_details['PAYERID'])\n            if capture_result['ACK'] == 'Success':\n                order.paid_via = 'paypal'\n                order.status = 'completed'\n                order.transaction_id = capture_result['PAYMENTINFO_0_TRANSACTIONID']\n                order.completed_at = datetime.utcnow()\n                save_to_db(order)\n                send_email_for_after_purchase(order.user.email, order.get_invoice_number(),\n                                              url_for('ticketing.view_order_after_payment',\n                                                      order_identifier=order.identifier, _external=True))\n                return True, order\n            else:\n                return False, capture_result['L_SHORTMESSAGE0']\n        else:\n            return False, 'Payer ID missing. Payment flow tampered.'\n\n    @staticmethod\n    def create_edit_discount_code(form, event_id, discount_code_id=None):\n        if not discount_code_id:\n            discount_code = DiscountCode()\n        else:\n            discount_code = TicketingManager.get_discount_code(event_id, discount_code_id)\n        discount_code.code = form.get('code')\n        discount_code.value = form.get('value')\n        discount_code.type = form.get('value_type')\n        discount_code.min_quantity = form.get('min_quantity', None)\n        discount_code.max_quantity = form.get('max_quantity', None)\n        discount_code.tickets_number = form.get('tickets_number')\n        discount_code.event_id = event_id\n\n        if discount_code.min_quantity == \"\":\n            discount_code.min_quantity = None\n        if discount_code.max_quantity == \"\":\n            discount_code.max_quantity = None\n        if discount_code.tickets_number == \"\":\n            discount_code.tickets_number = None\n\n        try:\n            discount_code.valid_from = datetime.strptime(form.get('start_date', None) + ' ' +\n                                                         form.get('start_time', None), '%m/%d/%Y %H:%M')\n        except:\n            discount_code.valid_from = None\n\n        try:\n            discount_code.valid_till = datetime.strptime(form.get('end_date', None) + ' ' +\n                                                         form.get('end_time', None), '%m/%d/%Y %H:%M')\n        except:\n            discount_code.valid_till = None\n\n        discount_code.tickets = \",\".join(form.getlist('tickets[]'))\n\n        save_to_db(discount_code)\n\n        return discount_code\n", "path": "app/helpers/ticketing.py"}]}