Compare commits

..

No commits in common. "master" and "v0.3.3" have entirely different histories.

14 changed files with 114 additions and 271 deletions

View file

@ -5,46 +5,6 @@ All notable changes to rattail-corepos will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## v0.3.9 (2024-08-19)
### Fix
- improve logic for matching CORE stock purchase to Rattail payment
## v0.3.8 (2024-08-18)
### Fix
- avoid deprecated base class for config extension
- work around, log error when datasync can't locate member
## v0.3.7 (2024-08-13)
### Fix
- improve `core-office anonymize` command logic
## v0.3.6 (2024-08-06)
### Fix
- fix DELETE triggers for `meminfo`, `employees`
- avoid deprecated `AppProvider.load_object()` method
## v0.3.5 (2024-07-14)
### Fix
- update app provider entry point, per wuttjamaican
- fix CORE op model reference
## v0.3.4 (2024-07-13)
### Fix
- refactor `config.get_model()` => `app.model`
- avoid error when CORE API gives record with no upc
## v0.3.3 (2024-07-05)
### Fix

View file

@ -1,11 +0,0 @@
# rattail-corepos
Rattail is a retail software framework, released under the GNU General Public
License.
This package contains software interfaces for the [CORE
POS](https://github.com/CORE-POS/IS4C) system.
Please see Rattail's [home page](https://rattailproject.org/) for more
information.

14
README.rst Normal file
View file

@ -0,0 +1,14 @@
rattail_corepos
===============
Rattail is a retail software framework, released under the GNU General Public
License.
This package contains software interfaces for the `CORE POS`_ system.
.. _`CORE POS`: https://github.com/CORE-POS/IS4C
Please see Rattail's `home page`_ for more information.
.. _`home page`: https://rattailproject.org/

View file

@ -6,9 +6,9 @@ build-backend = "hatchling.build"
[project]
name = "rattail_corepos"
version = "0.3.9"
version = "0.3.3"
description = "Rattail Software Interfaces for CORE POS"
readme = "README.md"
readme = "README.rst"
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
license = {text = "GNU GPL v3+"}
classifiers = [
@ -33,10 +33,10 @@ dependencies = [
[project.urls]
Homepage = "https://rattailproject.org"
Repository = "https://forgejo.wuttaproject.org/rattail/rattail-corepos"
Issues = "https://forgejo.wuttaproject.org/rattail/rattail-corepos/issues"
Changelog = "https://forgejo.wuttaproject.org/rattail/rattail-corepos/src/branch/master/CHANGELOG.md"
Homepage = "https://redmine.rattailproject.org/projects/corepos-integration"
Repository = "https://kallithea.rattailproject.org/rattail-project/rattail-corepos"
Issues = "https://redmine.rattailproject.org/projects/corepos-integration/issues"
Changelog = "https://kallithea.rattailproject.org/rattail-project/rattail-corepos/files/master/CHANGELOG.md"
[project.scripts]
@ -64,7 +64,7 @@ rattail_corepos = "rattail_corepos.emails"
"to_trainwreck.from_corepos_db_office_trans" = "rattail_corepos.trainwreck.importing.corepos:FromCoreToTrainwreck"
[project.entry-points."wutta.app.providers"]
[project.entry-points."rattail.providers"]
rattail_corepos = "rattail_corepos.app:CoreProvider"

View file

@ -34,9 +34,9 @@ class CoreProvider(RattailProvider):
def get_corepos_handler(self, **kwargs):
if not hasattr(self, 'corepos_handler'):
spec = self.config.get('rattail.corepos.handler',
spec = self.config.get('rattail', 'corepos.handler',
default='rattail_corepos.app:CoreHandler')
factory = self.app.load_object(spec)
factory = self.load_object(spec)
self.corepos_handler = factory(self.config, **kwargs)
return self.corepos_handler

View file

@ -26,11 +26,12 @@ Rattail-COREPOS Config Extension
import warnings
from wuttjamaican.conf import WuttaConfigExtension
from wuttjamaican.db.conf import get_engines
from rattail.config import ConfigExtension
class RattailCOREPOSExtension(WuttaConfigExtension):
class RattailCOREPOSExtension(ConfigExtension):
"""
Config extension for Rattail-COREPOS
"""

View file

@ -37,13 +37,8 @@ class Anonymizer(GenericHandler):
"""
def anonymize_all(self, dbkey=None, dry_run=False, progress=None):
# nb. these must be installed with:
# pip install names us zipcodes
import names
import us
import zipcodes
self.all_zipcodes = zipcodes.list_all()
core_handler = self.app.get_corepos_handler()
op_session = core_handler.make_session_office_op(dbkey=dbkey)
@ -51,56 +46,45 @@ class Anonymizer(GenericHandler):
states = [state.abbr for state in us.states.STATES]
# meminfo
members = op_session.query(op_model.MemberInfo).all()
members_by_card_number = {}
def anon_meminfo(member, i):
member.first_name = names.get_first_name()
member.last_name = names.get_last_name()
member.other_first_name = names.get_first_name()
member.other_last_name = names.get_last_name()
member.street = '123 Main St.'
member.city = 'Anytown'
member.state = random.choice(states)
member.zipcode = self.random_zipcode()
member.phone = self.random_phone()
member.email = self.random_email()
member.notes.clear()
members_by_card_number[member.card_number] = member
self.app.progress_loop(anon_meminfo, members, progress,
message="Anonymizing meminfo")
# custdata
customers = op_session.query(op_model.CustomerClassic)\
.order_by(op_model.CustomerClassic.card_number,
op_model.CustomerClassic.person_number)\
.all()
customers = op_session.query(op_model.CustomerClassic).all()
blueline_template = get_blueline_template(self.config)
customers_by_card_number = {}
def anon_custdata(customer, i):
member = members_by_card_number.get(customer.card_number)
if member:
customer.first_name = member.first_name
customer.last_name = member.last_name
else:
customer.first_name = names.get_first_name()
customer.last_name = names.get_last_name()
customer.blue_line = make_blueline(self.config, customer,
template=blueline_template)
customers_by_card_number.setdefault(customer.card_number, []).append(customer)
self.app.progress_loop(anon_custdata, customers, progress,
message="Anonymizing custdata")
# meminfo
members = op_session.query(op_model.MemberInfo).all()
def anon_meminfo(member, i):
if member.first_name:
member.first_name = names.get_first_name()
if member.last_name:
member.last_name = names.get_last_name()
if member.other_first_name:
member.other_first_name = names.get_first_name()
if member.other_last_name:
member.other_last_name = names.get_last_name()
member.street = '123 Main St.'
member.city = 'Anytown'
member.state = random.choice(states)
member.zip = self.random_zipcode()
member.phone = self.random_phone()
customers = customers_by_card_number.get(member.card_number)
if customers:
customer = customers[0]
member.email = f'{customer.first_name}_{customer.last_name}@mailinator.com'\
.lower()
else:
member.email = self.random_email()
member.notes.clear()
self.app.progress_loop(anon_meminfo, members, progress,
message="Anonymizing meminfo")
# Customers
customers = op_session.query(op_model.Customer).all()
@ -149,7 +133,9 @@ class Anonymizer(GenericHandler):
import names
name = names.get_full_name()
name = name.replace(' ', '_')
return f'{name}@mailinator.com'.lower()
return f'{name}@mailinator.com'
def random_zipcode(self):
return random.choice(self.all_zipcodes)['zip_code']
digits = [random.choice('0123456789')
for i in range(5)]
return ''.join(digits)

View file

@ -95,13 +95,6 @@ def anonymize(
"\tpip install us\n")
sys.exit(2)
try:
import zipcodes
except ImportError:
sys.stderr.write("must install the `zipcodes` package first!\n\n"
"\tpip install zipcodes\n")
sys.exit(2)
anonymizer = Anonymizer(config)
anonymizer.anonymize_all(dbkey=dbkey, dry_run=dry_run,
progress=progress)

View file

@ -222,7 +222,7 @@ class CoreTriggerHandler(GenericHandler):
op_session.execute(sa.text(f"""
CREATE TRIGGER record_meminfo_delete
AFTER DELETE ON meminfo
FOR EACH ROW INSERT INTO {changes_table} (object_type, object_key, deleted) VALUES ('Member', CONVERT(OLD.card_no, CHAR), 1);
FOR EACH ROW INSERT INTO {changes_table} (object_type, object_key, deleted) VALUES ('Member', CONVERT(OLD.card_no, CHAR));
"""))
def create_triggers_employees(self, op_session, changes_table):
@ -242,7 +242,7 @@ class CoreTriggerHandler(GenericHandler):
op_session.execute(sa.text(f"""
CREATE TRIGGER record_employees_delete
AFTER DELETE ON employees
FOR EACH ROW INSERT INTO {changes_table} (object_type, object_key, deleted) VALUES ('Employee', CONVERT(OLD.emp_no, CHAR), 1);
FOR EACH ROW INSERT INTO {changes_table} (object_type, object_key, deleted) VALUES ('Employee', CONVERT(OLD.emp_no, CHAR));
"""))
def create_triggers_departments(self, op_session, changes_table):

View file

@ -24,16 +24,11 @@
DataSync for Rattail DB
"""
import logging
from sqlalchemy import orm
from rattail.datasync import DataSyncImportConsumer
log = logging.getLogger(__name__)
class FromCOREAPIToRattail(DataSyncImportConsumer):
"""
Consumer for CORE POS (API) -> Rattail datasync
@ -74,11 +69,6 @@ class FromCOREAPIToRattail(DataSyncImportConsumer):
else:
# import member data from API, into various Rattail tables
member = self.get_host_object(session, change)
if not member:
# TODO: should log.warning() instead but for now i
# need to see this in action and further troubleshoot
log.error("CORE member not found for change: %s", change)
continue
self.process_change(session, self.importers['Customer'],
host_object=member)
shoppers = self.importers['CustomerShopper'].get_shoppers_for_member(member)

View file

@ -528,7 +528,6 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
products = OrderedDict()
def collect(product, i):
if product.get('upc'):
if product['upc'] in products:
log.warning("duplicate UPC encountered for '%s'; will discard: %s",
product['upc'], product)
@ -540,7 +539,7 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
return list(products.values())
def identify_product(self, corepos_product):
model = self.app.model
model = self.config.get_model()
corepos_id = int(corepos_product['id'])
if hasattr(self, 'core_existing'):
@ -712,7 +711,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
def setup(self):
super().setup()
model = self.app.model
model = self.config.get_model()
query = self.session.query(model.Vendor)\
.join(model.CoreVendor)\
@ -756,7 +755,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
warn_for_missing_vendor_id = self.should_warn_for_missing_vendor_id()
def cache(item, i):
if not item.get('upc'):
if not item['upc']:
log.warning("CORE vendor item has no upc: %s", item)
return
if item['vendorID'] == '0':
@ -798,7 +797,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
if hasattr(self, 'vendors'):
return self.vendors.get(corepos_id)
model = self.app.model
model = self.config.get_model()
try:
return self.session.query(model.Vendor)\
.join(model.CoreVendor)\

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2024 Lance Edgar
# Copyright © 2010-2023 Lance Edgar
#
# This file is part of Rattail.
#
@ -32,7 +32,11 @@ from collections import OrderedDict
import sqlalchemy as sa
from sqlalchemy import orm
from corepos.db.office_op import model as corepos, Session as CoreSession
from corepos.db.office_trans import model as coretrans, Session as CoreTransSession
from rattail import importing
from rattail.gpc import GPC
from rattail.db.util import normalize_full_name
from rattail_corepos import importing as corepos_importing
@ -54,16 +58,13 @@ class FromCOREPOSToRattail(importing.FromSQLAlchemyHandler, importing.ToRattailH
return "CORE-POS (DB/{})".format(self.corepos_dbkey)
def make_host_session(self):
corepos = self.app.get_corepos_handler()
# session type depends on the --corepos-dbtype arg
if self.corepos_dbtype == 'office_trans':
return corepos.make_session_office_trans(
bind=self.config.coretrans_engines[self.corepos_dbkey])
return CoreTransSession(bind=self.config.coretrans_engines[self.corepos_dbkey])
# assume office_op by default
return corepos.make_session_office_op(
bind=self.config.corepos_engines[self.corepos_dbkey])
return CoreSession(bind=self.config.corepos_engines[self.corepos_dbkey])
def get_importers(self):
importers = OrderedDict()
@ -119,13 +120,7 @@ class StoreImporter(FromCOREPOS, corepos_importing.model.StoreImporter):
"""
Importer for store data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Store
host_model_class = corepos.Store
key = 'corepos_id'
supported_fields = [
'corepos_id',
@ -145,13 +140,7 @@ class EmployeeImporter(FromCOREPOS, corepos_importing.model.EmployeeImporter):
"""
Importer for employee data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Employee
host_model_class = corepos.Employee
key = 'corepos_number'
supported_fields = [
'corepos_number',
@ -175,13 +164,7 @@ class CustomerImporter(FromCOREPOS, corepos_importing.model.CustomerImporter):
"""
Importer for customer data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.MemberInfo
host_model_class = corepos.MemberInfo
key = 'corepos_card_number'
supported_fields = [
'corepos_card_number',
@ -292,13 +275,7 @@ class MemberImporter(FromCOREPOS, corepos_importing.model.MemberImporter):
"""
Importer for member data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.MemberInfo
host_model_class = corepos.MemberInfo
# TODO use this key instead
#key = 'corepos_card_number'
key = 'number'
@ -430,13 +407,7 @@ class TaxImporter(FromCOREPOS, corepos_importing.model.TaxImporter):
"""
Importer for tax data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.TaxRate
host_model_class = corepos.TaxRate
key = 'corepos_id'
supported_fields = [
'corepos_id',
@ -458,13 +429,7 @@ class TenderImporter(FromCOREPOS, corepos_importing.model.TenderImporter):
"""
Importer for tender data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Tender
host_model_class = corepos.Tender
key = 'corepos_id'
supported_fields = [
'corepos_id',
@ -484,13 +449,7 @@ class VendorImporter(FromCOREPOS, corepos_importing.model.VendorImporter):
"""
Importer for vendor data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Vendor
host_model_class = corepos.Vendor
key = 'corepos_id'
supported_fields = [
'corepos_id',
@ -508,7 +467,7 @@ class VendorImporter(FromCOREPOS, corepos_importing.model.VendorImporter):
"""
# can't just use rattail.db.model b/c the CoreVendor would normally not
# be in there! this still requires custom model to be configured though.
model = self.app.model
model = self.config.get_model()
# first get default query
query = super().cache_query()
@ -543,13 +502,7 @@ class DepartmentImporter(FromCOREPOS, corepos_importing.model.DepartmentImporter
"""
Importer for department data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Department
host_model_class = corepos.Department
key = 'corepos_number'
supported_fields = [
'corepos_number',
@ -573,13 +526,7 @@ class SubdepartmentImporter(FromCOREPOS, corepos_importing.model.SubdepartmentIm
"""
Importer for subdepartment data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Subdepartment
host_model_class = corepos.Subdepartment
key = 'corepos_number'
supported_fields = [
'corepos_number',
@ -601,13 +548,7 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
"""
Importer for product data from CORE POS.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.Product
host_model_class = corepos.Product
key = 'corepos_id'
supported_fields = [
'corepos_id',
@ -638,8 +579,6 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
def setup(self):
super().setup()
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
if self.fields_active(self.sale_price_fields):
self.core_batch_items = {}
@ -649,11 +588,11 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
# determine which would "win" but not clear what sort
# order should be used, e.g. CORE does not seem to use one
today = self.app.today()
batches = self.host_session.query(op_model.Batch)\
.filter(op_model.Batch.start_date <= today)\
.filter(op_model.Batch.end_date >= today)\
.filter(op_model.Batch.discount_type > 0)\
.options(orm.joinedload(op_model.Batch.items))\
batches = self.host_session.query(corepos.Batch)\
.filter(corepos.Batch.start_date <= today)\
.filter(corepos.Batch.end_date >= today)\
.filter(corepos.Batch.discount_type > 0)\
.options(orm.joinedload(corepos.Batch.items))\
.all()
def cache(batch, i):
@ -681,7 +620,7 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
def normalize_host_object(self, product):
try:
upc = self.app.make_gpc(product.upc, calc_check_digit='upc')
upc = GPC(product.upc, calc_check_digit='upc')
except (TypeError, ValueError):
log.debug("CORE POS product has invalid UPC: %s", product.upc)
if len(self.key) == 1 and self.key[0] == 'upc':
@ -752,13 +691,7 @@ class ProductCostImporter(FromCOREPOS, corepos_importing.model.ProductCostImport
"""
Importer for product cost data from CORE POS API.
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
return op_model.VendorItem
host_model_class = corepos.VendorItem
key = ('corepos_vendor_id', 'corepos_sku')
supported_fields = [
'corepos_vendor_id',
@ -786,12 +719,9 @@ class ProductCostImporter(FromCOREPOS, corepos_importing.model.ProductCostImport
self.products_by_item_id = self.cache_model(model.Product, key='item_id')
def query(self):
corepos = self.app.get_corepos_handler()
op_model = corepos.get_model_office_op()
query = super().query()
query = query.options(orm.joinedload(op_model.VendorItem.product))
query = query.options(orm.joinedload(corepos.VendorItem.product))
return query
@ -801,7 +731,7 @@ class ProductCostImporter(FromCOREPOS, corepos_importing.model.ProductCostImport
if hasattr(self, 'vendors_by_corepos_id'):
return self.vendors_by_corepos_id.get(corepos_id)
model = self.app.model
model = self.config.get_model()
try:
return self.session.query(model.Vendor)\
.join(model.CoreVendor)\
@ -868,13 +798,7 @@ class MemberEquityPaymentImporter(FromCOREPOS, corepos_importing.model.MemberEqu
"""
Imports equity payment data from CORE-POS
"""
@property
def host_model_class(self):
corepos = self.app.get_corepos_handler()
trans_model = corepos.get_model_office_trans()
return trans_model.StockPurchase
host_model_class = coretrans.StockPurchase
key = 'uuid'
supported_fields = [
'uuid',
@ -953,17 +877,7 @@ class MemberEquityPaymentImporter(FromCOREPOS, corepos_importing.model.MemberEqu
if len(match) == 1:
return match[0]
# then try to match on date only, not time
match = [payment for payment in payments
if payment.corepos_transaction_number == stock_purchase.transaction_number
and payment.corepos_transaction_id == stock_purchase.transaction_id
and payment.amount == stock_purchase.amount
and payment.corepos_department_number == stock_purchase.department_number
and self.app.localtime(payment.corepos_datetime, from_utc=True).date() == dt.date()]
if len(match) == 1:
return match[0]
# nb. avoid date/time for this one
# nb. avoid datetime for this one
matches = [payment for payment in payments
if payment.corepos_transaction_number == stock_purchase.transaction_number
and payment.corepos_transaction_id == stock_purchase.transaction_id
@ -976,9 +890,6 @@ class MemberEquityPaymentImporter(FromCOREPOS, corepos_importing.model.MemberEqu
stock_purchase.amount,
stock_purchase.datetime)
# TODO: now that we try to match on date above, this logic
# may no longer be necssary/useful?
# so there is one match, but its timestamp may be way off,
# so let's also make sure at least date matches
payment = matches[0]

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2024 Lance Edgar
# Copyright © 2010-2023 Lance Edgar
#
# This file is part of Rattail.
#
@ -27,6 +27,7 @@ Rattail model importer extensions, for CORE-POS integration
import decimal
from rattail import importing
from rattail.util import pretty_quantity
##############################
@ -43,7 +44,7 @@ class PersonImporter(importing.model.PersonImporter):
def cache_query(self):
query = super().cache_query()
model = self.app.model
model = self.config.get_model()
# we want to ignore people with no CORE ID, if that's (part of) our key
if 'corepos_customer_id' in self.key:
@ -176,7 +177,7 @@ class ProductImporter(importing.model.ProductImporter):
def cache_query(self):
query = super().cache_query()
model = self.app.model
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:
@ -218,10 +219,9 @@ class ProductImporter(importing.model.ProductImporter):
uom_code = self.get_uom_code(uom_abbrev) or self.enum.UNIT_OF_MEASURE_NONE
if unit_size is not None and uom_abbrev is not None:
size = self.app.render_quantity(unit_size)
size = f"{size} {uom_abbrev}"
size = "{} {}".format(pretty_quantity(unit_size), uom_abbrev)
elif unit_size is not None:
size = self.app.render_quantity(unit_size)
size = pretty_quantity(unit_size)
elif uom_abbrev is not None:
size = uom_abbrev
else:
@ -247,7 +247,7 @@ class ProductCostImporter(importing.model.ProductCostImporter):
def cache_query(self):
query = super().cache_query()
model = self.app.model
model = self.config.get_model()
# we want to ignore items with no CORE ID, if that's (part of) our key
if 'corepos_id' in self.key:

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2024 Lance Edgar
# Copyright © 2010-2023 Lance Edgar
#
# This file is part of Rattail.
#
@ -51,7 +51,7 @@ class CorePersonImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CorePerson
@ -59,7 +59,7 @@ class CoreEmployeeImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreEmployee
@ -67,7 +67,7 @@ class CoreCustomerImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreCustomer
@ -82,7 +82,7 @@ class CoreMemberImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreMember
@ -90,7 +90,7 @@ class CoreMemberEquityPaymentImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreMemberEquityPayment
@ -98,7 +98,7 @@ class CoreStoreImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreStore
@ -106,7 +106,7 @@ class CoreDepartmentImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreDepartment
@ -114,7 +114,7 @@ class CoreSubdepartmentImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreSubdepartment
@ -122,7 +122,7 @@ class CoreVendorImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreVendor
@ -130,5 +130,5 @@ class CoreProductImporter(base.VersionImporter):
@property
def host_model_class(self):
model = self.app.model
model = self.config.get_model()
return model.CoreProduct