sligro: Keep track of announced substitute products
All checks were successful
Test / pytest (push) Successful in 19s
All checks were successful
Test / pytest (push) Successful in 19s
This commit is contained in:
parent
7a8997835d
commit
9d16212e2e
1 changed files with 52 additions and 12 deletions
|
@ -5,7 +5,14 @@ import logging
|
|||
import scrapers
|
||||
import shlex
|
||||
|
||||
profit_margin = Decimal('1.3')
|
||||
|
||||
def resale_price(prod: scrapers.Product) -> Decimal:
|
||||
profit_margin = Decimal('1.3')
|
||||
|
||||
# Apply profit margin and divide by the number of units per sold packaging.
|
||||
unit_price = prod.price * profit_margin / prod.units
|
||||
# Round up to 5ct.
|
||||
return (unit_price * 20).quantize(Decimal('1'), rounding=ROUND_UP) / 20
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -42,6 +49,15 @@ class Product:
|
|||
metadata=metadata,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_scraper(prod: scrapers.Product):
|
||||
return Product(
|
||||
aliases=[prod.gtin, *sorted(prod.aliases)],
|
||||
price=resale_price(prod),
|
||||
description=prod.name,
|
||||
metadata={},
|
||||
)
|
||||
|
||||
def format_line(self):
|
||||
aliases = ','.join(self.aliases)
|
||||
price = f'{self.price:.2f}'
|
||||
|
@ -83,36 +99,60 @@ def update_product_pricings(src):
|
|||
|
||||
try:
|
||||
prod_info = find_product_details(product)
|
||||
|
||||
except NoAutoUpdate:
|
||||
logging.debug('no auto update: "%s"', product.description)
|
||||
lines_out.append(line)
|
||||
continue
|
||||
|
||||
except scrapers.ProductNotFoundError:
|
||||
logging.warn('not found "%s"', product.description)
|
||||
product.metadata['err'] = 'not_found'
|
||||
# If this product was not found and has a substitute reference in its metadata, clear the scraping trigger.
|
||||
if 'sub' in product.metadata and 'sligro' in product.metadata:
|
||||
del product.metadata['sligro']
|
||||
logging.info('"%s" is EOL', product.description)
|
||||
else:
|
||||
logging.warn('not found "%s"', product.description)
|
||||
lines_out.append(product.format_line())
|
||||
continue
|
||||
|
||||
except Exception as err:
|
||||
logging.error('did not update "%s": %s', product.description, err)
|
||||
lines_out.append(line)
|
||||
continue
|
||||
|
||||
aliases = sorted(set(product.aliases) - {prod_info.gtin})
|
||||
product.aliases = [prod_info.gtin, *aliases]
|
||||
new_product = Product.from_scraper(prod_info)
|
||||
|
||||
# Apply profit margin and divide by the number of units per sold packaging.
|
||||
unit_price = prod_info.price * profit_margin / prod_info.units
|
||||
# Round up to 5ct.
|
||||
product.description = new_product.description
|
||||
logging.debug(f'Found "{new_product.description}", buy €{prod_info.price/prod_info.units:.2f}, sell €{new_product.price:.2f}')
|
||||
|
||||
# Merge any new aliases, keeping the gtin first.
|
||||
product.aliases = [
|
||||
prod_info.gtin,
|
||||
*sorted((set(product.aliases) | set(new_product.aliases)) - {prod_info.gtin})
|
||||
]
|
||||
# Adjust the price.
|
||||
previous_price = product.price
|
||||
product.price = (unit_price * 20).quantize(Decimal('1'), rounding=ROUND_UP) / 20
|
||||
|
||||
product.price = new_product.price
|
||||
if product.price != previous_price:
|
||||
logging.info(f'Adjusted "{product.description}", €{previous_price:.2f} -> €{product.price:.2f}')
|
||||
# If this product had an error set for any reason, clear it.
|
||||
if 'err' in product.metadata:
|
||||
del product.metadata['err']
|
||||
|
||||
# If this product is being substituted by another product, leave a reference.
|
||||
# This will also help us determine whether the substitute has been rewritten already.
|
||||
substitute_product = None
|
||||
if prod_info.replacement is not None:
|
||||
if 'sub' not in product.metadata:
|
||||
substitute_product = Product.from_scraper(prod_info.replacement)
|
||||
substitute_product.metadata['sligro'] = None
|
||||
product.metadata['sub'] = prod_info.replacement.gtin
|
||||
|
||||
lines_out.append(product.format_line())
|
||||
|
||||
logging.debug(f'Found "{prod_info.name}", buy €{prod_info.price/prod_info.units:.2f}, sell €{product.price:.2f}')
|
||||
if product.price != previous_price:
|
||||
logging.info(f'Adjusted "{prod_info.name}", €{previous_price:.2f} -> €{product.price:.2f}')
|
||||
if substitute_product is not None:
|
||||
lines_out.append(substitute_product.format_line())
|
||||
logging.info(f'Found replacement of "{product.description}": {substitute_product.aliases[0]}')
|
||||
|
||||
return '\n'.join(lines_out)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue