Changeset - 314024585767
[Not reviewed]
0 9 0
Lance Edgar - 3 years ago 2021-12-06 20:07:42
lance@edbob.org
OMG a ridiculous commit to overhaul import handler config etc.

- register all import/export handlers via setup.py and config
- use "handler key" lookup for all import/export commands
- fix logic bugs w/ CORE -> Trainwreck importer
9 files changed with 122 insertions and 97 deletions:
0 comments (0 inline, 0 general) First comment
rattail_corepos/commands.py
Show inline comments
 
@@ -34,15 +34,7 @@ class ExportCore(commands.ImportSubcommand):
 
    """
 
    name = 'export-corepos'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.importing.rattail:FromRattailToCore'
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail.exporting', 'corepos.handler',
 
                                   default=self.default_handler_spec)
 
        else:
 
            spec = self.default_handler_spec
 
        return load_object(spec)
 
    handler_key = 'to_corepos_api.from_rattail.export'
 

	
 

	
 
class ImportCOREPOSAPI(commands.ImportSubcommand):
 
@@ -51,15 +43,7 @@ class ImportCOREPOSAPI(commands.ImportSubcommand):
 
    """
 
    name = 'import-corepos-api'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.importing.corepos.api:FromCOREPOSToRattail'
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail.importing', 'corepos_api.handler',
 
                                   default=self.default_handler_spec)
 
        else:
 
            spec = self.default_handler_spec
 
        return load_object(spec)
 
    handler_key = 'to_rattail.from_corepos_api.import'
 

	
 

	
 
class ImportCOREPOSDB(commands.ImportSubcommand):
 
@@ -68,6 +52,7 @@ class ImportCOREPOSDB(commands.ImportSubcommand):
 
    """
 
    name = 'import-corepos-db'
 
    description = __doc__.strip()
 
    handler_key = 'to_rattail.from_corepos_db_office_op.import'
 

	
 
    def add_parser_args(self, parser):
 
        super(ImportCOREPOSDB, self).add_parser_args(parser)
 
@@ -77,14 +62,6 @@ class ImportCOREPOSDB(commands.ImportSubcommand):
 
                            "defined in the [rattail_corepos.db] section of your config file.  "
 
                            "Defaults to 'default'.")
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail.importing', 'corepos.handler',
 
                                   default='rattail_corepos.importing.corepos:FromCOREPOSToRattail')
 
        else:
 
            spec = 'rattail_corepos.importing.corepos:FromCOREPOSToRattail'
 
        return load_object(spec)
 

	
 
    def get_handler_kwargs(self, **kwargs):
 
        if 'args' in kwargs:
 
            kwargs['corepos_dbkey'] = kwargs['args'].corepos_dbkey
 
@@ -97,4 +74,4 @@ class CoreImportSquare(commands.ImportFromCSV):
 
    """
 
    name = 'corepos-import-square'
 
    description = __doc__.strip()
 
    handler_spec = 'rattail_corepos.corepos.importing.square:FromSquareToCoreTrans'
 
    handler_key = 'to_corepos_db_office_trans.from_square_csv.import'
rattail_corepos/config.py
Show inline comments
 
