## File: app/schemas.py (or your equivalent path) from pydantic import BaseModel, ConfigDict, Field, field_validator from typing import List, Optional from datetime import datetime from decimal import Decimal import re # --- NEW SCHEMAS FOR CIM WORKFLOW (Now with correct Pydantic V2 config) --- class CardCreate(BaseModel): card_number: str = Field(..., min_length=13, max_length=19, description="Credit card number (13-19 digits)") expiration_date: str = Field(..., description="Expiration date in YYYY-MM format") cvv: str = Field(..., min_length=3, max_length=4, description="Card security code (3-4 digits)") main_card: bool = False @field_validator('card_number') @classmethod def validate_card_number(cls, v): digits_only = re.sub(r'\D', '', v) if len(digits_only) < 13 or len(digits_only) > 19: raise ValueError('Card number must be 13-19 digits') return digits_only @field_validator('expiration_date') @classmethod def validate_expiration_date(cls, v): if not re.match(r'^\d{4}-\d{2}$', v): raise ValueError('Expiration date must be in YYYY-MM format') return v @field_validator('cvv') @classmethod def validate_cvv(cls, v): if not re.match(r'^\d{3,4}$', v): raise ValueError('CVV must be 3-4 digits') return v class Card(BaseModel): id: int user_id: int last_four_digits: str type_of_card: Optional[str] = None expiration_month: int expiration_year: int # --- MODIFICATION: This is the new syntax for Pydantic V2 --- model_config = ConfigDict(from_attributes=True) # The line above replaces the old `class Config: orm_mode = True` class TransactionCreateByCardID(BaseModel): card_id: int charge_amount: Decimal tax_amount: Optional[Decimal] = Decimal("0.0") service_id: Optional[int] = None delivery_id: Optional[int] = None class TransactionAuthorizeByCardID(BaseModel): card_id: int preauthorize_amount: Decimal tax_amount: Optional[Decimal] = Decimal("0.0") service_id: Optional[int] = None delivery_id: Optional[int] = None auto_id: Optional[int] = None # --- YOUR EXISTING SCHEMAS (UPDATED for Pydantic V2) --- class TransactionBase(BaseModel): preauthorize_amount: Optional[Decimal] = None charge_amount: Optional[Decimal] = None transaction_type: int service_id: Optional[int] = None delivery_id: Optional[int] = None auto_id: Optional[int] = None card_id: Optional[int] = None payment_gateway: int = 1 rejection_reason: Optional[str] = None class TransactionCreate(TransactionBase): charge_amount: Decimal card_number: str expiration_date: str cvv: str class TransactionAuthorize(TransactionBase): preauthorize_amount: Decimal card_number: str expiration_date: str cvv: str class TransactionCapture(BaseModel): charge_amount: Decimal auth_net_transaction_id: str class Transaction(TransactionBase): id: int transaction_type: int status: int auth_net_transaction_id: Optional[str] = None customer_id: int created_at: datetime # --- MODIFICATION: This is the new syntax for Pydantic V2 --- model_config = ConfigDict(from_attributes=True) class CustomerBase(BaseModel): account_number: Optional[str] = None customer_last_name: Optional[str] = Field(None, max_length=50, description="Last name (max 50 chars)") customer_first_name: Optional[str] = Field(None, max_length=50, description="First name (max 50 chars)") customer_town: Optional[str] = Field(None, max_length=40, description="City (max 40 chars)") customer_state: Optional[int] = None customer_zip: Optional[str] = Field(None, max_length=20, description="ZIP code (max 20 chars)") customer_first_call: Optional[datetime] = None customer_email: Optional[str] = Field(None, max_length=255, description="Email (max 255 chars)") customer_automatic: Optional[int] = None customer_phone_number: Optional[str] = None customer_home_type: Optional[int] = None customer_apt: Optional[str] = None customer_address: Optional[str] = Field(None, max_length=60, description="Address (max 60 chars)") company_id: Optional[int] = None customer_latitude: Optional[str] = None customer_longitude: Optional[str] = None correct_address: Optional[bool] = None class Customer(CustomerBase): id: int auth_net_profile_id: Optional[str] = None # --- MODIFICATION: This is the new syntax for Pydantic V2 --- model_config = ConfigDict(from_attributes=True) class CustomerCardResponse(Card): # We are inheriting all fields from `Card` # Now, add the extra customer fields the frontend needs. # We define it as a string because we will be returning the # two-letter abbreviation, not the database ID. customer_state: str