PRICING
This commit is contained in:
@ -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)
|
||||
|
Reference in New Issue
Block a user