@@ -63,6 +63,88 @@ class RattailCOREPOSExtension(ConfigExtension):
 
        config.core_lane_op_engine = engines.get('default')
 
        Session.configure(bind=config.core_lane_op_engine)
 

	
 
        # rattail corepos-import-square
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_trans.from_square_csv.import.default_handler',
 
                          'rattail_corepos.corepos.importing.db.square:FromSquareToCoreTrans')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_trans.from_square_csv.import.default_cmd',
 
                          'rattail corepos-import-square')
 
        # TODO: there was not a legacy setting in place for this one
 
        # config.setdefault('rattail.importing', 'to_corepos_db_office_trans.from_square_csv.import.legacy_handler_setting',
 
        #                   'corepos.importing, square.handler')
 

	
 
        # rattail export-corepos
 
        config.setdefault('rattail.importing', 'to_corepos_api.from_rattail.export.default_handler',
 
                          'rattail_corepos.corepos.importing.rattail:FromRattailToCore')
 
        config.setdefault('rattail.importing', 'to_corepos_api.from_rattail.export.default_cmd',
 
                          'rattail export-corepos')
 
        config.setdefault('rattail.importing', 'to_corepos_api.from_rattail.export.legacy_handler_setting',
 
                          'rattail.exporting, corepos.handler')
 

	
 
        # rattail import-corepos-api
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_api.import.default_handler',
 
                          'rattail_corepos.importing.corepos.api:FromCOREPOSToRattail')
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_api.import.default_cmd',
 
                          'rattail import-corepos-api')
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_api.import.legacy_handler_setting',
 
                          'rattail.importing, corepos_api.handler')
 

	
 
        # rattail import-corepos-db
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_db_office_op.import.default_handler',
 
                          'rattail_corepos.importing.corepos.db:FromCOREPOSToRattail')
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_db_office_op.import.default_cmd',
 
                          'rattail import-corepos-db')
 
        config.setdefault('rattail.importing', 'to_rattail.from_corepos_db_office_op.import.legacy_handler_setting',
 
                          'rattail.importing, corepos.handler')
 

	
 
        # trainwreck import-corepos
 
        config.setdefault('rattail.importing', 'to_trainwreck.from_corepos_db_office_trans.import.default_handler',
 
                          'rattail_corepos.trainwreck.importing.corepos:FromCoreToTrainwreck')
 
        config.setdefault('rattail.importing', 'to_trainwreck.from_corepos_db_office_trans.import.default_cmd',
 
                          'trainwreck import-corepos')
 
        # TODO: there was not a legacy setting in place for this one
 
        # config.setdefault('rattail.importing', 'to_trainwreck.from_corepos_db_office_trans.import.legacy_handler_setting',
 
        #                   'trainwreck.importing, corepos.handler')
 

	
 
        # core-office export-lane-op
 
        config.setdefault('rattail.importing', 'to_corepos_db_lane_op.from_corepos_db_office_op.export.default_handler',
 
                          'rattail_corepos.corepos.lane.importing.op.office:FromCoreOfficeToCoreLane')
 
        config.setdefault('rattail.importing', 'to_corepos_db_lane_op.from_corepos_db_office_op.export.default_cmd',
 
                          'core-office export-lane-op')
 
        config.setdefault('rattail.importing', 'to_corepos_db_lane_op.from_corepos_db_office_op.export.legacy_setting',
 
                          'corepos.lane.importing, office.handler')
 

	
 
        # crepes export-core
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.export.default_handler',
 
                          'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreExport')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.export.default_cmd',
 
                          'crepes export-core')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.export.legacy_setting',
 
                          'rattail_corepos.exporting, corepos.handler')
 

	
 
        # crepes export-csv
 
        config.setdefault('rattail.importing', 'to_csv.from_corepos_db_office_op.export.default_handler',
 
                          'rattail_corepos.corepos.importing.db.exporters.csv:FromCoreToCSV')
 
        config.setdefault('rattail.importing', 'to_csv.from_corepos_db_office_op.export.default_cmd',
 
                          'crepes export-csv')
 
        config.setdefault('rattail.importing', 'to_csv.from_corepos_db_office_op.export.legacy_setting',
 
                          'rattail_corepos.exporting, csv.handler')
 

	
 
        # crepes import-core
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.import.default_handler',
 
                          'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreImport')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.import.default_cmd',
 
                          'crepes import-core')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.import.legacy_setting',
 
                          'rattail_corepos.importing, corepos.handler')
 

	
 
        # crepes import-csv
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_csv.import.default_handler',
 
                          'rattail_corepos.corepos.importing.db.csv:FromCSVToCore')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_csv.import.default_cmd',
 
                          'crepes import-csv')
 
        config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_csv.import.legacy_setting',
 
                          'rattail_corepos.importing, csv.handler')
 

	
 

	
 
