Add core-office import-self
command, to fix custdata.blueLine
This commit is contained in:
parent
5e1afa2c5c
commit
80084e13da
|
@ -3,4 +3,6 @@ include *.txt
|
||||||
include *.rst
|
include *.rst
|
||||||
include *.md
|
include *.md
|
||||||
|
|
||||||
|
recursive-include rattail_corepos/corepos/office/scripts *.php
|
||||||
|
|
||||||
recursive-include rattail_corepos/db/alembic *.py
|
recursive-include rattail_corepos/db/alembic *.py
|
||||||
|
|
|
@ -131,6 +131,12 @@ class RattailCOREPOSExtension(ConfigExtension):
|
||||||
config.setdefault('rattail.importing', 'to_corepos_db_lane_op.from_corepos_db_office_op.export.legacy_setting',
|
config.setdefault('rattail.importing', 'to_corepos_db_lane_op.from_corepos_db_office_op.export.legacy_setting',
|
||||||
'corepos.lane.importing, office.handler')
|
'corepos.lane.importing, office.handler')
|
||||||
|
|
||||||
|
# core-office import-self
|
||||||
|
config.setdefault('rattail.importing', 'to_self.from_corepos_db_office_op.import.default_handler',
|
||||||
|
'rattail_corepos.corepos.office.importing.db.local:FromCoreOfficeToSelf')
|
||||||
|
config.setdefault('rattail.importing', 'to_self.from_corepos_db_office_op.import.default_cmd',
|
||||||
|
'core-office import-self')
|
||||||
|
|
||||||
# crepes export-core
|
# crepes export-core
|
||||||
config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.export.default_handler',
|
config.setdefault('rattail.importing', 'to_corepos_db_office_op.from_corepos_db_office_op.export.default_handler',
|
||||||
'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreExport')
|
'rattail_corepos.corepos.importing.db.corepos:FromCoreToCoreExport')
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2021 Lance Edgar
|
# Copyright © 2010-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -29,6 +29,7 @@ import sys
|
||||||
from rattail import commands
|
from rattail import commands
|
||||||
from rattail_corepos import __version__
|
from rattail_corepos import __version__
|
||||||
from rattail.util import load_object
|
from rattail.util import load_object
|
||||||
|
from rattail_corepos.corepos.office.util import get_fannie_config_value
|
||||||
|
|
||||||
|
|
||||||
def main(*args):
|
def main(*args):
|
||||||
|
@ -76,3 +77,29 @@ class ExportLaneOp(commands.ImportSubcommand):
|
||||||
if 'args' in kwargs:
|
if 'args' in kwargs:
|
||||||
kwargs['dbkey'] = kwargs['args'].dbkey
|
kwargs['dbkey'] = kwargs['args'].dbkey
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
class GetConfigValue(commands.Subcommand):
|
||||||
|
"""
|
||||||
|
Get a value from CORE Office `fannie/config.php`
|
||||||
|
"""
|
||||||
|
name = 'get-config-value'
|
||||||
|
description = __doc__.strip()
|
||||||
|
|
||||||
|
def add_parser_args(self, parser):
|
||||||
|
parser.add_argument('name', metavar='NAME',
|
||||||
|
help="Name of the config value to get. "
|
||||||
|
"Prefix of `FANNIE_` is not required.")
|
||||||
|
|
||||||
|
def run(self, args):
|
||||||
|
value = get_fannie_config_value(self.config, args.name)
|
||||||
|
self.stdout.write(f"{value}\n")
|
||||||
|
|
||||||
|
|
||||||
|
class ImportSelf(commands.ImportSubcommand):
|
||||||
|
"""
|
||||||
|
Import data from CORE Office ("op" DB) to "self"
|
||||||
|
"""
|
||||||
|
name = 'import-self'
|
||||||
|
description = __doc__.strip()
|
||||||
|
handler_key = 'to_self.from_corepos_db_office_op.import'
|
||||||
|
|
99
rattail_corepos/corepos/office/importing/db/local.py
Normal file
99
rattail_corepos/corepos/office/importing/db/local.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Rattail -- Retail Software Framework
|
||||||
|
# Copyright © 2010-2023 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 -> "self" data import
|
||||||
|
"""
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from corepos.db.office_op import model as corepos
|
||||||
|
|
||||||
|
from rattail import importing
|
||||||
|
from rattail_corepos.corepos.office.importing import db as corepos_importing
|
||||||
|
from rattail_corepos.corepos.office.importing.db.corepos import FromCoreHandler
|
||||||
|
from rattail_corepos.corepos.office.util import get_fannie_config_value
|
||||||
|
|
||||||
|
|
||||||
|
class FromCoreOfficeToSelf(FromCoreHandler, corepos_importing.model.ToCoreHandler):
|
||||||
|
"""
|
||||||
|
Common base class for import handlers which read data from the
|
||||||
|
CORE Office DB for the sake of updating misc. other tables in that
|
||||||
|
same DB.
|
||||||
|
"""
|
||||||
|
local_key = 'self'
|
||||||
|
|
||||||
|
def begin_local_transaction(self):
|
||||||
|
self.session = self.host_session
|
||||||
|
|
||||||
|
def rollback_transaction(self):
|
||||||
|
self.rollback_host_transaction()
|
||||||
|
|
||||||
|
def commit_transaction(self):
|
||||||
|
self.commit_host_transaction()
|
||||||
|
|
||||||
|
def get_importers(self):
|
||||||
|
importers = OrderedDict()
|
||||||
|
importers['CustData'] = CustDataImporter
|
||||||
|
return importers
|
||||||
|
|
||||||
|
|
||||||
|
class FromCoreOffice(importing.FromSQLAlchemy):
|
||||||
|
"""
|
||||||
|
Common base class for the "host" side of importers which read data
|
||||||
|
from the CORE Office DB for the sake of updating misc. other
|
||||||
|
tables in that same DB.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class CustDataImporter(FromCoreOffice, corepos_importing.model.CustDataImporter):
|
||||||
|
"""
|
||||||
|
custdata -> custdata
|
||||||
|
|
||||||
|
Primarily used to update the ``blueLine`` field.
|
||||||
|
"""
|
||||||
|
host_model_class = corepos.CustData
|
||||||
|
supported_fields = [
|
||||||
|
'id',
|
||||||
|
'blue_line',
|
||||||
|
]
|
||||||
|
allow_create = False
|
||||||
|
allow_delete = False
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
super().setup()
|
||||||
|
self.blueline_template = get_fannie_config_value(self.config,
|
||||||
|
'BLUELINE_TEMPLATE')
|
||||||
|
|
||||||
|
def normalize_host_object(self, customer):
|
||||||
|
blueline = self.blueline_template
|
||||||
|
blueline = blueline.replace('{{ACCOUNTNO}}', str(customer.card_number))
|
||||||
|
blueline = blueline.replace('{{ACCOUNTTYPE}}', customer.member_type.description)
|
||||||
|
blueline = blueline.replace('{{FIRSTNAME}}', customer.first_name or '')
|
||||||
|
blueline = blueline.replace('{{FIRSTINITIAL}}', customer.first_name[0] if customer.first_name else '')
|
||||||
|
blueline = blueline.replace('{{LASTNAME}}', customer.last_name or '')
|
||||||
|
blueline = blueline.replace('{{LASTINITIAL}}', customer.last_name[0] if customer.last_name else '')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': customer.id,
|
||||||
|
'blue_line': blueline,
|
||||||
|
}
|
|
@ -198,12 +198,13 @@ class MemberInfoImporter(ToCore):
|
||||||
data['first_name'] = customer.first_name
|
data['first_name'] = customer.first_name
|
||||||
data['last_name'] = customer.last_name
|
data['last_name'] = customer.last_name
|
||||||
|
|
||||||
if self.normalize_phone_numbers:
|
if self.normalize_phone_numbers and 'phone' in self.fields:
|
||||||
data['phone'] = self.app.normalize_phone_number(data['phone'])
|
data['phone'] = self.app.normalize_phone_number(data['phone'])
|
||||||
|
|
||||||
if self.strip_address_street or self.strip_address_all:
|
if ((self.strip_address_street or self.strip_address_all)
|
||||||
|
and 'street' in self.fields):
|
||||||
data['street'] = (data['street'] or '').strip()
|
data['street'] = (data['street'] or '').strip()
|
||||||
if self.strip_address_all:
|
if self.strip_address_all and self.fields_active(['city', 'state', 'zip']):
|
||||||
data['city'] = (data['city'] or '').strip()
|
data['city'] = (data['city'] or '').strip()
|
||||||
data['state'] = (data['state'] or '').strip()
|
data['state'] = (data['state'] or '').strip()
|
||||||
data['zip'] = (data['zip'] or '').strip()
|
data['zip'] = (data['zip'] or '').strip()
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$options = getopt('h', array(
|
||||||
|
'help',
|
||||||
|
'path:',
|
||||||
|
'setting:',
|
||||||
|
));
|
||||||
|
|
||||||
|
$help = isset($options['h']) or isset($options['help']);
|
||||||
|
$path = isset($options['path']) ? $options['path'] : null;
|
||||||
|
$setting = isset($options['setting']) ? $options['setting'] : null;
|
||||||
|
|
||||||
|
if ($help or !$path or !$setting) {
|
||||||
|
$script = basename($argv[0]);
|
||||||
|
echo "Usage: $script --path FANNIE_CONFIG_PATH --setting NAME_OF_SETTING\n";
|
||||||
|
exit($help ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_file(realpath($path))) {
|
||||||
|
echo "Config file does not exist: $path\n";
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
$path = realpath($path);
|
||||||
|
include($path);
|
||||||
|
|
||||||
|
if (!isset($$setting)) {
|
||||||
|
echo "Config file does not contain setting: $setting\n";
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
$value = $$setting;
|
||||||
|
|
||||||
|
echo json_encode($value);
|
||||||
|
|
||||||
|
?>
|
62
rattail_corepos/corepos/office/util.py
Normal file
62
rattail_corepos/corepos/office/util.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Rattail -- Retail Software Framework
|
||||||
|
# Copyright © 2010-2023 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 Office utility logic
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from rattail.files import resource_path
|
||||||
|
|
||||||
|
|
||||||
|
def get_fannie_config_value(config, name):
|
||||||
|
"""
|
||||||
|
Retrieve a config value from `fannie/config.php`
|
||||||
|
|
||||||
|
:param config: Rattail config object.
|
||||||
|
|
||||||
|
:param name: Name of the config value to be returned. This need
|
||||||
|
not be prefixed with ``FANNIE_`` although it can be.
|
||||||
|
|
||||||
|
:returns: Config value as Python object, e.g. a string or dict.
|
||||||
|
This is believed to work okay but since the Fannie config file
|
||||||
|
represents data with PHP code, which is then converted to JSON
|
||||||
|
and finally to Python, some discrepancies may be possible.
|
||||||
|
"""
|
||||||
|
if not name.startswith('FANNIE_'):
|
||||||
|
name = f'FANNIE_{name}'
|
||||||
|
|
||||||
|
is4c = config.require('corepos', 'srcdir')
|
||||||
|
path = os.path.join(is4c, 'fannie', 'config.php')
|
||||||
|
script = resource_path('rattail_corepos.corepos.office:scripts/parse-fannie-config.php')
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(['php', script,
|
||||||
|
'--path', path,
|
||||||
|
'--setting', name])
|
||||||
|
except subprocess.CalledProcessError as error:
|
||||||
|
raise ValueError(f"failed to read value: {error.output.decode('utf_8')}")
|
||||||
|
|
||||||
|
return json.loads(output.decode('utf_8'))
|
|
@ -42,6 +42,8 @@ console_scripts =
|
||||||
|
|
||||||
core_office.commands =
|
core_office.commands =
|
||||||
export-lane-op = rattail_corepos.corepos.office.commands:ExportLaneOp
|
export-lane-op = rattail_corepos.corepos.office.commands:ExportLaneOp
|
||||||
|
import-self = rattail_corepos.corepos.office.commands:ImportSelf
|
||||||
|
get-config-value = rattail_corepos.corepos.office.commands:GetConfigValue
|
||||||
|
|
||||||
crepes.commands =
|
crepes.commands =
|
||||||
export-core = rattail_corepos.corepos.commands:ExportCore
|
export-core = rattail_corepos.corepos.commands:ExportCore
|
||||||
|
|
Loading…
Reference in a new issue