Add customer, member importers from CORE DB
API is just not cutting it, need more flexibility
This commit is contained in:
parent
124a510c17
commit
d08c475223
5 changed files with 276 additions and 9 deletions
|
@ -144,6 +144,8 @@ class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter)
|
|||
'corepos_account_id',
|
||||
'number',
|
||||
'name',
|
||||
# 'account_holder_first_name',
|
||||
# 'account_holder_last_name',
|
||||
'address_street',
|
||||
'address_street2',
|
||||
'address_city',
|
||||
|
@ -182,6 +184,8 @@ class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter)
|
|||
'name': normalize_full_name(customer['firstName'],
|
||||
customer['lastName']),
|
||||
|
||||
# 'account_holder_first_name': customer['firstName'],
|
||||
# 'account_holder_last_name': customer['lastName'],
|
||||
'address_street': member['addressFirstLine'] or None,
|
||||
'address_street2': member['addressSecondLine'] or None,
|
||||
'address_city': member['city'] or None,
|
||||
|
@ -783,10 +787,13 @@ class MemberImporter(FromCOREPOSAPI, corepos_importing.model.MemberImporter):
|
|||
"""
|
||||
Importer for member data from CORE POS API.
|
||||
"""
|
||||
# TODO use this key instead
|
||||
#key = 'corepos_card_number'
|
||||
key = 'number'
|
||||
supported_fields = [
|
||||
'number',
|
||||
'corepos_account_id',
|
||||
'corepos_card_number',
|
||||
'customer_uuid',
|
||||
'person_first_name',
|
||||
'person_last_name',
|
||||
|
@ -857,6 +864,8 @@ class MemberImporter(FromCOREPOSAPI, corepos_importing.model.MemberImporter):
|
|||
joined = datetime.datetime.strptime(member['startDate'],
|
||||
'%Y-%m-%d %H:%M:%S')
|
||||
joined = joined.date()
|
||||
if joined == datetime.date(1900, 1, 1):
|
||||
joined = None
|
||||
|
||||
withdrew = None
|
||||
if (member['endDate']
|
||||
|
@ -865,19 +874,20 @@ class MemberImporter(FromCOREPOSAPI, corepos_importing.model.MemberImporter):
|
|||
withdrew = datetime.datetime.strptime(member['endDate'],
|
||||
'%Y-%m-%d %H:%M:%S')
|
||||
withdrew = withdrew.date()
|
||||
if withdrew == datetime.date(1900, 1, 1):
|
||||
withdrew = None
|
||||
|
||||
typeno = int(member['customerTypeID']) or None
|
||||
if typeno:
|
||||
memtype = self.get_membership_type_by_number(typeno)
|
||||
if not memtype:
|
||||
logger = log.warning if self.get_warn_for_unknown_membership_type() else log.debug
|
||||
logger("unknown customerTypeID (membership_type_number) %s for: %s",
|
||||
member['customerTypeID'], member)
|
||||
typeno = None
|
||||
typeno = int(member['customerTypeID'])
|
||||
memtype = self.get_membership_type_by_number(typeno)
|
||||
if not memtype:
|
||||
log.warning("unknown customerTypeID (membership_type_number) %s for: %s",
|
||||
member['customerTypeID'], member)
|
||||
typeno = None
|
||||
|
||||
data = {
|
||||
'number': card_number,
|
||||
'corepos_account_id': int(member['customerAccountID']),
|
||||
'corepos_card_number': card_number,
|
||||
'customer_uuid': customer.uuid if customer else None,
|
||||
'person_first_name': None,
|
||||
'person_last_name': None,
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
CORE POS (DB) -> Rattail data importing
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import decimal
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from corepos.db.office_op import model as corepos, Session as CoreSession
|
||||
|
@ -67,6 +69,8 @@ class FromCOREPOSToRattail(importing.FromSQLAlchemyHandler, importing.ToRattailH
|
|||
def get_importers(self):
|
||||
importers = OrderedDict()
|
||||
importers['Employee'] = EmployeeImporter
|
||||
importers['Customer'] = CustomerImporter
|
||||
importers['Member'] = MemberImporter
|
||||
importers['Tax'] = TaxImporter
|
||||
importers['Tender'] = TenderImporter
|
||||
importers['Vendor'] = VendorImporter
|
||||
|
@ -90,6 +94,25 @@ class FromCOREPOS(importing.FromSQLAlchemy):
|
|||
Base class for all CORE POS data importers.
|
||||
"""
|
||||
|
||||
def setup(self):
|
||||
super().setup()
|
||||
self.ignore_new_members = self.should_ignore_new_members()
|
||||
|
||||
def should_ignore_new_members(self):
|
||||
if hasattr(self, 'ignore_new_members'):
|
||||
return self.ignore_new_members
|
||||
|
||||
return self.config.getbool('rattail_corepos',
|
||||
'importing_ignore_new_members',
|
||||
default=False)
|
||||
|
||||
def is_new_member(self, member):
|
||||
if member.customers:
|
||||
customer = member.customers[0]
|
||||
if customer.last_name == 'NEW MEMBER'and not customer.first_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class EmployeeImporter(FromCOREPOS, corepos_importing.model.EmployeeImporter):
|
||||
"""
|
||||
|
@ -115,6 +138,195 @@ class EmployeeImporter(FromCOREPOS, corepos_importing.model.EmployeeImporter):
|
|||
}
|
||||
|
||||
|
||||
class CustomerImporter(FromCOREPOS, corepos_importing.model.CustomerImporter):
|
||||
"""
|
||||
Importer for customer data from CORE POS.
|
||||
"""
|
||||
host_model_class = corepos.MemberInfo
|
||||
key = 'corepos_card_number'
|
||||
supported_fields = [
|
||||
'corepos_card_number',
|
||||
'number',
|
||||
'name',
|
||||
'account_holder_uuid',
|
||||
'account_holder_first_name',
|
||||
'account_holder_last_name',
|
||||
'email_address',
|
||||
'phone_number',
|
||||
'address_street',
|
||||
'address_street2',
|
||||
'address_city',
|
||||
'address_state',
|
||||
'address_zipcode',
|
||||
]
|
||||
|
||||
def setup(self):
|
||||
super().setup()
|
||||
model = self.model
|
||||
|
||||
query = self.session.query(model.Person)\
|
||||
.outerjoin(model.Customer,
|
||||
model.Customer.account_holder_uuid == model.Person.uuid)\
|
||||
.outerjoin(model.CoreCustomer)\
|
||||
.outerjoin(model.Member,
|
||||
model.Member.person_uuid == model.Person.uuid)\
|
||||
.outerjoin(model.CoreMember)\
|
||||
.filter(sa.or_(
|
||||
model.CoreCustomer.corepos_card_number != None,
|
||||
model.CoreMember.corepos_card_number != None))\
|
||||
.options(orm.joinedload(model.Person.customer_accounts)\
|
||||
.joinedload(model.Customer._corepos))
|
||||
def card_number(person, normal):
|
||||
customer = self.app.get_customer(person)
|
||||
if customer and customer.corepos_card_number:
|
||||
return customer.corepos_card_number
|
||||
member = self.app.get_member(person)
|
||||
if member and member.corepos_card_number:
|
||||
return member.corepos_card_number
|
||||
self.people_by_card_number = self.cache_model(model.Person, query=query,
|
||||
key=card_number)
|
||||
|
||||
def get_person(self, member):
|
||||
|
||||
if hasattr(self, 'people_by_card_number'):
|
||||
return self.people_by_card_number.get(member.card_number)
|
||||
|
||||
model = self.model
|
||||
|
||||
try:
|
||||
return self.session.query(model.Person)\
|
||||
.join(model.Customer,
|
||||
model.Customer.account_holder_uuid == model.Person.uuid)\
|
||||
.join(model.CoreCustomer)\
|
||||
.filter(model.CoreCustomer.corepos_card_number == member.card_number)\
|
||||
.one()
|
||||
except orm.exc.NoResultFound:
|
||||
pass
|
||||
|
||||
try:
|
||||
return self.session.query(model.Person)\
|
||||
.join(model.Member,
|
||||
model.Member.person_uuid == model.Person.uuid)\
|
||||
.join(model.CoreMember)\
|
||||
.filter(model.CoreMember.corepos_card_number == member.card_number)\
|
||||
.one()
|
||||
except orm.exc.NoResultFound:
|
||||
pass
|
||||
|
||||
def normalize_host_object(self, member):
|
||||
card_number = member.card_number
|
||||
|
||||
# maybe ignore NEW MEMBER accounts
|
||||
if self.should_ignore_new_members():
|
||||
if self.is_new_member(member):
|
||||
return
|
||||
|
||||
contact = member
|
||||
if member.customers:
|
||||
contact = member.customers[0]
|
||||
|
||||
person = self.get_person(member)
|
||||
|
||||
street = (member.street or '').split('\n')
|
||||
|
||||
return {
|
||||
'corepos_card_number': card_number,
|
||||
'number': card_number,
|
||||
'name': normalize_full_name(contact.first_name, contact.last_name),
|
||||
'account_holder_uuid': person.uuid if person else None,
|
||||
'account_holder_first_name': contact.first_name,
|
||||
'account_holder_last_name': contact.last_name,
|
||||
'email_address': (member.email or '').strip() or None,
|
||||
'phone_number': self.app.format_phone_number((member.phone or '').strip() or None),
|
||||
'address_street': street[0] or None,
|
||||
'address_street2': (street[1] or None) if len(street) > 1 else None,
|
||||
'address_city': member.city or None,
|
||||
'address_state': member.state or None,
|
||||
'address_zipcode': member.zip or None,
|
||||
}
|
||||
|
||||
|
||||
class MemberImporter(FromCOREPOS, corepos_importing.model.MemberImporter):
|
||||
"""
|
||||
Importer for member data from CORE POS.
|
||||
"""
|
||||
host_model_class = corepos.MemberInfo
|
||||
# TODO use this key instead
|
||||
#key = 'corepos_card_number'
|
||||
key = 'number'
|
||||
supported_fields = [
|
||||
'number',
|
||||
'corepos_card_number',
|
||||
'customer_uuid',
|
||||
'person_first_name',
|
||||
'person_last_name',
|
||||
'membership_type_number',
|
||||
'joined',
|
||||
'withdrew',
|
||||
'active',
|
||||
]
|
||||
|
||||
def setup(self):
|
||||
super().setup()
|
||||
model = self.model
|
||||
|
||||
self.customers_by_number = self.app.cache_model(self.session,
|
||||
model.Customer,
|
||||
key='number')
|
||||
|
||||
def get_customer_by_number(self, number):
|
||||
if hasattr(self, 'customers_by_number'):
|
||||
return self.customers_by_number.get(number)
|
||||
|
||||
model = self.model
|
||||
try:
|
||||
return self.session.query(model.Customer)\
|
||||
.filter(model.Customer.number == number)\
|
||||
.one()
|
||||
except orm.exc.NoResultFound:
|
||||
pass
|
||||
|
||||
def normalize_host_object(self, core_member):
|
||||
|
||||
# maybe ignore NEW MEMBER accounts
|
||||
if self.should_ignore_new_members():
|
||||
if self.is_new_member(core_member):
|
||||
return
|
||||
|
||||
core_customer = core_member.customers[0] if core_member.customers else None
|
||||
core_contact = core_customer or core_member
|
||||
|
||||
card_number = core_member.card_number
|
||||
customer = self.get_customer_by_number(card_number)
|
||||
|
||||
typeno = None
|
||||
if core_customer and core_customer.member_type:
|
||||
typeno = core_customer.member_type.id
|
||||
|
||||
joined = None
|
||||
withdrew = None
|
||||
if core_member.dates:
|
||||
dates = core_member.dates
|
||||
joined = dates.start_date.date() if dates.start_date else None
|
||||
withdrew = dates.end_date.date() if dates.end_date else None
|
||||
if joined and joined == datetime.date(1900, 1, 1):
|
||||
joined = None
|
||||
if withdrew and withdrew == datetime.date(1900, 1, 1):
|
||||
withdrew = None
|
||||
|
||||
return {
|
||||
'number': card_number,
|
||||
'corepos_card_number': card_number,
|
||||
'customer_uuid': customer.uuid if customer else None,
|
||||
'person_first_name': core_contact.first_name,
|
||||
'person_last_name': core_contact.last_name,
|
||||
'membership_type_number': typeno,
|
||||
'joined': joined,
|
||||
'withdrew': withdrew,
|
||||
'active': not bool(withdrew),
|
||||
}
|
||||
|
||||
|
||||
class TaxImporter(FromCOREPOS, corepos_importing.model.TaxImporter):
|
||||
"""
|
||||
Importer for tax data from CORE POS.
|
||||
|
|
|
@ -87,6 +87,7 @@ class MemberImporter(importing.model.MemberImporter):
|
|||
extensions = {
|
||||
'_corepos': [
|
||||
'corepos_account_id',
|
||||
'corepos_card_number',
|
||||
],
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue