Add CustomerShopper.corepos_customer_id and refactor importers
				
					
				
			removes phone/email support for now..also change how we handle default/empty values for member start/end date..
This commit is contained in:
		
							parent
							
								
									86a8e2d241
								
							
						
					
					
						commit
						660637522d
					
				
					 7 changed files with 150 additions and 37 deletions
				
			
		|  | @ -2,7 +2,7 @@ | |||
| ################################################################################ | ||||
| # | ||||
| #  Rattail -- Retail Software Framework | ||||
| #  Copyright © 2010-2021 Lance Edgar | ||||
| #  Copyright © 2010-2023 Lance Edgar | ||||
| # | ||||
| #  This file is part of Rattail. | ||||
| # | ||||
|  | @ -121,7 +121,8 @@ class MemberImporter(ToCoreAPI): | |||
|         # 'modified', | ||||
|     ] | ||||
| 
 | ||||
|     empty_date_value = '0000-00-00 00:00:00' | ||||
|     #empty_date_value = '0000-00-00 00:00:00' | ||||
|     empty_date_value = '1900-01-01 00:00:00' | ||||
| 
 | ||||
|     def get_local_objects(self, host_data=None): | ||||
|         return get_core_members(self.config, self.api, progress=self.progress) | ||||
|  | @ -144,14 +145,14 @@ class MemberImporter(ToCoreAPI): | |||
|             if not self.customer_data_differs(local_data, host_data): | ||||
|                 diffs.remove('customers') | ||||
| 
 | ||||
|         # also the start/end dates should be looked at more closely.  if they | ||||
|         # contain the special '__omit__' value then we won't ever count as diff | ||||
|         if 'startDate' in self.fields and 'startDate' in diffs: | ||||
|             if host_data['startDate'] == '__omit__': | ||||
|                 diffs.remove('startDate') | ||||
|         if 'endDate' in self.fields and 'endDate' in diffs: | ||||
|             if host_data['endDate'] == '__omit__': | ||||
|                 diffs.remove('endDate') | ||||
|         # # also the start/end dates should be looked at more closely.  if they | ||||
|         # # contain the special '__omit__' value then we won't ever count as diff | ||||
|         # if 'startDate' in self.fields and 'startDate' in diffs: | ||||
|         #     if host_data['startDate'] == '__omit__': | ||||
|         #         diffs.remove('startDate') | ||||
|         # if 'endDate' in self.fields and 'endDate' in diffs: | ||||
|         #     if host_data['endDate'] == '__omit__': | ||||
|         #         diffs.remove('endDate') | ||||
| 
 | ||||
|         return diffs | ||||
| 
 | ||||
|  | @ -220,11 +221,11 @@ class MemberImporter(ToCoreAPI): | |||
|             return data | ||||
| 
 | ||||
|         cardNo = data.pop('cardNo') | ||||
|         data = dict(data) | ||||
|         if data.get('startDate') == '__omit__': | ||||
|             data.pop('startDate') | ||||
|         if data.get('endDate') == '__omit__': | ||||
|             data.pop('endDate') | ||||
|         # data = dict(data) | ||||
|         # if data.get('startDate') == '__omit__': | ||||
|         #     data.pop('startDate') | ||||
|         # if data.get('endDate') == '__omit__': | ||||
|         #     data.pop('endDate') | ||||
|         member = self.api.set_member(cardNo, **data) | ||||
|         return member | ||||
| 
 | ||||
|  |  | |||
|  | @ -97,9 +97,9 @@ class MemberImporter(FromRattail, corepos_importing.model.MemberImporter): | |||
|         'firstName', | ||||
|         'lastName', | ||||
|         'accountHolder', | ||||
|         'phone', | ||||
|         'altPhone', | ||||
|         'email', | ||||
|         # 'phone', | ||||
|         # 'altPhone', | ||||
|         # 'email', | ||||
|     ] | ||||
| 
 | ||||
|     def query(self): | ||||
|  | @ -117,23 +117,24 @@ class MemberImporter(FromRattail, corepos_importing.model.MemberImporter): | |||
| 
 | ||||
