""" Vendors API Router Endpoints for managing suppliers and vendors """ from fastapi import APIRouter, HTTPException, Query from typing import List, Optional from app.models.schemas import Vendor, VendorCreate, VendorUpdate from app.core.database import execute_query import logging logger = logging.getLogger(__name__) router = APIRouter() @router.get("/vendors", response_model=List[Vendor], tags=["Vendors"]) async def list_vendors( search: Optional[str] = Query(None, description="Search by name, CVR, or domain"), category: Optional[str] = Query(None, description="Filter by category"), is_active: Optional[bool] = Query(None, description="Filter by active status"), skip: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=100) ): """Get list of vendors with optional filtering""" query = "SELECT * FROM vendors WHERE 1=1" params = [] if search: query += " AND (name ILIKE %s OR cvr_number ILIKE %s OR domain ILIKE %s)" search_param = f"%{search}%" params.extend([search_param, search_param, search_param]) if category: query += " AND category = %s" params.append(category) if is_active is not None: query += " AND is_active = %s" params.append(is_active) query += " ORDER BY name LIMIT %s OFFSET %s" params.extend([limit, skip]) result = execute_query(query, tuple(params)) return result or [] @router.get("/vendors/{vendor_id}", response_model=Vendor, tags=["Vendors"]) async def get_vendor(vendor_id: int): """Get vendor by ID""" query = "SELECT * FROM vendors WHERE id = %s" result = execute_query(query, (vendor_id,)) if not result or len(result) == 0: raise HTTPException(status_code=404, detail="Vendor not found") return result[0] @router.post("/vendors", response_model=Vendor, tags=["Vendors"]) async def create_vendor(vendor: VendorCreate): """Create a new vendor""" try: query = """ INSERT INTO vendors ( name, cvr_number, email, phone, address, postal_code, city, website, domain, email_pattern, category, priority, notes, is_active ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING * """ params = ( vendor.name, vendor.cvr_number, vendor.email, vendor.phone, vendor.address, vendor.postal_code, vendor.city, vendor.website, vendor.domain, vendor.email_pattern, vendor.category, vendor.priority, vendor.notes, vendor.is_active ) result = execute_query(query, params) if not result or len(result) == 0: raise HTTPException(status_code=500, detail="Failed to create vendor") logger.info(f"✅ Created vendor: {vendor.name}") return result[0] except Exception as e: logger.error(f"❌ Error creating vendor: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.put("/vendors/{vendor_id}", response_model=Vendor, tags=["Vendors"]) async def update_vendor(vendor_id: int, vendor: VendorUpdate): """Update an existing vendor""" # Check if vendor exists existing = execute_query("SELECT id FROM vendors WHERE id = %s", (vendor_id,)) if not existing: raise HTTPException(status_code=404, detail="Vendor not found") # Build update query update_fields = [] params = [] if vendor.name is not None: update_fields.append("name = %s") params.append(vendor.name) if vendor.cvr_number is not None: update_fields.append("cvr_number = %s") params.append(vendor.cvr_number) if vendor.email is not None: update_fields.append("email = %s") params.append(vendor.email) if vendor.phone is not None: update_fields.append("phone = %s") params.append(vendor.phone) if vendor.address is not None: update_fields.append("address = %s") params.append(vendor.address) if vendor.postal_code is not None: update_fields.append("postal_code = %s") params.append(vendor.postal_code) if vendor.city is not None: update_fields.append("city = %s") params.append(vendor.city) if vendor.website is not None: update_fields.append("website = %s") params.append(vendor.website) if vendor.domain is not None: update_fields.append("domain = %s") params.append(vendor.domain) if vendor.email_pattern is not None: update_fields.append("email_pattern = %s") params.append(vendor.email_pattern) if vendor.category is not None: update_fields.append("category = %s") params.append(vendor.category) if vendor.priority is not None: update_fields.append("priority = %s") params.append(vendor.priority) if vendor.notes is not None: update_fields.append("notes = %s") params.append(vendor.notes) if vendor.is_active is not None: update_fields.append("is_active = %s") params.append(vendor.is_active) if not update_fields: raise HTTPException(status_code=400, detail="No fields to update") params.append(vendor_id) query = f"UPDATE vendors SET {', '.join(update_fields)} WHERE id = %s RETURNING *" try: result = execute_query(query, tuple(params)) if not result: raise HTTPException(status_code=500, detail="Failed to update vendor") logger.info(f"✅ Updated vendor: {vendor_id}") return result[0] except Exception as e: logger.error(f"❌ Error updating vendor: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.delete("/vendors/{vendor_id}", tags=["Vendors"]) async def delete_vendor(vendor_id: int): """Soft delete a vendor (set is_active = false)""" query = "UPDATE vendors SET is_active = false WHERE id = %s RETURNING id" result = execute_query(query, (vendor_id,)) if not result: raise HTTPException(status_code=404, detail="Vendor not found") logger.info(f"✅ Deleted vendor: {vendor_id}") return {"message": "Vendor deleted successfully"}