Changeset - 9d2411bccb56
[Not reviewed]
0 2 2
Lance Edgar - 5 years ago 2019-07-28 14:52:50
ledgar@techsupport.coop
Add commands for import/export of data between CORE systems

just a staring point for now, only "operational" data for the most part
4 files changed with 358 insertions and 4 deletions:
0 comments (0 inline, 0 general) First comment
rattail_corepos/corepos/commands.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8; -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2019 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/>.
 
#
 
################################################################################
 
"""
 
CORE-POS commands
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 

	
 
import sys
 

	
 
from rattail import commands
 
from rattail_corepos import __version__
 
from rattail.util import load_object
 

	
 

	
 
def main(*args):
 
    """
 
    Primary entry point for Crepes command system
 
    """
 
    if args:
 
        args = list(args)
 
    else:
 
        args = sys.argv[1:]
 

	
 
    cmd = Command()
 
    cmd.run(*args)
 

	
 

	
 
class Command(commands.Command):
 
    """
 
    Primary command for Crepes (CORE-POS)
 
    """
 
    name = 'crepes'
 
    version = __version__
 
    description = "Crepes -- command line interface for CORE-POS"
 
    long_description = ""
 

	
 

	
 
class ImportToCore(commands.ImportSubcommand):
 
    """
 
    Generic base class for commands which import *to* a CORE DB.
 
    """
 
    # subclass must set these!
 
    handler_key = None
 
    default_handler_spec = None
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail.corepos.importing', '{}.handler'.format(self.handler_key),
 
                                   default=self.default_handler_spec)
 
        else:
 
            # just use default, for sake of cmd line help
 
            spec = self.default_handler_spec
 
        return load_object(spec)
 

	
 

	
 
class ExportCore(commands.ImportSubcommand):
 
    """
 
    Export data to another CORE database
 
    """
 
    name = 'export-core'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.importing.corepos:FromCoreToCoreExport'
 
    default_dbkey = 'host'
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail_corepos.exporting', 'corepos.handler',
 
                                   default=self.default_handler_spec)
 
        else:
 
            # just use default, for sake of cmd line help
 
            spec = self.default_handler_spec
 
        return load_object(spec)
 

	
 
    def add_parser_args(self, parser):
 
        super(ExportCore, self).add_parser_args(parser)
 
        parser.add_argument('--dbkey', metavar='KEY', default=self.default_dbkey,
 
                            help="Config key for database engine to be used as the \"target\" "
 
                            "CORE DB, i.e. where data will be exported.  This key must be "
 
                            "defined in the [rattail_corepos.db] section of your config file.")
 

	
 
    def get_handler_kwargs(self, **kwargs):
 
        if 'args' in kwargs:
 
            kwargs['dbkey'] = kwargs['args'].dbkey
 
        return kwargs
 

	
 

	
 
class ImportCore(ImportToCore):
 
    """
 
    Import data from another CORE database
 
    """
 
    name = 'import-core'
 
    description = __doc__.strip()
 
    handler_key = 'corepos'
 
    default_handler_spec = 'rattail_corepos.corepos.importing.corepos:FromCoreToCoreImport'
 
    accepts_dbkey_param = True
 

	
 
    def add_parser_args(self, parser):
 
        super(ImportCore, self).add_parser_args(parser)
 
        if self.accepts_dbkey_param:
 
            parser.add_argument('--dbkey', metavar='KEY', default='host',
 
                                help="Config key for database engine to be used as the CORE "
 
                                "\"host\", i.e. the source of the data to be imported.  This key "
 
                                "must be defined in the [rattail_corepos.db] section of your config file.  "
 
                                "Defaults to 'host'.")
 

	
 
    def get_handler_kwargs(self, **kwargs):
 
        if self.accepts_dbkey_param:
 
            if 'args' in kwargs:
 
                kwargs['dbkey'] = kwargs['args'].dbkey
 
        return kwargs
rattail_corepos/corepos/importing/corepos.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8; -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2019 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/>.
 
#
 
################################################################################
 
"""
 
