Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DanielRivera03/SistemaBancario/llms.txt

Use this file to discover all available pages before exploring further.

Triggers in CashMan H.A. automate state transitions and cross-table updates without requiring any application-level logic in PHP. Whenever a row is inserted, updated, or deleted in a key table, the database itself enforces the downstream consequences — balance recalculations, flag updates, audit entries, and notification delivery all happen inside the same transaction. Scheduled events complement triggers by handling time-based operations that cannot be tied to a user action: detecting newly overdue installments, applying late penalties, expiring security codes, and closing idle support tickets. All trigger and event definitions live in:
  • ScriptSQL/Triggers/tg_cashmanha.sql — 21 triggers
  • ScriptSQL/Events/ev_cashmanha.sql — 5 events

Triggers

Overview Table

Trigger NameTableEventAction
HabilitarSistemaCuentasClientes_PortalCashmancuentasAFTER INSERTSets poseecuenta='si' on usuarios for the new account’s owner
CambioEstadoComprobadorCuotasMensualesClientescuotasAFTER INSERTSets cuotas_generadas='si' on creditos once any installment is inserted
HabilitarSistemaPortalClientes_CreditoscuotasAFTER INSERTSets habilitarsistema='si' on usuarios, unlocking the client portal
ComprobacionCompletarPerfilUsuariosdetalleusuariosAFTER INSERTSets completoperfil='si' on usuarios once the KYC profile row is created
HabilitarNuevasSolicitudesCrediticias_ClienteshistoricocreditosAFTER INSERTSets habilitarnuevoscreditos='si' on usuarios when a credit is archived to history
ComprobacionSolicitudCrediticiaCanceladaClientes_EnvioHistoricohistoricocuotascreditosAFTER INSERTSets enviaralhistorico='si' on the parent credit record
OcultarTransaccionesProcesadasPortalClientes_CreditosCanceladoshistoricocuotascreditosAFTER INSERTSets ocultartransacciones_clientes='si' on the parent credit, hiding old payment rows from the client portal
EnvioNotificacionNuevosMensajesUsuariosmensajeriaAFTER INSERTInserts a nuevomensaje notification row in notificaciones for the recipient
CambioEstadoCancelacionCreditosClientes_UltimaCuotaPagadatransaccionesAFTER INSERTSets credit estado='cancelado' when saldocredito drops below 1 or to 0
CambioEstadoCrediticio_EstadoExcelenteCreditosClientestransaccionesAFTER INSERTPromotes credit rating to Excelente if ≥ 10 on-time payments and current rating is Nuevo Cliente
CambioEstadoCuotasVencidastransaccionesAFTER INSERTChanges overdue installment flag from SI to PT (paid-late) when a payment is received
CambioEstadoCuotas_OrdenPagoCreditosClientestransaccionesAFTER INSERTSets the paid installment’s estadocuota='cancelado'
CambioEstadoRecordCrediticio_CreditocClientestransaccionesAFTER INSERTSets credit rating to Regular after 2 late payments; Deficiente after more than 5
EnvioNotificacionPagoRecibidoClientesCashmanHatransaccionesAFTER INSERTInserts a pagorecibido notification for the paying client
RecalcularSaldoFinal_CreditosClientestransaccionesAFTER INSERTSubtracts the capital portion from creditos.saldocredito (mortgage: annual term ÷ 12; other products: monthly term)
RegistroTransaccionesCuotasCreditosClientes_HistoricotransaccionesAFTER INSERTMirrors every payment row into historicotransacciones for immutable audit
AnularTransaccionesCuentasClientestransaccionescuentasclientesAFTER UPDATEOn AnularRetiro adds amount back to account balance; on AnularDeposito subtracts it
RecalcularSaldoFinal_CuentasAhorroClientestransaccionescuentasclientesAFTER INSERTAdds amount to cuentas.montocuenta for Entrada; subtracts for Salida
RecalcularSaldoFinal_TransferenciasClientestransferenciasAFTER INSERTDebits source account and credits destination account atomically
RegistroMovimientosTransferencias_EnvioTransferenciastransferenciasAFTER INSERTInserts two rows in transaccionescuentasclientes: one EnvioTransferencia for sender, one DepositoTransferencia for recipient
EnviarSolicitudesCreditosDenegadas_HistoricoCreditoscreditosAFTER DELETEArchives the deleted credit’s key fields into historicocreditos

Trigger Details

