Skip to content

Commit

Permalink
chore: Release v1.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
iamareebjamal authored Feb 20, 2020
2 parents a60e630 + 25e6a09 commit d08a143
Show file tree
Hide file tree
Showing 41 changed files with 317 additions and 274 deletions.
94 changes: 80 additions & 14 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
version: 2
jobs:
build:
dependencies:
docker:
- image: circleci/python:3.7.4-node
environment:
APP_CONFIG: config.TestingConfig
DATABASE_URL: postgresql://postgres@localhost/test
TEST_DATABASE_URL: postgresql://postgres@localhost/test
# Services
- image: circleci/postgres:11.5-alpine-ram
environment:
POSTGRES_USER: postgres
POSTGRES_DB: test
- image: circleci/redis:5.0.6-alpine

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/tests.txt" }}-{{ checksum "package.json" }}
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

Expand All @@ -32,7 +25,7 @@ jobs:
python3 -m venv venv
. venv/bin/activate
pip install --exists-action w -r requirements/tests.txt
- run:
name: Install Node Dependencies
command: yarn
Expand All @@ -43,7 +36,36 @@ jobs:
- ./node_modules
- ~/.cache/yarn
- ~/.yarn/bin
key: v1.3-dependencies-{{ checksum "requirements/tests.txt" }}-{{ checksum "package.json" }}
key: v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}

dredd:
docker:
- image: circleci/python:3.7.4-node
environment:
APP_CONFIG: config.TestingConfig
DATABASE_URL: postgresql://postgres@localhost/test
TEST_DATABASE_URL: postgresql://postgres@localhost/test
# Services
- image: circleci/postgres:11.5-alpine-ram
environment:
POSTGRES_USER: postgres
POSTGRES_DB: test
- image: circleci/redis:5.0.6-alpine

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

- run:
name: Create API blueprint
Expand All @@ -52,3 +74,47 @@ jobs:
- run:
name: Test API Doc
command: . venv/bin/activate && npx dredd

pytype:
docker:
- image: circleci/python:3.7.4-node

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

- restore_cache:
keys:
- v1-pytype

- run:
name: Test pytype
command: . venv/bin/activate && pytype

- save_cache:
paths:
- ./.pytype
key: v1-pytype

workflows:
version: 2
build-and-test:
jobs:
- dependencies
- dredd:
requires:
- dependencies
- pytype:
requires:
- dependencies
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ generated/
docker-compose.override.yml
celerybeat-schedule.*
.coverage
.pytype
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## Changelog

#### v1.13.0 (2020-02-20):

- Fix cron job timings preventing multiple emails to attendees
- Change email links to be more accessible
- Fix invoice email generation errors
- Add proper etag support by changing to weak etags

#### v1.12.0 (2020-02-02):

- Add check if donation ticket has payment method enabled
Expand Down
Empty file added app/api/__init__.py
Empty file.
Empty file added app/api/admin_sales/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion app/api/attendees.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def before_update_object(self, obj, data, kwargs):
checkout_times = (
obj.checkout_times.split(',') if obj.checkout_times else []
)
checkout_times.append(str(datetime.utcnow()))
checkout_times.append(str(datetime.datetime.utcnow()))
data['checkout_times'] = ','.join(checkout_times)

if 'attendee_notes' in data:
Expand Down
Empty file added app/api/custom/__init__.py
Empty file.
Empty file added app/api/data_layers/__init__.py
Empty file.
Empty file.
Empty file added app/api/helpers/__init__.py
Empty file.
5 changes: 3 additions & 2 deletions app/api/helpers/import_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from flask import current_app as app
from flask import request
from flask_jwt_extended import current_user
from werkzeug import secure_filename
from werkzeug.utils import secure_filename

from app.api.helpers.db import save_to_db
from app.api.helpers.errors import NotFoundError, ServerError
Expand Down Expand Up @@ -369,6 +369,7 @@ def import_event_json(task_handle, zip_path, creator_id):
except Exception as e:
raise make_error('event', er=e)
# create other services
item = [] # TODO: Remove workaround for pytype
try:
service_ids = {}
for item in IMPORT_SERIES:
Expand All @@ -384,7 +385,7 @@ def import_event_json(task_handle, zip_path, creator_id):
except IOError:
db.session.delete(new_event)
db.session.commit()
raise NotFoundError('File %s missing in event zip' % item[0])
raise NotFoundError('file', 'File %s missing in event zip' % item[0])
except ValueError:
db.session.delete(new_event)
db.session.commit()
Expand Down
2 changes: 1 addition & 1 deletion app/api/helpers/jwt.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import _app_ctx_stack as ctx_stack
from flask import _app_ctx_stack as ctx_stack # pytype: disable=import-error
from flask_jwt_extended.config import config
from flask_jwt_extended.exceptions import JWTExtendedException, UserLoadError
from flask_jwt_extended.view_decorators import _decode_jwt_from_request, _load_user
Expand Down
4 changes: 2 additions & 2 deletions app/api/helpers/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ def send_email_to_attendees(order, purchaser_id, attachments=None):
frontend_url=get_settings()['frontend_url'],
),
html=MAILS[TICKET_PURCHASED]['message'].format(
pdf_url=holder.pdf_url,
event_name=order.event.name,
frontend_url=get_settings()['frontend_url'],
),
Expand All @@ -351,7 +350,8 @@ def send_email_to_attendees(order, purchaser_id, attachments=None):
event_name=order.event.name, invoice_id=order.invoice_number
),
html=MAILS[TICKET_PURCHASED_ATTENDEE]['message'].format(
pdf_url=holder.pdf_url, event_name=order.event.name
my_tickets_url=get_settings()['frontend_url'] + '/my-tickets',
event_name=order.event.name,
),
attachments=attachments,
)
Expand Down
11 changes: 7 additions & 4 deletions app/api/helpers/permission_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Union
from flask import request
from flask_jwt_extended import current_user, verify_jwt_in_request
from sqlalchemy.orm.exc import NoResultFound
Expand Down Expand Up @@ -357,7 +358,7 @@ def create_event(view, view_args, view_kwargs, *args, **kwargs):
}


