✨ New Features: - Company module: Single company management with comprehensive business info - Client & Provider module: Manages clients/providers with address/program relationships - GParts module: Parts/components management for SCAII, SCAF, and WINSAAI systems - GClass module: Class classifications for SCAII and SCAF with tariff information 🔗 Database Relationships: - GPart ↔ GClass: Composite key relationship (client_key, part_class ↔ class_code) - GPart → Country: Foreign key to public.countries (country_of_origin) - GPart → CurrencyType: Foreign key to public.currency_types (currency_key) - GClass → MaterialType: Foreign key to public.material_types (material_key) 📊 API Endpoints Added: Company Module (/company): - POST / - Create company - GET / - Get single company Client & Provider Module (/clients-providers): - POST / - Create client/provider - GET / - List all with pagination - GET /clients - List only clients - GET /providers - List only providers - GET /search/rfc/{rfc} - Search by RFC - GET /{client_id} - Get by ID - PUT /{client_id} - Update client/provider - DELETE /{client_id} - Delete client/provider - PATCH /{client_id}/toggle-status - Toggle status - GET /{client_id}/address - Get address info - GET /{client_id}/programs - Get programs info - GET /{client_id}/basic - Get basic info GParts Module (/parts): - POST / - Create part - GET / - List all with pagination and filters - GET /client/{client_key} - Get parts by client - GET /search/fraction/{fraction} - Search by tariff fraction - GET /search/supplier/{supplier} - Search by supplier - GET /search/country/{country_code} - Search by country - GET /statistics - Get parts statistics - GET /{client_key}/{part_number} - Get specific part - PUT /{client_key}/{part_number} - Update part - DELETE /{client_key}/{part_number} - Delete part - PATCH /{client_key}/{part_number}/toggle-status - Toggle status - GET /{client_key}/{part_number}/basic - Get basic info - GET /{client_key}/{part_number}/regulatory - Get regulatory info GClass Module (/classes): - POST / - Create class - GET / - List all with pagination and filters - GET /client/{client_key} - Get classes by client - GET /search/fraction/{fraction} - Search by tariff fraction - GET /search/material/{material_key} - Search by material - GET /search/unit-measure/{unit_of_measure} - Search by unit of measure - GET /search/physical-review/{physical_review} - Search by physical review status - GET /statistics - Get class statistics - GET /{client_key}/{class_code} - Get specific class - PUT /{client_key}/{class_code} - Update class - DELETE /{client_key}/{class_code} - Delete class - GET /{client_key}/{class_code}/basic - Get basic info - GET /{client_key}/{class_code}/tariff - Get tariff information 🏗️ Architecture: - Modular design with models, DTOs, services, and routes for each entity - English field names with composite primary keys where applicable - Comprehensive CRUD operations with specialized search endpoints - SQLAlchemy relationships with proper foreign key constraints - Type-safe DTOs with Pydantic validation 📝 Documentation: - RELATIONSHIPS.md: Complete documentation of database relationships - Detailed type hints and comprehensive service methods - Consistent patterns across all modules for maintainability
3.6 KiB
Relaciones entre Modelos A76
Resumen de Relaciones Establecidas
GPart (Tabla: gparts)
El modelo GPart representa las partes/componentes en los sistemas SCAII, SCAF y WINSAAI.
Relaciones:
-
Con Country (public.countries)
- Campo:
country_of_origin→countries.m3_key - Relación: Many-to-One
- Propósito: País de origen de la parte
- Campo:
-
Con CurrencyType (public.currency_types)
- Campo:
currency_key→currency_types.code - Relación: Many-to-One
- Propósito: Tipo de moneda para el costo unitario
- Campo:
-
Con GClass (gclasses)
- Campos:
(client_key, part_class)→(client_key, class_code) - Relación: Many-to-One (usando primaryjoin complejo)
- Propósito: Clasificación de la parte
- Atributo:
part_class_info
- Campos:
GClass (Tabla: gclasses)
El modelo GClass representa las clases de clasificación en sistemas SCAII y SCAF.
Relaciones:
-
Con MaterialType (public.material_types)
- Campo:
material_key→material_types.key - Relación: Many-to-One
- Propósito: Tipo de material de la clase
- Campo:
-
Con GPart (gparts)
- Campos:
(client_key, class_code)→(client_key, part_class) - Relación: One-to-Many (inversa de la relación en GPart)
- Propósito: Partes que pertenecen a esta clase
- Atributo:
parts
- Campos:
Esquema de Relaciones
GPart
├── country (Country) # País de origen
├── currency (CurrencyType) # Tipo de moneda
└── part_class_info (GClass) # Información de clasificación
└── material_type (MaterialType) # Tipo de material
GClass
├── material_type (MaterialType) # Tipo de material
└── parts (List[GPart]) # Partes que usan esta clase
Uso de las Relaciones
En consultas:
# Obtener una parte con su información completa
part = session.query(GPart).options(
joinedload(GPart.country),
joinedload(GPart.currency),
joinedload(GPart.part_class_info).joinedload(GClass.material_type)
).filter(
GPart.client_key == 1,
GPart.part_number == "PART001"
).first()
# Acceder a los datos relacionados
print(f"País: {part.country.description_es}")
print(f"Moneda: {part.currency.currency_name}")
print(f"Clase: {part.part_class_info.description_spanish}")
print(f"Material: {part.part_class_info.material_type.description}")
En DTOs:
Los DTOs pueden incluir información relacionada:
class PartDetailResponseDTO(BaseModel):
client_key: int
part_number: str
description_spanish: Optional[str]
country_name: Optional[str] = None
currency_name: Optional[str] = None
class_description: Optional[str] = None
material_type: Optional[str] = None
Consideraciones Técnicas
-
Composite Foreign Keys: La relación entre
GPartyGClassusa claves foráneas compuestas que requierenprimaryjoinpersonalizado. -
Viewonly Relationships: Algunas relaciones están marcadas como
viewonly=Truepara evitar problemas de escritura accidental. -
Lazy Loading: Por defecto, las relaciones usan lazy loading. Para consultas que necesiten datos relacionados, usar
joinedloadoselectinload. -
Type Hints: Se usan
TYPE_CHECKINGimports para evitar import circulares mientras se mantienen los type hints.
Futuras Relaciones
Potenciales relaciones adicionales que se pueden agregar:
- Con Sectors (public.sectors) - para clasificación sectorial
- Con Transport Types (public.transport_types) - para modo de transporte
- Con Customs Sections (public.customs_sections) - para sección aduanera
- Relaciones con tablas subsidiarias como
SPartes,QPartes, etc.