This commit is contained in:
2025-04-29 00:00:47 -04:00
parent 56ba750aad
commit c9bba8a26e
25 changed files with 1266 additions and 152052 deletions

View File

@ -2,6 +2,11 @@ from typing import Dict, List, Optional
from app.services.external_api.tcgplayer.base_tcgplayer_service import BaseTCGPlayerService
from sqlalchemy.orm import Session
from app.schemas.file import FileInDB
from app.models.tcgplayer_inventory import TCGPlayerInventory, UnmanagedTCGPlayerInventory
import csv
from app.db.database import transaction
from app.models.inventory_management import MarketplaceListing, InventoryItem, Marketplace
from sqlalchemy import func
class TCGPlayerInventoryService(BaseTCGPlayerService):
def __init__(self):
@ -24,10 +29,101 @@ class TCGPlayerInventoryService(BaseTCGPlayerService):
raise ValueError(f"Invalid export type: {export_type}, must be 'staged', 'live', or 'pricing'")
file_bytes = await self._make_request("GET", endpoint, download_file=True)
return await self.save_file(
return await self.file_service.save_file(
db=db,
file_data=file_bytes,
file_name=f"tcgplayer_{export_type}_export.csv",
filename=f"tcgplayer_{export_type}_export.csv",
subdir="tcgplayer/inventory",
file_type=file_type
)
)
async def refresh_tcgplayer_inventory_table(self, db: Session):
"""
Refresh the TCGPlayer inventory table
"""
export = await self.get_tcgplayer_export(db, "live")
csv_string = await self.file_service.file_in_db_to_csv(db, export)
reader = csv.DictReader(csv_string.splitlines())
# Convert CSV rows to list of dictionaries for bulk insert
inventory_data = []
for row in reader:
if row.get("TCGplayer Id") is None:
continue
inventory_data.append({
"tcgplayer_sku_id": int(row.get("TCGplayer Id")),
"product_line": row.get("Product Line") if row.get("Product Line") else None,
"set_name": row.get("Set Name") if row.get("Set Name") else None,
"product_name": row.get("Product Name") if row.get("Product Name") else None,
"title": row.get("Title") if row.get("Title") else None,
"number": row.get("Number") if row.get("Number") else None,
"rarity": row.get("Rarity") if row.get("Rarity") else None,
"condition": row.get("Condition") if row.get("Condition") else None,
"tcg_market_price": float(row.get("TCG Market Price")) if row.get("TCG Market Price") else None,
"tcg_direct_low": float(row.get("TCG Direct Low")) if row.get("TCG Direct Low") else None,
"tcg_low_price_with_shipping": float(row.get("TCG Low Price With Shipping")) if row.get("TCG Low Price With Shipping") else None,
"tcg_low_price": float(row.get("TCG Low Price")) if row.get("TCG Low Price") else None,
"total_quantity": int(row.get("Total Quantity")) if row.get("Total Quantity") else None,
"add_to_quantity": int(row.get("Add to Quantity")) if row.get("Add to Quantity") else None,
"tcg_marketplace_price": float(row.get("TCG Marketplace Price")) if row.get("TCG Marketplace Price") else None,
"photo_url": row.get("Photo URL") if row.get("Photo URL") else None
})
with transaction(db):
# Bulk insert new data
db.bulk_insert_mappings(TCGPlayerInventory, inventory_data)
async def refresh_unmanaged_tcgplayer_inventory_table(self, db: Session):
"""
Refresh the TCGPlayer unmanaged inventory table
unmanaged inventory is any inventory that cannot be mapped to a card with a marketplace listing
"""
with transaction(db):
# Get active marketplace listings with their physical items in a single query
listed_cards = (
db.query(MarketplaceListing)
.join(MarketplaceListing.inventory_item)
.join(InventoryItem.physical_item)
.filter(
func.lower(Marketplace.name) == func.lower("tcgplayer"),
MarketplaceListing.delisting_date == None,
MarketplaceListing.deleted_at == None,
MarketplaceListing.listing_date != None
)
.all()
)
# Get current inventory and create lookup dict
current_inventory = db.query(TCGPlayerInventory).all()
# Create a set of SKUs that have active listings
listed_skus = {
card.inventory_item.physical_item.tcgplayer_sku_id
for card in listed_cards
}
unmanaged_inventory = []
for inventory in current_inventory:
# Only include SKUs that have no active listings
if inventory.tcgplayer_sku_id not in listed_skus:
unmanaged_inventory.append({
"tcgplayer_inventory_id": inventory.id,
"tcgplayer_sku_id": inventory.tcgplayer_sku_id,
"product_line": inventory.product_line,
"set_name": inventory.set_name,
"product_name": inventory.product_name,
"title": inventory.title,
"number": inventory.number,
"rarity": inventory.rarity,
"condition": inventory.condition,
"tcg_market_price": inventory.tcg_market_price,
"tcg_direct_low": inventory.tcg_direct_low,
"tcg_low_price_with_shipping": inventory.tcg_low_price_with_shipping,
"tcg_low_price": inventory.tcg_low_price,
"total_quantity": inventory.total_quantity,
"add_to_quantity": inventory.add_to_quantity,
"tcg_marketplace_price": inventory.tcg_marketplace_price,
"photo_url": inventory.photo_url
})
db.bulk_insert_mappings(UnmanagedTCGPlayerInventory, unmanaged_inventory)