All eight triggers below fire on the same event — AFTER INSERT ON transacciones. MySQL fires them in definition order. A single installment payment therefore atomically:
  1. Marks the installment paid (CambioEstadoCuotas_OrdenPagoCreditosClientes)
  2. Flips the overdue flag to paid-late if applicable (CambioEstadoCuotasVencidas)
  3. Recalculates the running credit balance (RecalcularSaldoFinal_CreditosClientes)
  4. Checks if the balance has hit zero and marks the credit cancelled (CambioEstadoCancelacionCreditosClientes_UltimaCuotaPagada)
  5. Updates the client credit rating for on-time payment track record (CambioEstadoCrediticio_EstadoExcelenteCreditosClientes)
  6. Updates the client credit rating for late payment track record (CambioEstadoRecordCrediticio_CreditocClientes)
  7. Sends a payment confirmation notification (EnvioNotificacionPagoRecibidoClientesCashmanHa)
  8. Mirrors the row to the audit history table (RegistroTransaccionesCuotasCreditosClientes_Historico)
The trigger computes the capital portion to deduct from saldocredito depending on the product type:
-- Mortgage products (idproducto = 3): term is in years, convert to months
IF _idproducto = 3 THEN
    SET calculocapital = _montocredito / (_plazocredito * 12);
-- All other products: term already in months
ELSE
    SET calculocapital = _montocredito / _plazocredito;
END IF;

UPDATE creditos
    SET saldocredito = saldocredito - calculocapital
    WHERE idcreditos = NEW.idcreditos;
When a row is inserted into transferencias, this trigger performs two sequential UPDATEs inside the same trigger body, ensuring the debit and credit happen atomically:
-- Debit the sender's account
UPDATE cuentas
    SET montocuenta = montocuenta - _monto
    WHERE idcuentas = NEW.idcuentas;

-- Credit the recipient's account
UPDATE cuentas
    SET montocuenta = montocuenta + _monto
    WHERE idcuentas = NEW.idcuentadestino;
The companion trigger RegistroMovimientosTransferencias_EnvioTransferencias then writes two ledger rows into transaccionescuentasclientes for both parties.
Three triggers on transacciones collaborate to maintain creditos.estadocrediticio across the credit lifetime:
Initial state: "Nuevo Cliente"
    ↓ ≥ 10 on-time payments
"Excelente"
    ↓ 2+ late payments
"Regular"
    ↓ more than 5 late payments
"Deficiente"
The views vista_contadorpagosatiempo_creditosclientes and vista_contadorpagoscuotastardias_creditosclientes power the counts queried inside the trigger bodies.

Known Issue

Precision mismatch in RecalcularSaldoFinal_CreditosClientesThe local variable _montocredito inside this trigger is declared as decimal(9,2):
DECLARE _montocredito decimal(9,2);
The corresponding column creditos.montocredito is also decimal(9,2), so this is consistent. However, the intermediate calculation variable calculocapital is declared as decimal(15,6) — which is correct for precision. If you are importing the schema and a credit amount causes intermediate values to exceed decimal(9,2) range (values above 9,999,999.99), the local variable assignment silently truncates.For very large mortgage principals, change the declaration to:
DECLARE _montocredito decimal(15,6);
before importing tg_cashmanha.sql into production.

Scheduled Events

The 5 events defined in ScriptSQL/Events/ev_cashmanha.sql run automatically as long as the MySQL event scheduler is enabled. All five were created with STARTS '2022-04-08 00:00:00' as the anchor date.
The MySQL event scheduler is disabled by default in most installations. Before importing the events file, enable it with:
SET GLOBAL event_scheduler = ON;
To persist across restarts, add event_scheduler = ON to my.cnf / my.ini under the [mysqld] section.

Events Reference

Event NameSchedulePreservationAction
CambioEstadosCodigoSeguridadEvery 30 secondsON COMPLETION PRESERVECalls CALL CambioEstadoCodigoSeguridad() — marks expired password-recovery tokens as vencido
CambioEstadoCuotasClientes_IncumplimientoPagosEvery 100 secondsON COMPLETION NOT PRESERVESets incumplimiento_pago='SI' on cuotas rows via vista_calculodiasfechavencimiento_cuotasclientes where dias_incumplimiento > 0 and installment is still pendiente
SumatoriaMoraCuotasClientesVencidasEvery 1 dayON COMPLETION NOT PRESERVEAdds $5.99 penalty to montocancelar on every overdue installment (incumplimiento_pago='SI')
CambioEstadoTicketsReportesPlataforma_InactividadEvery 2 minutesON COMPLETION NOT PRESERVEAuto-closes support tickets via vista_calculo_ultimaactividad_ticketsreportesplataforma where status is resuelto, no resuelto, or idle for more than 3 days
ExpirarCodigoSeguridad_TransferenciasClientesEvery 30 secondsON COMPLETION NOT PRESERVESets transfer OTP codes to Vencido via vista_calculaduracioncodigoseguridad_transferencias where minutos_expiracion > 2