def core_office_url(config, require=False, **kwargs):
 
    """
rattail_corepos/corepos/commands.py
Show inline comments
 
@@ -2,7 +2,7 @@
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2019 Lance Edgar
 
#  Copyright © 2010-2021 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
@@ -60,18 +60,6 @@ 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):
 
@@ -80,18 +68,9 @@ class ExportCore(commands.ImportSubcommand):
 
    """
 
    name = 'export-core'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreExport'
 
    handler_key = 'to_corepos_db_office_op.from_corepos_db_office_op.export'
 
    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,
 
@@ -111,16 +90,7 @@ class ExportCSV(commands.ExportFileSubcommand):
 
    """
 
    name = 'export-csv'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.importing.db.exporters.csv:FromCoreToCSV'
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail_corepos.exporting', 'csv.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)
 
    handler_key = 'to_csv.from_corepos_db_office_op.export'
 

	
 

	
 
class ImportCore(ImportToCore):
 
@@ -129,8 +99,7 @@ class ImportCore(ImportToCore):
 
    """
 
    name = 'import-core'
 
    description = __doc__.strip()
 
    handler_key = 'corepos'
 
    default_handler_spec = 'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreImport'
 
    handler_key = 'to_corepos_db_office_op.from_corepos_db_office_op.import'
 
    accepts_dbkey_param = True
 

	
 
    def add_parser_args(self, parser):
 
@@ -155,7 +124,7 @@ class ImportCSV(commands.ImportFileSubcommand):
 
    """
 
    name = 'import-csv'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.importing.db.csv:FromCSVToCore'
 
    handler_key = 'to_corepos_db_office_op.from_csv.import'
 

	
 
    def add_parser_args(self, parser):
 
        super(ImportCSV, self).add_parser_args(parser)
 
@@ -170,12 +139,3 @@ class ImportCSV(commands.ImportFileSubcommand):
 
            args = kwargs['args']
 
            kwargs['dbkey'] = args.dbkey
 
        return kwargs
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('rattail_corepos.importing', 'csv.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)
rattail_corepos/corepos/importing/db/corepos.py
Show inline comments
 
@@ -2,7 +2,7 @@
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2020 Lance Edgar
 
#  Copyright © 2010-2021 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
@@ -37,6 +37,7 @@ class FromCoreHandler(FromSQLAlchemyHandler):
 
    Base class for import handlers which use a CORE database as the host / source.
 
    """
 
    host_title = "CORE"
 
    host_key = 'corepos_db_office_op'
 

	
 
    def make_host_session(self):
 
        return CoreSession()
 
