class Payment(db.Model): __tablname__ = 'payment' id = db.Column(db.Integer, primary_key=True) amount = db.Column(db.Numeric(10, 2), nullable=False) date = db.Column(db.Date, nullable=False) notes = db.Column(db.UnicodeText) documents = association_proxy('document_payment', 'document') def add_documents(self, documents): for document in documents: document.add_payment(self)
class ProductSupplierInfo(db.Model): __tablename__ = 'productsupplier_info' supplier_id = db.Column(db.Integer, db.ForeignKey('supplier.supplier_id'), primary_key=True) supplier = db.relationship('Supplier', backref='products_info', lazy='joined') product_id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True) product = db.relationship('Product', backref='suppliers_info', lazy='joined') code = db.Column(db.Unicode(80)) description = db.Column(db.Unicode) base_cost = db.Column(db.Numeric(10, 2)) minimum_purchase = db.Column(db.Integer, default=1)
class DocumentPayment(db.Model): __tablename__ = 'document_payment' document_id = db.Column(db.Integer, db.ForeignKey('document.id'), primary_key=True) payment_id = db.Column(db.Integer, db.ForeignKey('payment.id'), primary_key=True) amount = db.Column(db.Numeric(10, 2), nullable=False) payment = db.relationship(Payment, lazy='joined', backref='document_payments') document = db.relationship('Document', lazy='joined', backref='document_payments') def __init__(self, payment, amount): self.payment = payment self.amount = amount
class Supplier(Entity): __tablename__ = 'supplier' __mapper_args__ = {'polymorphic_identity': 'supplier'} supplier_id = db.Column(db.Integer, db.ForeignKey('entity.id'), primary_key=True) rz = Entity._name_1 name = Entity._name_2 web = db.Column(db.Unicode, default=None) fiscal_data_id = db.Column(db.Integer, db.ForeignKey('fiscal_data.id')) fiscal_data = db.relationship(FiscalData, backref=db.backref('entity', uselist=False)) payment_term = db.Column(db.Integer) # in days leap_time = db.Column(db.Integer) # in days delivery_included = db.Column(db.Boolean) supplier_contacts = db.relationship('SupplierContact', cascade='all, delete-orphan', backref='supplier') contacts = association_proxy('supplier_contacts', 'contact') debt = db.Column(db.Numeric(10, 2)) expired = db.Column(db.Numeric(10, 2)) expiration_date = db.Column(db.DateTime, default=None) #: 'bank_accounts' attribute added by BankAccount.supplier relation #: 'orders' attribute added by PurchaseOrder.supplier relation #: 'documents' attribute added by Document.supplier relation #: Inherited from Entity #: - address (collection) #: - email (collection) #: - phone (collection) #: - extra field (collection) # products = association_proxy('products_info', 'product') def add_contact(self, contact, role): self.supplier_contacts.append(SupplierContact(contact, role)) # def add_product(self, product, **kwargs): # self.products_info.append(ProductSupplierInfo(product=product, **kwargs)) @property def full_name(self): n = " ({0})".format(self.name) if self.name else '' return "{0}{1}".format(self.rz, n) def _update_expiration_date(self): doc = self.documents\ .filter(Document.doc_status.in_([Document.STATUS_PENDING, Document.STATUS_EXPIRED]))\ .order_by(Document.expiration_date.asc())\ .first() if doc: self.expiration_date = doc.expiration_date else: self.expiration_date = None
class Document(db.Model, TimestampMixin): __tablename__ = 'document' TYPE_FACTURA_A = 'TYPE_FACTURA_A' TYPE_NOTA_CREDITO_A = 'TYPE_NOTA_CREDITO_A' TYPE_PRESUPUESTO = 'TYPE_PRESUPUESTO' _doc_type = { TYPE_FACTURA_A: 'Factura A', TYPE_NOTA_CREDITO_A: 'Nota de Crédito', TYPE_PRESUPUESTO: 'Presupuesto', } STATUS_PENDING = 'STATUS_PENDING' STATUS_EXPIRED = 'STATUS_EXPIRED' STATUS_PAID = 'STATUS_PAID' _doc_status = { STATUS_PENDING: 'Pendiente', STATUS_EXPIRED: 'Vencida', STATUS_PAID: 'Pagada', } id = db.Column(db.Integer, primary_key=True) doc_type = db.Column(db.Enum(*_doc_type.keys(), name='doc_type'), default=TYPE_FACTURA_A) point_sale = db.Column(db.Integer, nullable=False) number = db.Column(db.Integer, nullable=False) total = db.Column(db.Numeric(10, 2), nullable=False) doc_status = db.Column(db.Enum(*_doc_status.keys(), name='doc_status'), default=STATUS_PENDING) issue_date = db.Column(db.Date) expiration_date = db.Column(db.Date) notes = db.Column(db.UnicodeText) supplier_id = db.Column(db.Integer, db.ForeignKey('supplier.supplier_id'), nullable=False) supplier = db.relationship('Supplier', backref=db.backref('documents', order_by='Document.issue_date.asc()', lazy='dynamic')) #: document_payments added by DocumentPayment.document relationship def add_payment(self, payment, amount=None): if amount is None: amount = min([payment.amount, self.balance]) self.document_payments.append(DocumentPayment(payment, amount)) @property def type(self): return self._doc_type.get(self.doc_type) @property def status(self): return self._doc_status.get(self.doc_status) @property def full_desc(self): return u"%s %04d-%08d" % (self.type, self.point_sale, self.number) @property def cancelled_date(self): if self.state in (self.STATUS_PENDING, self.STATUS_EXPIRED): return None return Payment.query.join('document_payment')\ .filter(DocumentPayment.document==self)\ .order_by(Payment.date.desc())[0].date @property def balance(self): paid = db.session.query(db.func.sum(DocumentPayment.amount))\ .filter(DocumentPayment.document==self).scalar()\ or Decimal(0) return self.total - paid def __repr__(self): return "<Document '{}' of '{}' ({})>".format(self.full_desc, self.supplier.rz, self.status)