first commit
This commit is contained in:
278
schemas.py
Normal file
278
schemas.py
Normal file
@@ -0,0 +1,278 @@
|
||||
from pydantic import BaseModel, field_validator
|
||||
from typing import Optional
|
||||
from datetime import datetime, date
|
||||
from decimal import Decimal
|
||||
|
||||
# Customer schemas
|
||||
class CustomerBase(BaseModel):
|
||||
auth_net_profile_id: Optional[str] = None
|
||||
account_number: str
|
||||
customer_last_name: str
|
||||
customer_first_name: str
|
||||
customer_town: str
|
||||
customer_state: int
|
||||
customer_zip: str
|
||||
customer_first_call: Optional[datetime] = None
|
||||
customer_email: str
|
||||
customer_automatic: int
|
||||
customer_phone_number: str
|
||||
customer_home_type: int
|
||||
customer_apt: str
|
||||
customer_address: str
|
||||
company_id: int
|
||||
customer_latitude: str
|
||||
customer_longitude: str
|
||||
correct_address: bool
|
||||
|
||||
class CustomerCreate(BaseModel):
|
||||
customer_first_name: str
|
||||
customer_last_name: str
|
||||
customer_phone_number: str
|
||||
customer_email: str
|
||||
customer_address: str
|
||||
customer_apt: Optional[str] = None
|
||||
customer_town: str
|
||||
customer_zip: str
|
||||
customer_home_type: int = 0
|
||||
personal_notes: Optional[str] = None
|
||||
house_description: Optional[str] = None
|
||||
|
||||
class CustomerCreateStep1(BaseModel):
|
||||
customer_first_name: str
|
||||
customer_last_name: str
|
||||
customer_phone_number: str # Now accepts formatted: (123) 456-7890
|
||||
customer_address: str
|
||||
customer_apt: Optional[str] = None
|
||||
customer_town: str
|
||||
customer_zip: str
|
||||
customer_home_type: int = 0
|
||||
house_description: Optional[str] = None
|
||||
|
||||
class CustomerAccountCreate(BaseModel):
|
||||
account_number: str
|
||||
password: str
|
||||
confirm_password: str
|
||||
customer_email: str
|
||||
|
||||
class NewCustomerCreate(CustomerCreate):
|
||||
password: str
|
||||
confirm_password: str
|
||||
|
||||
class CustomerUpdate(BaseModel):
|
||||
auth_net_profile_id: Optional[str] = None
|
||||
account_number: Optional[str] = None
|
||||
customer_last_name: Optional[str] = None
|
||||
customer_first_name: Optional[str] = None
|
||||
customer_town: Optional[str] = None
|
||||
customer_state: Optional[int] = None
|
||||
customer_zip: Optional[str] = None
|
||||
customer_first_call: Optional[datetime] = None
|
||||
customer_email: Optional[str] = None
|
||||
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] = None
|
||||
company_id: Optional[int] = None
|
||||
customer_latitude: Optional[str] = None
|
||||
customer_longitude: Optional[str] = None
|
||||
correct_address: Optional[bool] = None
|
||||
|
||||
class CustomerResponse(CustomerBase):
|
||||
id: int
|
||||
|
||||
# Order schemas (Delivery_Delivery)
|
||||
class OrderBase(BaseModel):
|
||||
customer_id: int
|
||||
customer_name: str
|
||||
customer_address: str
|
||||
customer_town: str
|
||||
customer_state: str
|
||||
customer_zip: int
|
||||
gallons_ordered: int
|
||||
customer_asked_for_fill: int
|
||||
gallons_delivered: Decimal
|
||||
customer_filled: int
|
||||
delivery_status: int
|
||||
when_ordered: Optional[date] = None
|
||||
when_delivered: Optional[date] = None
|
||||
expected_delivery_date: Optional[date] = None
|
||||
automatic: int
|
||||
automatic_id: int
|
||||
oil_id: int
|
||||
supplier_price: Decimal
|
||||
customer_price: Decimal
|
||||
customer_temperature: Decimal
|
||||
dispatcher_notes: str
|
||||
prime: int
|
||||
same_day: int
|
||||
emergency: int
|
||||
payment_type: int
|
||||
payment_card_id: int
|
||||
cash_recieved: Decimal
|
||||
driver_employee_id: int
|
||||
driver_first_name: str
|
||||
driver_last_name: str
|
||||
pre_charge_amount: Decimal
|
||||
total_price: Decimal
|
||||
final_price: Decimal
|
||||
check_number: str
|
||||
promo_id: int
|
||||
promo_money_discount: Decimal
|
||||
|
||||
class OrderCreate(OrderBase):
|
||||
pass
|
||||
|
||||
class OrderUpdate(BaseModel):
|
||||
customer_id: Optional[int] = None
|
||||
customer_name: Optional[str] = None
|
||||
customer_address: Optional[str] = None
|
||||
customer_town: Optional[str] = None
|
||||
customer_state: Optional[str] = None
|
||||
customer_zip: Optional[int] = None
|
||||
gallons_ordered: Optional[int] = None
|
||||
customer_asked_for_fill: Optional[int] = None
|
||||
gallons_delivered: Optional[Decimal] = None
|
||||
customer_filled: Optional[int] = None
|
||||
delivery_status: Optional[int] = None
|
||||
when_ordered: Optional[date] = None
|
||||
when_delivered: Optional[date] = None
|
||||
expected_delivery_date: Optional[date] = None
|
||||
automatic: Optional[int] = None
|
||||
automatic_id: Optional[int] = None
|
||||
oil_id: Optional[int] = None
|
||||
supplier_price: Optional[Decimal] = None
|
||||
customer_price: Optional[Decimal] = None
|
||||
customer_temperature: Optional[Decimal] = None
|
||||
dispatcher_notes: Optional[str] = None
|
||||
prime: Optional[int] = None
|
||||
same_day: Optional[int] = None
|
||||
emergency: Optional[int] = None
|
||||
payment_type: Optional[int] = None
|
||||
payment_card_id: Optional[int] = None
|
||||
cash_recieved: Optional[Decimal] = None
|
||||
driver_employee_id: Optional[int] = None
|
||||
driver_first_name: Optional[str] = None
|
||||
driver_last_name: Optional[str] = None
|
||||
pre_charge_amount: Optional[Decimal] = None
|
||||
total_price: Optional[Decimal] = None
|
||||
final_price: Optional[Decimal] = None
|
||||
check_number: Optional[str] = None
|
||||
promo_id: Optional[int] = None
|
||||
promo_money_discount: Optional[Decimal] = None
|
||||
|
||||
class OrderResponse(OrderBase):
|
||||
id: int
|
||||
|
||||
class DeliveryCreate(BaseModel):
|
||||
gallons_ordered: int
|
||||
expected_delivery_date: date
|
||||
dispatcher_notes: Optional[str] = None
|
||||
payment_type: int # 0=cash, 1=credit
|
||||
prime: Optional[int] = 0
|
||||
same_day: Optional[int] = 0
|
||||
emergency: Optional[int] = 0
|
||||
pre_charge_amount: Optional[float] = None
|
||||
|
||||
# Card schemas
|
||||
class CardBase(BaseModel):
|
||||
auth_net_payment_profile_id: Optional[str] = None
|
||||
card_number: Optional[str] = None
|
||||
last_four_digits: int
|
||||
name_on_card: Optional[str] = None
|
||||
expiration_month: str
|
||||
expiration_year: str
|
||||
type_of_card: Optional[str] = None
|
||||
security_number: Optional[str] = None
|
||||
accepted_or_declined: Optional[int] = None
|
||||
main_card: Optional[bool] = None
|
||||
zip_code: Optional[str] = None
|
||||
|
||||
class CardCreate(BaseModel):
|
||||
card_number: str
|
||||
name_on_card: str
|
||||
expiration_month: str
|
||||
expiration_year: str
|
||||
security_number: str
|
||||
zip_code: str
|
||||
save_card: bool = False
|
||||
|
||||
class CardResponse(CardBase):
|
||||
id: int
|
||||
date_added: datetime
|
||||
user_id: int
|
||||
|
||||
class CardUpdate(BaseModel):
|
||||
name_on_card: Optional[str] = None
|
||||
expiration_month: Optional[str] = None
|
||||
expiration_year: Optional[str] = None
|
||||
zip_code: Optional[str] = None
|
||||
|
||||
# Payment schemas
|
||||
class PaymentCreate(BaseModel):
|
||||
amount: Decimal
|
||||
card_id: Optional[int] = None # For saved cards
|
||||
card_details: Optional[CardCreate] = None # For new cards
|
||||
delivery_id: Optional[int] = None
|
||||
|
||||
class PaymentResponse(BaseModel):
|
||||
transaction_id: str
|
||||
status: str
|
||||
amount: Decimal
|
||||
auth_net_transaction_id: str
|
||||
|
||||
# Auth schemas
|
||||
class UserCreate(BaseModel):
|
||||
account_number: str
|
||||
house_number: str
|
||||
email: str
|
||||
password: str
|
||||
confirm_password: str
|
||||
|
||||
@field_validator('house_number')
|
||||
@classmethod
|
||||
def validate_house_number(cls, v: str) -> str:
|
||||
"""Validate house_number contains only safe characters.
|
||||
|
||||
Allows alphanumeric characters, spaces, hyphens, and forward slashes
|
||||
(for addresses like "123-A" or "45 1/2").
|
||||
"""
|
||||
import re
|
||||
if not v or not v.strip():
|
||||
raise ValueError('House number cannot be empty')
|
||||
# Allow alphanumeric, spaces, hyphens, forward slashes
|
||||
if not re.match(r'^[a-zA-Z0-9\s\-/]+$', v):
|
||||
raise ValueError('House number contains invalid characters')
|
||||
if len(v) > 20:
|
||||
raise ValueError('House number is too long')
|
||||
return v.strip()
|
||||
|
||||
class UserLogin(BaseModel):
|
||||
email: str
|
||||
password: str
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
token_type: str
|
||||
|
||||
class TokenData(BaseModel):
|
||||
username: Optional[str] = None
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
email: str
|
||||
member_since: datetime
|
||||
last_seen: datetime
|
||||
admin: int
|
||||
admin_role: int
|
||||
confirmed: int
|
||||
active: int
|
||||
|
||||
class ForgotPasswordRequest(BaseModel):
|
||||
email: str
|
||||
|
||||
class ResetPasswordRequest(BaseModel):
|
||||
token: str
|
||||
password: str
|
||||
confirm_password: str
|
||||
Reference in New Issue
Block a user