✨ 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
107 lines
3.6 KiB
Markdown
107 lines
3.6 KiB
Markdown
# 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:
|
|
|
|
1. **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
|
|
|
|
2. **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
|
|
|
|
3. **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`
|
|
|
|
### GClass (Tabla: gclasses)
|
|
El modelo `GClass` representa las clases de clasificación en sistemas SCAII y SCAF.
|
|
|
|
#### Relaciones:
|
|
|
|
1. **Con MaterialType (public.material_types)**
|
|
- Campo: `material_key` → `material_types.key`
|
|
- Relación: Many-to-One
|
|
- Propósito: Tipo de material de la clase
|
|
|
|
2. **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`
|
|
|
|
## 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:
|
|
```python
|
|
# 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:
|
|
```python
|
|
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
|
|
|
|
1. **Composite Foreign Keys**: La relación entre `GPart` y `GClass` usa claves foráneas compuestas que requieren `primaryjoin` personalizado.
|
|
|
|
2. **Viewonly Relationships**: Algunas relaciones están marcadas como `viewonly=True` para evitar problemas de escritura accidental.
|
|
|
|
3. **Lazy Loading**: Por defecto, las relaciones usan lazy loading. Para consultas que necesiten datos relacionados, usar `joinedload` o `selectinload`.
|
|
|
|
4. **Type Hints**: Se usan `TYPE_CHECKING` imports para evitar import circulares mientras se mantienen los type hints.
|
|
|
|
## Futuras Relaciones
|
|
|
|
Potenciales relaciones adicionales que se pueden agregar:
|
|
|
|
1. **Con Sectors** (public.sectors) - para clasificación sectorial
|
|
2. **Con Transport Types** (public.transport_types) - para modo de transporte
|
|
3. **Con Customs Sections** (public.customs_sections) - para sección aduanera
|
|
4. **Relaciones con tablas subsidiarias** como `SPartes`, `QPartes`, etc. |