fix(core): crear compañía real en a76.company por tenant (arregla FK y desbloqueo)
my-companies usaba company_id = tenant_id, pero user_tenants.company_id tiene FK a a76.company (entidad real heredada de Anexo76). Con el tenant real (aduanasoft=11) no existía fila de compañía → ForeignKeyViolation → sin compañía → todo bloqueado. Ahora my-companies lista las compañías del tenant desde a76.company y, si no hay ninguna, crea una por defecto (nombre = el del tenant) en el primer acceso, usando su id real; luego asegura el vínculo usuario↔compañía. Base para el módulo de gestión de compañías. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -431,32 +431,61 @@ async def get_my_companies(
|
||||
_ensure_user_tenant_for_company,
|
||||
)
|
||||
from api.v1.modules.core.tenants.models import Tenant
|
||||
from sqlalchemy import text
|
||||
import logging as _logging
|
||||
|
||||
_log = _logging.getLogger(__name__)
|
||||
|
||||
tenant_id = resolve_effective_tenant_id_from_user(current_user)
|
||||
if not tenant_id:
|
||||
# Usuario sin tenant (p. ej. hub_admin global): no hay compañía que resolver.
|
||||
return []
|
||||
tenant_id = int(tenant_id)
|
||||
|
||||
tenant = db.query(Tenant).filter(Tenant.id == int(tenant_id)).first()
|
||||
name = (
|
||||
(tenant.name if tenant else None)
|
||||
or current_user.get("tenant_slug")
|
||||
or "Mi empresa"
|
||||
)
|
||||
# La compañía es una entidad REAL del CRM (a76.company, heredada de Anexo76).
|
||||
# Se listan las compañías del tenant; si no hay ninguna, se crea una por defecto
|
||||
# en el primer acceso (nombre = el del tenant).
|
||||
rows = db.execute(
|
||||
text("SELECT id, name, rfc, logo FROM a76.company WHERE tenant_id = :tid ORDER BY id"),
|
||||
{"tid": tenant_id},
|
||||
).fetchall()
|
||||
|
||||
# Garantizar el vínculo usuario↔tenant↔company (company_id = tenant_id).
|
||||
if not rows:
|
||||
tenant = db.query(Tenant).filter(Tenant.id == tenant_id).first()
|
||||
default_name = (
|
||||
(tenant.name if tenant else None)
|
||||
or current_user.get("tenant_slug")
|
||||
or "Mi empresa"
|
||||
)
|
||||
created = db.execute(
|
||||
text(
|
||||
"INSERT INTO a76.company (tenant_id, name) VALUES (:tid, :name) "
|
||||
"RETURNING id, name, rfc, logo"
|
||||
),
|
||||
{"tid": tenant_id, "name": default_name},
|
||||
).fetchone()
|
||||
# Alinear la secuencia por si hubo inserts con id explícito (seed dev).
|
||||
db.execute(text("SELECT setval('a76.company_id_seq', (SELECT MAX(id) FROM a76.company))"))
|
||||
db.commit()
|
||||
rows = [created]
|
||||
_log.info("Compañía por defecto creada para tenant=%s: id=%s", tenant_id, created[0])
|
||||
|
||||
# Asegurar el vínculo usuario↔compañía por cada compañía del tenant.
|
||||
user_id = current_user.get("sub") or current_user.get("id")
|
||||
if user_id:
|
||||
try:
|
||||
_ensure_user_tenant_for_company(db, str(user_id), int(tenant_id), int(tenant_id))
|
||||
except Exception as exc:
|
||||
logger = __import__("logging").getLogger(__name__)
|
||||
logger.warning("no se pudo asegurar user_tenant (no bloquea): %s", exc)
|
||||
|
||||
return [{
|
||||
"id": int(tenant_id),
|
||||
"name": name,
|
||||
"tenant_id": int(tenant_id),
|
||||
"rfc": None,
|
||||
"logo": None,
|
||||
"is_active": True,
|
||||
}]
|
||||
companies = []
|
||||
for r in rows:
|
||||
cid = int(r[0])
|
||||
if user_id:
|
||||
try:
|
||||
_ensure_user_tenant_for_company(db, str(user_id), tenant_id, cid)
|
||||
except Exception as exc:
|
||||
_log.warning("no se pudo asegurar user_tenant (no bloquea): %s", exc)
|
||||
companies.append({
|
||||
"id": cid,
|
||||
"name": r[1] or "Mi empresa",
|
||||
"tenant_id": tenant_id,
|
||||
"rfc": r[2],
|
||||
"logo": r[3],
|
||||
"is_active": True,
|
||||
})
|
||||
return companies
|
||||
|
||||
Reference in New Issue
Block a user