You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
6.8 KiB
Python
211 lines
6.8 KiB
Python
import random
|
|
from datetime import datetime
|
|
|
|
from app.core.settings import settings
|
|
from app.db.mock_database import SessionMockLocal
|
|
from app.db.mock_models import Customer, Order, RentalVehicle, Vehicle
|
|
|
|
|
|
VEHICLE_MODELS = [
|
|
"Toyota Corolla",
|
|
"Honda Civic",
|
|
"Chevrolet Onix",
|
|
"Hyundai HB20",
|
|
"Volkswagen T-Cross",
|
|
"Jeep Compass",
|
|
"Fiat Argo",
|
|
"Nissan Kicks",
|
|
"Renault Duster",
|
|
"Ford Ranger",
|
|
]
|
|
|
|
CATEGORIES = ["hatch", "sedan", "suv", "pickup"]
|
|
NAMES = [
|
|
"Ana Souza",
|
|
"Bruno Lima",
|
|
"Carla Mendes",
|
|
"Diego Santos",
|
|
"Eduarda Alves",
|
|
"Felipe Rocha",
|
|
"Gabriela Costa",
|
|
"Henrique Martins",
|
|
"Isabela Ferreira",
|
|
"Joao Ribeiro",
|
|
]
|
|
|
|
TARGET_VEHICLE_COUNT = 180
|
|
TARGET_CUSTOMER_COUNT = 320
|
|
TARGET_ORDER_COUNT = 80
|
|
VEHICLE_PRICE_BANDS = (
|
|
38990,
|
|
42990,
|
|
46990,
|
|
50990,
|
|
54990,
|
|
58990,
|
|
62990,
|
|
66990,
|
|
69990,
|
|
73990,
|
|
77990,
|
|
82990,
|
|
87990,
|
|
93990,
|
|
99990,
|
|
106990,
|
|
114990,
|
|
123990,
|
|
132990,
|
|
141990,
|
|
)
|
|
|
|
RENTAL_FLEET = [
|
|
("RAA1A01", "Chevrolet Tracker", "suv", 2024, 219.90, "disponivel"),
|
|
("RAA1A02", "Fiat Pulse", "suv", 2024, 189.90, "disponivel"),
|
|
("RAA1A03", "Volkswagen Nivus", "suv", 2024, 209.90, "disponivel"),
|
|
("RAA1A04", "Hyundai Creta", "suv", 2024, 239.90, "disponivel"),
|
|
("RAA1A05", "Jeep Renegade", "suv", 2023, 249.90, "disponivel"),
|
|
("RAA1A06", "Honda HR-V", "suv", 2024, 269.90, "disponivel"),
|
|
("RAA1A07", "Toyota Corolla Cross", "suv", 2024, 289.90, "disponivel"),
|
|
("RAA1A08", "Fiat Toro", "pickup", 2024, 319.90, "disponivel"),
|
|
("RAA1A09", "Chevrolet S10", "pickup", 2023, 369.90, "manutencao"),
|
|
("RAA1A10", "Toyota Hilux", "pickup", 2023, 429.90, "disponivel"),
|
|
("RAA1A11", "Ram Rampage", "pickup", 2024, 459.90, "disponivel"),
|
|
("RAA1A12", "Peugeot 208", "hatch", 2024, 149.90, "disponivel"),
|
|
("RAA1A13", "Renault Kwid", "hatch", 2024, 119.90, "disponivel"),
|
|
("RAA1A14", "Volkswagen Polo", "hatch", 2024, 159.90, "disponivel"),
|
|
("RAA1A15", "BYD Dolphin", "hatch", 2024, 279.90, "disponivel"),
|
|
("RAA1A16", "Toyota Yaris", "sedan", 2023, 179.90, "disponivel"),
|
|
("RAA1A17", "Honda City", "sedan", 2024, 199.90, "disponivel"),
|
|
("RAA1A18", "Nissan Versa", "sedan", 2024, 189.90, "disponivel"),
|
|
("RAA1A19", "Chevrolet Onix Plus", "sedan", 2024, 169.90, "alugado"),
|
|
("RAA1A20", "Fiat Fastback", "suv", 2024, 229.90, "disponivel"),
|
|
("RAA1A21", "Caoa Chery Tiggo 5X", "suv", 2024, 219.90, "disponivel"),
|
|
("RAA1A22", "Hyundai HB20S", "sedan", 2024, 164.90, "disponivel"),
|
|
("RAA1A23", "Jeep Compass", "suv", 2023, 309.90, "alugado"),
|
|
("RAA1A24", "Ford Maverick", "pickup", 2024, 399.90, "disponivel"),
|
|
]
|
|
|
|
|
|
def _cpf_check_digit(base_digits: str) -> str:
|
|
total = sum(int(digit) * weight for digit, weight in zip(base_digits, range(len(base_digits) + 1, 1, -1)))
|
|
remainder = 11 - (total % 11)
|
|
return "0" if remainder >= 10 else str(remainder)
|
|
|
|
|
|
def _cpf_from_index(index: int) -> str:
|
|
"""Gera um CPF valido e deterministico de 11 digitos a partir do indice."""
|
|
base_digits = f"{100_000_000 + index:09d}"[-9:]
|
|
first_digit = _cpf_check_digit(base_digits)
|
|
second_digit = _cpf_check_digit(base_digits + first_digit)
|
|
return f"{base_digits}{first_digit}{second_digit}"
|
|
|
|
|
|
def _vehicle_price_from_index(index: int, rng: random.Random) -> float:
|
|
band_price = VEHICLE_PRICE_BANDS[index % len(VEHICLE_PRICE_BANDS)]
|
|
cycle_increment = (index // len(VEHICLE_PRICE_BANDS)) * 750
|
|
noise = rng.randint(-1800, 2200)
|
|
return float(max(35000, band_price + cycle_increment + noise))
|
|
|
|
|
|
def _seed_vehicle_records(existing_count: int, target_count: int, rng: random.Random) -> list[Vehicle]:
|
|
vehicles = []
|
|
for idx in range(existing_count, target_count):
|
|
model = VEHICLE_MODELS[idx % len(VEHICLE_MODELS)]
|
|
category = CATEGORIES[idx % len(CATEGORIES)]
|
|
vehicles.append(
|
|
Vehicle(
|
|
modelo=f"{model} {2020 + (idx % 6)}",
|
|
categoria=category,
|
|
preco=_vehicle_price_from_index(idx, rng),
|
|
)
|
|
)
|
|
return vehicles
|
|
|
|
|
|
def _seed_customer_records(existing_count: int, target_count: int) -> list[Customer]:
|
|
customers = []
|
|
for idx in range(existing_count, target_count):
|
|
entropy = (idx * 9973) % 10_000
|
|
customers.append(
|
|
Customer(
|
|
cpf=_cpf_from_index(idx),
|
|
nome=f"{NAMES[idx % len(NAMES)]} {idx + 1}",
|
|
score=300 + (entropy % 550),
|
|
limite_credito=float(30_000 + (entropy * 12)),
|
|
possui_restricao=(idx % 11 == 0),
|
|
)
|
|
)
|
|
return customers
|
|
|
|
|
|
def _seed_order_records(existing_count: int, target_count: int) -> list[Order]:
|
|
orders = []
|
|
created = datetime(2026, 1, 1, 8, 0, 0)
|
|
for idx in range(existing_count, target_count):
|
|
orders.append(
|
|
Order(
|
|
numero_pedido=f"PED-MOCK-2026-{idx + 1:05d}",
|
|
cpf=_cpf_from_index(idx),
|
|
status="Ativo",
|
|
created_at=created,
|
|
)
|
|
)
|
|
return orders
|
|
|
|
|
|
def seed_mock_data() -> None:
|
|
"""Popula dados mock iniciais de veiculos, clientes e pedidos quando habilitado."""
|
|
if not settings.mock_seed_enabled:
|
|
return
|
|
|
|
rng = random.Random(42)
|
|
db = SessionMockLocal()
|
|
try:
|
|
vehicle_count = db.query(Vehicle).count()
|
|
if vehicle_count < TARGET_VEHICLE_COUNT:
|
|
vehicles = _seed_vehicle_records(
|
|
existing_count=vehicle_count,
|
|
target_count=TARGET_VEHICLE_COUNT,
|
|
rng=rng,
|
|
)
|
|
db.add_all(vehicles)
|
|
db.commit()
|
|
|
|
existing_rental_plates = {placa for (placa,) in db.query(RentalVehicle.placa).all()}
|
|
missing_rental_vehicles = [
|
|
RentalVehicle(
|
|
placa=plate,
|
|
modelo=model,
|
|
categoria=category,
|
|
ano=year,
|
|
valor_diaria=daily_rate,
|
|
status=status,
|
|
)
|
|
for plate, model, category, year, daily_rate, status in RENTAL_FLEET
|
|
if plate not in existing_rental_plates
|
|
]
|
|
if missing_rental_vehicles:
|
|
db.add_all(missing_rental_vehicles)
|
|
db.commit()
|
|
|
|
customer_count = db.query(Customer).count()
|
|
if customer_count < TARGET_CUSTOMER_COUNT:
|
|
customers = _seed_customer_records(
|
|
existing_count=customer_count,
|
|
target_count=TARGET_CUSTOMER_COUNT,
|
|
)
|
|
db.add_all(customers)
|
|
db.commit()
|
|
|
|
order_count = db.query(Order).count()
|
|
if order_count < TARGET_ORDER_COUNT:
|
|
orders = _seed_order_records(
|
|
existing_count=order_count,
|
|
target_count=TARGET_ORDER_COUNT,
|
|
)
|
|
db.add_all(orders)
|
|
db.commit()
|
|
finally:
|
|
db.close()
|