Migrations
in package
Ejecutor de migraciones del núcleo y de los plugins.
Cada migración es una pequeña tarea idempotente que arregla datos heredados o ajusta el esquema tras un cambio incompatible (por ejemplo, desvincular registros huérfanos, normalizar valores de excepciones de IVA o forzar la creación/comprobación de una tabla instanciando su modelo).
Las migraciones se identifican por nombre y solo se ejecutan una vez: el listado de las ya
aplicadas se guarda en MyFiles/migrations.json. Si el JSON se borra, todas las migraciones
volverán a ejecutarse, por eso cada una está pensada para ser segura de re-ejecutar (comprueba
existencia de tablas/columnas, sólo actúa si hay datos a corregir, etc.).
Las migraciones del núcleo se registran en run(). Los plugins pueden registrar las suyas
extendiendo MigrationClass y llamando a runPluginMigration() / runPluginMigrations()
desde su inicialización.
Table of Contents
Constants
- FILE_NAME : mixed = 'migrations.json'
- Nombre del fichero JSON, dentro de MyFiles, donde se persisten las migraciones ya ejecutadas.
Properties
- $database : mixed
- Conexión perezosa a la base de datos, compartida entre todas las migraciones de la ejecución.
Methods
- run() : void
- Ejecuta todas las migraciones del núcleo en el orden definido.
- runPluginMigration() : void
- Ejecuta una migración de plugin si no se había ejecutado previamente.
- runPluginMigrations() : void
- Ejecuta una lista de migraciones de plugin en el orden recibido.
- clearLogs() : void
- Purga logs antiguos del canal "master" cuando la tabla supera 20.000 filas.
- db() : DataBase
- Devuelve la conexión a base de datos, abriéndola la primera vez (singleton perezoso interno).
- fixAgenciasTransporte() : void
- Pone a NULL los `codtrans` huérfanos en documentos de venta.
- fixAgentes() : void
- Pone a NULL los `codagente` huérfanos en documentos y entidades relacionadas.
- fixApiKeysUsers() : void
- Desvincula las api_keys cuyo `nick` apunta a un usuario que ya no existe.
- fixClientesOperationFromVatException() : void
- Rellena `clientes.operacion` a partir de `clientes.excepcioniva` cuando viene vacía.
- fixFormasPago() : void
- Recupera formas de pago referenciadas pero inexistentes recreándolas como inactivas.
- fixRectifiedInvoices() : void
- Anula `idfacturarect` en facturas que rectifican a una factura inexistente.
- fixSeries() : void
- Marca con tipo "R" la serie configurada como rectificativa en el panel de control.
- fixTaxException() : void
- Renombra códigos antiguos de excepción de IVA a su nuevo identificador en todas las tablas afectadas.
- getExecutedMigrations() : array<string|int, mixed>
- Devuelve la lista de migraciones ya ejecutadas, leyéndola del fichero JSON.
- isMigrationExecuted() : bool
- Indica si la migración con ese nombre ya consta como ejecutada en el JSON de control.
- markMigrationAsExecuted() : void
- Registra una migración como ejecutada, persistiendo el cambio en `MyFiles/migrations.json`.
- runMigration() : void
- Ejecuta el callback indicado y marca la migración como aplicada, salvo que ya lo estuviera.
Constants
FILE_NAME
Nombre del fichero JSON, dentro de MyFiles, donde se persisten las migraciones ya ejecutadas.
public
mixed
FILE_NAME
= 'migrations.json'
Properties
$database
Conexión perezosa a la base de datos, compartida entre todas las migraciones de la ejecución.
private
static mixed
$database
@var DataBase
Methods
run()
Ejecuta todas las migraciones del núcleo en el orden definido.
public
static run() : void
Cada migración se invoca a través de runMigration(), que se encarga de saltarla si ya
había sido aplicada anteriormente. El orden importa: hay migraciones que dependen de que
otras hayan creado/normalizado datos antes (por ejemplo, las que desvinculan registros
huérfanos asumen que las tablas referenciadas ya existen).
runPluginMigration()
Ejecuta una migración de plugin si no se había ejecutado previamente.
public
static runPluginMigration(MigrationClass $migration) : void
El nombre completo (que se compara contra el registro persistido) lo proporciona la propia
migración mediante getFullMigrationName(), lo que permite a cada plugin elegir un esquema
de nombrado que evite colisiones con otros plugins o con el núcleo.
Parameters
- $migration : MigrationClass
-
instancia ya construida de la migración a ejecutar
runPluginMigrations()
Ejecuta una lista de migraciones de plugin en el orden recibido.
public
static runPluginMigrations(array<string|int, MigrationClass> $migrations) : void
Es un simple atajo sobre runPluginMigration(); cada migración decide individualmente
si debe ejecutarse según el registro persistido.
Parameters
- $migrations : array<string|int, MigrationClass>
-
migraciones a ejecutar, en orden
clearLogs()
Purga logs antiguos del canal "master" cuando la tabla supera 20.000 filas.
private
static clearLogs() : void
Si el canal master tiene menos de 20.000 registros no se hace nada. En caso contrario, se borran las entradas con más de un mes de antigüedad para evitar que la tabla siga creciendo y degrade el rendimiento de las consultas que la usan (página de logs, etc.).
db()
Devuelve la conexión a base de datos, abriéndola la primera vez (singleton perezoso interno).
private
static db() : DataBase
Return values
DataBasefixAgenciasTransporte()
Pone a NULL los `codtrans` huérfanos en documentos de venta.
private
static fixAgenciasTransporte() : void
Se instancia AgenciaTransporte para asegurar que la tabla agenciastrans existe y, a
continuación, se anulan los códigos de agencia que ya no se encuentran en ella.
fixAgentes()
Pone a NULL los `codagente` huérfanos en documentos y entidades relacionadas.
private
static fixAgentes() : void
Versión 2025.01, fecha 02-12-2025. Se instancia el modelo Agente para forzar la creación
o comprobación de la tabla agentes antes de la limpieza. A partir de ahí, en cada tabla
existente se anulan los códigos de agente que ya no aparecen en agentes, evitando claves
foráneas rotas que romperían validaciones posteriores.
fixApiKeysUsers()
Desvincula las api_keys cuyo `nick` apunta a un usuario que ya no existe.
private
static fixApiKeysUsers() : void
Versión 2025.01, fecha 02-12-2025. Si alguna de las dos tablas (api_keys o users)
todavía no existe, la migración no hace nada y se da por aplicada en la siguiente vuelta.
fixClientesOperationFromVatException()
Rellena `clientes.operacion` a partir de `clientes.excepcioniva` cuando viene vacía.
private
static fixClientesOperationFromVatException() : void
Versión 2026.01, fecha 06-03-2026. Con la nueva validación, ciertas excepciones de IVA
(exportaciones y operaciones intracomunitarias) requieren que el cliente tenga informada
la operación. Para no romper a clientes ya existentes, esta migración mapea las excepciones
conocidas a su operación correspondiente, pero sólo cuando la columna operacion está NULL
(no se sobrescriben valores ya configurados manualmente).
fixFormasPago()
Recupera formas de pago referenciadas pero inexistentes recreándolas como inactivas.
private
static fixFormasPago() : void
Versión 2024.5, fecha 15-04-2024. En lugar de anular los codpago huérfanos (lo que
perdería la trazabilidad histórica de los documentos), se reconstruyen los registros
faltantes en formaspago con activa=false y descripción "deleted". Si el modelo no
puede guardarlos (por ejemplo por validaciones), se recurre a un INSERT directo por SQL
para garantizar que la integridad referencial queda restaurada.
fixRectifiedInvoices()
Anula `idfacturarect` en facturas que rectifican a una factura inexistente.
private
static fixRectifiedInvoices() : void
Versión 2024.5, fecha 16-04-2024. La subconsulta se envuelve en otro SELECT (alias
subquery) para sortear la limitación de MySQL que impide referenciar la misma tabla
que se está actualizando dentro de un IN/NOT IN; ese rodeo hace que MySQL la materialice
y la trate como una fuente independiente.
fixSeries()
Marca con tipo "R" la serie configurada como rectificativa en el panel de control.
private
static fixSeries() : void
Versión 2023.06, fecha 07-10-2023. Antes la serie rectificativa se identificaba sólo por
el ajuste default.codserierec; ahora cada serie lleva además un campo tipo. Si no hay
serie configurada, la migración no hace nada.
fixTaxException()
Renombra códigos antiguos de excepción de IVA a su nuevo identificador en todas las tablas afectadas.
private
static fixTaxException() : void
TODO: añadir versión y fecha de lanzamiento. Se instancian primero los modelos para forzar
la creación/comprobación de las tablas, y después se aplica un UPDATE con CASE que mapea los
códigos heredados (ES_N1, ES_ART_7, etc.) a los nuevos (ES_7, ES_84, ...). Las tablas
sin la columna excepcioniva se saltan, lo que permite que la migración sea segura aunque
algún plugin haya alterado el esquema.
getExecutedMigrations()
Devuelve la lista de migraciones ya ejecutadas, leyéndola del fichero JSON.
private
static getExecutedMigrations() : array<string|int, mixed>
Cualquier problema (fichero ausente, lectura fallida o JSON corrupto) se trata como "no hay migraciones ejecutadas", lo que provoca que se reintenten todas. Por eso cada migración debe ser idempotente.
Return values
array<string|int, mixed>isMigrationExecuted()
Indica si la migración con ese nombre ya consta como ejecutada en el JSON de control.
private
static isMigrationExecuted(string $migrationName) : bool
Parameters
- $migrationName : string
Return values
boolmarkMigrationAsExecuted()
Registra una migración como ejecutada, persistiendo el cambio en `MyFiles/migrations.json`.
private
static markMigrationAsExecuted(string $migrationName) : void
Si el nombre ya estaba registrado no se hace nada. Antes de escribir se asegura que el
directorio MyFiles existe; el JSON se guarda con JSON_PRETTY_PRINT para que sea legible
y diffeable a mano.
Parameters
- $migrationName : string
runMigration()
Ejecuta el callback indicado y marca la migración como aplicada, salvo que ya lo estuviera.
private
static runMigration(string $migrationName, callable $callback) : void
Es el único punto por el que pasan todas las migraciones del núcleo. Si el callback lanza una excepción, la migración no se marcará como ejecutada y se reintentará en el próximo arranque.
Parameters
- $migrationName : string
- $callback : callable