|         address = customer.addresses[0] if customer.addresses else None | ||||
| 
 | ||||
|         people = [] | ||||
|         for i, person in enumerate(customer.people, 1): | ||||
|             phones = person.phones | ||||
|             phone1 = phones[0] if phones else None | ||||
|             phone2 = phones[1] if len(phones) > 1 else None | ||||
|             email = person.emails[0] if person.emails else None | ||||
|             people.append({ | ||||
|                 'customerID': str(person.corepos_customer_id), | ||||
|         shoppers = [] | ||||
|         for shopper in customer.shoppers: | ||||
|             person = shopper.person | ||||
|             # phones = person.phones | ||||
|             # phone1 = phones[0] if phones else None | ||||
|             # phone2 = phones[1] if len(phones) > 1 else None | ||||
|             # email = person.emails[0] if person.emails else None | ||||
|             shoppers.append({ | ||||
|                 'customerID': str(shopper.corepos_customer_id), | ||||
|                 'firstName': person.first_name, | ||||
|                 'lastName': person.last_name, | ||||
|                 'accountHolder': i == 1, | ||||
|                 'phone': phone1.number if phone1 else '', | ||||
|                 'altPhone': phone2.number if phone2 else '', | ||||
|                 'email': email.address if email else '', | ||||
|                 'accountHolder': shopper.shopper_number == 1, | ||||
|                 # 'phone': phone1.number if phone1 else '', | ||||
|                 # 'altPhone': phone2.number if phone2 else '', | ||||
|                 # 'email': email.address if email else '', | ||||
|             }) | ||||
| 
 | ||||
|         member = customer.only_member(require=False) | ||||
|         member = self.app.get_member(customer) | ||||
|         if member: | ||||
|             if member.joined: | ||||
|                 start_date = member.joined.strftime('%Y-%m-%d 00:00:00') | ||||
|  | @ -144,12 +145,14 @@ class MemberImporter(FromRattail, corepos_importing.model.MemberImporter): | |||
|             else: | ||||
|                 end_date = self.empty_date_value | ||||
|         else: | ||||
|             start_date = '__omit__' | ||||
|             end_date = '__omit__' | ||||
|             # start_date = '__omit__' | ||||
|             # end_date = '__omit__' | ||||
|             start_date = self.empty_date_value | ||||
|             end_date = self.empty_date_value | ||||
| 
 | ||||
|         return { | ||||
|             'cardNo': customer.number, | ||||
|             'customerAccountID': customer.id, | ||||
|             'customerAccountID': str(customer.corepos_account_id or ''), | ||||
|             'addressFirstLine': address.street if address else '', | ||||
|             'addressSecondLine': address.street2 if address else '', | ||||
|             'city': address.city if address else '', | ||||
|  | @ -157,7 +160,7 @@ class MemberImporter(FromRattail, corepos_importing.model.MemberImporter): | |||
|             'zip': address.zipcode if address else '', | ||||
|             'startDate': start_date, | ||||
|             'endDate': end_date, | ||||
|             'customers': people, | ||||
|             'customers': shoppers, | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,51 @@ | |||
| # -*- coding: utf-8; -*- | ||||
| """add CustomerShopper.corepos_customer_id | ||||
| 
 | ||||
| Revision ID: b025df7cf41b | ||||
| Revises: ae74c537ea51 | ||||
| Create Date: 2023-06-10 13:24:40.735959 | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = 'b025df7cf41b' | ||||
| down_revision = 'ae74c537ea51' | ||||
| branch_labels = None | ||||
| depends_on = None | ||||
| 
 | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
| import rattail.db.types | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def upgrade(): | ||||
| 
 | ||||
|     # corepos_customer_shopper | ||||
|     op.create_table('corepos_customer_shopper', | ||||
|                     sa.Column('uuid', sa.String(length=32), nullable=False), | ||||
|                     sa.Column('corepos_customer_id', sa.Integer(), nullable=True), | ||||
|                     sa.ForeignKeyConstraint(['uuid'], ['customer_shopper.uuid'], name='corepos_customer_shopper_fk_shopper'), | ||||
|                     sa.PrimaryKeyConstraint('uuid') | ||||
|                     ) | ||||
|     op.create_table('corepos_customer_shopper_version', | ||||
|                     sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), | ||||
|                     sa.Column('corepos_customer_id', sa.Integer(), autoincrement=False, nullable=True), | ||||
|                     sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), | ||||
|                     sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), | ||||
|                     sa.Column('operation_type', sa.SmallInteger(), nullable=False), | ||||
|                     sa.PrimaryKeyConstraint('uuid', 'transaction_id') | ||||
|                     ) | ||||
|     op.create_index(op.f('ix_corepos_customer_shopper_version_end_transaction_id'), 'corepos_customer_shopper_version', ['end_transaction_id'], unique=False) | ||||
|     op.create_index(op.f('ix_corepos_customer_shopper_version_operation_type'), 'corepos_customer_shopper_version', ['operation_type'], unique=False) | ||||
|     op.create_index(op.f('ix_corepos_customer_shopper_version_transaction_id'), 'corepos_customer_shopper_version', ['transaction_id'], unique=False) | ||||
| 
 | ||||
| 
 | ||||
| def downgrade(): | ||||
| 
 | ||||
|     # corepos_customer_shopper | ||||
|     op.drop_index(op.f('ix_corepos_customer_shopper_version_transaction_id'), table_name='corepos_customer_shopper_version') | ||||
|     op.drop_index(op.f('ix_corepos_customer_shopper_version_operation_type'), table_name='corepos_customer_shopper_version') | ||||
|     op.drop_index(op.f('ix_corepos_customer_shopper_version_end_transaction_id'), table_name='corepos_customer_shopper_version') | ||||
|     op.drop_table('corepos_customer_shopper_version') | ||||
|     op.drop_table('corepos_customer_shopper') | ||||
|  | @ -91,7 +91,8 @@ class CoreCustomer(model.Base): | |||
|             """)) | ||||
| 
 | ||||
|     corepos_account_id = sa.Column(sa.Integer(), nullable=True, doc=""" | ||||
|     ``Customers.customerAccountID`` value for this customer, within CORE-POS. | ||||
|     ``CustomerAccounts.customerAccountID`` value for this customer | ||||
|     account, within CORE-POS. | ||||
|     """) | ||||
| 
 | ||||
|     corepos_card_number = sa.Column(sa.Integer(), nullable=True, doc=""" | ||||
|  | @ -105,6 +106,42 @@ CoreCustomer.make_proxy(model.Customer, '_corepos', 'corepos_account_id') | |||
| CoreCustomer.make_proxy(model.Customer, '_corepos', 'corepos_card_number') | ||||
| 
 | ||||
| 
 | ||||
| class CoreCustomerShopper(model.Base): | ||||
|     """ | ||||
|     CORE-specific extensions to | ||||
|     :class:`~rattail:rattail.db.model.CustomerShopper`. | ||||
|     """ | ||||
|     __tablename__ = 'corepos_customer_shopper' | ||||
|     __table_args__ = ( | ||||
|         sa.ForeignKeyConstraint(['uuid'], ['customer_shopper.uuid'], | ||||
|                                 name='corepos_customer_shopper_fk_shopper'), | ||||
|     ) | ||||
|     __versioned__ = {} | ||||
| 
 | ||||
|     uuid = model.uuid_column(default=None) | ||||
|     shopper = orm.relationship( | ||||
|         model.CustomerShopper, doc=""" | ||||
|         Reference to the actual shopper record, which this one extends. | ||||
|         """, | ||||
|         cascade_backrefs=False, | ||||
|         backref=orm.backref( | ||||
|             '_corepos', doc=""" | ||||
|             Reference to the CORE-POS extension record for this customer. | ||||
|             """, | ||||
|             uselist=False, | ||||
|             cascade='all, delete-orphan', | ||||
|             cascade_backrefs=False)) | ||||
| 
 | ||||
|     corepos_customer_id = sa.Column(sa.Integer(), nullable=True, doc=""" | ||||
|     ``Customers.customerID`` value for this shopper, within CORE-POS. | ||||
|     """) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return str(self.shopper) | ||||
| 
 | ||||
| CoreCustomerShopper.make_proxy(model.CustomerShopper, '_corepos', 'corepos_customer_id') | ||||
| 
 | ||||
| 
 | ||||
| class CoreMember(model.Base): | ||||
|     """ | ||||
|     CORE-specific extensions to :class:`rattail:rattail.db.model.Member`. | ||||
|  |  | |||
|  | @ -62,6 +62,14 @@ class corepos_problems_invalid_person_numbers(ProblemReportEmail): | |||
|         } | ||||
| 
 | ||||
| 
 | ||||
| class rattail_export_corepos_updates(ImporterEmail): | ||||
|     """ | ||||
|     Sent when a Rattail -> CORE-POS API export involves data changes. | ||||
|     """ | ||||
|     handler_spec = 'rattail_corepos.corepos.office.importing.rattail:FromRattailToCore' | ||||
|     abstract = False | ||||
| 
 | ||||
| 
 | ||||
| class rattail_import_corepos_api_updates(ImporterEmail): | ||||
|     """ | ||||
|     Sent when a CORE-POS API -> Rattail import involves data changes. | ||||
|  |  | |||
|  | @ -136,6 +136,7 @@ class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter) | |||
|     key = 'corepos_card_number' | ||||
|     supported_fields = [ | ||||
|         'corepos_card_number', | ||||
|         'corepos_account_id', | ||||
|         'number', | ||||
|         'name', | ||||
|         # 'address_street', | ||||
|  | @ -171,6 +172,7 @@ class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter) | |||
| 
 | ||||
|         return { | ||||
|             'corepos_card_number': card_number, | ||||
|             'corepos_account_id': int(customer['customerAccountID']), | ||||
|             'number': card_number, | ||||
|             'name': normalize_full_name(customer['firstName'], | ||||
|                                         customer['lastName']), | ||||
|  | @ -183,7 +185,7 @@ class CustomerImporter(FromCOREPOSAPI, corepos_importing.model.CustomerImporter) | |||
|         } | ||||
| 
 | ||||
| 
 | ||||
| class CustomerShopperImporter(FromCOREPOSAPI, importing.model.CustomerShopperImporter): | ||||
| class CustomerShopperImporter(FromCOREPOSAPI, corepos_importing.model.CustomerShopperImporter): | ||||
|     """ | ||||
|     Importer for customer shopper data from CORE POS API. | ||||
|     """ | ||||
|  | @ -191,6 +193,7 @@ class CustomerShopperImporter(FromCOREPOSAPI, importing.model.CustomerShopperImp | |||
|     supported_fields = [ | ||||
|         'customer_uuid', | ||||
|         'shopper_number', | ||||
|         'corepos_customer_id', | ||||
|         'first_name', | ||||
|         'last_name', | ||||
|         'display_name', | ||||
|  | @ -281,6 +284,7 @@ class CustomerShopperImporter(FromCOREPOSAPI, importing.model.CustomerShopperImp | |||
|         data = { | ||||
|             'customer_uuid': customer.uuid, | ||||
|             'shopper_number': shopper['shopper_number'], | ||||
|             'corepos_customer_id': int(shopper['customerID']), | ||||
| 
 | ||||
|             'first_name': shopper['firstName'], | ||||
|             'last_name': shopper['lastName'], | ||||
|  |  | |||
|  | @ -64,6 +64,15 @@ class CustomerImporter(importing.model.CustomerImporter): | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
| class CustomerShopperImporter(importing.model.CustomerShopperImporter): | ||||
| 
 | ||||
|     extensions = { | ||||
|         '_corepos': [ | ||||
|             'corepos_customer_id', | ||||
|         ], | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| class MemberImporter(importing.model.MemberImporter): | ||||
| 
 | ||||
|     extensions = { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar