-
Notifications
You must be signed in to change notification settings - Fork 5
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
Settlement report #184
Settlement report #184
Changes from all commits
b67d4f2
cb988fd
206d0bc
a917fa2
9c2348a
ce5faed
374b917
4820a42
d708182
91f8f54
50ecd3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from .razorpay import * | ||
from .razorpay_status import * |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from baseframe import __ | ||
from coaster.utils import LabeledEnum | ||
|
||
__all__ = ['RAZORPAY_PAYMENT_STATUS'] | ||
|
||
class RAZORPAY_PAYMENT_STATUS(LabeledEnum): | ||
""" | ||
Reflects payment statuses as specified in | ||
https://docs.razorpay.com/docs/return-objects | ||
""" | ||
CREATED = (0, __("Created")) | ||
AUTHORIZED = (1, __("Authorized")) | ||
CAPTURED = (2, __("Captured")) | ||
#: Only fully refunded payments. | ||
REFUNDED = (3, __("Refunded")) | ||
FAILED = (4, __("Failed")) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ class LINE_ITEM_STATUS(LabeledEnum): | |
#: A line item can be made void by the system to invalidate | ||
#: a line item. Eg: a discount no longer applicable on a line item as a result of a cancellation | ||
VOID = (3, __("Void")) | ||
|
||
TRANSACTION = {CONFIRMED, VOID, CANCELLED} | ||
|
||
LineItemTuple = namedtuple('LineItemTuple', ['item_id', 'id', 'base_amount', 'discount_policy_id', 'discount_coupon_id', 'discounted_amount', 'final_amount']) | ||
|
||
|
@@ -66,7 +66,8 @@ class LineItem(BaseMixin, db.Model): | |
""" | ||
__tablename__ = 'line_item' | ||
__uuid_primary_key__ = True | ||
__table_args__ = (db.UniqueConstraint('customer_order_id', 'line_item_seq'),) | ||
__table_args__ = (db.UniqueConstraint('customer_order_id', 'line_item_seq'), | ||
db.UniqueConstraint('previous_id')) | ||
|
||
# line_item_seq is the relative number of the line item per order. | ||
line_item_seq = db.Column(db.Integer, nullable=False) | ||
|
@@ -78,6 +79,12 @@ class LineItem(BaseMixin, db.Model): | |
item_id = db.Column(None, db.ForeignKey('item.id'), nullable=False, index=True, unique=False) | ||
item = db.relationship(Item, backref=db.backref('line_items', cascade='all, delete-orphan')) | ||
|
||
previous_id = db.Column(None, db.ForeignKey('line_item.id'), nullable=True, index=True, unique=True) | ||
previous = db.relationship('LineItem', | ||
primaryjoin='line_item.c.id==line_item.c.previous_id', | ||
backref=db.backref('revision', uselist=False), | ||
remote_side='LineItem.id') | ||
|
||
discount_policy_id = db.Column(None, db.ForeignKey('discount_policy.id'), nullable=True, index=True, unique=False) | ||
discount_policy = db.relationship('DiscountPolicy', backref=db.backref('line_items')) | ||
|
||
|
@@ -325,6 +332,11 @@ def get_confirmed_line_items(self): | |
Order.get_confirmed_line_items = property(get_confirmed_line_items) | ||
|
||
|
||
def initial_line_items(self): | ||
return LineItem.query.filter(LineItem.order == self, LineItem.previous == None, LineItem.status.in_(LINE_ITEM_STATUS.TRANSACTION)) | ||
Order.initial_line_items = property(initial_line_items) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both this and the other function could be lazy relationships with elaborate |
||
|
||
|
||
def get_from_item(cls, item, qty, coupon_codes=[]): | ||
""" | ||
Returns a list of (discount_policy, discount_coupon) tuples | ||
|
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from flask import jsonify | ||
from flask import jsonify, request, g, abort | ||
from .. import app, lastuser | ||
from coaster.views import load_models, render_with | ||
from baseframe import localize_timezone, get_locale | ||
from boxoffice.models import Organization, ItemCollection, LineItem, INVOICE_STATUS | ||
from boxoffice.views.utils import check_api_access, csv_response | ||
from boxoffice.views.utils import check_api_access, csv_response, api_error | ||
from babel.dates import format_datetime | ||
from datetime import datetime | ||
from datetime import datetime, date | ||
from ..extapi.razorpay import get_settled_transactions | ||
|
||
|
||
def jsonify_report(data_dict): | ||
|
@@ -28,7 +29,7 @@ def admin_report(item_collection): | |
|
||
|
||
def jsonify_org_report(data_dict): | ||
return jsonify(org_title=data_dict['organization'].title) | ||
return jsonify(org_title=data_dict['organization'].title, siteadmin=data_dict['siteadmin']) | ||
|
||
|
||
@app.route('/admin/o/<org_name>/reports') | ||
|
@@ -38,7 +39,7 @@ def jsonify_org_report(data_dict): | |
(Organization, {'name': 'org_name'}, 'organization'), | ||
permission='org_admin') | ||
def admin_org_report(organization): | ||
return dict(organization=organization) | ||
return dict(organization=organization, siteadmin=lastuser.has_permission('siteadmin')) | ||
|
||
|
||
@app.route('/admin/ic/<ic_id>/tickets.csv') | ||
|
@@ -169,3 +170,20 @@ def row_handler(row): | |
return dict_row | ||
|
||
return csv_response(headers, rows, row_type='dict', row_handler=row_handler) | ||
|
||
|
||
@app.route('/admin/o/<org_name>/settlements.csv') | ||
@lastuser.requires_permission('siteadmin') | ||
@load_models( | ||
(Organization, {'name': 'org_name'}, 'organization')) | ||
def settled_transactions(organization): | ||
year = int(request.args.get('year')) | ||
month = int(request.args.get('month')) | ||
try: | ||
date(year, month, 1) | ||
except (ValueError, TypeError): | ||
return api_error(message='Invalid year/month', | ||
status_code=403, | ||
errors=['invalid_date']) | ||
headers, rows = get_settled_transactions({'year': year, 'month': month}, g.user.timezone) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This call does not specify the organization it's being called for. Since the RazorPay API key is global to the app, there is no reason to drag the organization into this. Just use Lastuser's |
||
return csv_response(headers, rows, row_type='dict') |
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.
If you want the timezone object, it's
app.config['tz']
. Our convention is to usetimezone
andTIMEZONE
for the string andtz
for the object.