diff --git a/rattail_corepos/importing/corepos/api.py b/rattail_corepos/importing/corepos/api.py index ed94bc0..92837ed 100644 --- a/rattail_corepos/importing/corepos/api.py +++ b/rattail_corepos/importing/corepos/api.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2023 Lance Edgar +# Copyright © 2010-2024 Lance Edgar # # This file is part of Rattail. # @@ -32,9 +32,6 @@ from collections import OrderedDict from sqlalchemy import orm from rattail import importing -from rattail.gpc import GPC -from rattail.time import localtime, make_utc -from rattail.core import get_uuid from rattail.db.util import normalize_full_name from rattail_corepos import importing as corepos_importing from rattail_corepos.corepos.util import get_core_members @@ -68,7 +65,7 @@ class FromCOREPOSToRattail(importing.ToRattailHandler): return importers def get_default_keys(self): - keys = super(FromCOREPOSToRattail, self).get_default_keys() + keys = super().get_default_keys() if 'ProductMovement' in keys: keys.remove('ProductMovement') @@ -410,7 +407,7 @@ class SubdepartmentImporter(FromCOREPOSAPI, corepos_importing.model.Subdepartmen return { 'corepos_number': int(subdepartment['subdept_no']), 'number': int(subdepartment['subdept_no']), - 'name': subdepartment['subdept_name'], + 'name': subdepartment.get('subdept_name'), 'department_number': department_number, } @@ -438,7 +435,7 @@ class VendorImporter(FromCOREPOSAPI, corepos_importing.model.VendorImporter): return { 'corepos_id': int(vendor['vendorID']), 'id': str(vendor['vendorID']), - 'name': vendor['vendorName'], + 'name': vendor.get('vendorName'), 'abbreviation': vendor.get('vendorAbbreviation') or None, 'special_discount': decimal.Decimal(vendor['discountRate']), 'phone_number': vendor.get('phone') or None, @@ -476,7 +473,7 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): ] def setup(self): - super(ProductImporter, self).setup() + super().setup() model = self.model query = self.session.query(model.Product)\ @@ -496,6 +493,8 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): self.progress_loop(cache, self.api.get_vendor_items(), message="Caching CORE Vendor Items") + self.maxval_unit_size = self.app.maxval(model.Product.unit_size) + def get_host_objects(self): return self.api.get_products() @@ -528,7 +527,7 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): product = self.identify_product(corepos_product) if product: return product.uuid - return get_uuid() + return self.app.make_uuid() def get_vendor_items(self, api_product): if hasattr(self, 'vendor_items_by_upc'): @@ -537,8 +536,12 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): return self.api.get_vendor_items(upc=api_product['upc']) def normalize_host_object(self, product): + if 'upc' not in product: + log.warning("CORE-POS product has no UPC: %s", product) + return + try: - upc = GPC(product['upc'], calc_check_digit='upc') + upc = self.app.make_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': @@ -587,9 +590,14 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter): 'size': size_info['size'], 'unit_size': size_info['unit_size'], 'unit_of_measure': size_info['uom_code'], - 'uom_abbreviation': size_info['uom_abbrev'], + 'uom_abbreviation': (size_info['uom_abbrev'] or '').strip() or None, }) + if data['unit_size'] and data['unit_size'] >= self.maxval_unit_size: + log.warning("unit_size too large (%s) for product %s, will use null instead: %s", + data['unit_size'], data['upc'], product) + data['unit_size'] = None + if 'case_size' in self.fields: case_size = None items = self.get_vendor_items(product) @@ -633,8 +641,8 @@ class ProductMovementImporter(FromCOREPOSAPI, corepos_importing.model.ProductImp last_sold = None if 'last_sold' in product: last_sold = datetime.datetime.strptime(product['last_sold'], '%Y-%m-%d %H:%M:%S') - last_sold = localtime(self.config, last_sold) - last_sold = make_utc(last_sold) + last_sold = self.app.localtime(last_sold) + last_sold = self.app.make_utc(last_sold) return { 'corepos_id': int(product['id']), @@ -662,7 +670,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp ] def setup(self): - super(ProductCostImporter, self).setup() + super().setup() model = self.config.get_model() query = self.session.query(model.Vendor)\ @@ -676,7 +684,8 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp self.corepos_products = {} def cache(product, i): - self.corepos_products[product['upc']] = product + if 'upc' in product: + self.corepos_products[product['upc']] = product self.progress_loop(cache, self.api.get_products(), message="Caching Products from CORE-POS API") @@ -881,10 +890,10 @@ class MemberImporter(FromCOREPOSAPI, corepos_importing.model.MemberImporter): if withdrew == datetime.date(1900, 1, 1): withdrew = None - typeno = int(member['customerTypeID']) + typeno = int(member['customerTypeID'] or 0) memtype = self.get_membership_type_by_number(typeno) if not memtype: - log.warning("unknown customerTypeID (membership_type_number) %s for: %s", + log.warning("unknown customerTypeID (membership_type_number) '%s' for: %s", member['customerTypeID'], member) typeno = None