class InvoiceLink(db.Model): __tablename__ = 'invoice_link' #column definitions id = db.Column(db.Integer(11), primary_key=True, nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id'), nullable=False) invoice_id = db.Column(db.Integer(11), db.ForeignKey('invoice.id'), nullable=False) link = db.Column(db.Unicode(25), default=u'', nullable=False) link_hash = db.Column(db.Unicode(50), nullable=False) created_at = db.Column(db.DateTime, default=datetime.now) def generate_link_code(self): code = random_id(8) while True: obj = InvoiceLink.query.filter_by(link=code).first() if not obj: break else: code = random_id(8) self.link = code return self.link def get_url(self): url = 'http://%s.%s/portal/invoice/%s' % ( self.user.username, current_app.config['SERVER_NAME'], self.link) return url
class CustomField(db.Model): __tablename__ = 'custom_field' id = db.Column(u'id', db.BigInteger, primary_key=True, nullable=False) user_id = db.Column(u'user_id', db.Integer, db.ForeignKey('user.id'), nullable=False) name = db.Column(u'name', db.Unicode(length=255)) value = db.Column(u'value', db.Unicode(length=255)) # user user = db.relation('User', backref=db.backref('custom_fields'))
class Payment(db.Model): __tablename__ = 'payment' id = db.Column(db.BigInteger, primary_key=True, nullable=False) invoice_id = db.Column(db.BigInteger, db.ForeignKey('invoice.id')) date = db.Column(db.DateTime, default=datetime.now, nullable=False) currency_code = db.Column(db.Unicode(3), nullable=False) method = db.Column(db.Unicode(50), nullable=False) description = db.Column(db.Unicode(255), nullable=True) amount = db.Column(db.Numeric(8, 2), default=0, nullable=False) created_at = db.Column(db.DateTime, default=datetime.now, nullable=False) #relation definitions invoice = db.relation('Invoice', primaryjoin='Payment.invoice_id==Invoice.id', backref=db.backref('payments', lazy='dyanmic'))
class StripePayment(db.Model): __tablename__ = 'stripe_payment' id = db.Column(db.Integer(11), primary_key=True, nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id'), nullable=False) payment_id = db.Column(db.Integer(11), db.ForeignKey('payment.id'), nullable=True) invoice_id = db.Column(db.Integer(11), db.ForeignKey('invoice.id'), nullable=False) amount = db.Column(db.Numeric(8, 2), default=0) token = db.Column(db.Unicode(100), nullable=False) state = db.Column(db.Unicode(20), default=u'initialized') error_message = db.Column(db.Unicode(255), nullable=True) charge_id = db.Column(db.Unicode(100), nullable=True) charge = db.Column(db.UnicodeText(4294967295), nullable=False, default=u'{}') created_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) @classmethod def get_or_create_for_user(cls, user_id): account = cls.query.filter_by(user_id=user_id).first() if not account: model = cls() model.user_id = user_id db.session.add(model) db.session.commit() return account def create_payment_object(self): """Create related payment object""" payment = Payment() payment.invoice_id = self.invoice_id payment.date = datetime.now() payment.currency_code = self.invoice.currency_code payment.amount = self.amount payment.method = 'stripe' payment.description = 'Credit card payment' db.session.add(payment) db.session.commit() return payment
class Company(db.Model): __tablename__ = 'company' id = db.Column(u'id', db.BigInteger, primary_key=True, nullable=False) user_id = db.Column(u'user_id', db.BigInteger, db.ForeignKey('user.id'), nullable=False) logo_id = db.Column(u'logo_id', db.BigInteger, db.ForeignKey('logo.id'), nullable=False) company_type_id = db.Column(u'company_type_id', db.BigInteger, db.ForeignKey('company_type.id'), nullable=False) name = db.Column(u'name', db.Unicode(length=255)) address1 = db.Column(u'address1', db.Unicode(length=255)) address2 = db.Column(u'address2', db.Unicode(length=255)) town = db.Column(u'town', db.Unicode(length=100)) city = db.Column(u'city', db.Unicode(length=100)) county = db.Column(u'county', db.Unicode(length=255)) country = db.Column(u'country', db.Unicode(length=2)) post_code = db.Column(u'post_code', db.Unicode(length=20)) registration_number = db.Column(u'registration_number', db.Unicode(length=20)) created_at = db.Column(u'created_at', db.DateTime, nullable=False, default=get_current_time()) updated_at = db.Column(u'updated_at', db.DateTime, nullable=False, default=get_current_time()) # user user = db.relation('User', primaryjoin='Company.user_id==User.id', backref=db.backref('company', uselist=False)) # logo logo = db.relation('Logo', primaryjoin='Company.logo_id==Logo.id') # account type company_type = db.relation('CompanyType', backref=db.backref('companies', lazy='dynamic'))
class StripeAccount(db.Model): __tablename__ = 'stripe_account' id = db.Column(db.Integer(11), primary_key=True, nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id')) secret_key = db.Column(db.Unicode(255)) public_key = db.Column(db.Unicode(255)) enabled = db.Column(db.Boolean, default=False) updated_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) created_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) @classmethod def get_or_create_for_user(cls, user_id): account = cls.query.filter_by(user_id=user_id).first() if not account: model = cls() model.user_id = user_id db.session.add(model) db.session.commit() return account
class GoCardlessAccount(db.Model): __tablename__ = 'gocardless_account' id = db.Column(db.Integer(11), primary_key=True, nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id')) app_identifier = db.Column(db.Unicode(255)) app_secret = db.Column(db.Unicode(255)) merchant_access_token = db.Column(db.Unicode(255)) merchant_id = db.Column(db.Unicode(255)) enabled = db.Column(db.Boolean, default=False) updated_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) created_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) @classmethod def get_or_create_for_user(cls, user_id): account = cls.query.filter_by(user_id=user_id).first() if not account: model = cls() model.user_id = user_id db.session.add(model) db.session.commit() return account
class Plan(db.Model): __tablename__ = 'plan' id = db.Column(db.Integer(11), primary_key=True, nullable=False) name = db.Column(db.Unicode(20)) gateway_uid = db.Column(db.Unicode(255)) description = db.Column(db.Unicode(255)) amount = db.Column(db.Numeric(8, 2), default=0) billing_interval = db.Column(db.Enum('daily', 'weekly', 'monthly', 'yearly'), default='monthly') created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) # relationships subscriptions = db.relation('Subscription', backref=db.backref('plan', lazy='joined', uselist=False)) @property def interval_name(self): if self.billing_interval == 'monthly': return 'month'
class GoCardlessPayment(db.Model): __tablename__ = 'gocardless_payment' id = db.Column(db.Integer(11), primary_key=True, nullable=False) invoice_id = db.Column(db.Integer(11), db.ForeignKey('invoice.id'), nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id'), nullable=False) payment_id = db.Column(db.Integer(11), db.ForeignKey('payment.id'), nullable=True) amount = db.Column(db.Numeric(8, 2), default=0) reference = db.Column(db.Unicode(100), nullable=False) state = db.Column(db.Unicode(20), default=u'initialized') resource_id = db.Column(db.Unicode(100), nullable=True) resource_uri = db.Column(db.Unicode(255), nullable=True) error_message = db.Column(db.Unicode(255), nullable=True) created_at = db.Column(db.DateTime(), nullable=False, default=datetime.now) def create_payment_object(self): """Create related payment object""" payment = Payment() payment.invoice_id = self.invoice_id payment.date = datetime.now() payment.currency_code = self.invoice.currency_code payment.amount = self.amount payment.method = 'gocardless' payment.description = 'Direct debit payment' db.session.add(payment) db.session.commit() return payment
class Setting(db.Model): __tablename__ = 'setting' id = db.Column(db.BigInteger, primary_key=True, nullable=False) user_id = db.Column(db.BigInteger, db.ForeignKey('user.id')) key = db.Column(db.Unicode(100)) value = db.Column(db.BLOB()) created_at = db.Column(db.DateTime, default=datetime.now) updated_at = db.Column(db.DateTime, default=datetime.now) def set_value(self, value): self.value = json.dumps(value) def get_value(self): return json.loads(self.value)
class Transaction(db.Model): __tablename__ = 'transaction' id = db.Column(db.Integer(11), primary_key=True, nullable=False) user_id = db.Column(db.Integer(11), db.ForeignKey('user.id'), nullable=False) subscription_id = db.Column(db.Integer(11), db.ForeignKey('subscription.id'), nullable=False) success = db.Column(db.Boolean, default=False) amount = db.Column(db.Numeric(8, 2), default=0) charge_id = db.Column(db.Unicode(100), nullable=True) charge = db.Column(db.UnicodeText(4294967295), nullable=True, default=u'{}') updated_at = db.Column(db.DateTime, nullable=False, default=datetime.now) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
class Invoice(db.Model): __tablename__ = 'invoice' DATE_FORMAT = '%a %b %d %Y' id = db.Column(u'id', db.Integer, primary_key=True, nullable=False) user_id = db.Column(u'user_id', db.Integer, db.ForeignKey('user.id')) contact_id = db.Column(u'contact_id', db.Integer, db.ForeignKey('contact.id')) payment_term_id = db.Column(u'payment_term_id', db.Integer, db.ForeignKey('payment_term.id')) status = db.Column(u'status', db.String(255)) reference = db.Column(u'reference', db.String(255)) po_reference = db.Column(u'po_reference', db.String(255)) currency_code = db.Column(u'currency_code', db.String(5)) date_issued = db.Column(u'date_issued', db.DateTime) due_date = db.Column(u'due_date', db.DateTime) written_off_date = db.Column(u'written_off_date', db.DateTime) sub_total = db.Column(u'sub_total', db.Numeric(8, 2)) tax = db.Column(u'tax', db.Numeric(8, 2)) total = db.Column(u'total', db.Numeric(8, 2)) payment_status = db.Column(u'payment_status', db.Unicode(10), default=u'unpaid') updated_at = db.Column(u'updated_at', db.DateTime, nullable=False, default=get_current_time()) created_at = db.Column(u'created_at', db.DateTime, nullable=False, default=get_current_time()) # relations user = db.relation('User', primaryjoin='Invoice.user_id==User.id', backref='invoices') contact = db.relation('Contact', primaryjoin='Invoice.contact_id==Contact.id', backref='invoices') payment_term = db.relation('PaymentTerm', primaryjoin='Invoice.payment_term_id==PaymentTerm.id') invoice_link = db.relation('InvoiceLink', backref=db.backref('invoice', uselist=False, lazy='joined')) gocardless_payments = db.relation('GoCardlessPayment', backref=db.backref('invoice', uselist=False, lazy='joined')) stripe_payments = db.relation('StripePayment', backref=db.backref('invoice', uselist=False, lazy='joined')) @classmethod def next_invoice_number(cls, user): """Next the next invoice number for the user""" cur_max = cls.query.filter_by(user_id=user.id).count() cur_max += 1 return str(cur_max) @property def due_date_nice(self): return self.due_date.strftime(self.DATE_FORMAT) @property def date_issued_nice(self): return self.date_issued.strftime(self.DATE_FORMAT) def next_item_sort_order(self): """Generate the next number for the invoice item's sort order""" from nano.models import InvoiceItem total = InvoiceItem.query.filter_by(invoice_id=self.id).count() return total+1 def update_totals(self, commit=False): """Update total and tax""" sub_total = 0.0 tax = 0.0 for item in self.invoice_items: sub_total += float(item.total if item.total else 0) tax += float(item.tax if item.tax else 0) self.tax = tax self.sub_total = sub_total self.total = float(self.tax) + float(self.sub_total) if commit: db.session.add(self) db.session.commit() return True def serialize(self): d = model_to_dict(self) d['InvoiceItems'] = [item.serialize() for item in self.invoice_items] return d def update_payment_status(self): """Returns true if the amount has been paid""" payments = Payment.query.filter_by(invoice_id=self.id).all() total = 0.0 for payment in payments: total += float(payment.amount) if total >= self.total: self.payment_status = u'paid' else: self.payment_status = u'unpaid' db.session.add(self) db.session.commit() return False def get_status(self): if self.status == 'draft': return 'draft' if self.status == 'saved': paid = True if self.payment_status == 'paid' else False if paid: return 'paid' if self.due_date <= datetime.now(): return 'overdue' else: return 'saved' def __json__(self): return json_dumps(self.serialize())