-- ---------------------------------------------------------------------------
-- Contas a Pagar guarda o motivo e o autor do que desfaz ou dispensa dinheiro
-- (D205, D207 e D199; as respostas 139, 140 e 18 do dono, 13/10/2026).
--
--   mysql franquia_producao < scripts/migracao-saidas-motivos-e-autores.sql
--
-- Roda no laco do passo 0 de `docs/procedimento-de-corte.md`, em PRODUCAO, e no
-- laco da copia do desenvolvimento de `docs/ensaio-geral-do-corte.md`, contra a
-- `franquiabv_dev`; os bancos da suite ja nascem com as colunas (`mysql.sql`, e o
-- `postgres/schema.sql` do gerador). NA COPIA LOCAL DESDE 13/10/2026, nos dois
-- bancos, pela resposta 83 do dono (a opcao (a): o esquema que so acrescenta entra
-- nas duas copias locais quando a resposta pedir). A base do teste do BVIP fica sem
-- elas ate a proxima copia exportada daqui, pela mao do dono.
--
-- AS OITO COLUNAS, nas tres tabelas:
--
--   saidas.excluida_por, excluida_em_nome_de
--       quem excluiu a despesa (a 18, a opcao (a): o estorno, a exclusao da
--       parcela e a da despesa ganham o autor);
--   saidas_parcelas.quitacao_motivo
--       por que a parcela foi dada por quitada SEM pagamento (a 139, a opcao (b):
--       o "Quitar" continua, com motivo obrigatorio; o estorno nao desfaz essa
--       quitacao);
--   saidas_parcelas.excluida_por, excluida_em_nome_de
--       quem excluiu a parcela (a 18);
--   saidas_parcelas_pagamentos.estorno_motivo, estornado_por, estornado_em_nome_de
--       o motivo do estorno, que a tela antiga exigia e jogava fora (a 140, a
--       opcao (a)), e quem estornou (a 18).
--
-- O AUTOR E O DO `CrudController::autorDaEscrita`, como a vigencia do horario
-- (`usuarios_horarios.gravado_por` e `em_nome_de`): quem entrou na sessao, e a
-- pessoa assumida so quando difere. Inteiro sem chave estrangeira, como la.
--
-- NULO QUER DIZER "DE ANTES": as 666 parcelas excluidas (sem a fixture), os 126
-- estornos e as 339 quitadas sem pagamento da copia nao tem motivo nem autor, e
-- ninguem sabe quais foram. Inventar um seria gravar como fato o que ninguem
-- verificou.
--
-- IDEMPOTENTE: cada tabela so recebe as colunas se a primeira delas nao existir.
-- As de cada tabela vao num ALTER so, e o ALTER do InnoDB e atomico.
--
-- NAO COPIA AS TABELAS: `ALGORITHM=INSTANT` acrescenta as colunas so no dicionario
-- (o MySQL de producao e 8.0.46; o INSTANT de coluna no fim da tabela existe desde
-- o 8.0.12). Na copia, em 13/10/2026: 13.238 despesas, 15.076 parcelas e 13.902
-- pagamentos (com as 2, 4 e 1 fixtures 9000xxxx que a copia carrega; sem elas,
-- 13.236, 15.072 e 13.901). Se o servidor recusar o INSTANT, o `ALTER` para com
-- erro, em vez de reescrever a tabela em silencio: rodar sem o `ALGORITHM` copia a
-- tabela.
--
-- ---------------------------------------------------------------------------
-- ESTA MIGRACAO PRECISA ESTAR EM PRODUCAO ANTES DO CORTE -- o passo 0 de
-- `docs/procedimento-de-corte.md` (D323).
--
-- O passo 1 do corte refaz o `mysql.sql` a partir da estrutura de producao; sem
-- as colunas la, elas somem do `schema.sql`, e Contas a Pagar volta a nao guardar
-- o motivo nem o autor (o codigo pergunta se elas existem,
-- `ISBase\Doctrine\ColunaNoBanco`, e nao quebra: so deixa de gravar e de ler -- e
-- o estorno volta a reabrir a quitacao com motivo). As entidades NAO as mapeiam,
-- de proposito: a base do teste do BVIP nao as tem ate a proxima copia exportada,
-- e a entidade mapeada pediria as colunas em toda leitura de despesa, parcela e
-- pagamento (o D473). O codigo antigo de producao nao as le nem as escreve, e o
-- nulo cobre o `INSERT` dele.
-- ---------------------------------------------------------------------------

