Add support for importing full size, uom data from CORE
also add core-specific product handler and mixin, to find all UOM abbreviations in the wild.
This commit is contained in:
parent
10c119ea60
commit
2faa0cb18b
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2020 Lance Edgar
|
# Copyright © 2010-2021 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -441,6 +441,9 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
||||||
'upc',
|
'upc',
|
||||||
'brand_name',
|
'brand_name',
|
||||||
'description',
|
'description',
|
||||||
|
'unit_size',
|
||||||
|
'unit_of_measure',
|
||||||
|
'uom_abbreviation',
|
||||||
'size',
|
'size',
|
||||||
'weighed',
|
'weighed',
|
||||||
'department_number',
|
'department_number',
|
||||||
|
@ -455,7 +458,7 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
super(ProductImporter, self).setup()
|
super(ProductImporter, self).setup()
|
||||||
model = self.config.get_model()
|
model = self.model
|
||||||
|
|
||||||
query = self.session.query(model.Product)\
|
query = self.session.query(model.Product)\
|
||||||
.join(model.CoreProduct)\
|
.join(model.CoreProduct)\
|
||||||
|
@ -519,14 +522,13 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
||||||
if product.get('normal_price') is not None:
|
if product.get('normal_price') is not None:
|
||||||
price = decimal.Decimal(product['normal_price'])
|
price = decimal.Decimal(product['normal_price'])
|
||||||
|
|
||||||
return {
|
data = {
|
||||||
'uuid': self.identify_product_uuid(product),
|
'uuid': self.identify_product_uuid(product),
|
||||||
'corepos_id': int(product['id']),
|
'corepos_id': int(product['id']),
|
||||||
'item_id': product['upc'],
|
'item_id': product['upc'],
|
||||||
'upc': upc,
|
'upc': upc,
|
||||||
'brand_name': product.get('brand') or None,
|
'brand_name': product.get('brand') or None,
|
||||||
'description': product.get('description') or '',
|
'description': product.get('description') or '',
|
||||||
'size': product.get('size', '').strip() or None,
|
|
||||||
|
|
||||||
'department_number': department_number,
|
'department_number': department_number,
|
||||||
'subdepartment_number': subdepartment_number,
|
'subdepartment_number': subdepartment_number,
|
||||||
|
@ -541,6 +543,17 @@ class ProductImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
||||||
'regular_price_type': self.enum.PRICE_TYPE_REGULAR if price is not None else None,
|
'regular_price_type': self.enum.PRICE_TYPE_REGULAR if price is not None else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.fields_active(self.size_fields):
|
||||||
|
size_info = self.normalize_size_info(product)
|
||||||
|
data.update({
|
||||||
|
'size': size_info['size'],
|
||||||
|
'unit_size': size_info['unit_size'],
|
||||||
|
'unit_of_measure': size_info['uom_code'],
|
||||||
|
'uom_abbreviation': size_info['uom_abbrev'],
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class ProductMovementImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
class ProductMovementImporter(FromCOREPOSAPI, corepos_importing.model.ProductImporter):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2020 Lance Edgar
|
# Copyright © 2010-2021 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -170,6 +170,9 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
|
||||||
'brand_name',
|
'brand_name',
|
||||||
'description',
|
'description',
|
||||||
'size',
|
'size',
|
||||||
|
'unit_size',
|
||||||
|
'unit_of_measure',
|
||||||
|
'uom_abbreviation',
|
||||||
'weighed',
|
'weighed',
|
||||||
'department_number',
|
'department_number',
|
||||||
'subdepartment_number',
|
'subdepartment_number',
|
||||||
|
@ -194,13 +197,12 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
|
||||||
if product.normal_price is not None:
|
if product.normal_price is not None:
|
||||||
price = decimal.Decimal('{:03f}'.format(product.normal_price))
|
price = decimal.Decimal('{:03f}'.format(product.normal_price))
|
||||||
|
|
||||||
return {
|
data = {
|
||||||
'corepos_id': product.id,
|
'corepos_id': product.id,
|
||||||
'item_id': product.upc,
|
'item_id': product.upc,
|
||||||
'upc': upc,
|
'upc': upc,
|
||||||
'brand_name': (product.brand or '').strip() or None,
|
'brand_name': (product.brand or '').strip() or None,
|
||||||
'description': (product.description or '').strip(),
|
'description': (product.description or '').strip(),
|
||||||
'size': (product.size or '').strip() or None,
|
|
||||||
|
|
||||||
'department_number': product.department_number or None,
|
'department_number': product.department_number or None,
|
||||||
'subdepartment_number': product.subdepartment_number or None,
|
'subdepartment_number': product.subdepartment_number or None,
|
||||||
|
@ -213,3 +215,14 @@ class ProductImporter(FromCOREPOS, corepos_importing.model.ProductImporter):
|
||||||
'regular_price_multiple': 1 if price is not None else None,
|
'regular_price_multiple': 1 if price is not None else None,
|
||||||
'regular_price_type': self.enum.PRICE_TYPE_REGULAR if price is not None else None,
|
'regular_price_type': self.enum.PRICE_TYPE_REGULAR if price is not None else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.fields_active(self.size_fields):
|
||||||
|
size_info = self.normalize_size_info(product)
|
||||||
|
data.update({
|
||||||
|
'size': size_info['size'],
|
||||||
|
'unit_size': size_info['unit_size'],
|
||||||
|
'unit_of_measure': size_info['uom_code'],
|
||||||
|
'uom_abbreviation': size_info['uom_abbrev'],
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2020 Lance Edgar
|
# Copyright © 2010-2021 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -24,7 +24,10 @@
|
||||||
Rattail model importer extensions, for CORE-POS integration
|
Rattail model importer extensions, for CORE-POS integration
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import decimal
|
||||||
|
|
||||||
from rattail import importing
|
from rattail import importing
|
||||||
|
from rattail.util import pretty_quantity
|
||||||
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
|
@ -97,6 +100,14 @@ class ProductImporter(importing.model.ProductImporter):
|
||||||
'corepos_id',
|
'corepos_id',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
super(ProductImporter, self).setup()
|
||||||
|
|
||||||
|
if self.fields_active(self.size_fields):
|
||||||
|
app = self.config.get_app()
|
||||||
|
handler = app.get_products_handler()
|
||||||
|
self.uoms = handler.get_uom_sil_codes(self.session, uppercase=True)
|
||||||
|
|
||||||
def cache_query(self):
|
def cache_query(self):
|
||||||
query = super(ProductImporter, self).cache_query()
|
query = super(ProductImporter, self).cache_query()
|
||||||
model = self.config.get_model()
|
model = self.config.get_model()
|
||||||
|
@ -108,6 +119,51 @@ class ProductImporter(importing.model.ProductImporter):
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
def get_uom_code(self, uom):
|
||||||
|
if hasattr(self, 'uoms'):
|
||||||
|
return self.uoms.get(uom.upper())
|
||||||
|
|
||||||
|
app = self.config.get_app()
|
||||||
|
handler = app.get_products_handler()
|
||||||
|
return handler.get_uom_sil_code(self.session, uom.upper())
|
||||||
|
|
||||||
|
def normalize_size_info(self, core_product):
|
||||||
|
|
||||||
|
# convert product to dict if needed
|
||||||
|
if isinstance(core_product, dict):
|
||||||
|
core_data = core_product
|
||||||
|
else:
|
||||||
|
core_data = {
|
||||||
|
'size': core_product.size,
|
||||||
|
'unitofmeasure': core_product.unit_of_measure,
|
||||||
|
}
|
||||||
|
|
||||||
|
unit_size = None
|
||||||
|
if 'size' in core_data and core_data['size'] is not None:
|
||||||
|
unit_size = decimal.Decimal(core_data['size'])
|
||||||
|
|
||||||
|
uom_abbrev = core_data.get('unitofmeasure')
|
||||||
|
|
||||||
|
uom_code = self.enum.UNIT_OF_MEASURE_NONE
|
||||||
|
if uom_abbrev is not None:
|
||||||
|
uom_code = self.get_uom_code(uom_abbrev) or self.enum.UNIT_OF_MEASURE_NONE
|
||||||
|
|
||||||
|
if unit_size is not None and uom_abbrev is not None:
|
||||||
|
size = "{} {}".format(pretty_quantity(unit_size), uom_abbrev)
|
||||||
|
elif unit_size is not None:
|
||||||
|
size = pretty_quantity(unit_size)
|
||||||
|
elif uom_abbrev is not None:
|
||||||
|
size = uom_abbrev
|
||||||
|
else:
|
||||||
|
size = None
|
||||||
|
|
||||||
|
return {
|
||||||
|
'size': size,
|
||||||
|
'unit_size': unit_size,
|
||||||
|
'uom_abbrev': uom_abbrev,
|
||||||
|
'uom_code': uom_code,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ProductCostImporter(importing.model.ProductCostImporter):
|
class ProductCostImporter(importing.model.ProductCostImporter):
|
||||||
|
|
||||||
|
|
57
rattail_corepos/products.py
Normal file
57
rattail_corepos/products.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Rattail -- Retail Software Framework
|
||||||
|
# Copyright © 2010-2021 Lance Edgar
|
||||||
|
#
|
||||||
|
# This file is part of Rattail.
|
||||||
|
#
|
||||||
|
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
"""
|
||||||
|
Products Handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
from corepos.db.office_op import Session as CoreSession
|
||||||
|
|
||||||
|
from rattail import products as base
|
||||||
|
|
||||||
|
|
||||||
|
class CoreProductsHandlerMixin(object):
|
||||||
|
"""
|
||||||
|
Products handler mixin for CORE-POS integration
|
||||||
|
"""
|
||||||
|
|
||||||
|
def find_wild_uoms_in_corepos(self, session, **kwargs):
|
||||||
|
core_session = CoreSession()
|
||||||
|
|
||||||
|
wild_uoms = core_session.execute("""
|
||||||
|
SELECT DISTINCT UPPER(TRIM(unitofmeasure))
|
||||||
|
FROM products
|
||||||
|
WHERE unitofmeasure IS NOT NULL AND TRIM(unitofmeasure) != ''
|
||||||
|
ORDER BY 1
|
||||||
|
""").fetchall()
|
||||||
|
|
||||||
|
core_session.close()
|
||||||
|
return [row[0] for row in wild_uoms]
|
||||||
|
|
||||||
|
|
||||||
|
class CoreProductsHandler(base.ProductsHandler, CoreProductsHandlerMixin):
|
||||||
|
"""
|
||||||
|
Custom products handler for use with CORE-POS.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def find_wild_uoms(self, session, **kwargs):
|
||||||
|
return self.find_wild_uoms_in_corepos(session, **kwargs)
|
Loading…
Reference in a new issue