api pricing

This commit is contained in:
2025-02-27 12:37:02 -05:00
parent e13b871fda
commit da492180b4
8 changed files with 326 additions and 37 deletions

View File

@@ -1,11 +1,12 @@
from sqlalchemy.orm import Session
from app.db.models import File, CardTCGPlayer, Price
from app.db.models import File, CardTCGPlayer, Price, TCGPlayerInventory
from app.services.util._dataframe import TCGPlayerPricingRow, DataframeUtil
from app.services.file import FileService
from app.services.tcgplayer import TCGPlayerService
from uuid import uuid4
from app.db.utils import db_transaction
from typing import List, Dict
from decimal import Decimal, ROUND_HALF_UP
import pandas as pd
import logging
@@ -115,34 +116,44 @@ class PricingService:
def default_pricing_algo(self, row: pd.Series) -> pd.Series:
"""Default pricing algorithm with complex pricing rules"""
tcg_low = row.get('tcg_low_price')
tcg_low_shipping = row.get('tcg_low_price_with_shipping')
tcg_market_price = row.get('tcg_market_price')
if pd.isna(tcg_low) or pd.isna(tcg_low_shipping):
# Convert input values to Decimal for precise arithmetic
tcg_low = Decimal(str(row.get('tcg_low_price'))) if not pd.isna(row.get('tcg_low_price')) else None
tcg_low_shipping = Decimal(str(row.get('tcg_low_price_with_shipping'))) if not pd.isna(row.get('tcg_low_price_with_shipping')) else None
tcg_market_price = Decimal(str(row.get('tcg_market_price'))) if not pd.isna(row.get('tcg_market_price')) else None
if tcg_low is None or tcg_low_shipping is None:
logger.warning(f"Missing pricing data for row: {row}")
row['new_price'] = None
return row
# Apply pricing rules
if tcg_market_price < 1 and tcg_market_price > 0.25:
new_price = tcg_market_price * 1.05
elif tcg_market_price < 0.25:
new_price = 0.25
elif tcg_low < 5 or tcg_low_shipping < 5:
new_price = round(tcg_low+((abs(tcg_market_price-tcg_low))*.75), 2)
elif tcg_low_shipping > 20:
new_price = round(tcg_low_shipping * 1.0125, 2)
else:
# new_price = round(tcg_low_shipping * 1.08, 2)
new_price = round(tcg_market_price * 1.03)
# if new price is less than half of market price, set to 90% market
if new_price < (tcg_market_price / 2):
new_price = round(tcg_market_price * 0.85, 2)
if new_price < 0.25:
new_price = 0.25
# Define precision for rounding
TWO_PLACES = Decimal('0.01')
row['new_price'] = new_price
# Apply pricing rules
if tcg_market_price < Decimal('1') and tcg_market_price > Decimal('0.25'):
new_price = tcg_market_price * Decimal('1.05')
elif tcg_market_price < Decimal('0.25'):
new_price = Decimal('0.25')
elif tcg_low < Decimal('5') or tcg_low_shipping < Decimal('5'):
new_price = tcg_low + ((abs(tcg_market_price - tcg_low)) * Decimal('0.75'))
elif tcg_low_shipping > Decimal('20'):
new_price = tcg_low_shipping * Decimal('1.0125')
else:
new_price = tcg_market_price * Decimal('1.03')
# if new price is less than half of market price, set to 90% market
if new_price < (tcg_market_price / Decimal('2')):
new_price = tcg_market_price * Decimal('0.85')
if new_price < Decimal('0.25'):
new_price = Decimal('0.25')
# Ensure exactly 2 decimal places
new_price = new_price.quantize(TWO_PLACES, rounding=ROUND_HALF_UP)
# Convert back to float or string as needed for your dataframe
row['new_price'] = float(new_price)
return row
def apply_pricing_algo(self, row: pd.Series, pricing_algo: callable = None) -> pd.Series:
@@ -218,6 +229,19 @@ class PricingService:
# Now do your column selection
df = df[desired_columns]
if update_type == 'update':
with db_transaction(self.db):
self.db.query(TCGPlayerInventory).delete()
self.db.flush()
# copy df to modify before inserting
df_copy = df.copy()
df_copy['id'] = df_copy.apply(lambda x: str(uuid4()), axis=1)
# rename columns lowercase no space
df_copy.columns = df_copy.columns.str.lower().str.replace(' ', '_')
for index, row in df_copy.iterrows():
tcgplayer_inventory = TCGPlayerInventory(**row.to_dict())
self.db.add(tcgplayer_inventory)
# remove any rows with no price
#df = df[df['TCG Marketplace Price'] != 0]
#df = df[df['TCG Marketplace Price'].notna()]