Skip to content

Plataforma técnica · Sevastopol

Legal Representatives View Island

Islands Sevastopol Administración

LegalRepresentativesViewIsland opera el padrón de representantes legales y socios del tenant: CRUD básico + dos acciones contables que afectan el plan de cuentas — activar/desactivar la cuenta corriente socio (sub-cuenta bajo 2204000) y revisar los movimientos del socio contra esa cuenta.

  • Directorysevastopol/src/components/islands/admin/
    • LegalRepresentativesViewIsland.tsx — componente único, internamente LegalRepresentativesView
  • Directorysevastopol/src/config/
    • headers.ts HEADERS_LEGAL_REPS
const { tenantId } = useActiveTenant((id) => void fetchData(id));
const [representatives, setRepresentatives] = createSignal<LegalRep[]>([]);
const [selectedRep, setSelectedRep] = createSignal<LegalRep | null>(null);
const [movimientos, setMovimientos] = createSignal<MovimientoSocio[]>([]);

Filtros y modal:

SignalTipoUso
qName / qRUTstringFiltros locales sub-string.
qActivestring"", "true" (vigentes), "false" (no vigentes).
showModal / editingId / formDataediciónModal de alta/edición.
selectedRep / movimientos / loadingMovpanelPanel lateral de movimientos del socio.
const filteredReps = createMemo(() => {
let list = [...representatives()];
if (qName()) {
const q = qName().toLowerCase();
list = list.filter(r =>
r.nombres.toLowerCase().includes(q) || r.apellidos.toLowerCase().includes(q),
);
}
if (qRUT()) list = list.filter(r => r.rut.includes(qRUT()));
if (qActive() === "true") list = list.filter(r => r.vigente);
if (qActive() === "false") list = list.filter(r => !r.vigente);
return list.sort((a, b) => a.apellidos.localeCompare(b.apellidos));
});

Orden estable por apellido — facilita lectura tipo guía telefónica.

MétricaCálculo
Totalrepresentatives.length
Vigentesrepresentatives.filter(r => r.vigente).length
Pendientesrepresentatives.filter(r => !r.vigente && !r.fecha_hasta).length (sin fecha de baja explícita)
Con cuentarepresentatives.filter(r => r.tiene_cuenta_socio).length
CampoObligatorioNotas
rutFormato ^\d{7,8}-[\dkK]$ (validado en backend).
nombres
apellidos
fecha_desdeInicio de vigencia.
fecha_hastaNoSi está, marca baja.
vigenteDefault true.
cargoNoTexto libre (gerente general, director, etc.).
emailNoValidado en backend si está.
telefonoNo
direccionNo
observacionesNo

Validación de cliente: los 4 primeros campos no vacíos. El resto va tal cual al backend.

if (!payload.rut || !payload.nombres || !payload.apellidos || !payload.fecha_desde) {
toast.push("RUT, Nombres, Apellidos y Fecha Desde son obligatorios", "error");
return;
}

Cada representante puede tener una cuenta corriente socio asociada: una sub-cuenta dinámica bajo 2204000 (cuentas por pagar socios) más un banco virtual que rastrea aportes/retiros del socio.

async function handleToggleCuenta(rep: LegalRep) {
const action = rep.tiene_cuenta_socio ? "desactivar" : "activar";
if (rep.tiene_cuenta_socio &&
!confirm("¿Desactivar la cuenta corriente socio? El banco quedará inactivo.")) {
return;
}
const r = await authenticatedFetch(
`${API_BASE}/${rep.id}/${action}-cuenta?tenant_id=${tenantId()}`,
{ method: "POST" },
);
}
EstadoAcción visibleEndpoint
Sin cuenta (tiene_cuenta_socio === false)Activar cuentaPOST /:id/activar-cuenta
Con cuenta (tiene_cuenta_socio === true)Desactivar cuentaPOST /:id/desactivar-cuenta (con confirm)

Solo la desactivación pide confirm — la activación es no destructiva.

Al clickear una fila, se carga el listado de MovimientoSocio del representante seleccionado:

ColumnaOrigen
FechafmtDate(movimiento.fecha)
TipoAPORTE / RETIRO / AJUSTE
MontofmtCLP(monto)
DescripciónGlosa o referencia al asiento.

loadingMov bloquea el panel mientras se hace el fetch. El panel se cierra al deseleccionar la fila.

MétodoRutaOperación
GET/api/admin/representatives?tenant_id=...Lista del padrón.
POST/api/admin/representatives?tenant_id=...Alta.
PUT/api/admin/representatives/:id?tenant_id=...Edición.
DELETE/api/admin/representatives/:id?tenant_id=...Eliminación.
POST/api/admin/representatives/:id/activar-cuenta?tenant_id=...Crea sub-cuenta socio + banco virtual.
POST/api/admin/representatives/:id/desactivar-cuenta?tenant_id=...Marca cuenta socio inactiva.
GET/api/admin/representatives/:id/movimientos?tenant_id=...Movimientos del socio.
ReglaMotivo
Validar 4 campos clave antes de enviarAcelera el feedback; el backend igual valida.
Confirm en desactivar cuenta, no en activarActivar no destruye nada; desactivar oculta el banco virtual.
Confirm en eliminar representanteEl backend impide eliminar si tiene movimientos asociados; la confirmación evita el viaje.
Conteo Con cuenta en pillDa visibilidad rápida del compromiso contable abierto.
Carga de movimientos a demanda (al seleccionar)El fetch puede ser pesado por representante; lazy load mejora la carga inicial.
Orden por apellido en la tablaPadrón con muchos socios se lee como guía.
Hereda RUT/nombres como identidad mostradaEl header de fila muestra “Nombres Apellidos” sobre “RUT” para escaneo rápido.
Sin filtrar por tiene_cuenta_socioEl filtro vigente cubre el caso normal; agregar otra dimensión saturaría la UI.