def is_multiple(data):
def is_multiple(data: Union[str, list]) -> bool:
if type(data) is list:
return True
if type(data) is str:
Expand Down Expand Up @@ -465,8 +466,10 @@ def permission_manager(view, view_args, view_kwargs, *args, **kwargs):
if not is_multiple(model):
model = [model]

if is_multiple(fetch_key_url):
fetch_key_url = fetch_key_url.split(",")
if type(fetch_key_url) == str and is_multiple(fetch_key_url):
fetch_key_url = fetch_key_url.split( # pytype: disable=attribute-error
","
)

found = False
for index, mod in enumerate(model):
Expand All @@ -477,7 +480,7 @@ def permission_manager(view, view_args, view_kwargs, *args, **kwargs):
if not view_kwargs.get(f_url):
continue
try:
data = mod.query.filter(
data = mod.query.filter( # pytype: disable=attribute-error
getattr(mod, fetch_key_model) == view_kwargs[f_url]
).one()
except NoResultFound:
Expand Down
43 changes: 30 additions & 13 deletions app/api/helpers/scheduled_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytz
from dateutil.relativedelta import relativedelta
from sqlalchemy.orm.exc import NoResultFound
from flask_rest_jsonapi.exceptions import ObjectNotFound
from flask import render_template
from flask_celeryext import RequestContextTask

Expand Down Expand Up @@ -249,22 +251,27 @@ def send_monthly_event_invoice():
user = event.owner
admin_info = get_settings()
currency = event.payment_currency
ticket_fee_object = (
db.session.query(TicketFees).filter_by(currency=currency).one()
)
try:
ticket_fee_object = (
db.session.query(TicketFees).filter_by(currency=currency).one()
)
except NoResultFound:
raise ObjectNotFound(
{'source': ''}, 'Ticket Fee not set for {}'.format(currency)
)
ticket_fee_percentage = ticket_fee_object.service_fee
ticket_fee_maximum = ticket_fee_object.maximum_fee
orders = Order.query.filter_by(event=event).all()
gross_revenue = event.calc_monthly_revenue()
ticket_fees = event.tickets_sold * (ticket_fee_percentage / 100)
if ticket_fees > ticket_fee_maximum:
ticket_fees = ticket_fee_maximum
net_revenue = gross_revenue - ticket_fees
invoice_amount = gross_revenue * (ticket_fee_percentage / 100)
if invoice_amount > ticket_fee_maximum:
invoice_amount = ticket_fee_maximum
net_revenue = gross_revenue - invoice_amount
payment_details = {
'tickets_sold': event.tickets_sold,
'gross_revenue': gross_revenue,
'net_revenue': net_revenue,
'amount_payable': ticket_fees,
'amount_payable': invoice_amount,
}
# save invoice as pdf
pdf = create_save_pdf(
Expand All @@ -286,7 +293,7 @@ def send_monthly_event_invoice():
# save event_invoice info to DB

event_invoice = EventInvoice(
amount=net_revenue, invoice_pdf_url=pdf, event_id=event.id
amount=invoice_amount, invoice_pdf_url=pdf, event_id=event.id
)
save_to_db(event_invoice)

Expand All @@ -295,17 +302,27 @@ def send_monthly_event_invoice():
def setup_scheduled_task(sender, **kwargs):
from celery.schedules import crontab

sender.add_periodic_task(crontab(hour='*/5', minute=30), send_after_event_mail)
sender.add_periodic_task(crontab(minute=0, hour=0), send_event_fee_notification)
# Every day at 5:30
sender.add_periodic_task(crontab(hour=5, minute=30), send_after_event_mail)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_event_fee_notification
)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_event_fee_notification_followup
)
# Every day at 5:30
sender.add_periodic_task(
crontab(hour='*/5', minute=30), change_session_state_on_event_completion
crontab(hour=5, minute=30), change_session_state_on_event_completion
)
# Every 45 minutes
sender.add_periodic_task(crontab(minute='*/45'), expire_pending_tickets)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_monthly_event_invoice
)
sender.add_periodic_task(crontab(minute=0, hour='*/5'), event_invoices_mark_due)
# Every day at 5:00
sender.add_periodic_task(crontab(minute=0, hour=5), event_invoices_mark_due)
# Every 5 minutes
sender.add_periodic_task(crontab(minute='*/5'), delete_ticket_holders_no_order_id)
4 changes: 3 additions & 1 deletion app/api/helpers/system_mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@
'message': (
u"Hi, this is a confirmation mail of your tickets for the event {event_name}"
u"<br/>Your order has been processed successfully."
+ u"<br/> <a href='{pdf_url}'>Click here</a> to view/download your ticket."
+ u"<br/> Your tickets & invoice have been enclosed."
u"<br><br>You can also download your tickets in <b>My Tickets</b> section."
u"<br/>Login to manage the orders at <a href='{mytickets_url}' target='_blank'>{mytickets_url}</a> </em>"
u"<br><br><em>Looking forward to seeing you at the event."
),
},
Expand Down
Loading

0 comments on commit d08a143

Please sign in to comment.