from typing import List, Dict import pandas as pd from datetime import datetime from pathlib import Path from jinja2 import Environment, FileSystemLoader from weasyprint import HTML import logging logger = logging.getLogger(__name__) class PullSheetService: def __init__(self): self.template_dir = Path("app/data/assets/templates") self.env = Environment(loader=FileSystemLoader(str(self.template_dir))) self.template = self.env.get_template("pull_sheet.html") self.output_dir = Path("app/data/cache/tcgplayer/pull_sheets") self.output_dir.mkdir(parents=True, exist_ok=True) def generate_pull_sheet_pdf(self, csv_path: str) -> str: """Generate a PDF pull sheet from a CSV file. Args: csv_path: Path to the CSV file containing pull sheet data Returns: Path to the generated PDF file """ try: # Read and process CSV data items = self._read_and_process_csv(csv_path) # Prepare template data template_data = { 'items': items, 'generation_date': datetime.now().strftime("%Y-%m-%d %H:%M:%S") } # Render HTML html_content = self.template.render(**template_data) # Generate PDF pdf_path = self.output_dir / f"pull_sheet_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" HTML(string=html_content).write_pdf(str(pdf_path)) return str(pdf_path) except Exception as e: logger.error(f"Error generating pull sheet PDF: {str(e)}") raise def _read_and_process_csv(self, csv_path: str) -> List[Dict]: """Read and process CSV data using pandas. Args: csv_path: Path to the CSV file Returns: List of processed items """ # Read CSV into pandas DataFrame df = pd.read_csv(csv_path) # Filter out the "Orders Contained in Pull Sheet" row df = df[df['Product Line'] != 'Orders Contained in Pull Sheet:'] # Convert Set Release Date to datetime df['Set Release Date'] = pd.to_datetime(df['Set Release Date'], format='%m/%d/%Y %H:%M:%S') # Sort by Set Release Date (descending) and then Product Name (ascending) df = df.sort_values(['Set Release Date', 'Product Name'], ascending=[False, True]) # Convert to list of dictionaries items = [] for _, row in df.iterrows(): items.append({ 'product_name': row['Product Name'], 'condition': row['Condition'], 'quantity': str(int(row['Quantity'])), # Convert to string for template 'set': row['Set'], 'rarity': row['Rarity'] }) return items