FacturaScripts

Migrations
in package

FinalYes

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
DataBase

fixAgenciasTransporte()

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
bool

markMigrationAsExecuted()

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
On this page

Search results