From 5a5927dce6e045ee6438eae1cc5ccaebf9345600 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 27 Mar 2020 20:50:36 -0500 Subject: [PATCH] Add "low-hanging fruit" fields for Catapult inventory export --- .../db/exporters/catapult_inventory.py | 155 +++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/rattail_corepos/corepos/importing/db/exporters/catapult_inventory.py b/rattail_corepos/corepos/importing/db/exporters/catapult_inventory.py index a80bdea..7c8796e 100644 --- a/rattail_corepos/corepos/importing/db/exporters/catapult_inventory.py +++ b/rattail_corepos/corepos/importing/db/exporters/catapult_inventory.py @@ -30,6 +30,7 @@ from sqlalchemy import orm from corepos.db.office_op import model as corepos +from rattail.gpc import GPC from rattail.util import OrderedDict from rattail.importing.handlers import ToFileHandler from rattail_corepos.corepos.importing.db.corepos import FromCoreHandler, FromCore @@ -65,6 +66,48 @@ class InventoryItemImporter(FromCore, catapult_importing.model.InventoryItemImpo 'brand', 'item_name', 'size', + # 'sugg_retail', + 'last_cost', + 'price_divider', + 'base_price', + # 'disc_mult', + # 'ideal_margin', + 'bottle_deposit', + # 'pos_menu_group', + # 'scale_label', + 'sold_by_ea_or_lb', + 'quantity_required', + # 'weight_profile', + 'tax_1', + 'tax_2', + 'spec_tend_1', + 'spec_tend_2', + # 'age_required', + # 'location', + # 'family_line', + # 'alt_id', + # 'alt_receipt_alias', + # 'alt_pkg_qty', + # 'alt_pkg_price', + # 'auto_discount', + # 'supplier_unit_id', + # 'supplier_id', + # 'unit', + # 'num_pkgs', + # 'cs_pk_multiplier', + # 'dsd', + # 'pf1', + # 'pf2', + # 'pf3', + # 'pf4', + # 'pf5', + # 'pf6', + # 'pf7', + # 'pf8', + # 'memo', + # 'scale_shelf_life', + # 'scale_shelf_life_type', + # 'scale_ingredient_text', ] def query(self): @@ -86,18 +129,128 @@ class InventoryItemImporter(FromCore, catapult_importing.model.InventoryItemImpo item_id, product.uuid, product) return + is_plu = False + if len(str(int(item_id))) < 6: + is_plu = True + item_id = str(int(item_id)) + else: # must add check digit, and re-format + upc = GPC(item_id, calc_check_digit='upc') + item_id = str(upc) + assert len(item_id) == 14 + # drop leading zero(s) + if item_id[1] == '0': # UPC-A + item_id = item_id[2:] + else: # EAN13 + item_id = item_id[1:] + department = product.department if not department: log.warning("item_id %s has no department: %s", item_id, product) return + sold_by_ea_or_lb = None + if is_plu: + sold_by_ea_or_lb = 'LB' if product.scale else 'EA' + + # TODO: need to finish the logic to map/calculate tax rates + tax_1 = 0 + tax_2 = 0 + + # # TODO: should let config drive these somehow, obviously + # tax_rate_ids_1 = (1,) + # tax_rate_ids_2 = (2,) + # tax_component_ids_1 = (1,) + # tax_component_ids_2 = (2,) + + # if product.tax_rate: + + # if product.tax_rate.components: + # for component in product.tax_rate.components: + # if tax_component_ids_1 and component.id in tax_component_ids_1: + # tax_1 += component.rate + # if tax_component_ids_2 and component.id in tax_component_ids_2: + # tax_2 += component.rate + + # else: # no components + # rate = product.tax_rate + # if tax_rate_ids_1 and rate.id in tax_rate_ids_1: + # tax_1 += rate.rate + # if tax_rate_ids_2 and rate.id in tax_rate_ids_2: + # tax_2 += rate.rate + return { 'item_id': item_id, 'dept_id': department.number, 'dept_name': department.name, - 'receipt_alias': None, # TODO + 'receipt_alias': product.description, 'brand': product.brand, 'item_name': product.description, 'size': product.size, + + # TODO: does CORE have this? + # 'sugg_retail': None, + + 'last_cost': product.cost, + 'price_divider': product.quantity or 1, # TODO: is this right? + 'base_price': product.normal_price, + + # TODO: does CORE have these? + # 'disc_mult': None, + # 'ideal_margin': None, + + 'bottle_deposit': product.deposit or None, + + # TODO: does CORE have these? + # 'pos_menu_group': None, + # 'scale_label': None, + + 'sold_by_ea_or_lb': sold_by_ea_or_lb, + 'quantity_required': 'Y' if product.quantity_enforced else None, + + # TODO: does CORE have this? + # 'weight_profile': None, + + 'tax_1': tax_1 or None, # TODO: logic above is unfinished + 'tax_2': tax_2 or None, # TODO: logic above is unfinished + 'spec_tend_1': 'EBT' if product.foodstamp else None, + 'spec_tend_2': 'WIC' if product.wicable else None, + + # TODO: does CORE have these? + # 'age_required': None, + # 'location': None, + # 'family_line': None, + + # TODO: does CORE have these? + # 'alt_id': None, + # 'alt_receipt_alias': None, + # 'alt_pkg_qty': None, + # 'alt_pkg_price': None, + # 'auto_discount': None, + + # TODO: pretty sure CORE has these, but i'm not sure where + # 'supplier_unit_id': None, + # 'supplier_id': None, + # 'unit': None, + # 'num_pkgs': None, + # 'cs_pk_multiplier': None, + + # TODO: does CORE have this? + # 'dsd': None, + + # TODO: are these needed? + # 'pf1', + # 'pf2', + # 'pf3', + # 'pf4', + # 'pf5', + # 'pf6', + # 'pf7', + # 'pf8', + + # TODO: does CORE have these? + # 'memo': None, + # 'scale_shelf_life', + # 'scale_shelf_life_type', + # 'scale_ingredient_text', }