CORE-POS -> CORE-POS data import
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 

	
 
from rattail.importing.handlers import FromSQLAlchemyHandler, ToSQLAlchemyHandler
 
from rattail.importing.sqlalchemy import FromSQLAlchemySameToSame
 
from rattail.util import OrderedDict
 
from rattail_corepos.db import Session as CoreSession
 
from rattail_corepos.corepos import importing as corepos_importing
 

	
 

	
 
class FromCoreHandler(FromSQLAlchemyHandler):
 
    """
 
    Base class for import handlers which use a CORE database as the host / source.
 
    """
 
    host_title = "CORE"
 

	
 
    def make_host_session(self):
 
        return CoreSession()
 

	
 

	
 
class ToCoreHandler(ToSQLAlchemyHandler):
 
    """
 
    Base class for import handlers which target a CORE database on the local side.
 
    """
 
    local_title = "CORE"
 

	
 
    def make_session(self):
 
        return CoreSession()
 

	
 

	
 
class FromCoreToCoreBase(object):
 
    """
 
    Common base class for Core -> Core data import/export handlers.
 
    """
 

	
 
    def get_importers(self):
 
        importers = OrderedDict()
 
        importers['Department'] = DepartmentImporter
 
        importers['Subdepartment'] = SubdepartmentImporter
 
        importers['Vendor'] = VendorImporter
 
        importers['VendorContact'] = VendorContactImporter
 
        importers['Product'] = ProductImporter
 
        importers['ProductFlag'] = ProductFlagImporter
 
        importers['Employee'] = EmployeeImporter
 
        importers['Customer'] = CustomerImporter
 
        importers['MemberType'] = MemberTypeImporter
 
        importers['MemberInfo'] = MemberInfoImporter
 
        importers['HouseCoupon'] = HouseCouponImporter
 
        return importers
 

	
 

	
 
class FromCoreToCoreImport(FromCoreToCoreBase, FromCoreHandler, ToCoreHandler):
 
    """
 
    Handler for CORE (other) -> CORE (local) data import.
 

	
 
    .. attribute:: direction
 

	
 
       Value is ``'import'`` - see also
 
       :attr:`rattail.importing.handlers.ImportHandler.direction`.
 
    """
 
    dbkey = 'host'
 
    local_title = "CORE (default)"
 

	
 
    @property
 
    def host_title(self):
 
        return "CORE ({})".format(self.dbkey)
 

	
 
    def make_host_session(self):
 
        return CoreSession(bind=self.config.corepos_engines[self.dbkey])
 

	
 

	
 
class FromCoreToCoreExport(FromCoreToCoreBase, FromCoreHandler, ToCoreHandler):
 
    """
 
    Handler for CORE (local) -> CORE (other) data export.
 

	
 
    .. attribute:: direction
 

	
 
       Value is ``'export'`` - see also
 
       :attr:`rattail.importing.handlers.ImportHandler.direction`.
 
    """
 
    direction = 'export'
 
    host_title = "CORE (default)"
 

	
 
    @property
 
    def local_title(self):
 
        return "CORE ({})".format(self.dbkey)
 

	
 
    def make_session(self):
 
        return CoreSession(bind=self.config.corepos_engines[self.dbkey])
 

	
 

	
 
class FromCore(FromSQLAlchemySameToSame):
 
    """
 
    Base class for CORE -> CORE data importers.
 
    """
 

	
 

	
 
class DepartmentImporter(FromCore, corepos_importing.model.DepartmentImporter):
 
    pass
 

	
 
class SubdepartmentImporter(FromCore, corepos_importing.model.SubdepartmentImporter):
 
    pass
 

	
 
class VendorImporter(FromCore, corepos_importing.model.VendorImporter):
 
    pass
 

	
 
class VendorContactImporter(FromCore, corepos_importing.model.VendorContactImporter):
 
    pass
 

	
 
class ProductImporter(FromCore, corepos_importing.model.ProductImporter):
 
    pass
 

	
 
class ProductFlagImporter(FromCore, corepos_importing.model.ProductFlagImporter):
 
    pass
 

	
 
class EmployeeImporter(FromCore, corepos_importing.model.EmployeeImporter):
 
    pass
 

	
 
class CustomerImporter(FromCore, corepos_importing.model.CustomerImporter):
 
    pass
 

	
 
class MemberTypeImporter(FromCore, corepos_importing.model.MemberTypeImporter):
 
    pass
 

	
 
class MemberInfoImporter(FromCore, corepos_importing.model.MemberInfoImporter):
 
    pass
 

	
 
class HouseCouponImporter(FromCore, corepos_importing.model.HouseCouponImporter):
 
    pass
rattail_corepos/corepos/importing/model.py
Show inline comments
 
@@ -12,19 +12,79 @@ from corepos.trans.db import model as coretrans
 

	
 

	
 
class ToCore(importing.ToSQLAlchemy):
 
    pass
 
    """
 
    Base class for all CORE (operational) model importers
 
    """
 
    # TODO: should we standardize on the 'id' primary key? (can we even?)
 
    # key = 'id'
 

	
 

	
 
class ToCoreTrans(importing.ToSQLAlchemy):
 
    pass
 

	
 

	
 
########################################
 
# CORE Operational
 
########################################
 

	
 
class DepartmentImporter(ToCore):
 
    model_class = corepos.Department
 
    key = 'number'
 

	
 

	
 
class SubdepartmentImporter(ToCore):
 
    model_class = corepos.Subdepartment
 
    key = 'number'
 

	
 

	
 
class VendorImporter(ToCore):
 
    model_class = corepos.Vendor
 
    key = 'id'
 

	
 

	
 
class VendorContactImporter(ToCore):
 
    model_class = corepos.VendorContact
 
    key = 'vendor_id'
 

	
 

	
 
class ProductImporter(ToCore):
 
    model_class = corepos.Product
 
    key = 'id'
 

	
 

	
 
class ProductFlagImporter(ToCore):
 
    model_class = corepos.ProductFlag
 
    key = 'bit_number'
 

	
 

	
 
class EmployeeImporter(ToCore):
 
    model_class = corepos.Employee
 
    key = 'emp_no'
 

	
 

	
 
class CustomerImporter(ToCore):
 
    """
 
    CORE-POS customer data importer.
 
    """
 
    model_class = corepos.Customer
 
    key = 'id'
 

	
 

	
 
class MemberTypeImporter(ToCore):
 
    model_class = corepos.MemberType
 
    key = 'id'
 

	
 

	
 
class MemberInfoImporter(ToCore):
 
    model_class = corepos.MemberInfo
 
    key = 'card_no'
 

	
 

	
 
class HouseCouponImporter(ToCore):
 
    model_class = corepos.HouseCoupon
 
    key = 'coupon_id'
 

	
 

	
 
########################################
 
# CORE Transactions
 
########################################
 

	
 
class TransactionDetailImporter(ToCoreTrans):
 
    """
setup.py
Show inline comments
 
@@ -99,6 +99,15 @@ setup(
 

	
 
    entry_points = {
 

	
 
        'console_scripts': [
 
            'crepes = rattail_corepos.corepos.commands:main',
 
        ],
 

	
 
        'crepes.commands': [
 
            'export-core = rattail_corepos.corepos.commands:ExportCore',
 
            'import-core = rattail_corepos.corepos.commands:ImportCore',
 
        ],
 

	
 
        'rattail.config.extensions': [
 
            'rattail-corepos = rattail_corepos.config:RattailCOREPOSExtension',
 
        ],
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now