@@ -47,6 +48,7 @@ class ToCoreHandler(ToSQLAlchemyHandler):
 
    Base class for import handlers which target a CORE database on the local side.
 
    """
 
    local_title = "CORE"
 
    local_key = 'corepos_db_office_op'
 

	
 
    def make_session(self):
 
        return CoreSession()
rattail_corepos/corepos/importing/rattail.py
Show inline comments
 
@@ -39,12 +39,22 @@ from rattail_corepos.corepos.util import get_max_existing_vendor_id
 
log = logging.getLogger(__name__)
 

	
 

	
 
class FromRattailToCore(importing.FromRattailHandler):
 
class ToCOREAPIHandler(importing.ImportHandler):
 
    """
 
    Rattail -> CORE-POS export handler
 
    Base class for handlers targeting the CORE API.
 
    """
 
    local_key = 'corepos_api'
 
    generic_local_title = "CORE Office (API)"
 

	
 
    @property
 
    def local_title(self):
 
        return "CORE-POS (API)"
 

	
 

	
 
class FromRattailToCore(importing.FromRattailHandler, ToCOREAPIHandler):
 
    """
 
    Rattail -> CORE-POS export handler
 
    """
 
    direction = 'export'
 

	
 
    def get_importers(self):
rattail_corepos/corepos/office/commands.py
Show inline comments
 
@@ -60,18 +60,9 @@ class ExportLaneOp(commands.ImportSubcommand):
 
    """
 
    name = 'export-lane-op'
 
    description = __doc__.strip()
 
    default_handler_spec = 'rattail_corepos.corepos.lane.importing.op.office:FromCoreOfficeToCoreLane'
 
    handler_key = 'to_corepos_db_lane_op.from_corepos_db_office_op.export'
 
    default_dbkey = 'default'
 

	
 
    def get_handler_factory(self, **kwargs):
 
        if self.config:
 
            spec = self.config.get('corepos.lane.importing', 'office.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(ExportLaneOp, self).add_parser_args(parser)
 
        parser.add_argument('--dbkey', metavar='KEY', default=self.default_dbkey,
rattail_corepos/trainwreck/commands.py
Show inline comments
 
@@ -33,4 +33,4 @@ class ImportCore(commands.ImportSubcommand):
 
    """
 
    name = 'import-corepos'
 
    description = __doc__.strip()
 
    handler_spec = 'rattail_corepos.trainwreck.importing.corepos:FromCoreToTrainwreck'
 
    handler_key = 'to_trainwreck.from_corepos_db_office_trans.import'
rattail_corepos/trainwreck/importing/corepos.py
Show inline comments
 
@@ -37,7 +37,9 @@ class FromCoreToTrainwreck(importing.FromSQLAlchemyHandler, trainwreck_importing
 
    """
 
    Import data from CORE-POS into Trainwreck
 
    """
 
    host_key = 'corepos_db_office_trans'
 
    host_title = "CORE-POS"
 
    generic_host_title = 'CORE Office (DB "trans")'
 
    corepos_dbkey = 'default'
 

	
 
    def make_host_session(self):
 
@@ -150,23 +152,23 @@ class TransactionImporter(FromCore, trainwreck_importing.model.TransactionImport
 
        current = {}
 

	
 
        def collect(detail, i):
 
            receipt_number = str(detail.transaction_number)
 

	
 
            system_id = self.make_system_id(detail)
 
            if current and current['system_id'] != system_id:
 
                transactions.append(dict(current))
 
                current.clear()
 

	
 
            date_time = detail.date_time
 
            if date_time:
 
                date_time = localtime(self.config, date_time)
 
                date_time = make_utc(date_time)
 

	
 
            if current and current['receipt_number'] != receipt_number:
 
                transactions.append(dict(current))
 
                current.clear()
 

	
 
            if not current:
 
                current.update({
 
                    'system': self.enum.TRAINWRECK_SYSTEM_COREPOS,
 
                    'system_id': self.make_system_id(detail),
 
                    'system_id': system_id,
 
                    'terminal_id': str(detail.register_number),
 
                    'receipt_number': receipt_number,
 
                    'receipt_number': str(detail.transaction_number),
 
                    'cashier_id': str(detail.employee_number) if detail.employee_number else None,
 
                    'customer_id': str(detail.card_number) if detail.card_number else None,
 
                    'start_time': date_time,
setup.py
Show inline comments
 
@@ -124,10 +124,11 @@ setup(
 
        ],
 

	
 
        'rattail.importing': [
 
            'to_rattail.from_corepos_api = rattail_corepos.importing.corepos.api:FromCOREPOSToRattail',
 
            'to_rattail.from_corepos_db_office_op = rattail_corepos.importing.corepos.db:FromCOREPOSToRattail',
 
            'to_corepos_api.from_rattail = rattail_corepos.corepos.importing.rattail:FromRattailToCore',
 
            'to_corepos_db_lane_op.from_corepos_db_office_op = rattail_corepos.corepos.lane.importing.op.office:FromCoreOfficeToCoreLane',
 
            'to_rattail.from_corepos_api.import = rattail_corepos.importing.corepos.api:FromCOREPOSToRattail',
 
            'to_rattail.from_corepos_db_office_op.import = rattail_corepos.importing.corepos.db:FromCOREPOSToRattail',
 
            'to_corepos_api.from_rattail.export = rattail_corepos.corepos.importing.rattail:FromRattailToCore',
 
            'to_corepos_db_lane_op.from_corepos_db_office_op.export = rattail_corepos.corepos.lane.importing.op.office:FromCoreOfficeToCoreLane',
 
            'to_trainwreck.from_corepos_db_office_trans = rattail_corepos.trainwreck.importing.corepos:FromCoreToTrainwreck',
 
        ],
 

	
 
        'trainwreck.commands': [
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now