File: //home/arjun/projects/buyercall_new/buyercall/buyercall/blueprints/billing/models/invoice.py
import datetime
from buyercall.lib.util_sqlalchemy import ResourceMixin
from buyercall.extensions import db
from buyercall.blueprints.billing.gateways.stripecom import \
Invoice as PaymentInvoice
class Invoice(ResourceMixin, db.Model):
__tablename__ = 'invoices'
id = db.Column(db.Integer, primary_key=True)
# Relationships.
partnership_id = db.Column(db.Integer, db.ForeignKey('partnerships.id',
onupdate='CASCADE',
ondelete='CASCADE'),
index=True, nullable=True)
partnership_account_id = db.Column(db.Integer, db.ForeignKey('partnership_accounts.id',
onupdate='CASCADE',
ondelete='CASCADE'),
index=True, nullable=True)
credit_card_id = db.Column(db.Integer, db.ForeignKey('credit_cards.id',
onupdate='CASCADE',
ondelete='CASCADE'),
index=True, nullable=True)
# Invoice details.
plan = db.Column(db.String(128), index=True)
receipt_number = db.Column(db.String(128), index=True)
description = db.Column(db.String(128))
period_start_on = db.Column(db.Date)
period_end_on = db.Column(db.Date)
currency = db.Column(db.String(8))
tax = db.Column(db.Integer())
tax_percent = db.Column(db.Float())
total = db.Column(db.Integer())
def __init__(self, **kwargs):
# Call Flask-SQLAlchemy's constructor.
super(Invoice, self).__init__(**kwargs)
@classmethod
def parse_from_event(cls, payload):
"""
Parse and return the invoice information that will get saved locally.
:return: dict
"""
data = payload['data']['object']
plan_info = data['lines']['data'][0]['plan']
period_start_on = datetime.datetime.utcfromtimestamp(
data['lines']['data'][0]['period']['start']).date()
period_end_on = datetime.datetime.utcfromtimestamp(
data['lines']['data'][0]['period']['end']).date()
invoice = {
'payment_id': data['customer'],
'plan': plan_info['name'],
'receipt_number': data['receipt_number'],
'description': plan_info['statement_descriptor'],
'period_start_on': period_start_on,
'period_end_on': period_end_on,
'currency': data['currency'],
'tax': data['tax'],
'tax_percent': data['tax_percent'],
'total': data['total']
}
return invoice
@classmethod
def parse_from_api(cls, payload):
"""
Parse and return the invoice information we are interested in.
:return: dict
"""
plan_info = payload['lines']['data'][0]['plan']
date = datetime.datetime.utcfromtimestamp(payload['date'])
invoice = {
'plan': plan_info['name'],
'description': plan_info['statement_descriptor'],
'next_bill_on': date,
'amount_due': payload['amount_due'],
'interval': plan_info['interval']
}
return invoice
@classmethod
def prepare_and_save(cls, parsed_event):
"""
Potentially save the invoice after argument the event fields.
:param parsed_event: Event params to be saved
:type parsed_event: dict
:return: Stripe invoice object or None
"""
# Avoid circular imports.
from buyercall.blueprints.user.models import User
# Only save the invoice if the user is valid at this point.
id = parsed_event.get('payment_id')
user = User.query.filter((User.payment_id == id)).first()
if user and user.credit_card:
parsed_event['user_id'] = user.id
parsed_event['brand'] = user.credit_card.brand
parsed_event['last4'] = user.credit_card.last4
parsed_event['exp_date'] = user.credit_card.exp_date
del parsed_event['payment_id']
invoice = Invoice(**parsed_event)
return invoice.save()
return None
@classmethod
def upcoming(cls, customer_id):
"""
Return the upcoming invoice item.
:param customer_id: Stripe customer id
:type customer_id: int
:return: Stripe invoice object
"""
invoice = PaymentInvoice.upcoming(customer_id)
return Invoice.parse_from_api(invoice)