Merge pull request 'fixed/logo_empresa' (#70) from fixed/logo_empresa into development
Reviewed-on: ADUANASOFT/anexo76#70
This commit is contained in:
@@ -61,7 +61,7 @@ class Company(Base, TimestampMixin):
|
||||
|
||||
# Configuración básica
|
||||
logo: Mapped[Optional[str]] = mapped_column(String(255))
|
||||
has_express_line: Mapped[Optional[bool]] = mapped_column(Boolean, default=False)
|
||||
has_express_line: Mapped[Optional[str]] = mapped_column(String(2), default="N")
|
||||
order_format_type: Mapped[Optional[str]] = mapped_column(String(19))
|
||||
is_service_company: Mapped[Optional[bool]] = mapped_column(Boolean, default=False)
|
||||
client_name: Mapped[Optional[str]] = mapped_column(String(300))
|
||||
@@ -78,6 +78,7 @@ class Company(Base, TimestampMixin):
|
||||
parts_replacement: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
activate_facmexame: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
part_reference: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
part_reference: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
international_firm: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
|
||||
# Configuraciones simples
|
||||
|
||||
@@ -50,7 +50,8 @@ async def create_company(
|
||||
)
|
||||
|
||||
service = CompanyService(db)
|
||||
return service.create_company_manually(data, tenant_id=tenant_id)
|
||||
new_company = service.create_company_manually(data, tenant_id=tenant_id)
|
||||
return CompanyResponseDTO.model_validate(service.flatten_company_dto(new_company))
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -94,7 +95,10 @@ async def list_companies(
|
||||
total_pages = (total + page_size - 1) // page_size
|
||||
|
||||
return {
|
||||
"items": [CompanyResponseDTO.model_validate(item) for item in items],
|
||||
"items": [
|
||||
CompanyResponseDTO.model_validate(service.flatten_company_dto(item))
|
||||
for item in items
|
||||
],
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
@@ -122,135 +126,12 @@ async def get_my_companies(
|
||||
service = CompanyService(db)
|
||||
companies = service.get_companies_by_tenant(tenant_id)
|
||||
|
||||
return [CompanyResponseDTO.model_validate(company) for company in companies]
|
||||
|
||||
|
||||
@router.get(
|
||||
"/status/exists",
|
||||
response_model=dict,
|
||||
summary="Check if company exists for tenant",
|
||||
)
|
||||
async def check_company_exists(
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Check if a company exists for the current tenant"""
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
if not tenant_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Tenant ID not found in user data",
|
||||
)
|
||||
|
||||
service = CompanyService(db)
|
||||
exists = service.exists_company(tenant_id)
|
||||
|
||||
return {"exists": exists}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/info/basic/{company_id}",
|
||||
response_model=dict,
|
||||
summary="Get basic company info",
|
||||
)
|
||||
async def get_basic_info(
|
||||
company_id: int,
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Get basic information about a company"""
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
company_id_from_user = current_user.get("company_id")
|
||||
|
||||
# Validate access
|
||||
validate_access_to_resource(
|
||||
db, tenant_id, company_id_from_user, Company, company_id, "id"
|
||||
)
|
||||
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_from_user)
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
return {
|
||||
"id": company.id,
|
||||
"name": company.name,
|
||||
"rfc": company.rfc,
|
||||
"program": company.program,
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/info/responsible/{company_id}",
|
||||
response_model=dict,
|
||||
summary="Get responsible person info",
|
||||
)
|
||||
async def get_responsible_info(
|
||||
company_id: int,
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Get responsible person information for a company"""
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
company_id_from_user = current_user.get("company_id")
|
||||
|
||||
# Validate access
|
||||
validate_access_to_resource(
|
||||
db, tenant_id, company_id_from_user, Company, company_id, "id"
|
||||
)
|
||||
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_from_user)
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
return {
|
||||
"responsible": company.responsible,
|
||||
"responsible_name": company.responsible_name,
|
||||
"responsible_last_name": company.responsible_last_name,
|
||||
"responsible_mother_last_name": company.responsible_mother_last_name,
|
||||
"responsible_rfc": company.responsible_rfc,
|
||||
"position": company.position,
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/info/program/{company_id}",
|
||||
response_model=dict,
|
||||
summary="Get program information",
|
||||
)
|
||||
async def get_program_info(
|
||||
company_id: int,
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Get program information for a company"""
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
company_id_from_user = current_user.get("company_id")
|
||||
|
||||
# Validate access
|
||||
validate_access_to_resource(
|
||||
db, tenant_id, company_id_from_user, Company, company_id, "id"
|
||||
)
|
||||
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_from_user)
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
return {
|
||||
"program": company.program,
|
||||
"program_number": company.program_number,
|
||||
"prosec": company.prosec,
|
||||
"prosec_authorization": company.prosec_authorization,
|
||||
}
|
||||
return [
|
||||
CompanyResponseDTO.model_validate(service.flatten_company_dto(company))
|
||||
for company in companies
|
||||
]
|
||||
|
||||
# ... existing code ...
|
||||
|
||||
@router.get(
|
||||
"/{company_id}",
|
||||
@@ -270,6 +151,7 @@ async def get_company(
|
||||
detail="Tenant ID not found in user data",
|
||||
)
|
||||
|
||||
service = CompanyService(db)
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, 0)
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
@@ -277,7 +159,7 @@ async def get_company(
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
return CompanyResponseDTO.model_validate(company)
|
||||
return CompanyResponseDTO.model_validate(service.flatten_company_dto(company))
|
||||
|
||||
|
||||
@router.put(
|
||||
@@ -299,81 +181,28 @@ async def update_company(
|
||||
detail="Tenant ID not found in user data",
|
||||
)
|
||||
|
||||
updated_company = CompanyService.update(db, company_id, tenant_id, 0, data)
|
||||
service = CompanyService(db)
|
||||
updated_company = service.update(db, company_id, tenant_id, 0, data)
|
||||
if not updated_company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
return CompanyResponseDTO.model_validate(updated_company)
|
||||
return CompanyResponseDTO.model_validate(service.flatten_company_dto(updated_company))
|
||||
|
||||
|
||||
return CompanyResponseDTO.model_validate(updated_company)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{company_id}/upload-logo",
|
||||
response_model=dict,
|
||||
summary="Upload company logo",
|
||||
)
|
||||
async def upload_company_logo(
|
||||
company_id: int,
|
||||
file: UploadFile = File(...),
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Upload logo for a company"""
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
if not tenant_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Tenant ID not found in user data",
|
||||
)
|
||||
|
||||
# 1. Verify company exists
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, 0)
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Company not found",
|
||||
)
|
||||
|
||||
# 2. Define upload path
|
||||
# Use a persistent path: 'app_data/logos/{company_id}'
|
||||
upload_dir = Path(f"app_data/logos/{company_id}")
|
||||
upload_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 3. Save file
|
||||
# Preserve original filename
|
||||
filename = file.filename or "logo.png"
|
||||
file_path = upload_dir / filename
|
||||
|
||||
try:
|
||||
# Check if file exists and remove it to avoid accumulation if needed,
|
||||
# or just overwrite (shutil.copyfileobj overwrites)
|
||||
with open(file_path, "wb") as buffer:
|
||||
shutil.copyfileobj(file.file, buffer)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Could not save file: {e}",
|
||||
)
|
||||
|
||||
# 4. Returns the absolute path keys
|
||||
abs_path = str(file_path.absolute())
|
||||
|
||||
return {"path": abs_path}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{company_id}/logo/image",
|
||||
summary="Get company logo image",
|
||||
)
|
||||
@router.get(
|
||||
"/{company_id}/logo/image",
|
||||
summary="Get company logo image",
|
||||
)
|
||||
|
||||
async def get_company_logo_image(
|
||||
company_id: int,
|
||||
db: Session = Depends(get_core_db),
|
||||
@@ -401,6 +230,13 @@ async def get_company_logo_image(
|
||||
raise HTTPException(status_code=404, detail="Logo file not found on server")
|
||||
|
||||
return FileResponse(file_path)
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/{company_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
summary="Delete a company",
|
||||
)
|
||||
async def delete_company(
|
||||
company_id: int,
|
||||
db: Session = Depends(get_core_db),
|
||||
@@ -497,7 +333,8 @@ async def upload_company_logo(
|
||||
|
||||
# Actualizar la empresa con la ruta del logo
|
||||
update_data = CompanyUpdateDTO(logo=file_path)
|
||||
updated_company = CompanyService.update(db, company_id, tenant_id, 0, update_data)
|
||||
service = CompanyService(db)
|
||||
updated_company = service.update(db, company_id, tenant_id, 0, update_data)
|
||||
|
||||
return {
|
||||
"message": "Logo uploaded successfully",
|
||||
|
||||
@@ -97,8 +97,139 @@ class CompanyService:
|
||||
logger.error(f"Error creating company: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Error creating company")
|
||||
|
||||
@staticmethod
|
||||
|
||||
# ==================== HELPERS FOR FIELD MAPPING ====================
|
||||
def _extract_company_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Extrae campos que pertenecen a la tabla Company principal"""
|
||||
company_fields = [
|
||||
"name", "rfc", "curp", "main_activity", "program", "program_number",
|
||||
"prosec", "prosec_authorization", "sector1", "sector2", "sector3",
|
||||
"manufacturer_id", "broker_company", "responsible", "responsible_name",
|
||||
"responsible_last_name", "responsible_mother_last_name", "responsible_rfc",
|
||||
"position", "logo", "has_express_line", "order_format_type",
|
||||
"is_service_company", "client_name", "subassembly_mode", "previous_code",
|
||||
"active_labels", "active_fractions", "activate_caat", "trans_interface",
|
||||
"american_costs", "scaf_readonly", "parts_replacement", "activate_facmexame",
|
||||
"part_reference", "international_firm", "ftp_key", "sifra_path",
|
||||
"version_type", "sql_language", "balance_operation_mode", "inter_db_name"
|
||||
]
|
||||
return {k: v for k, v in data.items() if k in company_fields}
|
||||
|
||||
def _extract_certification_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Extrae campos que pertenecen a CompanyCertification"""
|
||||
cert_fields = [
|
||||
"is_certified_company", "certified_company_registration",
|
||||
"certified_company_start_date", "certified_company_end_date",
|
||||
"annex31_certification_date", "annex31_certification_number",
|
||||
"annex31_modality", "annex31_company_type", "annex31_renewal_date",
|
||||
"annex31_final_certification_date", "is_oea_company", "ctpat_svi",
|
||||
"trusted_exporter_number", "neec_company"
|
||||
]
|
||||
return {k: v for k, v in data.items() if k in cert_fields}
|
||||
|
||||
def _extract_prevalidator_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Extrae campos que pertenecen a CompanyPrevalidator"""
|
||||
# Note: 'prevalidator_key' in DTO maps to 'key' in model
|
||||
fields = {}
|
||||
if "prevalidator_key" in data:
|
||||
fields["key"] = data["prevalidator_key"]
|
||||
|
||||
# Add other fields if present in DTO in the future
|
||||
return fields
|
||||
|
||||
def flatten_company_dto(self, company: Company) -> Dict[str, Any]:
|
||||
"""Flattens Company and its submodels into a single dict for DTO validation"""
|
||||
# 1. Base Company fields
|
||||
result = {
|
||||
k: getattr(company, k)
|
||||
for k in company.__mapper__.c.keys()
|
||||
}
|
||||
# Explicitly ensure logo is present (defensive programming)
|
||||
if hasattr(company, 'logo'):
|
||||
result['logo'] = company.logo
|
||||
|
||||
# Convert has_express_line from String "S"/"N" to Boolean
|
||||
if hasattr(company, 'has_express_line'):
|
||||
val = getattr(company, 'has_express_line', "N")
|
||||
result['has_express_line'] = (val == "S")
|
||||
|
||||
# 2. Certification fields
|
||||
if company.certification:
|
||||
cert_fields = [
|
||||
"is_certified_company", "certified_company_registration",
|
||||
"certified_company_start_date", "certified_company_end_date",
|
||||
"annex31_certification_date", "annex31_certification_number",
|
||||
"annex31_modality", "annex31_company_type", "annex31_renewal_date",
|
||||
"annex31_final_certification_date", "is_oea_company", "ctpat_svi",
|
||||
"trusted_exporter_number", "neec_company"
|
||||
]
|
||||
for field in cert_fields:
|
||||
val = getattr(company.certification, field, None)
|
||||
if val is not None:
|
||||
result[field] = val
|
||||
|
||||
# 3. Prevalidator fields
|
||||
if company.prevalidator:
|
||||
if company.prevalidator.key:
|
||||
result["prevalidator_key"] = company.prevalidator.key
|
||||
|
||||
return result
|
||||
|
||||
# ==================== CRUD METHODS ====================
|
||||
|
||||
def create_company_manually(self, data: CompanyCreateDTO, tenant_id: int) -> Company:
|
||||
from .submodels.certification import CompanyCertification
|
||||
from .submodels.prevalidator import CompanyPrevalidator
|
||||
|
||||
try:
|
||||
# 1. Preparar datos
|
||||
obj_data = data.model_dump(exclude_unset=True)
|
||||
|
||||
# Handle boolean flags for Company (Hybrid Approach)
|
||||
# has_express_line is String(2), is_service_company is Boolean
|
||||
if "has_express_line" in obj_data and isinstance(obj_data["has_express_line"], bool):
|
||||
obj_data["has_express_line"] = "S" if obj_data["has_express_line"] else "N"
|
||||
|
||||
# 2. Extract fields for each model
|
||||
company_data = self._extract_company_fields(obj_data)
|
||||
cert_data = self._extract_certification_fields(obj_data)
|
||||
preval_data = self._extract_prevalidator_fields(obj_data)
|
||||
|
||||
# 3. Create Company
|
||||
db_company = Company(**company_data, tenant_id=tenant_id)
|
||||
self.db.add(db_company)
|
||||
self.db.flush() # Generate ID
|
||||
|
||||
# 4. Create Certification if data exists
|
||||
if cert_data:
|
||||
cert = CompanyCertification(**cert_data, company_id=db_company.id)
|
||||
self.db.add(cert)
|
||||
|
||||
# 5. Create Prevalidator if data exists
|
||||
if preval_data:
|
||||
preval = CompanyPrevalidator(**preval_data, company_id=db_company.id)
|
||||
self.db.add(preval)
|
||||
|
||||
# 6. Commit
|
||||
self.db.commit()
|
||||
self.db.refresh(db_company)
|
||||
|
||||
return db_company
|
||||
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"IntegrityError creating company manually: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Error de integridad: Es posible que esta empresa ya exista.",
|
||||
)
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error creating company manually: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Error creando empresa: {str(e)}")
|
||||
|
||||
def update(
|
||||
self, # Changed to instance method to use self helper methods
|
||||
db: Session,
|
||||
company_id: int,
|
||||
tenant_id: int,
|
||||
@@ -106,23 +237,57 @@ class CompanyService:
|
||||
company_data: CompanyUpdateDTO,
|
||||
) -> Optional[Company]:
|
||||
"""Update a company"""
|
||||
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_unused)
|
||||
from .submodels.certification import CompanyCertification
|
||||
from .submodels.prevalidator import CompanyPrevalidator
|
||||
|
||||
# Use self.db if db is passed as None, or use passed db (legacy support)
|
||||
session = db if db else self.db
|
||||
|
||||
company = self.get_by_id(session, company_id, tenant_id, company_id_unused)
|
||||
if not company:
|
||||
return None
|
||||
|
||||
# Update only provided fields
|
||||
update_data = company_data.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
|
||||
# 1. Update Company fields
|
||||
company_fields = self._extract_company_fields(update_data)
|
||||
|
||||
# Hybrid Approach: has_express_line is String, is_service_company is Boolean
|
||||
if "has_express_line" in company_fields and isinstance(company_fields["has_express_line"], bool):
|
||||
company_fields["has_express_line"] = "S" if company_fields["has_express_line"] else "N"
|
||||
|
||||
for field, value in company_fields.items():
|
||||
setattr(company, field, value)
|
||||
|
||||
# 2. Update Certification
|
||||
cert_fields = self._extract_certification_fields(update_data)
|
||||
if cert_fields:
|
||||
if company.certification:
|
||||
for field, value in cert_fields.items():
|
||||
setattr(company.certification, field, value)
|
||||
else:
|
||||
new_cert = CompanyCertification(**cert_fields, company_id=company.id)
|
||||
session.add(new_cert)
|
||||
|
||||
# 3. Update Prevalidator
|
||||
preval_fields = self._extract_prevalidator_fields(update_data)
|
||||
if preval_fields:
|
||||
if company.prevalidator:
|
||||
for field, value in preval_fields.items():
|
||||
setattr(company.prevalidator, field, value)
|
||||
else:
|
||||
new_preval = CompanyPrevalidator(**preval_fields, company_id=company.id)
|
||||
session.add(new_preval)
|
||||
|
||||
try:
|
||||
db.commit()
|
||||
db.refresh(company)
|
||||
session.commit()
|
||||
session.refresh(company)
|
||||
return company
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
session.rollback()
|
||||
logger.error(f"Error updating company {company_id}: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Error updating company")
|
||||
raise HTTPException(status_code=500, detail=f"Error al actualizar la empresa: {str(e)}")
|
||||
|
||||
@staticmethod
|
||||
def delete(
|
||||
@@ -134,19 +299,56 @@ class CompanyService:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Manual cascade delete for submodels to ensure order and avoid FK issues
|
||||
# (Even though cascade="all, delete-orphan" is set, manual deletion is safer for strict DBs)
|
||||
|
||||
# 1. Delete Certification
|
||||
if company.certification:
|
||||
db.delete(company.certification)
|
||||
|
||||
# 2. Delete Prevalidator
|
||||
if company.prevalidator:
|
||||
db.delete(company.prevalidator)
|
||||
|
||||
# 3. Delete Electronic Agent
|
||||
if company.electronic_agent:
|
||||
db.delete(company.electronic_agent)
|
||||
|
||||
# 4. Delete VU
|
||||
if company.ventanilla_unica:
|
||||
db.delete(company.ventanilla_unica)
|
||||
|
||||
# 5. Delete CFDI
|
||||
if company.cfdi:
|
||||
db.delete(company.cfdi)
|
||||
|
||||
# 6. Delete Digital Certificates
|
||||
for cert in company.digital_certificates:
|
||||
db.delete(cert)
|
||||
|
||||
# 7. Delete Addresses
|
||||
for addr in company.addresses:
|
||||
db.delete(addr)
|
||||
|
||||
# Flush to execute submodel deletions first
|
||||
db.flush()
|
||||
|
||||
db.delete(company)
|
||||
db.commit()
|
||||
return True
|
||||
except IntegrityError as e:
|
||||
db.rollback()
|
||||
logger.error(f"IntegrityError deleting company {company_id}: {str(e)}")
|
||||
# Check if it's a foreign key constraint
|
||||
if "foreign key constraint" in str(e).lower():
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No se puede eliminar la empresa porque tiene registros relacionados (facturas, conceptos, etc.)"
|
||||
)
|
||||
raise HTTPException(status_code=400, detail="Error al eliminar la empresa")
|
||||
# Try to get detailed error from psycopg2
|
||||
detail = "No se puede eliminar la empresa porque tiene registros relacionados."
|
||||
if hasattr(e, 'orig') and hasattr(e.orig, 'diag'):
|
||||
if e.orig.diag.message_detail:
|
||||
detail += f" Detalles: {e.orig.diag.message_detail}"
|
||||
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=detail
|
||||
)
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
logger.error(f"Error deleting company {company_id}: {str(e)}")
|
||||
@@ -169,32 +371,4 @@ class CompanyService:
|
||||
.filter(Company.tenant_id == tenant_id)
|
||||
.first()
|
||||
is not None
|
||||
)
|
||||
|
||||
def create_company_manually(self, data: CompanyCreateDTO, tenant_id: int) -> Company:
|
||||
|
||||
try:
|
||||
# 1. Preparar datos
|
||||
obj_data = data.model_dump(exclude_unset=True)
|
||||
|
||||
# 2. Crear objeto SQLAlchemy
|
||||
db_obj = Company(**obj_data, tenant_id=tenant_id)
|
||||
|
||||
# 3. Guardar
|
||||
self.db.add(db_obj)
|
||||
self.db.commit()
|
||||
self.db.refresh(db_obj)
|
||||
|
||||
return db_obj
|
||||
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"IntegrityError creating company manually: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Error de integridad: Es posible que esta empresa ya exista.",
|
||||
)
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error creating company manually: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Error creando empresa: {str(e)}")
|
||||
)
|
||||
@@ -2,7 +2,7 @@
|
||||
Modelo de certificaciones de empresa
|
||||
"""
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from sqlalchemy import Integer, String, SmallInteger, ForeignKey
|
||||
from sqlalchemy import Integer, String, SmallInteger, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from core.database import Base
|
||||
from api.v1.common.base_models import TimestampMixin
|
||||
|
||||
@@ -17,6 +17,7 @@ ace_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(ace_router)
|
||||
|
||||
@@ -32,6 +33,7 @@ oma_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(oma_router)
|
||||
|
||||
@@ -47,6 +49,7 @@ american_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(american_router)
|
||||
|
||||
@@ -62,6 +65,7 @@ customs_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(customs_router)
|
||||
|
||||
@@ -77,6 +81,7 @@ general_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(general_router)
|
||||
|
||||
@@ -93,5 +98,6 @@ main_router = TenantCRUDRoutes(
|
||||
id_name="id",
|
||||
enable_list=True,
|
||||
enable_filters=True,
|
||||
max_page_size=10000,
|
||||
).router
|
||||
router.include_router(main_router)
|
||||
|
||||
Reference in New Issue
Block a user