-- Fase 1D -- Script de desarrollo idempotente y conservador para separar Proformas / Issued Invoices. -- Objetivo: -- 1. Crear tablas V2 si no existen. -- 2. Backfill conservador desde legacy sin borrar ni modificar tablas legacy. -- 3. Poder reejecutarse sin duplicar datos. -- -- Importante: -- - No ejecutar en produccion sin backup verificado y ventana controlada. -- - No usa DROP/TRUNCATE/DELETE sobre tablas V2 ni legacy. -- - No usa INSERT IGNORE para no ocultar inconsistencias. START TRANSACTION; -- --------------------------------------------------------------------------- -- 0. Compatibilidad transicional de Verifactu -- --------------------------------------------------------------------------- ALTER TABLE verifactu_records ADD COLUMN IF NOT EXISTS issued_invoice_id CHAR(36) NULL AFTER invoice_id; -- --------------------------------------------------------------------------- -- 1. Tablas V2 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS proformas ( id CHAR(36) NOT NULL, company_id CHAR(36) NOT NULL, status VARCHAR(255) NOT NULL DEFAULT 'draft', proforma_reference VARCHAR(32) NOT NULL, proforma_date DATE NOT NULL, operation_date DATE NULL, target_invoice_series_code VARCHAR(10) NULL, reference VARCHAR(255) NULL, description VARCHAR(255) NULL, notes TEXT NULL, language_code VARCHAR(2) NOT NULL DEFAULT 'es', currency_code VARCHAR(3) NOT NULL DEFAULT 'EUR', payment_method_id CHAR(36) NULL, payment_term_id CHAR(36) NULL, tax_regime_code VARCHAR(2) NULL, subtotal_amount_value BIGINT NOT NULL DEFAULT 0, subtotal_amount_scale SMALLINT NOT NULL DEFAULT 2, items_discount_amount_value BIGINT NOT NULL DEFAULT 0, items_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, global_discount_percentage_value SMALLINT NOT NULL DEFAULT 0, global_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, global_discount_amount_value BIGINT NOT NULL DEFAULT 0, global_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, total_discount_amount_value BIGINT NOT NULL DEFAULT 0, total_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NULL, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_amount_value BIGINT NULL, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_amount_value BIGINT NULL, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 2, total_amount_value BIGINT NOT NULL DEFAULT 0, total_amount_scale SMALLINT NOT NULL DEFAULT 2, customer_id CHAR(36) NOT NULL, customer_tin VARCHAR(255) NULL, customer_name VARCHAR(255) NULL, customer_street VARCHAR(255) NULL, customer_street2 VARCHAR(255) NULL, customer_city VARCHAR(255) NULL, customer_province VARCHAR(255) NULL, customer_postal_code VARCHAR(255) NULL, customer_country VARCHAR(255) NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, deleted_at DATETIME NULL, PRIMARY KEY (id), UNIQUE KEY uq_proformas_company_reference ( company_id, proforma_reference ), KEY idx_proformas_company (company_id), KEY idx_proformas_company_date ( company_id, deleted_at, proforma_date ) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS proforma_items ( item_id CHAR(36) NOT NULL, proforma_id CHAR(36) NOT NULL, position mediumint(8) unsigned NOT NULL, description TEXT NULL, quantity_value BIGINT NULL, quantity_scale SMALLINT NOT NULL DEFAULT 2, unit_amount_value BIGINT NULL, unit_amount_scale SMALLINT NOT NULL DEFAULT 4, subtotal_amount_value BIGINT NOT NULL DEFAULT 0, subtotal_amount_scale SMALLINT NOT NULL DEFAULT 4, item_discount_percentage_value SMALLINT NULL, item_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, item_discount_amount_value BIGINT NOT NULL DEFAULT 0, item_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, global_discount_percentage_value SMALLINT NOT NULL DEFAULT 0, global_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, global_discount_amount_value BIGINT NOT NULL DEFAULT 0, global_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, total_discount_amount_value BIGINT NOT NULL DEFAULT 0, total_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 4, iva_code VARCHAR(40) NULL, iva_percentage_value SMALLINT NULL, iva_percentage_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NOT NULL DEFAULT 0, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_code VARCHAR(40) NULL, rec_percentage_value SMALLINT NULL, rec_percentage_scale SMALLINT NOT NULL DEFAULT 2, rec_amount_value BIGINT NOT NULL DEFAULT 0, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_code VARCHAR(40) NULL, retention_percentage_value SMALLINT NULL, retention_percentage_scale SMALLINT NOT NULL DEFAULT 2, retention_amount_value BIGINT NOT NULL DEFAULT 0, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 4, total_amount_value BIGINT NOT NULL DEFAULT 0, total_amount_scale SMALLINT NOT NULL DEFAULT 4, PRIMARY KEY (item_id), KEY idx_proforma_items_proforma_id (proforma_id), KEY idx_proforma_items_proforma_position (proforma_id, position) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS proforma_taxes ( tax_id CHAR(36) NOT NULL, proforma_id CHAR(36) NOT NULL, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 4, iva_code VARCHAR(40) NULL, iva_percentage_value SMALLINT NULL, iva_percentage_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NULL, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_code VARCHAR(40) NULL, rec_percentage_value SMALLINT NULL, rec_percentage_scale SMALLINT NOT NULL DEFAULT 2, rec_amount_value BIGINT NULL, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_code VARCHAR(40) NULL, retention_percentage_value SMALLINT NULL, retention_percentage_scale SMALLINT NOT NULL DEFAULT 2, retention_amount_value BIGINT NULL, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 4, PRIMARY KEY (tax_id), UNIQUE KEY proforma_iva_code_unique (proforma_id, iva_code), KEY proforma_id_idx (proforma_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS issued_invoices ( id CHAR(36) NOT NULL, company_id CHAR(36) NOT NULL, status VARCHAR(255) NOT NULL DEFAULT 'issued', source_proforma_id CHAR(36) NULL, invoice_series_code VARCHAR(10) NOT NULL, invoice_number VARCHAR(12) NOT NULL, invoice_date DATE NOT NULL, operation_date DATE NULL, reference VARCHAR(255) NULL, description VARCHAR(255) NOT NULL DEFAULT '', notes TEXT NULL, language_code VARCHAR(2) NOT NULL DEFAULT 'es', currency_code VARCHAR(3) NOT NULL DEFAULT 'EUR', payment_method_id CHAR(36) NULL, payment_method_name VARCHAR(255) NULL, payment_method_description VARCHAR(255) NULL, payment_term_id CHAR(36) NULL, payment_term_name VARCHAR(255) NULL, payment_term_description VARCHAR(255) NULL, payment_term_snapshot_json TEXT NULL, tax_regime_code VARCHAR(2) NOT NULL, tax_regime_description VARCHAR(255) NOT NULL, subtotal_amount_value BIGINT NOT NULL DEFAULT 0, subtotal_amount_scale SMALLINT NOT NULL DEFAULT 2, items_discount_amount_value BIGINT NOT NULL DEFAULT 0, items_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, global_discount_percentage_value SMALLINT NOT NULL DEFAULT 0, global_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, global_discount_amount_value BIGINT NOT NULL DEFAULT 0, global_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, total_discount_amount_value BIGINT NOT NULL DEFAULT 0, total_discount_amount_scale SMALLINT NOT NULL DEFAULT 2, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NULL, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_amount_value BIGINT NULL, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_amount_value BIGINT NULL, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 2, total_amount_value BIGINT NOT NULL DEFAULT 0, total_amount_scale SMALLINT NOT NULL DEFAULT 2, customer_id CHAR(36) NOT NULL, customer_tin VARCHAR(255) NULL, customer_name VARCHAR(255) NULL, customer_street VARCHAR(255) NULL, customer_street2 VARCHAR(255) NULL, customer_city VARCHAR(255) NULL, customer_province VARCHAR(255) NULL, customer_postal_code VARCHAR(255) NULL, customer_country VARCHAR(255) NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, deleted_at DATETIME NULL, PRIMARY KEY (id), UNIQUE KEY uq_issued_invoice_company_series_number ( company_id, invoice_series_code, invoice_number ), UNIQUE KEY uq_issued_invoice_source_proforma_id (source_proforma_id), KEY idx_issued_invoices_company (company_id), KEY idx_issued_invoices_company_date ( company_id, deleted_at, invoice_date ) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS issued_invoice_items ( item_id CHAR(36) NOT NULL, issued_invoice_id CHAR(36) NOT NULL, position mediumint(8) unsigned NOT NULL, description TEXT NULL, quantity_value BIGINT NULL, quantity_scale SMALLINT NOT NULL DEFAULT 2, unit_amount_value BIGINT NULL, unit_amount_scale SMALLINT NOT NULL DEFAULT 4, subtotal_amount_value BIGINT NOT NULL DEFAULT 0, subtotal_amount_scale SMALLINT NOT NULL DEFAULT 4, item_discount_percentage_value SMALLINT NULL, item_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, item_discount_amount_value BIGINT NOT NULL DEFAULT 0, item_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, global_discount_percentage_value SMALLINT NOT NULL DEFAULT 0, global_discount_percentage_scale SMALLINT NOT NULL DEFAULT 2, global_discount_amount_value BIGINT NOT NULL DEFAULT 0, global_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, total_discount_amount_value BIGINT NOT NULL DEFAULT 0, total_discount_amount_scale SMALLINT NOT NULL DEFAULT 4, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 4, iva_code VARCHAR(40) NULL, iva_percentage_value SMALLINT NULL, iva_percentage_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NOT NULL DEFAULT 0, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_code VARCHAR(40) NULL, rec_percentage_value SMALLINT NULL, rec_percentage_scale SMALLINT NOT NULL DEFAULT 2, rec_amount_value BIGINT NOT NULL DEFAULT 0, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_code VARCHAR(40) NULL, retention_percentage_value SMALLINT NULL, retention_percentage_scale SMALLINT NOT NULL DEFAULT 2, retention_amount_value BIGINT NOT NULL DEFAULT 0, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 4, total_amount_value BIGINT NOT NULL DEFAULT 0, total_amount_scale SMALLINT NOT NULL DEFAULT 4, PRIMARY KEY (item_id), KEY idx_issued_invoice_items_invoice_id (issued_invoice_id), KEY idx_issued_invoice_items_invoice_position (issued_invoice_id, position) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS issued_invoice_taxes ( tax_id CHAR(36) NOT NULL, issued_invoice_id CHAR(36) NOT NULL, taxable_amount_value BIGINT NOT NULL DEFAULT 0, taxable_amount_scale SMALLINT NOT NULL DEFAULT 4, iva_code VARCHAR(40) NULL, iva_percentage_value SMALLINT NULL, iva_percentage_scale SMALLINT NOT NULL DEFAULT 2, iva_amount_value BIGINT NULL, iva_amount_scale SMALLINT NOT NULL DEFAULT 4, rec_code VARCHAR(40) NULL, rec_percentage_value SMALLINT NULL, rec_percentage_scale SMALLINT NOT NULL DEFAULT 2, rec_amount_value BIGINT NULL, rec_amount_scale SMALLINT NOT NULL DEFAULT 4, retention_code VARCHAR(40) NULL, retention_percentage_value SMALLINT NULL, retention_percentage_scale SMALLINT NOT NULL DEFAULT 2, retention_amount_value BIGINT NULL, retention_amount_scale SMALLINT NOT NULL DEFAULT 4, taxes_amount_value BIGINT NOT NULL DEFAULT 0, taxes_amount_scale SMALLINT NOT NULL DEFAULT 4, PRIMARY KEY (tax_id), UNIQUE KEY issued_invoice_iva_code_unique (issued_invoice_id, iva_code), KEY issued_invoice_id_idx (issued_invoice_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- --------------------------------------------------------------------------- -- 2. Backfill cabeceras -- --------------------------------------------------------------------------- INSERT INTO proformas ( id, company_id, status, proforma_reference, proforma_date, operation_date, target_invoice_series_code, reference, description, notes, language_code, currency_code, payment_method_id, payment_term_id, tax_regime_code, subtotal_amount_value, subtotal_amount_scale, items_discount_amount_value, items_discount_amount_scale, global_discount_percentage_value, global_discount_percentage_scale, global_discount_amount_value, global_discount_amount_scale, total_discount_amount_value, total_discount_amount_scale, taxable_amount_value, taxable_amount_scale, iva_amount_value, iva_amount_scale, rec_amount_value, rec_amount_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale, total_amount_value, total_amount_scale, customer_id, customer_tin, customer_name, customer_street, customer_street2, customer_city, customer_province, customer_postal_code, customer_country, created_at, updated_at, deleted_at ) SELECT ci.id, ci.company_id, ci.status, ci.invoice_number, ci.invoice_date, ci.operation_date, ci.series, ci.reference, ci.description, ci.notes, ci.language_code, ci.currency_code, ci.payment_method_id, NULL AS payment_term_id, ci.tax_regime_code, ci.subtotal_amount_value, ci.subtotal_amount_scale, ci.items_discount_amount_value, ci.items_discount_amount_scale, ci.global_discount_percentage_value, ci.global_discount_percentage_scale, ci.global_discount_amount_value, ci.global_discount_amount_scale, ci.total_discount_amount_value, ci.total_discount_amount_scale, ci.taxable_amount_value, ci.taxable_amount_scale, ci.iva_amount_value, ci.iva_amount_scale, ci.rec_amount_value, ci.rec_amount_scale, ci.retention_amount_value, ci.retention_amount_scale, ci.taxes_amount_value, ci.taxes_amount_scale, ci.total_amount_value, ci.total_amount_scale, ci.customer_id, ci.customer_tin, ci.customer_name, ci.customer_street, ci.customer_street2, ci.customer_city, ci.customer_province, ci.customer_postal_code, ci.customer_country, ci.created_at, ci.updated_at, ci.deleted_at FROM customer_invoices ci WHERE ci.is_proforma = 1 AND ci.invoice_number IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM proformas p WHERE p.id = ci.id ); INSERT INTO issued_invoices ( id, company_id, status, source_proforma_id, invoice_series_code, invoice_number, invoice_date, operation_date, reference, description, notes, language_code, currency_code, payment_method_id, payment_method_name, payment_method_description, payment_term_id, payment_term_name, payment_term_description, payment_term_snapshot_json, tax_regime_code, tax_regime_description, subtotal_amount_value, subtotal_amount_scale, items_discount_amount_value, items_discount_amount_scale, global_discount_percentage_value, global_discount_percentage_scale, global_discount_amount_value, global_discount_amount_scale, total_discount_amount_value, total_discount_amount_scale, taxable_amount_value, taxable_amount_scale, iva_amount_value, iva_amount_scale, rec_amount_value, rec_amount_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale, total_amount_value, total_amount_scale, customer_id, customer_tin, customer_name, customer_street, customer_street2, customer_city, customer_province, customer_postal_code, customer_country, created_at, updated_at, deleted_at ) SELECT ci.id, ci.company_id, ci.status, ci.proforma_id, COALESCE(ci.series, ''), ci.invoice_number, ci.invoice_date, ci.operation_date, ci.reference, COALESCE(ci.description, ''), ci.notes, ci.language_code, ci.currency_code, ci.payment_method_id, ci.payment_method_description, ci.payment_method_description, NULL AS payment_term_id, NULL AS payment_term_name, NULL AS payment_term_description, NULL AS payment_term_snapshot_json, COALESCE(ci.tax_regime_code, '01'), COALESCE( ci.tax_regime_description, ci.tax_regime_code, '01: Operación de régimen general.' ), ci.subtotal_amount_value, ci.subtotal_amount_scale, ci.items_discount_amount_value, ci.items_discount_amount_scale, ci.global_discount_percentage_value, ci.global_discount_percentage_scale, ci.global_discount_amount_value, ci.global_discount_amount_scale, ci.total_discount_amount_value, ci.total_discount_amount_scale, ci.taxable_amount_value, ci.taxable_amount_scale, ci.iva_amount_value, ci.iva_amount_scale, ci.rec_amount_value, ci.rec_amount_scale, ci.retention_amount_value, ci.retention_amount_scale, ci.taxes_amount_value, ci.taxes_amount_scale, ci.total_amount_value, ci.total_amount_scale, ci.customer_id, ci.customer_tin, ci.customer_name, ci.customer_street, ci.customer_street2, ci.customer_city, ci.customer_province, ci.customer_postal_code, ci.customer_country, ci.created_at, ci.updated_at, ci.deleted_at FROM customer_invoices ci WHERE ci.is_proforma = 0 AND ci.invoice_number IS NOT NULL AND ci.series IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM issued_invoices ii WHERE ii.id = ci.id ); -- --------------------------------------------------------------------------- -- 3. Backfill items -- --------------------------------------------------------------------------- INSERT INTO proforma_items ( item_id, proforma_id, position, description, quantity_value, quantity_scale, unit_amount_value, unit_amount_scale, subtotal_amount_value, subtotal_amount_scale, item_discount_percentage_value, item_discount_percentage_scale, item_discount_amount_value, item_discount_amount_scale, global_discount_percentage_value, global_discount_percentage_scale, global_discount_amount_value, global_discount_amount_scale, total_discount_amount_value, total_discount_amount_scale, taxable_amount_value, taxable_amount_scale, iva_code, iva_percentage_value, iva_percentage_scale, iva_amount_value, iva_amount_scale, rec_code, rec_percentage_value, rec_percentage_scale, rec_amount_value, rec_amount_scale, retention_code, retention_percentage_value, retention_percentage_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale, total_amount_value, total_amount_scale ) SELECT i.item_id, i.invoice_id, i.position, i.description, i.quantity_value, i.quantity_scale, i.unit_amount_value, i.unit_amount_scale, i.subtotal_amount_value, i.subtotal_amount_scale, i.item_discount_percentage_value, i.item_discount_percentage_scale, i.item_discount_amount_value, i.item_discount_amount_scale, i.global_discount_percentage_value, i.global_discount_percentage_scale, i.global_discount_amount_value, i.global_discount_amount_scale, i.total_discount_amount_value, i.total_discount_amount_scale, i.taxable_amount_value, i.taxable_amount_scale, i.iva_code, i.iva_percentage_value, i.iva_percentage_scale, i.iva_amount_value, i.iva_amount_scale, i.rec_code, i.rec_percentage_value, i.rec_percentage_scale, i.rec_amount_value, i.rec_amount_scale, i.retention_code, i.retention_percentage_value, i.retention_percentage_scale, i.retention_amount_value, i.retention_amount_scale, i.taxes_amount_value, i.taxes_amount_scale, i.total_amount_value, i.total_amount_scale FROM customer_invoice_items i JOIN customer_invoices ci ON ci.id = i.invoice_id JOIN proformas p ON p.id = ci.id WHERE ci.is_proforma = 1 AND NOT EXISTS ( SELECT 1 FROM proforma_items pi WHERE pi.item_id = i.item_id ); INSERT INTO issued_invoice_items ( item_id, issued_invoice_id, position, description, quantity_value, quantity_scale, unit_amount_value, unit_amount_scale, subtotal_amount_value, subtotal_amount_scale, item_discount_percentage_value, item_discount_percentage_scale, item_discount_amount_value, item_discount_amount_scale, global_discount_percentage_value, global_discount_percentage_scale, global_discount_amount_value, global_discount_amount_scale, total_discount_amount_value, total_discount_amount_scale, taxable_amount_value, taxable_amount_scale, iva_code, iva_percentage_value, iva_percentage_scale, iva_amount_value, iva_amount_scale, rec_code, rec_percentage_value, rec_percentage_scale, rec_amount_value, rec_amount_scale, retention_code, retention_percentage_value, retention_percentage_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale, total_amount_value, total_amount_scale ) SELECT i.item_id, i.invoice_id, i.position, i.description, i.quantity_value, i.quantity_scale, i.unit_amount_value, i.unit_amount_scale, i.subtotal_amount_value, i.subtotal_amount_scale, i.item_discount_percentage_value, i.item_discount_percentage_scale, i.item_discount_amount_value, i.item_discount_amount_scale, i.global_discount_percentage_value, i.global_discount_percentage_scale, i.global_discount_amount_value, i.global_discount_amount_scale, i.total_discount_amount_value, i.total_discount_amount_scale, i.taxable_amount_value, i.taxable_amount_scale, i.iva_code, i.iva_percentage_value, i.iva_percentage_scale, i.iva_amount_value, i.iva_amount_scale, i.rec_code, i.rec_percentage_value, i.rec_percentage_scale, i.rec_amount_value, i.rec_amount_scale, i.retention_code, i.retention_percentage_value, i.retention_percentage_scale, i.retention_amount_value, i.retention_amount_scale, i.taxes_amount_value, i.taxes_amount_scale, i.total_amount_value, i.total_amount_scale FROM customer_invoice_items i JOIN customer_invoices ci ON ci.id = i.invoice_id JOIN issued_invoices ii ON ii.id = ci.id WHERE ci.is_proforma = 0 AND NOT EXISTS ( SELECT 1 FROM issued_invoice_items iii WHERE iii.item_id = i.item_id ); -- --------------------------------------------------------------------------- -- 4. Backfill taxes -- --------------------------------------------------------------------------- INSERT INTO proforma_taxes ( tax_id, proforma_id, taxable_amount_value, taxable_amount_scale, iva_code, iva_percentage_value, iva_percentage_scale, iva_amount_value, iva_amount_scale, rec_code, rec_percentage_value, rec_percentage_scale, rec_amount_value, rec_amount_scale, retention_code, retention_percentage_value, retention_percentage_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale ) SELECT t.tax_id, t.invoice_id, t.taxable_amount_value, t.taxable_amount_scale, t.iva_code, t.iva_percentage_value, t.iva_percentage_scale, t.iva_amount_value, t.iva_amount_scale, t.rec_code, t.rec_percentage_value, t.rec_percentage_scale, t.rec_amount_value, t.rec_amount_scale, t.retention_code, t.retention_percentage_value, t.retention_percentage_scale, t.retention_amount_value, t.retention_amount_scale, t.taxes_amount_value, t.taxes_amount_scale FROM customer_invoice_taxes t JOIN customer_invoices ci ON ci.id = t.invoice_id JOIN proformas p ON p.id = ci.id WHERE ci.is_proforma = 1 AND NOT EXISTS ( SELECT 1 FROM proforma_taxes pt WHERE pt.tax_id = t.tax_id ); INSERT INTO issued_invoice_taxes ( tax_id, issued_invoice_id, taxable_amount_value, taxable_amount_scale, iva_code, iva_percentage_value, iva_percentage_scale, iva_amount_value, iva_amount_scale, rec_code, rec_percentage_value, rec_percentage_scale, rec_amount_value, rec_amount_scale, retention_code, retention_percentage_value, retention_percentage_scale, retention_amount_value, retention_amount_scale, taxes_amount_value, taxes_amount_scale ) SELECT t.tax_id, t.invoice_id, t.taxable_amount_value, t.taxable_amount_scale, t.iva_code, t.iva_percentage_value, t.iva_percentage_scale, t.iva_amount_value, t.iva_amount_scale, t.rec_code, t.rec_percentage_value, t.rec_percentage_scale, t.rec_amount_value, t.rec_amount_scale, t.retention_code, t.retention_percentage_value, t.retention_percentage_scale, t.retention_amount_value, t.retention_amount_scale, t.taxes_amount_value, t.taxes_amount_scale FROM customer_invoice_taxes t JOIN customer_invoices ci ON ci.id = t.invoice_id JOIN issued_invoices ii ON ii.id = ci.id WHERE ci.is_proforma = 0 AND NOT EXISTS ( SELECT 1 FROM issued_invoice_taxes iit WHERE iit.tax_id = t.tax_id ); -- --------------------------------------------------------------------------- -- 5. Backfill Verifactu transicional -- --------------------------------------------------------------------------- UPDATE verifactu_records vr JOIN customer_invoices ci ON ci.id = vr.invoice_id JOIN issued_invoices ii ON ii.id = ci.id SET vr.issued_invoice_id = vr.invoice_id WHERE ci.is_proforma = 0 AND vr.issued_invoice_id IS NULL; COMMIT; -- --------------------------------------------------------------------------- -- 6. Validaciones posteriores -- --------------------------------------------------------------------------- -- Ejecutar a continuacion: -- docs/customer-invoices/sql/validate-split-proformas-issued-invoices.sql -- -- Reset manual (NO ejecutable por defecto, solo referencia documental): -- -- DROP TABLE proformas; -- -- DROP TABLE proforma_items; -- -- DROP TABLE proforma_taxes; -- -- DROP TABLE issued_invoices; -- -- DROP TABLE issued_invoice_items; -- -- DROP TABLE issued_invoice_taxes;