Event Behaviour Notes

These two events look similar but target different tables and different security flows:
  • CambioEstadosCodigoSeguridad — Targets password recovery codes in the recuperacion table (via the vista_calculoexpiracion_codigocambiocredencialesusuarios view). It calls the stored procedure CambioEstadoCodigoSeguridad(). Codes expire after 6 minutes (minutos_expiracion > 6) and must already be in the usado state. This event is PRESERVEd — it continues to exist after it runs.
  • ExpirarCodigoSeguridad_TransferenciasClientes — Targets transfer OTP codes in the codigostransferencias table (via vista_calculaduracioncodigoseguridad_transferencias). OTPs expire after 2 minutes (minutos_expiracion > 2), setting estado='Vencido'. This is a direct UPDATE, not a procedure call.
SumatoriaMoraCuotasClientesVencidas runs once per day and adds a flat $5.99 fee to every installment where incumplimiento_pago = 'SI'. This means a client overdue by 10 days has accumulated $59.90 in penalties on top of the original montocuota.The stored procedure SumatoriaIncumplimientoMora_CuotasClientes performs the same calculation on demand and can be called manually to force a penalty recalculation outside the scheduled cycle.
Four of the five events are defined with ON COMPLETION NOT PRESERVE. In MySQL this means the event definition is automatically deleted from the mysql.event table after it would have naturally concluded. Because all four use ON SCHEDULE EVERY ... (recurring), they never naturally conclude and so are never dropped — the NOT PRESERVE flag only matters for one-time events. The net effect is the same as PRESERVE for recurring schedules.

Trigger & Event Dependency Map

INSERT cuotas
  └─► CambioEstadoComprobadorCuotasMensualesClientes  →  creditos.cuotas_generadas = 'si'
  └─► HabilitarSistemaPortalClientes_Creditos          →  usuarios.habilitarsistema = 'si'

INSERT detalleusuarios
  └─► ComprobacionCompletarPerfilUsuarios              →  usuarios.completoperfil = 'si'

INSERT cuentas
  └─► HabilitarSistemaCuentasClientes_PortalCashman    →  usuarios.poseecuenta = 'si'

INSERT mensajeria
  └─► EnvioNotificacionNuevosMensajesUsuarios          →  notificaciones (INSERT)

INSERT transacciones  (8 triggers)
  ├─► CambioEstadoCuotas_OrdenPagoCreditosClientes     →  cuotas.estadocuota = 'cancelado'
  ├─► CambioEstadoCuotasVencidas                       →  cuotas.incumplimiento_pago = 'PT'
  ├─► RecalcularSaldoFinal_CreditosClientes            →  creditos.saldocredito -= capital
  ├─► CambioEstadoCancelacionCreditosClientes_*        →  creditos.estado = 'cancelado' if balance ≤ 0
  ├─► CambioEstadoCrediticio_Excelente                 →  creditos.estadocrediticio = 'Excelente'
  ├─► CambioEstadoRecordCrediticio_*                   →  creditos.estadocrediticio = 'Regular'/'Deficiente'
  ├─► EnvioNotificacionPagoRecibido*                   →  notificaciones (INSERT)
  └─► RegistroTransacciones*_Historico                 →  historicotransacciones (INSERT)

INSERT transaccionescuentasclientes
  └─► RecalcularSaldoFinal_CuentasAhorroClientes       →  cuentas.montocuenta ± monto

UPDATE transaccionescuentasclientes
  └─► AnularTransaccionesCuentasClientes               →  cuentas.montocuenta ± monto (reversal)

INSERT transferencias  (2 triggers)
  ├─► RecalcularSaldoFinal_TransferenciasClientes      →  cuentas balance swap
  └─► RegistroMovimientosTransferencias_*              →  transaccionescuentasclientes (2 INSERTs)

INSERT historicocreditos
  └─► HabilitarNuevasSolicitudesCrediticias_Clientes   →  usuarios.habilitarnuevoscreditos = 'si'

INSERT historicocuotascreditos  (2 triggers)
  ├─► ComprobacionSolicitudCrediticia*_EnvioHistorico  →  creditos.enviaralhistorico = 'si'
  └─► OcultarTransacciones*_CreditosCancelados         →  creditos.ocultartransacciones_clientes = 'si'

DELETE creditos
  └─► EnviarSolicitudesCreditosDenegadas_*             →  historicocreditos (INSERT)

Build docs developers (and LLMs) love