fix: improve ProductCost sorting for import from CORE API
this hopefully ensures a more consistent preference order, fewer diffs
This commit is contained in:
parent
eb9a1ae4f0
commit
2f22be6e7e
|
@ -655,9 +655,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
"""
|
"""
|
||||||
Importer for product cost data from CORE POS API.
|
Importer for product cost data from CORE POS API.
|
||||||
"""
|
"""
|
||||||
# TODO: should change key after live sites are updated
|
key = ('corepos_vendor_id', 'corepos_sku')
|
||||||
key = ('vendor_uuid', 'code')
|
|
||||||
# key = ('corepos_vendor_id', 'corepos_sku')
|
|
||||||
supported_fields = [
|
supported_fields = [
|
||||||
'corepos_vendor_id',
|
'corepos_vendor_id',
|
||||||
'corepos_sku',
|
'corepos_sku',
|
||||||
|
@ -696,7 +694,63 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
key='item_id')
|
key='item_id')
|
||||||
|
|
||||||
def get_host_objects(self):
|
def get_host_objects(self):
|
||||||
return self.api.get_vendor_items()
|
|
||||||
|
# first we will cache API products by upc
|
||||||
|
products = OrderedDict()
|
||||||
|
|
||||||
|
def cache(product, i):
|
||||||
|
if product.get('upc'):
|
||||||
|
products[product['upc']] = product
|
||||||
|
|
||||||
|
self.progress_loop(cache, self.api.get_products(),
|
||||||
|
message="Caching product data from CORE")
|
||||||
|
|
||||||
|
# next we cache API vendor items, also by upc
|
||||||
|
vendor_items = {}
|
||||||
|
|
||||||
|
def cache(item, i):
|
||||||
|
if not item['upc']:
|
||||||
|
log.warning("CORE vendor item has no upc: %s", item)
|
||||||
|
return
|
||||||
|
if item['vendorID'] == '0':
|
||||||
|
log.warning("CORE vendor item has no vendorID: %s", item)
|
||||||
|
return
|
||||||
|
vendor_items.setdefault(item['upc'], []).append(item)
|
||||||
|
|
||||||
|
self.progress_loop(cache, self.api.get_vendor_items(),
|
||||||
|
message="Caching vendor item data from CORE")
|
||||||
|
|
||||||
|
# now we must "sort" the vendor items for each upc. to do
|
||||||
|
# this we just ensure the item for default vendor is first
|
||||||
|
|
||||||
|
def organize(upc, i):
|
||||||
|
product = products.get(upc)
|
||||||
|
if not product:
|
||||||
|
return # product not found
|
||||||
|
|
||||||
|
vendor_id = product['default_vendor_id']
|
||||||
|
if not vendor_id:
|
||||||
|
return # product has no default vendor
|
||||||
|
|
||||||
|
items = vendor_items[upc]
|
||||||
|
for item in items:
|
||||||
|
if item['vendorID'] == vendor_id:
|
||||||
|
# found the default vendor item
|
||||||
|
j = items.index(item)
|
||||||
|
if j != 0:
|
||||||
|
# it was not first; make it so
|
||||||
|
items.pop(j)
|
||||||
|
items.insert(0, item)
|
||||||
|
break
|
||||||
|
|
||||||
|
self.progress_loop(organize, list(vendor_items),
|
||||||
|
message="Sorting items by default vendor")
|
||||||
|
|
||||||
|
# keep the vendor item cache for reference later
|
||||||
|
self.api_vendor_items = vendor_items
|
||||||
|
|
||||||
|
# host objects are the API products (in original sequence)
|
||||||
|
return list(products.values())
|
||||||
|
|
||||||
def get_vendor(self, item):
|
def get_vendor(self, item):
|
||||||
corepos_id = int(item['vendorID'])
|
corepos_id = int(item['vendorID'])
|
||||||
|
@ -733,6 +787,31 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
except orm.exc.NoResultFound:
|
except orm.exc.NoResultFound:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def normalize_host_data(self, host_objects=None):
|
||||||
|
|
||||||
|
# TODO: this all seems a bit hacky but works for now..
|
||||||
|
# could even be we don't need this method?
|
||||||
|
|
||||||
|
if host_objects is None:
|
||||||
|
host_objects = self.get_host_objects()
|
||||||
|
normalized = []
|
||||||
|
self.sorted_vendor_items = {}
|
||||||
|
|
||||||
|
def normalize(product, i):
|
||||||
|
if not product.get('upc'):
|
||||||
|
log.warning("product has no upc: %s", product)
|
||||||
|
return
|
||||||
|
items = self.sort_vendor_items(product)
|
||||||
|
self.sorted_vendor_items[product['upc']] = items
|
||||||
|
for item in items:
|
||||||
|
data = self.normalize_host_object(item)
|
||||||
|
if data:
|
||||||
|
normalized.append(data)
|
||||||
|
|
||||||
|
self.progress_loop(normalize, host_objects,
|
||||||
|
message=f"Reading Product data from {self.host_system_title}")
|
||||||
|
return normalized
|
||||||
|
|
||||||
def normalize_host_object(self, item):
|
def normalize_host_object(self, item):
|
||||||
vendor = self.get_vendor(item)
|
vendor = self.get_vendor(item)
|
||||||
if not vendor:
|
if not vendor:
|
||||||
|
@ -752,10 +831,6 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
# log.warning("CORE POS product not found for item: %s", item)
|
# log.warning("CORE POS product not found for item: %s", item)
|
||||||
# return
|
# return
|
||||||
|
|
||||||
preferred = False
|
|
||||||
if core_product and core_product['default_vendor_id'] == item['vendorID']:
|
|
||||||
preferred = True
|
|
||||||
|
|
||||||
case_size = decimal.Decimal(item['units'])
|
case_size = decimal.Decimal(item['units'])
|
||||||
unit_cost = item.get('cost')
|
unit_cost = item.get('cost')
|
||||||
if unit_cost is not None:
|
if unit_cost is not None:
|
||||||
|
@ -764,7 +839,7 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
if unit_cost is not None:
|
if unit_cost is not None:
|
||||||
case_cost = unit_cost * case_size
|
case_cost = unit_cost * case_size
|
||||||
|
|
||||||
return {
|
data = {
|
||||||
'corepos_vendor_id': int(item['vendorID']),
|
'corepos_vendor_id': int(item['vendorID']),
|
||||||
'corepos_sku': item['sku'],
|
'corepos_sku': item['sku'],
|
||||||
'product_uuid': product.uuid,
|
'product_uuid': product.uuid,
|
||||||
|
@ -773,9 +848,35 @@ class ProductCostImporter(FromCOREPOSAPI, corepos_importing.model.ProductCostImp
|
||||||
'case_size': case_size,
|
'case_size': case_size,
|
||||||
'case_cost': case_cost,
|
'case_cost': case_cost,
|
||||||
'unit_cost': unit_cost,
|
'unit_cost': unit_cost,
|
||||||
'preferred': preferred,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.fields_active(['preference', 'preferred']):
|
||||||
|
items = self.get_sorted_vendor_items(item)
|
||||||
|
i = items.index(item)
|
||||||
|
data['preference'] = i + 1
|
||||||
|
data['preferred'] = i == 0
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_sorted_vendor_items(self, item):
|
||||||
|
if hasattr(self, 'sorted_vendor_items'):
|
||||||
|
return self.sorted_vendor_items.get(item['upc'])
|
||||||
|
|
||||||
|
product = self.api.get_product(item['upc'])
|
||||||
|
return self.sort_vendor_items(product)
|
||||||
|
|
||||||
|
def sort_vendor_items(self, product):
|
||||||
|
|
||||||
|
# TODO: this all seems a bit hacky but works for now..
|
||||||
|
|
||||||
|
if not product.get('upc'):
|
||||||
|
return []
|
||||||
|
|
||||||
|
if hasattr(self, 'api_vendor_items'):
|
||||||
|
return self.api_vendor_items.get(product['upc'], [])
|
||||||
|
|
||||||
|
raise NotImplementedError("must add real-time datasync support")
|
||||||
|
|
||||||
|
|
||||||
class MembershipTypeImporter(FromCOREPOSAPI, importing.model.MembershipTypeImporter):
|
class MembershipTypeImporter(FromCOREPOSAPI, importing.model.MembershipTypeImporter):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue