Initial tables and importer stubs, mostly for invoice exports to QB
This commit is contained in:
commit
9394171ba5
18 changed files with 1087 additions and 0 deletions
32
rattail_quickbooks/db/model/__init__.py
Normal file
32
rattail_quickbooks/db/model/__init__.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Quickbooks integration data models
|
||||
"""
|
||||
|
||||
from .stores import QuickbooksStore
|
||||
from .org import QuickbooksDepartment
|
||||
from .vendors import QuickbooksVendor
|
||||
from .invoices import (QuickbooksExportableInvoice,
|
||||
QuickbooksExportableInvoiceDistribution,
|
||||
QuickbooksInvoiceExport)
|
302
rattail_quickbooks/db/model/invoices.py
Normal file
302
rattail_quickbooks/db/model/invoices.py
Normal file
|
@ -0,0 +1,302 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Invoice data models
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.core import filename_column
|
||||
from rattail.util import OrderedDict
|
||||
|
||||
|
||||
class QuickbooksExportableInvoice(model.Base):
|
||||
"""
|
||||
Represents a vendor invoice capable of being exported to Quickbooks.
|
||||
"""
|
||||
__tablename__ = 'quickbooks_exportable_invoice'
|
||||
__table_args__ = (
|
||||
sa.ForeignKeyConstraint(['store_uuid'], ['store.uuid'],
|
||||
name='quickbooks_exportable_invoice_fk_store'),
|
||||
sa.ForeignKeyConstraint(['vendor_uuid'], ['vendor.uuid'],
|
||||
name='quickbooks_exportable_invoice_fk_vendor'),
|
||||
sa.ForeignKeyConstraint(['deleted_by_uuid'], ['user.uuid'],
|
||||
name='quickbooks_exportable_invoice_fk_deleted_by'),
|
||||
sa.ForeignKeyConstraint(['exported_by_uuid'], ['user.uuid'],
|
||||
name='quickbooks_exportable_invoice_fk_exported_by'),
|
||||
)
|
||||
__versioned__ = {}
|
||||
|
||||
STATUS_NOT_YET_REFRESHED = 1
|
||||
STATUS_EXPORTABLE = 2
|
||||
STATUS_STORE_NOT_FOUND = 3
|
||||
STATUS_VENDOR_NOT_FOUND = 4
|
||||
STATUS_VENDOR_BAD_INFO = 5
|
||||
STATUS_PO_NOT_FOUND = 6
|
||||
STATUS_PO_BAD_INFO = 7
|
||||
STATUS_DIST_PROBLEMS = 8
|
||||
STATUS_DEPTS_IGNORED = 9
|
||||
STATUS_EXPORTED = 10
|
||||
STATUS_DELETED = 11
|
||||
|
||||
STATUS = OrderedDict([
|
||||
(STATUS_NOT_YET_REFRESHED, "data not yet refreshed"),
|
||||
(STATUS_EXPORTABLE, "exportable"),
|
||||
(STATUS_STORE_NOT_FOUND, "store not found"),
|
||||
(STATUS_VENDOR_NOT_FOUND, "vendor not found"),
|
||||
(STATUS_VENDOR_BAD_INFO, "vendor info is invalid"),
|
||||
(STATUS_PO_NOT_FOUND, "PO not found"),
|
||||
(STATUS_PO_BAD_INFO, "PO info is invalid"),
|
||||
(STATUS_DIST_PROBLEMS, "see distribution problem(s)"),
|
||||
(STATUS_DEPTS_IGNORED, "all departments ignored"),
|
||||
(STATUS_EXPORTED, "exported"),
|
||||
(STATUS_DELETED, "deleted"),
|
||||
])
|
||||
|
||||
uuid = model.uuid_column()
|
||||
|
||||
##################################################
|
||||
# columns whose values come from source data
|
||||
##################################################
|
||||
|
||||
store_id = sa.Column(sa.String(length=4), nullable=True, doc="""
|
||||
ID string for the store which must pay the invoice.
|
||||
""")
|
||||
|
||||
vendor_id = sa.Column(sa.String(length=14), nullable=True, doc="""
|
||||
ID string for the vendor which sent the invoice.
|
||||
""")
|
||||
|
||||
txn_id = sa.Column(sa.String(length=20), nullable=True, doc="""
|
||||
ID string for the transaction represented by the invoice, if
|
||||
applicable.
|
||||
""")
|
||||
|
||||
invoice_number = sa.Column(sa.String(length=20), nullable=True, doc="""
|
||||
Invoice number, per source data.
|
||||
""")
|
||||
|
||||
invoice_date = sa.Column(sa.Date(), nullable=True, doc="""
|
||||
Date of the invoice, per source data.
|
||||
""")
|
||||
|
||||
invoice_total = sa.Column(sa.Numeric(precision=8, scale=2), nullable=False, doc="""
|
||||
Total amount for the invoice, per source data.
|
||||
""")
|
||||
|
||||
##################################################
|
||||
# columns whose values come from data refresh
|
||||
##################################################
|
||||
|
||||
store_uuid = sa.Column(sa.String(length=32), nullable=True)
|
||||
store = orm.relationship(
|
||||
model.Store,
|
||||
doc="""
|
||||
Reference to the :class:`rattail:~rattail.db.model.Store`
|
||||
instance associated with the invoice, or ``None``.
|
||||
""")
|
||||
|
||||
vendor_uuid = sa.Column(sa.String(length=32), nullable=True)
|
||||
vendor = orm.relationship(
|
||||
model.Vendor,
|
||||
doc="""
|
||||
Reference to the vendor associated with the invoice, or
|
||||
``None``.
|
||||
""",
|
||||
backref=orm.backref(
|
||||
'dtail_qbo_invoices',
|
||||
cascade='all'))
|
||||
|
||||
quickbooks_vendor_name = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks name for the invoice vendor.
|
||||
""")
|
||||
|
||||
quickbooks_vendor_terms = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks terms for the invoice vendor.
|
||||
""")
|
||||
|
||||
quickbooks_bank_account = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks bank account for the invoice vendor.
|
||||
""")
|
||||
|
||||
quickbooks_export_template = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Name of the Quickbooks export template to use for this invoice.
|
||||
""")
|
||||
|
||||
status_code = sa.Column(sa.Integer(), nullable=False, doc="""
|
||||
Status code for the invoice; indicates whether it's exportable etc.
|
||||
""")
|
||||
|
||||
status_text = sa.Column(sa.String(length=255), nullable=True, doc="""
|
||||
Extra text relating to the invoice status, if applicable.
|
||||
""")
|
||||
|
||||
##################################################
|
||||
# other columns
|
||||
##################################################
|
||||
|
||||
deleted = sa.Column(sa.DateTime(), nullable=True, doc="""
|
||||
Timestamp when the invoice was marked as deleted, or ``None``.
|
||||
""")
|
||||
|
||||
deleted_by_uuid = sa.Column(sa.String(length=32), nullable=True)
|
||||
deleted_by = orm.relationship(
|
||||
model.User,
|
||||
primaryjoin='User.uuid == QuickbooksExportableInvoice.deleted_by_uuid',
|
||||
doc="""
|
||||
Reference to the :class:`rattail:~rattail.db.model.User`
|
||||
instance who marked the invoice as deleted, or ``None``.
|
||||
""")
|
||||
|
||||
exported = sa.Column(sa.DateTime(), nullable=True, doc="""
|
||||
Timestamp when the invoice was exported, or ``None``.
|
||||
""")
|
||||
|
||||
exported_by_uuid = sa.Column(sa.String(length=32), nullable=True)
|
||||
exported_by = orm.relationship(
|
||||
model.User,
|
||||
primaryjoin='User.uuid == QuickbooksExportableInvoice.exported_by_uuid',
|
||||
doc="""
|
||||
Reference to the :class:`rattail:~rattail.db.model.User`
|
||||
instance who exported the invoice, or ``None``.
|
||||
""")
|
||||
|
||||
def __str__(self):
|
||||
return "{}, {}, {} (trans. {})".format(self.store_id,
|
||||
self.vendor_id,
|
||||
self.invoice_number,
|
||||
self.txn_id)
|
||||
|
||||
def add_distribution(self, **kwargs):
|
||||
dist = QuickbooksExportableInvoiceDistribution(**kwargs)
|
||||
if not dist.status_code:
|
||||
dist.status_code = dist.STATUS_NOT_YET_REFRESHED
|
||||
self.distributions.append(dist)
|
||||
|
||||
|
||||
class QuickbooksExportableInvoiceDistribution(model.Base):
|
||||
"""
|
||||
Represents a "distribution" for a department, within the context
|
||||
of a vendor invoice which is to be exported to Quickbooks.
|
||||
"""
|
||||
__tablename__ = 'quickbooks_exportable_invoice_dist'
|
||||
__table_args__ = (
|
||||
sa.ForeignKeyConstraint(['invoice_uuid'], ['quickbooks_exportable_invoice.uuid'],
|
||||
name='quickbooks_exportable_invoice_dist_fk_invoice'),
|
||||
sa.ForeignKeyConstraint(['department_uuid'], ['department.uuid'],
|
||||
name='quickbooks_exportable_invoice_dist_fk_department'),
|
||||
)
|
||||
|
||||
STATUS_NOT_YET_REFRESHED = 1
|
||||
STATUS_EXPORTABLE = 2
|
||||
STATUS_DEPT_NOT_FOUND = 3
|
||||
STATUS_DEPT_IGNORED = 4
|
||||
STATUS_DEPT_BAD_INFO = 5
|
||||
STATUS_EXPORTED = 6
|
||||
|
||||
STATUS = OrderedDict([
|
||||
(STATUS_NOT_YET_REFRESHED, "data not yet refreshed"),
|
||||
(STATUS_EXPORTABLE, "exportable"),
|
||||
(STATUS_DEPT_NOT_FOUND, "department not found"),
|
||||
(STATUS_DEPT_IGNORED, "department ignored"),
|
||||
(STATUS_DEPT_BAD_INFO, "department info is invalid"),
|
||||
(STATUS_EXPORTED, "exported"),
|
||||
])
|
||||
|
||||
uuid = model.uuid_column()
|
||||
|
||||
invoice_uuid = sa.Column(sa.String(length=32), nullable=False)
|
||||
invoice = orm.relationship(
|
||||
QuickbooksExportableInvoice,
|
||||
doc="""
|
||||
Reference to the parent invoice.
|
||||
""",
|
||||
backref=orm.backref(
|
||||
'distributions',
|
||||
cascade='all',
|
||||
doc="""
|
||||
Sequence of
|
||||
:class:`QuickbooksExportableInvoiceDistribution` instances
|
||||
which belong to the invoice.
|
||||
"""))
|
||||
|
||||
##################################################
|
||||
# columns whose values come from source data
|
||||
##################################################
|
||||
|
||||
department_id = sa.Column(sa.Integer(), nullable=False, doc="""
|
||||
Department ID for the distribution, per source data.
|
||||
""")
|
||||
|
||||
source_amount = sa.Column(sa.Numeric(precision=8, scale=2), nullable=False, doc="""
|
||||
Dollar amount for the distribution, per source data.
|
||||
""")
|
||||
|
||||
##################################################
|
||||
# columns whose values come from data refresh
|
||||
##################################################
|
||||
|
||||
department_uuid = sa.Column(sa.String(length=32), nullable=True)
|
||||
department = orm.relationship(
|
||||
model.Department,
|
||||
doc="""
|
||||
Reference to the :class:`rattail:~rattail.db.model.Department`
|
||||
instance associated with the distribution, or ``None``.
|
||||
""")
|
||||
|
||||
quickbooks_expense_account = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks expense account for the department.
|
||||
""")
|
||||
|
||||
quickbooks_expense_class = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks expense class for the department.
|
||||
""")
|
||||
|
||||
calculated_percent = sa.Column(sa.Numeric(precision=8, scale=3), nullable=True, doc="""
|
||||
Percentage of the invoice total which should be considered
|
||||
attributable to the current distribution (department). This is
|
||||
calculated after taking "ignored" departments into consideration,
|
||||
etc.
|
||||
""")
|
||||
|
||||
calculated_amount = sa.Column(sa.Numeric(precision=8, scale=2), nullable=True, doc="""
|
||||
Dollar amount for the distribution, per business logic.
|
||||
""")
|
||||
|
||||
status_code = sa.Column(sa.Integer(), nullable=False, doc="""
|
||||
Status code for the distribution; indicates whether it's
|
||||
exportable etc.
|
||||
""")
|
||||
|
||||
|
||||
class QuickbooksInvoiceExport(model.ExportMixin, model.Base):
|
||||
"""
|
||||
Invoice export file, for *consumption* by Quickbooks.
|
||||
"""
|
||||
__tablename__ = 'quickbooks_invoice_export'
|
||||
|
||||
filename = filename_column(nullable=True, doc="""
|
||||
Filename for the export.
|
||||
""")
|
69
rattail_quickbooks/db/model/org.py
Normal file
69
rattail_quickbooks/db/model/org.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Organizational data model extensions
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model
|
||||
|
||||
|
||||
class QuickbooksDepartment(model.Base):
|
||||
"""
|
||||
Quickbooks extensions to core Department model
|
||||
"""
|
||||
__tablename__ = 'quickbooks_department'
|
||||
__table_args__ = (
|
||||
sa.ForeignKeyConstraint(['uuid'], ['department.uuid'],
|
||||
name='quickbooks_department_fk_department'),
|
||||
)
|
||||
__versioned__ = {}
|
||||
|
||||
uuid = model.uuid_column(default=None)
|
||||
|
||||
department = orm.relationship(
|
||||
model.Department,
|
||||
doc="""
|
||||
Department to which this extension record pertains.
|
||||
""",
|
||||
backref=orm.backref(
|
||||
'_quickbooks',
|
||||
uselist=False,
|
||||
cascade='all, delete-orphan',
|
||||
doc="""
|
||||
Quickbooks extension record for the department.
|
||||
"""))
|
||||
|
||||
quickbooks_expense_account = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "expense account" for the department.
|
||||
""")
|
||||
|
||||
quickbooks_expense_class = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "expense class" for the department.
|
||||
""")
|
||||
|
||||
|
||||
QuickbooksDepartment.make_proxy(model.Department, '_quickbooks', 'quickbooks_expense_account')
|
||||
QuickbooksDepartment.make_proxy(model.Department, '_quickbooks', 'quickbooks_expense_class')
|
64
rattail_quickbooks/db/model/stores.py
Normal file
64
rattail_quickbooks/db/model/stores.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Store data model extensions
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model
|
||||
|
||||
|
||||
class QuickbooksStore(model.Base):
|
||||
"""
|
||||
Quickbooks extensions to core Store model
|
||||
"""
|
||||
__tablename__ = 'quickbooks_store'
|
||||
__table_args__ = (
|
||||
sa.ForeignKeyConstraint(['uuid'], ['store.uuid'],
|
||||
name='quickbooks_store_fk_store'),
|
||||
)
|
||||
__versioned__ = {}
|
||||
|
||||
uuid = model.uuid_column(default=None)
|
||||
|
||||
store = orm.relationship(
|
||||
model.Store,
|
||||
doc="""
|
||||
Store to which this extension record pertains.
|
||||
""",
|
||||
backref=orm.backref(
|
||||
'_quickbooks',
|
||||
uselist=False,
|
||||
cascade='all, delete-orphan',
|
||||
doc="""
|
||||
Quickbooks extension record for the store.
|
||||
"""))
|
||||
|
||||
quickbooks_location = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "location" for the store.
|
||||
""")
|
||||
|
||||
|
||||
QuickbooksStore.make_proxy(model.Store, '_quickbooks', 'quickbooks_location')
|
74
rattail_quickbooks/db/model/vendors.py
Normal file
74
rattail_quickbooks/db/model/vendors.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Vendor data model extensions
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model
|
||||
|
||||
|
||||
class QuickbooksVendor(model.Base):
|
||||
"""
|
||||
Quickbooks extensions to core Vendor model
|
||||
"""
|
||||
__tablename__ = 'quickbooks_vendor'
|
||||
__table_args__ = (
|
||||
sa.ForeignKeyConstraint(['uuid'], ['vendor.uuid'],
|
||||
name='quickbooks_vendor_fk_vendor'),
|
||||
)
|
||||
__versioned__ = {}
|
||||
|
||||
uuid = model.uuid_column(default=None)
|
||||
|
||||
vendor = orm.relationship(
|
||||
model.Vendor,
|
||||
doc="""
|
||||
Vendor to which this extension record pertains.
|
||||
""",
|
||||
backref=orm.backref(
|
||||
'_quickbooks',
|
||||
uselist=False,
|
||||
cascade='all, delete-orphan',
|
||||
doc="""
|
||||
Quickbooks extension record for the vendor.
|
||||
"""))
|
||||
|
||||
quickbooks_name = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "name" for the vendor.
|
||||
""")
|
||||
|
||||
quickbooks_bank_account = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "bank account" for the vendor.
|
||||
""")
|
||||
|
||||
quickbooks_terms = sa.Column(sa.String(length=100), nullable=True, doc="""
|
||||
Quickbooks "terms" for the vendor.
|
||||
""")
|
||||
|
||||
|
||||
QuickbooksVendor.make_proxy(model.Vendor, '_quickbooks', 'quickbooks_name')
|
||||
QuickbooksVendor.make_proxy(model.Vendor, '_quickbooks', 'quickbooks_bank_account')
|
||||
QuickbooksVendor.make_proxy(model.Vendor, '_quickbooks', 'quickbooks_terms')
|
Loading…
Add table
Add a link
Reference in a new issue