We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tab Sales in Admin section with relevant information
Add tab "Sales" in admin section at `https://open-event-dev.herokuapp.com/admin/`

We need to display ticket sales in a suitable way to understand the status of the system. How can this be best achieved. Useful information includes:
- [x] Sales by event
- [x] Sales by organizer, and email of organizer
- [x] Sales by location
- [x] Sale depending on date and period (maybe search option)
- [x] Fees by event
- [x] Status/list of (automatic) emails sent to organizer.
- [x] Status of fees paid (invoice to be sent, pending, late)
- [ ] What other information is useful?


--- 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/models/event_invoice.py`
Content:
```
1 import uuid
2 from datetime import datetime
3 import time
4 
5 from app.helpers.helpers import get_count
6 from . import db
7 
8 def get_new_identifier():
9     identifier = str(uuid.uuid4())
10     count = get_count(EventInvoice.query.filter_by(identifier=identifier))
11     if count == 0:
12         return identifier
13     else:
14         return get_new_identifier()
15 
16 class EventInvoice(db.Model):
17     """
18     Stripe authorization information for an event.
19     """
20     __tablename__ = 'event_invoices'
21 
22     id = db.Column(db.Integer, primary_key=True)
23     identifier = db.Column(db.String, unique=True)
24     amount = db.Column(db.Float)
25     address = db.Column(db.String)
26     city = db.Column(db.String)
27     state = db.Column(db.String)
28     country = db.Column(db.String)
29     zipcode = db.Column(db.String)
30 
31     user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
32     event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='SET NULL'))
33 
34     created_at = db.Column(db.DateTime)
35     completed_at = db.Column(db.DateTime, nullable=True, default=None)
36     transaction_id = db.Column(db.String)
37     paid_via = db.Column(db.String)
38     payment_mode = db.Column(db.String)
39     brand = db.Column(db.String)
40     exp_month = db.Column(db.Integer)
41     exp_year = db.Column(db.Integer)
42     last4 = db.Column(db.String)
43     stripe_token = db.Column(db.String)
44     paypal_token = db.Column(db.String)
45     status = db.Column(db.String)
46 
47     event = db.relationship('Event', backref='invoices')
48     user = db.relationship('User', backref='invoices')
49 
50     def __init__(self,
51                  amount=None,
52                  address=None,
53                  city=city,
54                  state=None,
55                  country=None,
56                  zipcode=None,
57                  transaction_id=None,
58                  paid_via=None,
59                  user_id=None,
60                  event_id=None):
61         self.identifier = get_new_identifier()
62         self.amount = amount
63         self.address = address
64         self.state = state
65         self.country = country
66         self.zipcode = zipcode
67         self.user_id = user_id
68         self.event_id = event_id
69         self.transaction_id = transaction_id
70         self.paid_via = paid_via
71         self.created_at = datetime.utcnow()
72 
73     def get_invoice_number(self):
74         return 'I' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id)
75 
76     def __repr__(self):
77         return '<EventInvoice %r>' % self.stripe_user_id
78 
79     def __str__(self):
80         return unicode(self).encode('utf-8')
81 
82     def __unicode__(self):
83         return self.stripe_user_id
84
```

Path: `app/views/admin/super_admin/sales.py`
Content:
```
1 import copy
2 from datetime import datetime
3 
4 from flask import request
5 from flask import url_for
6 from flask_admin import expose
7 from werkzeug.exceptions import abort
8 from werkzeug.utils import redirect
9 
10 from app import forex
11 from app.helpers.data_getter import DataGetter
12 from app.helpers.payment import get_fee
13 from app.views.admin.super_admin.super_admin_base import SuperAdminBaseView, SALES
14 from app.helpers.ticketing import TicketingManager
15 
16 class SuperAdminSalesView(SuperAdminBaseView):
17     PANEL_NAME = SALES
18     display_currency = 'USD'
19 
20     @expose('/')
21     def index(self):
22         return redirect(url_for('.sales_by_events_view', path='events'))
23 
24     @expose('/fees/')
25     def fees_by_events_view(self):
26         from_date = request.args.get('from_date')
27         to_date = request.args.get('to_date')
28 
29         if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \
30             ('from_date' in request.args and 'to_date' not in request.args) or \
31                 ('to_date' in request.args and 'from_date' not in request.args):
32 
33             return redirect(url_for('.fees_by_events_view'))
34 
35         if from_date and to_date:
36             orders = TicketingManager.get_orders(
37                 from_date=datetime.strptime(from_date, '%d/%m/%Y'),
38                 to_date=datetime.strptime(to_date, '%d/%m/%Y'),
39                 status='completed'
40             )
41         else:
42             orders = TicketingManager.get_orders(status='completed')
43 
44         events = DataGetter.get_all_events()
45 
46         fee_summary = {}
47         for event in events:
48             fee_summary[str(event.id)] = {
49                 'name': event.name,
50                 'payment_currency': event.payment_currency,
51                 'fee_rate': get_fee(event.payment_currency),
52                 'fee_amount': 0,
53                 'tickets_count': 0
54             }
55 
56         fee_total = 0
57         tickets_total = 0
58 
59         for order in orders:
60             for order_ticket in order.tickets:
61                 fee_summary[str(order.event.id)]['tickets_count'] += order_ticket.quantity
62                 tickets_total += order_ticket.quantity
63                 ticket = TicketingManager.get_ticket(order_ticket.ticket_id)
64                 if order.paid_via != 'free' and order.amount > 0 and ticket.price > 0:
65                     fee = ticket.price * (get_fee(order.event.payment_currency)/100)
66                     fee = forex(order.event.payment_currency, self.display_currency, fee)
67                     fee_summary[str(order.event.id)]['fee_amount'] += fee
68                     fee_total += fee
69 
70         return self.render('/gentelella/admin/super_admin/sales/fees.html',
71                            fee_summary=fee_summary,
72                            display_currency=self.display_currency,
73                            from_date=from_date,
74                            to_date=to_date,
75                            tickets_total=tickets_total,
76                            fee_total=fee_total)
77 
78     @expose('/<path>/')
79     def sales_by_events_view(self, path):
80 
81         from_date = request.args.get('from_date')
82         to_date = request.args.get('to_date')
83 
84         if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \
85             ('from_date' in request.args and 'to_date' not in request.args) or \
86                 ('to_date' in request.args and 'from_date' not in request.args):
87 
88             return redirect(url_for('.sales_by_events_view', path=path))
89 
90         if from_date and to_date:
91             orders = TicketingManager.get_orders(
92                 from_date=datetime.strptime(from_date, '%d/%m/%Y'),
93                 to_date=datetime.strptime(to_date, '%d/%m/%Y')
94             )
95         else:
96             orders = TicketingManager.get_orders()
97 
98         events = DataGetter.get_all_events()
99 
100         completed_count = 0
101         completed_amount = 0
102         tickets_count = 0
103 
104         orders_summary = {
105             'completed': {
106                 'class': 'success',
107                 'tickets_count': 0,
108                 'orders_count': 0,
109                 'total_sales': 0
110             },
111             'pending': {
112                 'class': 'warning',
113                 'tickets_count': 0,
114                 'orders_count': 0,
115                 'total_sales': 0
116             },
117             'expired': {
118                 'class': 'danger',
119                 'tickets_count': 0,
120                 'orders_count': 0,
121                 'total_sales': 0
122             }
123         }
124 
125         tickets_summary_event_wise = {}
126         tickets_summary_organizer_wise = {}
127         tickets_summary_location_wise = {}
128         for event in events:
129             tickets_summary_event_wise[str(event.id)] = {
130                 'name': event.name,
131                 'payment_currency': event.payment_currency,
132                 'completed': {
133                     'tickets_count': 0,
134                     'sales': 0
135                 },
136                 'pending': {
137                     'tickets_count': 0,
138                     'sales': 0
139                 },
140                 'expired': {
141                     'class': 'danger',
142                     'tickets_count': 0,
143                     'sales': 0
144                 }
145             }
146             tickets_summary_organizer_wise[str(event.creator_id)] = \
147                 copy.deepcopy(tickets_summary_event_wise[str(event.id)])
148             if event.creator:
149                 tickets_summary_organizer_wise[str(event.creator_id)]['name'] = event.creator.email
150 
151             tickets_summary_location_wise[unicode(event.searchable_location_name)] = \
152                 copy.deepcopy(tickets_summary_event_wise[str(event.id)])
153             tickets_summary_location_wise[unicode(event.searchable_location_name)]['name'] = \
154                 event.searchable_location_name
155 
156         for order in orders:
157             if order.status == 'initialized':
158                 order.status = 'pending'
159             orders_summary[str(order.status)]['orders_count'] += 1
160             orders_summary[str(order.status)]['total_sales'] += forex(order.event.payment_currency,
161                                                                       self.display_currency, order.amount)
162             for order_ticket in order.tickets:
163                 orders_summary[str(order.status)]['tickets_count'] += order_ticket.quantity
164                 ticket = TicketingManager.get_ticket(order_ticket.ticket_id)
165                 tickets_summary_event_wise[str(order.event_id)][str(order.status)]['tickets_count'] \
166                     += order_ticket.quantity
167                 tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['tickets_count'] \
168                     += order_ticket.quantity
169                 tickets_summary_location_wise[str(order
170                                                   .event.searchable_location_name)][str(order
171                                                                                         .status)]['tickets_count'] \
172                     += order_ticket.quantity
173 
174                 if order.paid_via != 'free' and order.amount > 0:
175                     tickets_summary_event_wise[str(order.event_id)][str(order.status)]['sales'] += \
176                         order_ticket.quantity * ticket.price
177                     tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['sales'] += \
178                         order_ticket.quantity * ticket.price
179                     tickets_summary_location_wise[str(order.event.
180                                                       searchable_location_name)][str(order.
181                                                                                      status)]['sales'] += \
182                         order_ticket.quantity * ticket.price
183 
184         if path == 'events':
185             return self.render('/gentelella/admin/super_admin/sales/by_events.html',
186                                tickets_summary=tickets_summary_event_wise,
187                                display_currency=self.display_currency,
188                                from_date=from_date,
189                                to_date=to_date,
190                                orders_summary=orders_summary)
191         elif path == 'organizers':
192             return self.render('/gentelella/admin/super_admin/sales/by_organizer.html',
193                                tickets_summary=tickets_summary_organizer_wise,
194                                display_currency=self.display_currency,
195                                from_date=from_date,
196                                to_date=to_date,
197                                orders_summary=orders_summary)
198         elif path == 'locations':
199             return self.render('/gentelella/admin/super_admin/sales/by_location.html',
200                                tickets_summary=tickets_summary_location_wise,
201                                display_currency=self.display_currency,
202                                from_date=from_date,
203                                to_date=to_date,
204                                orders_summary=orders_summary)
205 
206         else:
207             abort(404)
208
```
--- 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/models/event_invoice.py b/app/models/event_invoice.py
--- a/app/models/event_invoice.py
+++ b/app/models/event_invoice.py
@@ -69,6 +69,7 @@
         self.transaction_id = transaction_id
         self.paid_via = paid_via
         self.created_at = datetime.utcnow()
+        self.status = 'pending'
 
     def get_invoice_number(self):
         return 'I' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id)
diff --git a/app/views/admin/super_admin/sales.py b/app/views/admin/super_admin/sales.py
--- a/app/views/admin/super_admin/sales.py
+++ b/app/views/admin/super_admin/sales.py
@@ -1,5 +1,5 @@
 import copy
-from datetime import datetime
+from datetime import datetime, timedelta
 
 from flask import request
 from flask import url_for
@@ -12,6 +12,7 @@
 from app.helpers.payment import get_fee
 from app.views.admin.super_admin.super_admin_base import SuperAdminBaseView, SALES
 from app.helpers.ticketing import TicketingManager
+from app.helpers.invoicing import InvoicingManager
 
 class SuperAdminSalesView(SuperAdminBaseView):
     PANEL_NAME = SALES
@@ -75,6 +76,33 @@
                            tickets_total=tickets_total,
                            fee_total=fee_total)
 
+    @expose('/fees/status/')
+    def fees_status_view(self):
+        from_date = request.args.get('from_date')
+        to_date = request.args.get('to_date')
+
+        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \
+            ('from_date' in request.args and 'to_date' not in request.args) or \
+                ('to_date' in request.args and 'from_date' not in request.args):
+
+            return redirect(url_for('.fees_status_view'))
+
+        if from_date and to_date:
+            invoices = InvoicingManager.get_invoices(
+                from_date=datetime.strptime(from_date, '%d/%m/%Y'),
+                to_date=datetime.strptime(to_date, '%d/%m/%Y'),
+            )
+        else:
+            invoices = InvoicingManager.get_invoices()
+
+        return self.render('/gentelella/admin/super_admin/sales/fees_status.html',
+                           display_currency=self.display_currency,
+                           from_date=from_date,
+                           current_date=datetime.now(),
+                           overdue_date=datetime.now() + timedelta(days=15),
+                           invoices=invoices,
+                           to_date=to_date)
+
     @expose('/<path>/')
     def sales_by_events_view(self, path):

{"golden_diff": "diff --git a/app/models/event_invoice.py b/app/models/event_invoice.py\n--- a/app/models/event_invoice.py\n+++ b/app/models/event_invoice.py\n@@ -69,6 +69,7 @@\n         self.transaction_id = transaction_id\n         self.paid_via = paid_via\n         self.created_at = datetime.utcnow()\n+        self.status = 'pending'\n \n     def get_invoice_number(self):\n         return 'I' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id)\ndiff --git a/app/views/admin/super_admin/sales.py b/app/views/admin/super_admin/sales.py\n--- a/app/views/admin/super_admin/sales.py\n+++ b/app/views/admin/super_admin/sales.py\n@@ -1,5 +1,5 @@\n import copy\n-from datetime import datetime\n+from datetime import datetime, timedelta\n \n from flask import request\n from flask import url_for\n@@ -12,6 +12,7 @@\n from app.helpers.payment import get_fee\n from app.views.admin.super_admin.super_admin_base import SuperAdminBaseView, SALES\n from app.helpers.ticketing import TicketingManager\n+from app.helpers.invoicing import InvoicingManager\n \n class SuperAdminSalesView(SuperAdminBaseView):\n     PANEL_NAME = SALES\n@@ -75,6 +76,33 @@\n                            tickets_total=tickets_total,\n                            fee_total=fee_total)\n \n+    @expose('/fees/status/')\n+    def fees_status_view(self):\n+        from_date = request.args.get('from_date')\n+        to_date = request.args.get('to_date')\n+\n+        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n+            ('from_date' in request.args and 'to_date' not in request.args) or \\\n+                ('to_date' in request.args and 'from_date' not in request.args):\n+\n+            return redirect(url_for('.fees_status_view'))\n+\n+        if from_date and to_date:\n+            invoices = InvoicingManager.get_invoices(\n+                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n+                to_date=datetime.strptime(to_date, '%d/%m/%Y'),\n+            )\n+        else:\n+            invoices = InvoicingManager.get_invoices()\n+\n+        return self.render('/gentelella/admin/super_admin/sales/fees_status.html',\n+                           display_currency=self.display_currency,\n+                           from_date=from_date,\n+                           current_date=datetime.now(),\n+                           overdue_date=datetime.now() + timedelta(days=15),\n+                           invoices=invoices,\n+                           to_date=to_date)\n+\n     @expose('/<path>/')\n     def sales_by_events_view(self, path):\n", "issue": "Tab Sales in Admin section with relevant information\nAdd tab \"Sales\" in admin section at `https://open-event-dev.herokuapp.com/admin/`\n\nWe need to display ticket sales in a suitable way to understand the status of the system. How can this be best achieved. Useful information includes:\n- [x] Sales by event\n- [x] Sales by organizer, and email of organizer\n- [x] Sales by location\n- [x] Sale depending on date and period (maybe search option)\n- [x] Fees by event\n- [x] Status/list of (automatic) emails sent to organizer.\n- [x] Status of fees paid (invoice to be sent, pending, late)\n- [ ] What other information is useful?\n\n", "before_files": [{"content": "import uuid\nfrom datetime import datetime\nimport time\n\nfrom app.helpers.helpers import get_count\nfrom . import db\n\ndef get_new_identifier():\n    identifier = str(uuid.uuid4())\n    count = get_count(EventInvoice.query.filter_by(identifier=identifier))\n    if count == 0:\n        return identifier\n    else:\n        return get_new_identifier()\n\nclass EventInvoice(db.Model):\n    \"\"\"\n    Stripe authorization information for an event.\n    \"\"\"\n    __tablename__ = 'event_invoices'\n\n    id = db.Column(db.Integer, primary_key=True)\n    identifier = db.Column(db.String, unique=True)\n    amount = db.Column(db.Float)\n    address = db.Column(db.String)\n    city = db.Column(db.String)\n    state = db.Column(db.String)\n    country = db.Column(db.String)\n    zipcode = db.Column(db.String)\n\n    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))\n    event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='SET NULL'))\n\n    created_at = db.Column(db.DateTime)\n    completed_at = db.Column(db.DateTime, nullable=True, default=None)\n    transaction_id = db.Column(db.String)\n    paid_via = db.Column(db.String)\n    payment_mode = db.Column(db.String)\n    brand = db.Column(db.String)\n    exp_month = db.Column(db.Integer)\n    exp_year = db.Column(db.Integer)\n    last4 = db.Column(db.String)\n    stripe_token = db.Column(db.String)\n    paypal_token = db.Column(db.String)\n    status = db.Column(db.String)\n\n    event = db.relationship('Event', backref='invoices')\n    user = db.relationship('User', backref='invoices')\n\n    def __init__(self,\n                 amount=None,\n                 address=None,\n                 city=city,\n                 state=None,\n                 country=None,\n                 zipcode=None,\n                 transaction_id=None,\n                 paid_via=None,\n                 user_id=None,\n                 event_id=None):\n        self.identifier = get_new_identifier()\n        self.amount = amount\n        self.address = address\n        self.state = state\n        self.country = country\n        self.zipcode = zipcode\n        self.user_id = user_id\n        self.event_id = event_id\n        self.transaction_id = transaction_id\n        self.paid_via = paid_via\n        self.created_at = datetime.utcnow()\n\n    def get_invoice_number(self):\n        return 'I' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id)\n\n    def __repr__(self):\n        return '<EventInvoice %r>' % self.stripe_user_id\n\n    def __str__(self):\n        return unicode(self).encode('utf-8')\n\n    def __unicode__(self):\n        return self.stripe_user_id\n", "path": "app/models/event_invoice.py"}, {"content": "import copy\nfrom datetime import datetime\n\nfrom flask import request\nfrom flask import url_for\nfrom flask_admin import expose\nfrom werkzeug.exceptions import abort\nfrom werkzeug.utils import redirect\n\nfrom app import forex\nfrom app.helpers.data_getter import DataGetter\nfrom app.helpers.payment import get_fee\nfrom app.views.admin.super_admin.super_admin_base import SuperAdminBaseView, SALES\nfrom app.helpers.ticketing import TicketingManager\n\nclass SuperAdminSalesView(SuperAdminBaseView):\n    PANEL_NAME = SALES\n    display_currency = 'USD'\n\n    @expose('/')\n    def index(self):\n        return redirect(url_for('.sales_by_events_view', path='events'))\n\n    @expose('/fees/')\n    def fees_by_events_view(self):\n        from_date = request.args.get('from_date')\n        to_date = request.args.get('to_date')\n\n        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n            ('from_date' in request.args and 'to_date' not in request.args) or \\\n                ('to_date' in request.args and 'from_date' not in request.args):\n\n            return redirect(url_for('.fees_by_events_view'))\n\n        if from_date and to_date:\n            orders = TicketingManager.get_orders(\n                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n                to_date=datetime.strptime(to_date, '%d/%m/%Y'),\n                status='completed'\n            )\n        else:\n            orders = TicketingManager.get_orders(status='completed')\n\n        events = DataGetter.get_all_events()\n\n        fee_summary = {}\n        for event in events:\n            fee_summary[str(event.id)] = {\n                'name': event.name,\n                'payment_currency': event.payment_currency,\n                'fee_rate': get_fee(event.payment_currency),\n                'fee_amount': 0,\n                'tickets_count': 0\n            }\n\n        fee_total = 0\n        tickets_total = 0\n\n        for order in orders:\n            for order_ticket in order.tickets:\n                fee_summary[str(order.event.id)]['tickets_count'] += order_ticket.quantity\n                tickets_total += order_ticket.quantity\n                ticket = TicketingManager.get_ticket(order_ticket.ticket_id)\n                if order.paid_via != 'free' and order.amount > 0 and ticket.price > 0:\n                    fee = ticket.price * (get_fee(order.event.payment_currency)/100)\n                    fee = forex(order.event.payment_currency, self.display_currency, fee)\n                    fee_summary[str(order.event.id)]['fee_amount'] += fee\n                    fee_total += fee\n\n        return self.render('/gentelella/admin/super_admin/sales/fees.html',\n                           fee_summary=fee_summary,\n                           display_currency=self.display_currency,\n                           from_date=from_date,\n                           to_date=to_date,\n                           tickets_total=tickets_total,\n                           fee_total=fee_total)\n\n    @expose('/<path>/')\n    def sales_by_events_view(self, path):\n\n        from_date = request.args.get('from_date')\n        to_date = request.args.get('to_date')\n\n        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n            ('from_date' in request.args and 'to_date' not in request.args) or \\\n                ('to_date' in request.args and 'from_date' not in request.args):\n\n            return redirect(url_for('.sales_by_events_view', path=path))\n\n        if from_date and to_date:\n            orders = TicketingManager.get_orders(\n                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n                to_date=datetime.strptime(to_date, '%d/%m/%Y')\n            )\n        else:\n            orders = TicketingManager.get_orders()\n\n        events = DataGetter.get_all_events()\n\n        completed_count = 0\n        completed_amount = 0\n        tickets_count = 0\n\n        orders_summary = {\n            'completed': {\n                'class': 'success',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            },\n            'pending': {\n                'class': 'warning',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            },\n            'expired': {\n                'class': 'danger',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            }\n        }\n\n        tickets_summary_event_wise = {}\n        tickets_summary_organizer_wise = {}\n        tickets_summary_location_wise = {}\n        for event in events:\n            tickets_summary_event_wise[str(event.id)] = {\n                'name': event.name,\n                'payment_currency': event.payment_currency,\n                'completed': {\n                    'tickets_count': 0,\n                    'sales': 0\n                },\n                'pending': {\n                    'tickets_count': 0,\n                    'sales': 0\n                },\n                'expired': {\n                    'class': 'danger',\n                    'tickets_count': 0,\n                    'sales': 0\n                }\n            }\n            tickets_summary_organizer_wise[str(event.creator_id)] = \\\n                copy.deepcopy(tickets_summary_event_wise[str(event.id)])\n            if event.creator:\n                tickets_summary_organizer_wise[str(event.creator_id)]['name'] = event.creator.email\n\n            tickets_summary_location_wise[unicode(event.searchable_location_name)] = \\\n                copy.deepcopy(tickets_summary_event_wise[str(event.id)])\n            tickets_summary_location_wise[unicode(event.searchable_location_name)]['name'] = \\\n                event.searchable_location_name\n\n        for order in orders:\n            if order.status == 'initialized':\n                order.status = 'pending'\n            orders_summary[str(order.status)]['orders_count'] += 1\n            orders_summary[str(order.status)]['total_sales'] += forex(order.event.payment_currency,\n                                                                      self.display_currency, order.amount)\n            for order_ticket in order.tickets:\n                orders_summary[str(order.status)]['tickets_count'] += order_ticket.quantity\n                ticket = TicketingManager.get_ticket(order_ticket.ticket_id)\n                tickets_summary_event_wise[str(order.event_id)][str(order.status)]['tickets_count'] \\\n                    += order_ticket.quantity\n                tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['tickets_count'] \\\n                    += order_ticket.quantity\n                tickets_summary_location_wise[str(order\n                                                  .event.searchable_location_name)][str(order\n                                                                                        .status)]['tickets_count'] \\\n                    += order_ticket.quantity\n\n                if order.paid_via != 'free' and order.amount > 0:\n                    tickets_summary_event_wise[str(order.event_id)][str(order.status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n                    tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n                    tickets_summary_location_wise[str(order.event.\n                                                      searchable_location_name)][str(order.\n                                                                                     status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n\n        if path == 'events':\n            return self.render('/gentelella/admin/super_admin/sales/by_events.html',\n                               tickets_summary=tickets_summary_event_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n        elif path == 'organizers':\n            return self.render('/gentelella/admin/super_admin/sales/by_organizer.html',\n                               tickets_summary=tickets_summary_organizer_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n        elif path == 'locations':\n            return self.render('/gentelella/admin/super_admin/sales/by_location.html',\n                               tickets_summary=tickets_summary_location_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n\n        else:\n            abort(404)\n", "path": "app/views/admin/super_admin/sales.py"}], "after_files": [{"content": "import uuid\nfrom datetime import datetime\nimport time\n\nfrom app.helpers.helpers import get_count\nfrom . import db\n\ndef get_new_identifier():\n    identifier = str(uuid.uuid4())\n    count = get_count(EventInvoice.query.filter_by(identifier=identifier))\n    if count == 0:\n        return identifier\n    else:\n        return get_new_identifier()\n\nclass EventInvoice(db.Model):\n    \"\"\"\n    Stripe authorization information for an event.\n    \"\"\"\n    __tablename__ = 'event_invoices'\n\n    id = db.Column(db.Integer, primary_key=True)\n    identifier = db.Column(db.String, unique=True)\n    amount = db.Column(db.Float)\n    address = db.Column(db.String)\n    city = db.Column(db.String)\n    state = db.Column(db.String)\n    country = db.Column(db.String)\n    zipcode = db.Column(db.String)\n\n    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))\n    event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='SET NULL'))\n\n    created_at = db.Column(db.DateTime)\n    completed_at = db.Column(db.DateTime, nullable=True, default=None)\n    transaction_id = db.Column(db.String)\n    paid_via = db.Column(db.String)\n    payment_mode = db.Column(db.String)\n    brand = db.Column(db.String)\n    exp_month = db.Column(db.Integer)\n    exp_year = db.Column(db.Integer)\n    last4 = db.Column(db.String)\n    stripe_token = db.Column(db.String)\n    paypal_token = db.Column(db.String)\n    status = db.Column(db.String)\n\n    event = db.relationship('Event', backref='invoices')\n    user = db.relationship('User', backref='invoices')\n\n    def __init__(self,\n                 amount=None,\n                 address=None,\n                 city=city,\n                 state=None,\n                 country=None,\n                 zipcode=None,\n                 transaction_id=None,\n                 paid_via=None,\n                 user_id=None,\n                 event_id=None):\n        self.identifier = get_new_identifier()\n        self.amount = amount\n        self.address = address\n        self.state = state\n        self.country = country\n        self.zipcode = zipcode\n        self.user_id = user_id\n        self.event_id = event_id\n        self.transaction_id = transaction_id\n        self.paid_via = paid_via\n        self.created_at = datetime.utcnow()\n        self.status = 'pending'\n\n    def get_invoice_number(self):\n        return 'I' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id)\n\n    def __repr__(self):\n        return '<EventInvoice %r>' % self.stripe_user_id\n\n    def __str__(self):\n        return unicode(self).encode('utf-8')\n\n    def __unicode__(self):\n        return self.stripe_user_id\n", "path": "app/models/event_invoice.py"}, {"content": "import copy\nfrom datetime import datetime, timedelta\n\nfrom flask import request\nfrom flask import url_for\nfrom flask_admin import expose\nfrom werkzeug.exceptions import abort\nfrom werkzeug.utils import redirect\n\nfrom app import forex\nfrom app.helpers.data_getter import DataGetter\nfrom app.helpers.payment import get_fee\nfrom app.views.admin.super_admin.super_admin_base import SuperAdminBaseView, SALES\nfrom app.helpers.ticketing import TicketingManager\nfrom app.helpers.invoicing import InvoicingManager\n\nclass SuperAdminSalesView(SuperAdminBaseView):\n    PANEL_NAME = SALES\n    display_currency = 'USD'\n\n    @expose('/')\n    def index(self):\n        return redirect(url_for('.sales_by_events_view', path='events'))\n\n    @expose('/fees/')\n    def fees_by_events_view(self):\n        from_date = request.args.get('from_date')\n        to_date = request.args.get('to_date')\n\n        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n            ('from_date' in request.args and 'to_date' not in request.args) or \\\n                ('to_date' in request.args and 'from_date' not in request.args):\n\n            return redirect(url_for('.fees_by_events_view'))\n\n        if from_date and to_date:\n            orders = TicketingManager.get_orders(\n                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n                to_date=datetime.strptime(to_date, '%d/%m/%Y'),\n                status='completed'\n            )\n        else:\n            orders = TicketingManager.get_orders(status='completed')\n\n        events = DataGetter.get_all_events()\n\n        fee_summary = {}\n        for event in events:\n            fee_summary[str(event.id)] = {\n                'name': event.name,\n                'payment_currency': event.payment_currency,\n                'fee_rate': get_fee(event.payment_currency),\n                'fee_amount': 0,\n                'tickets_count': 0\n            }\n\n        fee_total = 0\n        tickets_total = 0\n\n        for order in orders:\n            for order_ticket in order.tickets:\n                fee_summary[str(order.event.id)]['tickets_count'] += order_ticket.quantity\n                tickets_total += order_ticket.quantity\n                ticket = TicketingManager.get_ticket(order_ticket.ticket_id)\n                if order.paid_via != 'free' and order.amount > 0 and ticket.price > 0:\n                    fee = ticket.price * (get_fee(order.event.payment_currency)/100)\n                    fee = forex(order.event.payment_currency, self.display_currency, fee)\n                    fee_summary[str(order.event.id)]['fee_amount'] += fee\n                    fee_total += fee\n\n        return self.render('/gentelella/admin/super_admin/sales/fees.html',\n                           fee_summary=fee_summary,\n                           display_currency=self.display_currency,\n                           from_date=from_date,\n                           to_date=to_date,\n                           tickets_total=tickets_total,\n                           fee_total=fee_total)\n\n    @expose('/fees/status/')\n    def fees_status_view(self):\n        from_date = request.args.get('from_date')\n        to_date = request.args.get('to_date')\n\n        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n            ('from_date' in request.args and 'to_date' not in request.args) or \\\n                ('to_date' in request.args and 'from_date' not in request.args):\n\n            return redirect(url_for('.fees_status_view'))\n\n        if from_date and to_date:\n            invoices = InvoicingManager.get_invoices(\n                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n                to_date=datetime.strptime(to_date, '%d/%m/%Y'),\n            )\n        else:\n            invoices = InvoicingManager.get_invoices()\n\n        return self.render('/gentelella/admin/super_admin/sales/fees_status.html',\n                           display_currency=self.display_currency,\n                           from_date=from_date,\n                           current_date=datetime.now(),\n                           overdue_date=datetime.now() + timedelta(days=15),\n                           invoices=invoices,\n                           to_date=to_date)\n\n    @expose('/<path>/')\n    def sales_by_events_view(self, path):\n\n        from_date = request.args.get('from_date')\n        to_date = request.args.get('to_date')\n\n        if ('from_date' in request.args and not from_date) or ('to_date' in request.args and not to_date) or \\\n            ('from_date' in request.args and 'to_date' not in request.args) or \\\n                ('to_date' in request.args and 'from_date' not in request.args):\n\n            return redirect(url_for('.sales_by_events_view', path=path))\n\n        if from_date and to_date:\n            orders = TicketingManager.get_orders(\n                from_date=datetime.strptime(from_date, '%d/%m/%Y'),\n                to_date=datetime.strptime(to_date, '%d/%m/%Y')\n            )\n        else:\n            orders = TicketingManager.get_orders()\n\n        events = DataGetter.get_all_events()\n\n        completed_count = 0\n        completed_amount = 0\n        tickets_count = 0\n\n        orders_summary = {\n            'completed': {\n                'class': 'success',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            },\n            'pending': {\n                'class': 'warning',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            },\n            'expired': {\n                'class': 'danger',\n                'tickets_count': 0,\n                'orders_count': 0,\n                'total_sales': 0\n            }\n        }\n\n        tickets_summary_event_wise = {}\n        tickets_summary_organizer_wise = {}\n        tickets_summary_location_wise = {}\n        for event in events:\n            tickets_summary_event_wise[str(event.id)] = {\n                'name': event.name,\n                'payment_currency': event.payment_currency,\n                'completed': {\n                    'tickets_count': 0,\n                    'sales': 0\n                },\n                'pending': {\n                    'tickets_count': 0,\n                    'sales': 0\n                },\n                'expired': {\n                    'class': 'danger',\n                    'tickets_count': 0,\n                    'sales': 0\n                }\n            }\n            tickets_summary_organizer_wise[str(event.creator_id)] = \\\n                copy.deepcopy(tickets_summary_event_wise[str(event.id)])\n            if event.creator:\n                tickets_summary_organizer_wise[str(event.creator_id)]['name'] = event.creator.email\n\n            tickets_summary_location_wise[unicode(event.searchable_location_name)] = \\\n                copy.deepcopy(tickets_summary_event_wise[str(event.id)])\n            tickets_summary_location_wise[unicode(event.searchable_location_name)]['name'] = \\\n                event.searchable_location_name\n\n        for order in orders:\n            if order.status == 'initialized':\n                order.status = 'pending'\n            orders_summary[str(order.status)]['orders_count'] += 1\n            orders_summary[str(order.status)]['total_sales'] += forex(order.event.payment_currency,\n                                                                      self.display_currency, order.amount)\n            for order_ticket in order.tickets:\n                orders_summary[str(order.status)]['tickets_count'] += order_ticket.quantity\n                ticket = TicketingManager.get_ticket(order_ticket.ticket_id)\n                tickets_summary_event_wise[str(order.event_id)][str(order.status)]['tickets_count'] \\\n                    += order_ticket.quantity\n                tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['tickets_count'] \\\n                    += order_ticket.quantity\n                tickets_summary_location_wise[str(order\n                                                  .event.searchable_location_name)][str(order\n                                                                                        .status)]['tickets_count'] \\\n                    += order_ticket.quantity\n\n                if order.paid_via != 'free' and order.amount > 0:\n                    tickets_summary_event_wise[str(order.event_id)][str(order.status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n                    tickets_summary_organizer_wise[str(order.event.creator_id)][str(order.status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n                    tickets_summary_location_wise[str(order.event.\n                                                      searchable_location_name)][str(order.\n                                                                                     status)]['sales'] += \\\n                        order_ticket.quantity * ticket.price\n\n        if path == 'events':\n            return self.render('/gentelella/admin/super_admin/sales/by_events.html',\n                               tickets_summary=tickets_summary_event_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n        elif path == 'organizers':\n            return self.render('/gentelella/admin/super_admin/sales/by_organizer.html',\n                               tickets_summary=tickets_summary_organizer_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n        elif path == 'locations':\n            return self.render('/gentelella/admin/super_admin/sales/by_location.html',\n                               tickets_summary=tickets_summary_location_wise,\n                               display_currency=self.display_currency,\n                               from_date=from_date,\n                               to_date=to_date,\n                               orders_summary=orders_summary)\n\n        else:\n            abort(404)\n", "path": "app/views/admin/super_admin/sales.py"}]}