diff --git a/rattail_corepos/db/alembic/versions/9c5029effe93_more_model_extensions.py b/rattail_corepos/db/alembic/versions/9c5029effe93_more_model_extensions.py new file mode 100644 index 0000000..1bfb1f6 --- /dev/null +++ b/rattail_corepos/db/alembic/versions/9c5029effe93_more_model_extensions.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8; -*- +"""more model extensions + +Revision ID: 9c5029effe93 +Revises: c61f78243ff3 +Create Date: 2020-07-06 19:27:06.156401 + +""" + +from __future__ import unicode_literals + +# revision identifiers, used by Alembic. +revision = '9c5029effe93' +down_revision = 'c61f78243ff3' +branch_labels = None +depends_on = None + +from alembic import op +import sqlalchemy as sa +import rattail.db.types + + + +def upgrade(): + + # corepos_customer + op.create_table('corepos_customer', + sa.Column('uuid', sa.String(length=32), nullable=False), + sa.Column('corepos_account_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['uuid'], ['customer.uuid'], name='corepos_customer_fk_customer'), + sa.PrimaryKeyConstraint('uuid') + ) + op.create_table('corepos_customer_version', + sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), + sa.Column('corepos_account_id', sa.Integer(), autoincrement=False, nullable=True), + sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), + sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), + sa.Column('operation_type', sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint('uuid', 'transaction_id') + ) + op.create_index(op.f('ix_corepos_customer_version_end_transaction_id'), 'corepos_customer_version', ['end_transaction_id'], unique=False) + op.create_index(op.f('ix_corepos_customer_version_operation_type'), 'corepos_customer_version', ['operation_type'], unique=False) + op.create_index(op.f('ix_corepos_customer_version_transaction_id'), 'corepos_customer_version', ['transaction_id'], unique=False) + + # corepos_member + op.create_table('corepos_member', + sa.Column('uuid', sa.String(length=32), nullable=False), + sa.Column('corepos_account_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['uuid'], ['member.uuid'], name='corepos_member_fk_member'), + sa.PrimaryKeyConstraint('uuid') + ) + op.create_table('corepos_member_version', + sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), + sa.Column('corepos_account_id', sa.Integer(), autoincrement=False, nullable=True), + sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), + sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), + sa.Column('operation_type', sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint('uuid', 'transaction_id') + ) + op.create_index(op.f('ix_corepos_member_version_end_transaction_id'), 'corepos_member_version', ['end_transaction_id'], unique=False) + op.create_index(op.f('ix_corepos_member_version_operation_type'), 'corepos_member_version', ['operation_type'], unique=False) + op.create_index(op.f('ix_corepos_member_version_transaction_id'), 'corepos_member_version', ['transaction_id'], unique=False) + + # corepos_department + op.create_table('corepos_department', + sa.Column('uuid', sa.String(length=32), nullable=False), + sa.Column('corepos_number', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['uuid'], ['department.uuid'], name='corepos_department_fk_department'), + sa.PrimaryKeyConstraint('uuid') + ) + op.create_table('corepos_department_version', + sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), + sa.Column('corepos_number', sa.Integer(), autoincrement=False, nullable=True), + sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), + sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), + sa.Column('operation_type', sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint('uuid', 'transaction_id') + ) + op.create_index(op.f('ix_corepos_department_version_end_transaction_id'), 'corepos_department_version', ['end_transaction_id'], unique=False) + op.create_index(op.f('ix_corepos_department_version_operation_type'), 'corepos_department_version', ['operation_type'], unique=False) + op.create_index(op.f('ix_corepos_department_version_transaction_id'), 'corepos_department_version', ['transaction_id'], unique=False) + + # corepos_subdepartment + op.create_table('corepos_subdepartment', + sa.Column('uuid', sa.String(length=32), nullable=False), + sa.Column('corepos_number', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['uuid'], ['subdepartment.uuid'], name='corepos_subdepartment_fk_subdepartment'), + sa.PrimaryKeyConstraint('uuid') + ) + op.create_table('corepos_subdepartment_version', + sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), + sa.Column('corepos_number', sa.Integer(), autoincrement=False, nullable=True), + sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), + sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), + sa.Column('operation_type', sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint('uuid', 'transaction_id') + ) + op.create_index(op.f('ix_corepos_subdepartment_version_end_transaction_id'), 'corepos_subdepartment_version', ['end_transaction_id'], unique=False) + op.create_index(op.f('ix_corepos_subdepartment_version_operation_type'), 'corepos_subdepartment_version', ['operation_type'], unique=False) + op.create_index(op.f('ix_corepos_subdepartment_version_transaction_id'), 'corepos_subdepartment_version', ['transaction_id'], unique=False) + + # corepos_product + op.create_table('corepos_product', + sa.Column('uuid', sa.String(length=32), nullable=False), + sa.Column('corepos_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['uuid'], ['product.uuid'], name='corepos_product_fk_product'), + sa.PrimaryKeyConstraint('uuid') + ) + op.create_table('corepos_product_version', + sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), + sa.Column('corepos_id', sa.Integer(), autoincrement=False, nullable=True), + sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), + sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), + sa.Column('operation_type', sa.SmallInteger(), nullable=False), + sa.PrimaryKeyConstraint('uuid', 'transaction_id') + ) + op.create_index(op.f('ix_corepos_product_version_end_transaction_id'), 'corepos_product_version', ['end_transaction_id'], unique=False) + op.create_index(op.f('ix_corepos_product_version_operation_type'), 'corepos_product_version', ['operation_type'], unique=False) + op.create_index(op.f('ix_corepos_product_version_transaction_id'), 'corepos_product_version', ['transaction_id'], unique=False) + + +def downgrade(): + + # corepos_product + op.drop_index(op.f('ix_corepos_product_version_transaction_id'), table_name='corepos_product_version') + op.drop_index(op.f('ix_corepos_product_version_operation_type'), table_name='corepos_product_version') + op.drop_index(op.f('ix_corepos_product_version_end_transaction_id'), table_name='corepos_product_version') + op.drop_table('corepos_product_version') + op.drop_table('corepos_product') + + # corepos_subdepartment + op.drop_index(op.f('ix_corepos_subdepartment_version_transaction_id'), table_name='corepos_subdepartment_version') + op.drop_index(op.f('ix_corepos_subdepartment_version_operation_type'), table_name='corepos_subdepartment_version') + op.drop_index(op.f('ix_corepos_subdepartment_version_end_transaction_id'), table_name='corepos_subdepartment_version') + op.drop_table('corepos_subdepartment_version') + op.drop_table('corepos_subdepartment') + + # corepos_department + op.drop_index(op.f('ix_corepos_department_version_transaction_id'), table_name='corepos_department_version') + op.drop_index(op.f('ix_corepos_department_version_operation_type'), table_name='corepos_department_version') + op.drop_index(op.f('ix_corepos_department_version_end_transaction_id'), table_name='corepos_department_version') + op.drop_table('corepos_department_version') + op.drop_table('corepos_department') + + # corepos_member + op.drop_index(op.f('ix_corepos_member_version_transaction_id'), table_name='corepos_member_version') + op.drop_index(op.f('ix_corepos_member_version_operation_type'), table_name='corepos_member_version') + op.drop_index(op.f('ix_corepos_member_version_end_transaction_id'), table_name='corepos_member_version') + op.drop_table('corepos_member_version') + op.drop_table('corepos_member') + + # corepos_customer + op.drop_index(op.f('ix_corepos_customer_version_transaction_id'), table_name='corepos_customer_version') + op.drop_index(op.f('ix_corepos_customer_version_operation_type'), table_name='corepos_customer_version') + op.drop_index(op.f('ix_corepos_customer_version_end_transaction_id'), table_name='corepos_customer_version') + op.drop_table('corepos_customer_version') + op.drop_table('corepos_customer') diff --git a/rattail_corepos/db/model/__init__.py b/rattail_corepos/db/model/__init__.py new file mode 100644 index 0000000..e21080a --- /dev/null +++ b/rattail_corepos/db/model/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2020 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 . +# +################################################################################ +""" +Database schema extensions for CORE-POS integration +""" + +from .people import CorePerson, CoreCustomer, CoreMember +from .products import (CoreDepartment, CoreSubdepartment, + CoreVendor, CoreProduct) diff --git a/rattail_corepos/db/model.py b/rattail_corepos/db/model/people.py similarity index 61% rename from rattail_corepos/db/model.py rename to rattail_corepos/db/model/people.py index 9bf3dbf..d63b4fa 100644 --- a/rattail_corepos/db/model.py +++ b/rattail_corepos/db/model/people.py @@ -30,9 +30,6 @@ from sqlalchemy import orm from rattail.db import model -__all__ = ['CorePerson', 'CoreVendor'] - - class CorePerson(model.Base): """ CORE-specific extensions to :class:`rattail:rattail.db.model.Person`. @@ -68,36 +65,71 @@ class CorePerson(model.Base): CorePerson.make_proxy(model.Person, '_corepos', 'corepos_customer_id') -class CoreVendor(model.Base): +class CoreCustomer(model.Base): """ - CORE-specific extensions to :class:`rattail:rattail.db.model.Vendor`. + CORE-specific extensions to :class:`rattail:rattail.db.model.Customer`. """ - __tablename__ = 'corepos_vendor' + __tablename__ = 'corepos_customer' __table_args__ = ( - sa.ForeignKeyConstraint(['uuid'], ['vendor.uuid'], - name='corepos_vendor_fk_vendor'), + sa.ForeignKeyConstraint(['uuid'], ['customer.uuid'], + name='corepos_customer_fk_customer'), ) __versioned__ = {} uuid = model.uuid_column(default=None) - vendor = orm.relationship( - model.Vendor, + customer = orm.relationship( + model.Customer, doc=""" - Reference to the actual vendor record, which this one extends. + Reference to the actual customer record, which this one extends. """, backref=orm.backref( '_corepos', uselist=False, cascade='all, delete-orphan', doc=""" - Reference to the CORE-POS extension record for this vendor. + Reference to the CORE-POS extension record for this customer. """)) - corepos_id = sa.Column(sa.Integer(), nullable=False, doc=""" - ``vendorID`` value for the vendor, within CORE-POS. + corepos_account_id = sa.Column(sa.Integer(), nullable=False, doc=""" + ``Customers.customerAccountID`` value for this customer, within CORE-POS. """) def __str__(self): - return str(self.vendor) + return str(self.customer) -CoreVendor.make_proxy(model.Vendor, '_corepos', 'corepos_id') +CoreCustomer.make_proxy(model.Customer, '_corepos', 'corepos_account_id') + + +class CoreMember(model.Base): + """ + CORE-specific extensions to :class:`rattail:rattail.db.model.Member`. + """ + __tablename__ = 'corepos_member' + __table_args__ = ( + sa.ForeignKeyConstraint(['uuid'], ['member.uuid'], + name='corepos_member_fk_member'), + ) + __versioned__ = {} + + uuid = model.uuid_column(default=None) + member = orm.relationship( + model.Member, + doc=""" + Reference to the actual member record, which this one extends. + """, + backref=orm.backref( + '_corepos', + uselist=False, + cascade='all, delete-orphan', + doc=""" + Reference to the CORE-POS extension record for this member. + """)) + + corepos_account_id = sa.Column(sa.Integer(), nullable=False, doc=""" + ``Customers.customerAccountID`` value for this member, within CORE-POS. + """) + + def __str__(self): + return str(self.member) + +CoreMember.make_proxy(model.Member, '_corepos', 'corepos_account_id') diff --git a/rattail_corepos/db/model/products.py b/rattail_corepos/db/model/products.py new file mode 100644 index 0000000..ad664f6 --- /dev/null +++ b/rattail_corepos/db/model/products.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2020 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 . +# +################################################################################ +""" +Database schema extensions for CORE-POS integration +""" + +import sqlalchemy as sa +from sqlalchemy import orm + +from rattail.db import model + + +class CoreDepartment(model.Base): + """ + CORE-specific extensions to :class:`rattail:rattail.db.model.Department`. + """ + __tablename__ = 'corepos_department' + __table_args__ = ( + sa.ForeignKeyConstraint(['uuid'], ['department.uuid'], + name='corepos_department_fk_department'), + ) + __versioned__ = {} + + uuid = model.uuid_column(default=None) + department = orm.relationship( + model.Department, + doc=""" + Reference to the actual department record, which this one extends. + """, + backref=orm.backref( + '_corepos', + uselist=False, + cascade='all, delete-orphan', + doc=""" + Reference to the CORE-POS extension record for this department. + """)) + + corepos_number = sa.Column(sa.Integer(), nullable=False, doc=""" + ``dept_no`` value for the department, within CORE-POS. + """) + + def __str__(self): + return str(self.department) + +CoreDepartment.make_proxy(model.Department, '_corepos', 'corepos_number') + + +class CoreSubdepartment(model.Base): + """ + CORE-specific extensions to :class:`rattail:rattail.db.model.Subdepartment`. + """ + __tablename__ = 'corepos_subdepartment' + __table_args__ = ( + sa.ForeignKeyConstraint(['uuid'], ['subdepartment.uuid'], + name='corepos_subdepartment_fk_subdepartment'), + ) + __versioned__ = {} + + uuid = model.uuid_column(default=None) + subdepartment = orm.relationship( + model.Subdepartment, + doc=""" + Reference to the actual subdepartment record, which this one extends. + """, + backref=orm.backref( + '_corepos', + uselist=False, + cascade='all, delete-orphan', + doc=""" + Reference to the CORE-POS extension record for this subdepartment. + """)) + + corepos_number = sa.Column(sa.Integer(), nullable=False, doc=""" + ``subdept_no`` value for the subdepartment, within CORE-POS. + """) + + def __str__(self): + return str(self.subdepartment) + +CoreSubdepartment.make_proxy(model.Subdepartment, '_corepos', 'corepos_number') + + +class CoreVendor(model.Base): + """ + CORE-specific extensions to :class:`rattail:rattail.db.model.Vendor`. + """ + __tablename__ = 'corepos_vendor' + __table_args__ = ( + sa.ForeignKeyConstraint(['uuid'], ['vendor.uuid'], + name='corepos_vendor_fk_vendor'), + ) + __versioned__ = {} + + uuid = model.uuid_column(default=None) + vendor = orm.relationship( + model.Vendor, + doc=""" + Reference to the actual vendor record, which this one extends. + """, + backref=orm.backref( + '_corepos', + uselist=False, + cascade='all, delete-orphan', + doc=""" + Reference to the CORE-POS extension record for this vendor. + """)) + + corepos_id = sa.Column(sa.Integer(), nullable=False, doc=""" + ``vendorID`` value for the vendor, within CORE-POS. + """) + + def __str__(self): + return str(self.vendor) + +CoreVendor.make_proxy(model.Vendor, '_corepos', 'corepos_id') + + +class CoreProduct(model.Base): + """ + CORE-specific extensions to :class:`rattail:rattail.db.model.Product`. + """ + __tablename__ = 'corepos_product' + __table_args__ = ( + sa.ForeignKeyConstraint(['uuid'], ['product.uuid'], + name='corepos_product_fk_product'), + ) + __versioned__ = {} + + uuid = model.uuid_column(default=None) + product = orm.relationship( + model.Product, + doc=""" + Reference to the actual product record, which this one extends. + """, + backref=orm.backref( + '_corepos', + uselist=False, + cascade='all, delete-orphan', + doc=""" + Reference to the CORE-POS extension record for this product. + """)) + + corepos_id = sa.Column(sa.Integer(), nullable=False, doc=""" + ``id`` value for the product, within CORE-POS. + """) + + def __str__(self): + return str(self.product) + +CoreProduct.make_proxy(model.Product, '_corepos', 'corepos_id') diff --git a/rattail_corepos/importing/corepos/api.py b/rattail_corepos/importing/corepos/api.py index 35d719b..25e2c48 100644 --- a/rattail_corepos/importing/corepos/api.py +++ b/rattail_corepos/importing/corepos/api.py @@ -81,12 +81,13 @@ class FromCOREPOSAPI(importing.Importer): return get_core_members(self.api, progress=self.progress) -class CustomerImporter(FromCOREPOSAPI, importing.model.CustomerImporter): +class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter): """ Importer for customer data from CORE POS API. """ - key = 'number' + key = 'corepos_account_id' supported_fields = [ + 'corepos_account_id', 'id', 'number', 'name', @@ -126,6 +127,7 @@ class CustomerImporter(FromCOREPOSAPI, importing.model.CustomerImporter): raise NotImplementedError("TODO: how to handle member with no customers?") return { + 'corepos_account_id': int(member['customerAccountID']), 'id': member['customerAccountID'], 'number': int(member['cardNo']), 'name': normalize_full_name(customer['firstName'], @@ -256,7 +258,10 @@ class CustomerPersonImporter(FromCOREPOSAPI, importing.model.CustomerPersonImpor super(CustomerPersonImporter, self).setup() model = self.config.get_model() - self.customers = self.cache_model(model.Customer, key='id') + query = self.session.query(model.Customer)\ + .join(model.CoreCustomer) + self.customers = self.cache_model(model.Customer, query=query, + key='corepos_account_id') query = self.session.query(model.Person)\ .join(model.CorePerson)\ @@ -279,7 +284,7 @@ class CustomerPersonImporter(FromCOREPOSAPI, importing.model.CustomerPersonImpor reverse=True) for i, customer in enumerate(customers, 1): normalized.append({ - 'customer_account_id': member['customerAccountID'], + 'customer_account_id': int(member['customerAccountID']), 'person_customer_id': customer['customerID'], 'ordinal': i, }) @@ -288,13 +293,14 @@ class CustomerPersonImporter(FromCOREPOSAPI, importing.model.CustomerPersonImpor message="Collecting CustomerPerson data from CORE") return normalized - def get_customer(self, id): + def get_customer(self, account_id): if hasattr(self, 'customers'): - return self.customers.get(id) + return self.customers.get(account_id) try: return self.session.query(model.Customer)\ - .filter(model.Customer.id == id)\ + .join(model.CoreCustomer)\ + .filter(model.CoreCustomer.corepos_account_id == account_id)\ .one() except NoResultFound: pass @@ -333,12 +339,13 @@ class CustomerPersonImporter(FromCOREPOSAPI, importing.model.CustomerPersonImpor } -class DepartmentImporter(FromCOREPOSAPI, importing.model.DepartmentImporter): +class DepartmentImporter(FromCOREPOSAPI, corepos_importing.model.DepartmentImporter): """ Importer for department data from CORE POS API. """ - key = 'number' + key = 'corepos_number' supported_fields = [ + 'corepos_number', 'number', 'name', ] @@ -348,17 +355,19 @@ class DepartmentImporter(FromCOREPOSAPI, importing.model.DepartmentImporter): def normalize_host_object(self, department): return { + 'corepos_number': int(department['dept_no']), 'number': int(department['dept_no']), 'name': department['dept_name'], } -class SubdepartmentImporter(FromCOREPOSAPI, importing.model.SubdepartmentImporter): +class SubdepartmentImporter(FromCOREPOSAPI, corepos_importing.model.SubdepartmentImporter): """ Importer for subdepartment data from CORE POS API. """ - key = 'number' + key = 'corepos_number' supported_fields = [ + 'corepos_number', 'number', 'name', 'department_number', @@ -373,6 +382,7 @@ class SubdepartmentImporter(FromCOREPOSAPI, importing.model.SubdepartmentImporte department_number = int(subdepartment['dept_ID']) return { + 'corepos_number': int(subdepartment['subdept_no']), 'number': int(subdepartment['subdept_no']), 'name': subdepartment['subdept_name'], 'department_number': department_number, @@ -409,12 +419,13 @@ class VendorImporter(FromCOREPOSAPI, corepos_importing.model.VendorImporter): } -class ProductImporter(FromCOREPOSAPI, importing.model.ProductImporter): +class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): """ Importer for product data from CORE POS API. """ - key = 'item_id' + key = 'corepos_id' supported_fields = [ + 'corepos_id', 'item_id', 'upc', 'brand_name', @@ -456,6 +467,7 @@ class ProductImporter(FromCOREPOSAPI, importing.model.ProductImporter): price = decimal.Decimal(product['normal_price']) return { + 'corepos_id': int(product['id']), 'item_id': product['upc'], 'upc': upc, 'brand_name': product.get('brand') or None, @@ -476,12 +488,13 @@ class ProductImporter(FromCOREPOSAPI, importing.model.ProductImporter): } -class MemberImporter(FromCOREPOSAPI, importing.model.MemberImporter): +class MemberImporter(FromCOREPOSAPI, corepos_importing.model.MemberImporter): """ Importer for member data from CORE POS API. """ - key = 'number' + key = 'corepos_account_id' supported_fields = [ + 'corepos_account_id', 'number', 'id', 'customer_uuid', @@ -555,6 +568,7 @@ class MemberImporter(FromCOREPOSAPI, importing.model.MemberImporter): withdrew = withdrew.date() return { + 'corepos_account_id': int(member['customerAccountID']), 'number': int(member['cardNo']), 'id': str(member['customerAccountID']), 'customer_uuid': customer.uuid, diff --git a/rattail_corepos/importing/corepos/db.py b/rattail_corepos/importing/corepos/db.py index 434a1c6..46292ab 100644 --- a/rattail_corepos/importing/corepos/db.py +++ b/rattail_corepos/importing/corepos/db.py @@ -115,31 +115,34 @@ class VendorImporter(FromCOREPOS, corepos_importing.model.VendorImporter): } -class DepartmentImporter(FromCOREPOS, importing.model.DepartmentImporter): +class DepartmentImporter(FromCOREPOS, corepos_importing.model.DepartmentImporter): """ Importer for department data from CORE POS. """ host_model_class = corepos.Department - key = 'number' + key = 'corepos_number' supported_fields = [ + 'corepos_number', 'number', 'name', ] def normalize_host_object(self, department): return { + 'corepos_number': department.number, 'number': department.number, 'name': department.name, } -class SubdepartmentImporter(FromCOREPOS, importing.model.SubdepartmentImporter): +class SubdepartmentImporter(FromCOREPOS, corepos_importing.model.SubdepartmentImporter): """ Importer for subdepartment data from CORE POS. """ host_model_class = corepos.Subdepartment - key = 'number' + key = 'corepos_number' supported_fields = [ + 'corepos_number', 'number', 'name', 'department_number', @@ -147,19 +150,21 @@ class SubdepartmentImporter(FromCOREPOS, importing.model.SubdepartmentImporter): def normalize_host_object(self, subdepartment): return { + 'corepos_number': subdepartment.number, 'number': subdepartment.number, 'name': subdepartment.name, 'department_number': subdepartment.department_number, } -class ProductImporter(FromCOREPOS, importing.model.ProductImporter): +class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter): """ Importer for product data from CORE POS. """ host_model_class = corepos.Product - key = 'item_id' + key = 'corepos_id' supported_fields = [ + 'corepos_id', 'item_id', 'upc', 'brand_name', @@ -190,6 +195,7 @@ class ProductImporter(FromCOREPOS, importing.model.ProductImporter): price = decimal.Decimal('{:03f}'.format(product.normal_price)) return { + 'corepos_id': product.id, 'item_id': product.upc, 'upc': upc, 'brand_name': (product.brand or '').strip() or None, diff --git a/rattail_corepos/importing/model.py b/rattail_corepos/importing/model.py index 450ec31..96c8d2d 100644 --- a/rattail_corepos/importing/model.py +++ b/rattail_corepos/importing/model.py @@ -50,9 +50,60 @@ class PersonImporter(importing.model.PersonImporter): return query +class CustomerImporter(importing.model.CustomerImporter): + + extension_attr = '_corepos' + extension_fields = [ + 'corepos_account_id', + ] + + +class MemberImporter(importing.model.MemberImporter): + + extension_attr = '_corepos' + extension_fields = [ + 'corepos_account_id', + ] + + +class DepartmentImporter(importing.model.DepartmentImporter): + + extension_attr = '_corepos' + extension_fields = [ + 'corepos_number', + ] + + +class SubdepartmentImporter(importing.model.SubdepartmentImporter): + + extension_attr = '_corepos' + extension_fields = [ + 'corepos_number', + ] + + class VendorImporter(importing.model.VendorImporter): extension_attr = '_corepos' extension_fields = [ 'corepos_id', ] + + +class ProductImporter(importing.model.ProductImporter): + + extension_attr = '_corepos' + extension_fields = [ + 'corepos_id', + ] + + def cache_query(self): + query = super(ProductImporter, self).cache_query() + model = self.config.get_model() + + # we want to ignore products with no CORE ID, if that's (part of) our key + if 'corepos_id' in self.key: + query = query.join(model.CoreProduct)\ + .filter(model.CoreProduct.corepos_id != None) + + return query diff --git a/rattail_corepos/importing/versions.py b/rattail_corepos/importing/versions.py index 69b8eef..06c1d12 100644 --- a/rattail_corepos/importing/versions.py +++ b/rattail_corepos/importing/versions.py @@ -35,7 +35,12 @@ class FromRattailToRattailVersions(base.FromRattailToRattailVersions): def get_importers(self): importers = super(FromRattailToRattailVersions, self).get_importers() importers['CorePerson'] = CorePersonImporter + importers['CoreCustomer'] = CoreCustomerImporter + importers['CoreMember'] = CoreMemberImporter + importers['CoreDepartment'] = CoreDepartmentImporter + importers['CoreSubdepartment'] = CoreSubdepartmentImporter importers['CoreVendor'] = CoreVendorImporter + importers['CoreProduct'] = CoreProductImporter return importers @@ -47,9 +52,49 @@ class CorePersonImporter(base.VersionImporter): return model.CorePerson +class CoreCustomerImporter(base.VersionImporter): + + @property + def host_model_class(self): + model = self.config.get_model() + return model.CoreCustomer + + +class CoreMemberImporter(base.VersionImporter): + + @property + def host_model_class(self): + model = self.config.get_model() + return model.CoreMember + + +class CoreDepartmentImporter(base.VersionImporter): + + @property + def host_model_class(self): + model = self.config.get_model() + return model.CoreDepartment + + +class CoreSubdepartmentImporter(base.VersionImporter): + + @property + def host_model_class(self): + model = self.config.get_model() + return model.CoreSubdepartment + + class CoreVendorImporter(base.VersionImporter): @property def host_model_class(self): model = self.config.get_model() return model.CoreVendor + + +class CoreProductImporter(base.VersionImporter): + + @property + def host_model_class(self): + model = self.config.get_model() + return model.CoreProduct