-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Single endpoint for creating creating an order #6635
feat: Single endpoint for creating creating an order #6635
Conversation
Codecov Report
@@ Coverage Diff @@
## development #6635 +/- ##
===============================================
+ Coverage 65.15% 65.39% +0.23%
===============================================
Files 299 300 +1
Lines 15319 15315 -4
===============================================
+ Hits 9981 10015 +34
+ Misses 5338 5300 -38
Continue to review full report at Codecov.
|
app/api/custom/orders.py
Outdated
if result.errors: | ||
return jsonify(result.errors) | ||
for ticket in tickets: | ||
ticket_info = db.session.query(Ticket).filter_by(id=int(ticket['id']), deleted_at=None).first() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do this in a single query filter(ids in ticket_ids, event_id=event_id, deleted_at=None)
app/api/custom/orders.py
Outdated
db.session.add(attendee) | ||
db.session.commit() | ||
db.session.refresh(attendee) | ||
attendee_list.append(attendee.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Append attendee directly
app/api/custom/orders.py
Outdated
error="Ticket with id {} belongs to a different Event.".format(ticket['id'])) | ||
if (ticket_info.quantity - get_count(db.session.query(TicketHolder.id).filter_by( | ||
ticket_id=int(ticket['id']), deleted_at=None))) < ticket['quantity']: | ||
return jsonify(status='Order Unsuccessful', error='Ticket already sold out.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These checks should be in calculate amount function itself
app/api/custom/orders.py
Outdated
for ticket_amount in range(ticket['quantity']): | ||
attendee = TicketHolder(**result[0], event_id=int(data['event_id']), ticket_id=int(ticket['id'])) | ||
db.session.add(attendee) | ||
db.session.commit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit once after the loop
app/api/custom/orders.py
Outdated
db.session.refresh(order) | ||
order_tickets = {} | ||
for attendee_id in attendee_list: | ||
holder = TicketHolder.query.filter(TicketHolder.id == attendee_id).one() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to refetch the ticket holder
app/api/custom/orders.py
Outdated
for attendee_id in attendee_list: | ||
holder = TicketHolder.query.filter(TicketHolder.id == attendee_id).one() | ||
holder.order_id = order.id | ||
save_to_db(holder) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, commit once after the loop
app/api/custom/orders.py
Outdated
|
||
for ticket in order_tickets: | ||
od = OrderTicket(order_id=order.id, ticket_id=ticket, quantity=order_tickets[ticket]) | ||
save_to_db(od) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commit once after loop
app/api/custom/orders.py
Outdated
save_to_db(od) | ||
|
||
order.quantity = order.tickets_count | ||
return jsonify("Order successful.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newly created order should be returned
As asked previously, never use update branch feature unless just before merging. The triggers and CI is ran again without any change for no reason and maintainers get a notification thinking that something has changed |
@iamareebjamal Done. I am thinking to refactor the whole calculate-order function in another PR. |
app/api/custom/orders.py
Outdated
if result.errors: | ||
return jsonify(result.errors) | ||
ticket_ids = [ticket['id'] for ticket in tickets] | ||
ticket_info_list = db.session.query(Ticket).filter(Ticket.id.in_(ticket_ids)).all() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will allow deleted tickets as well. And as previously instructed, event filtering should be done here itself
@iamareebjamal Done the required changes. |
app/api/custom/orders.py
Outdated
if not args: | ||
data = request.get_json() | ||
else: | ||
data = json.loads(args[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned previously, this should not be done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No benefit of merging an intermediate state PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iamareebjamal I will start working on that PR as soon as this gets merged. I wanted to keep them separate as this PR already contains a big change. And the second change is more of a refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's why it can be taken in this PR only. It's not a huge change compared to what has been done already. It makes no sense to break something first and then fix later in a separate PR
app/api/custom/orders.py
Outdated
for ticket_information in ticket_info_list: | ||
if ticket_information.id == int(ticket['id']): | ||
ticket_info = ticket_information | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have unnecessariy made an O(n) function to ne O(n^2)
@iamareebjamal Did the changes. Please review. |
app/api/custom/orders.py
Outdated
ticket_ids = [int(ticket['id']) for ticket in tickets] | ||
ticket_info_list = db.session.query(Ticket).filter(Ticket.id.in_(ticket_ids)).filter_by(event_id=data['event_id'], | ||
deleted_at=None).all() | ||
ticket_ids_found = [ticket_information.id for ticket_information in ticket_info_list] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ticket_ids_found = [ticket_information.id for ticket_information in ticket_info_list] | |
ticket_ids_found = {ticket_information.id for ticket_information in ticket_info_list} |
app/api/custom/orders.py
Outdated
if result.errors: | ||
return jsonify(result.errors) | ||
ticket_ids = [int(ticket['id']) for ticket in tickets] | ||
ticket_info_list = db.session.query(Ticket).filter(Ticket.id.in_(ticket_ids)).filter_by(event_id=data['event_id'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not tickets or ticket_list
app/api/custom/orders.py
Outdated
ticket_ids_found = [ticket_information.id for ticket_information in ticket_info_list] | ||
tickets_not_found = list(set(ticket_ids) - set(ticket_ids_found)) | ||
if tickets_not_found: | ||
return jsonify(status='Order Unsuccessful', error='Ticket with id {} was not found.'.format(tickets_not_found)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be multiple tickets not found. Also, send event ID as well. Ticket 324 may exist but not under the event requested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iamareebjamal I am sending the list of all the tickets not found. Regarding example of ticket 324, I am already passing event_id as well which fetching the tickets, so those tickets will also throw tickets not found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will throw: Ticket with ID 324, 325, 326 was not found
Everyone wants to see: Tickets with ID 324, 325, 326 were not found in Event 432
Hence, again #6635 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will throw: Ticket with ID 324, 325, 326 was not found in Event 432
Everyone wants to see: Tickets with ID 324, 325, 326 were not found in Event 432
app/api/custom/orders.py
Outdated
return jsonify(status='Order Unsuccessful', error='Ticket with id {} was not found.'.format(tickets_not_found)) | ||
for ticket in tickets: | ||
ticket_info = None | ||
for ticket_information in ticket_info_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nested for loop = Automatically not approved. There is no need of nested for loop here
app/api/custom/orders.py
Outdated
ticket_ids_found = [ticket_information.id for ticket_information in ticket_info_list] | ||
tickets_not_found = list(set(ticket_ids) - set(ticket_ids_found)) | ||
if tickets_not_found: | ||
return jsonify(status='Order Unsuccessful', error='Ticket with id {} was not found.'.format(tickets_not_found)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will send HTTP status code as 200, which means OK. Which means order was created successfully
app/api/custom/orders.py
Outdated
ticket_info = ticket_information | ||
if (ticket_info.quantity - get_count(db.session.query(TicketHolder.id).filter_by( | ||
ticket_id=int(ticket['id']), deleted_at=None))) < ticket['quantity']: | ||
return jsonify(status='Order Unsuccessful', error='Ticket already sold out.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will send HTTP status code as 200, which means OK. Which means order was created successfully
app/api/custom/orders.py
Outdated
json_api_attendee = {"data": {"attributes": data['attendee'], "type": "attendee"}} | ||
result = schema.load(json_api_attendee) | ||
if result.errors: | ||
return jsonify(result.errors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will send HTTP status code as 200, which means OK. Which means order was created successfully
@iamareebjamal Done. |
@iamareebjamal Did those changes. |
Read again |
app/api/helpers/order.py
Outdated
@@ -213,5 +223,5 @@ def calculate_order_amount(tickets, discount_code): | |||
'ticket_fee': round(ticket_fee, 2), | |||
'sub_total': round(sub_total, 2) | |||
}) | |||
return dict(tax_included=tax_included, total_amount=round(total_amount, 2), total_tax=round(total_tax, 2), | |||
total_discount=round(total_discount, 2), tickets=ticket_list) | |||
return jsonify(dict(tax_included=tax_included, total_amount=round(total_amount, 2), total_tax=round(total_tax, 2), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not return JSON response. This function should have no idea about request or response or anything. This function does not know that it is part of flask application. This should be a pure python function, otherwise what was the point of extracting it out?
app/api/helpers/order.py
Outdated
@@ -134,7 +135,16 @@ def create_onsite_attendees_for_order(data): | |||
del data['on_site_tickets'] | |||
|
|||
|
|||
def calculate_order_amount(tickets, discount_code): | |||
def calculate_order_amount(data): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't change the function signature, it was fine. This should take tickets and discount code only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a wrapper function if you want to
app/api/helpers/order.py
Outdated
@@ -214,4 +224,4 @@ def calculate_order_amount(tickets, discount_code): | |||
'sub_total': round(sub_total, 2) | |||
}) | |||
return dict(tax_included=tax_included, total_amount=round(total_amount, 2), total_tax=round(total_tax, 2), | |||
total_discount=round(total_discount, 2), tickets=ticket_list) | |||
total_discount=round(total_discount, 2), tickets=ticket_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continuation line over-indented for visual indent
app/api/helpers/order.py
Outdated
@@ -1,16 +1,17 @@ | |||
import logging | |||
from datetime import timedelta, datetime, timezone | |||
|
|||
from flask import render_template | |||
from flask import render_template, jsonify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'flask.jsonify' imported but unused
app/api/custom/orders.py
Outdated
@@ -1,22 +1,26 @@ | |||
from flask import Blueprint, jsonify, request | |||
import json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'json' imported but unused
Here is an overview of what got changed by this pull request: Issues
======
+ Solved 2
- Added 2
Complexity increasing per file
==============================
- app/api/custom/orders.py 10
- app/api/helpers/order.py 2
See the complete overview on Codacy |
Fixes #6320
Checklist
development
branch.