SET @existe = (
    SELECT COUNT(*) FROM information_schema.columns
     WHERE table_schema = DATABASE()
       AND table_name = 'saidas'
       AND column_name = 'excluida_por'
);

SET @sql = IF(@existe = 0,
    'ALTER TABLE saidas
       ADD COLUMN excluida_por int DEFAULT NULL
       COMMENT ''Quem entrou na sessao ao excluir a despesa (CrudController::autorDaEscrita); nulo nas de antes (D199)''
       AFTER data_alteracao,
       ADD COLUMN excluida_em_nome_de int DEFAULT NULL
       COMMENT ''A pessoa da sessao, so quando difere de excluida_por (personificacao)''
       AFTER excluida_por,
       ALGORITHM=INSTANT',
    'SELECT ''saidas: colunas ja existem, nada a fazer'' AS aviso'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @existe = (
    SELECT COUNT(*) FROM information_schema.columns
     WHERE table_schema = DATABASE()
       AND table_name = 'saidas_parcelas'
       AND column_name = 'quitacao_motivo'
);

SET @sql = IF(@existe = 0,
    'ALTER TABLE saidas_parcelas
       ADD COLUMN quitacao_motivo varchar(100) DEFAULT NULL
       COMMENT ''Por que foi dada por quitada sem pagamento (D205); o estorno nao desfaz essa quitacao''
       AFTER data_alteracao,
       ADD COLUMN excluida_por int DEFAULT NULL
       COMMENT ''Quem entrou na sessao ao excluir a parcela (CrudController::autorDaEscrita); nulo nas de antes (D199)''
       AFTER quitacao_motivo,
       ADD COLUMN excluida_em_nome_de int DEFAULT NULL
       COMMENT ''A pessoa da sessao, so quando difere de excluida_por (personificacao)''
       AFTER excluida_por,
       ALGORITHM=INSTANT',
    'SELECT ''saidas_parcelas: colunas ja existem, nada a fazer'' AS aviso'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @existe = (
    SELECT COUNT(*) FROM information_schema.columns
     WHERE table_schema = DATABASE()
       AND table_name = 'saidas_parcelas_pagamentos'
       AND column_name = 'estorno_motivo'
);

SET @sql = IF(@existe = 0,
    'ALTER TABLE saidas_parcelas_pagamentos
       ADD COLUMN estorno_motivo varchar(100) DEFAULT NULL
       COMMENT ''Por que o pagamento foi estornado (D207); nulo nos estornos de antes''
       AFTER data_alteracao,
       ADD COLUMN estornado_por int DEFAULT NULL
       COMMENT ''Quem entrou na sessao ao estornar (CrudController::autorDaEscrita); nulo nos de antes''
       AFTER estorno_motivo,
       ADD COLUMN estornado_em_nome_de int DEFAULT NULL
       COMMENT ''A pessoa da sessao, so quando difere de estornado_por (personificacao)''
       AFTER estornado_por,
       ALGORITHM=INSTANT',
    'SELECT ''saidas_parcelas_pagamentos: colunas ja existem, nada a fazer'' AS aviso'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

-- Conferencia. Antes do codigo novo no ar, o esperado e nenhuma linha com motivo
-- ou autor.
SELECT
    (SELECT COUNT(*) FROM saidas)                                                   AS despesas,
    (SELECT COUNT(*) FROM saidas WHERE excluida_por IS NOT NULL)                    AS despesas_com_autor,
    (SELECT COUNT(*) FROM saidas_parcelas)                                          AS parcelas,
    (SELECT COUNT(*) FROM saidas_parcelas
      WHERE quitacao_motivo IS NOT NULL OR excluida_por IS NOT NULL)                AS parcelas_com_motivo_ou_autor,
    (SELECT COUNT(*) FROM saidas_parcelas_pagamentos)                               AS pagamentos,
    (SELECT COUNT(*) FROM saidas_parcelas_pagamentos
      WHERE estorno_motivo IS NOT NULL OR estornado_por IS NOT NULL)                AS pagamentos_com_motivo_ou_autor;
