-- ---------------------------------------------------------------------------
-- O irmao no PostgreSQL de `scripts/acertar-convenio-das-vendas.sql` (07/11/2026, a fatia 132, CONVENIO-SEGUE-O-ITEM;
-- o D632, a resposta 358 do dono, (c) com a (b)): grava nas vendas antigas o convenio pelo nome que esta no motivo do
-- ULTIMO item do convenio, quando o nome bate com exatamente um convenio, com a contagem antes, a lista com o convenio
-- de antes e a conferencia. As mesmas regras, o mesmo porque e o mesmo caminho de volta: leia o cabecalho do irmao.
--
--   psql -v ON_ERROR_STOP=1 -f postgres/acertar-convenio-das-vendas.sql | tee /root/acertar-convenio-das-vendas-pg-<data>.txt
--   docker exec -i franquiabv-postgres-1 sh -c 'psql -U "$POSTGRES_USER" -d <banco descartavel> -v ON_ERROR_STOP=1' \
--     < postgres/acertar-convenio-das-vendas.sql
--
-- ONDE RODA: o dono, depois da etapa 2, quando quiser, so se o irmao nao tiver rodado no MySQL da producao com o codigo
-- novo ja no lugar (a carga entao trouxe as vendas acertadas, e este roteiro conta 0 a mudar e nao muda nada). NA COPIA
-- franquiabv_dev NAO RODA: so a contagem; o roteiro inteiro, num banco descartavel.
--
-- O NOME DO CONVENIO E COMPARADO EXATO (o texto do PostgreSQL ja compara byte a byte, sem a colacao do MySQL), e o
-- convenio e o do MESMO inquilino do item.
--
-- O INQUILINO: as tabelas tem RLS forcado. COMO O DONO SUPERUSUARIO -- o `psql` acima --, o RLS nao vale e o `SET`
-- abaixo nao filtra: o roteiro conta e acerta TODO inquilino (hoje, so o 1). Como o `bvip_app`, com o `SET`, so o
-- inquilino 1.
--
-- A ESCRITA E A LISTA numa transacao so; as tabelas temporarias saem antes do COMMIT (e morreriam nele). SO A COLUNA
-- `vendas.convenio`, E A "ULTIMA VENDA" DOS CONVENIOS QUE RECEBEM VENDA CONCLUIDA (08/11/2026, a fatia 136; a resposta
-- 363 (a) do dono): ela anda para a `data_criacao` da venda concluida acertada mais nova, quando passa da gravada (ou
-- a gravada e nula), e nunca volta; a lista com a data de antes vem antes da escrita. O porque, no cabecalho do irmao.
-- PARA DESFAZER A DATA: `UPDATE convenios SET data_ultima_venda = <a de antes, ou NULL> WHERE id = <convenio>;`.
--
-- PARA DESFAZER, pela lista guardada: `UPDATE vendas SET convenio = <o de antes, ou NULL> WHERE id = <venda>;` para
-- cada linha dela.
-- ---------------------------------------------------------------------------

SET app.inquilino_id = '1';
SET client_encoding = 'UTF8';

BEGIN;

-- 1. As vendas com item do convenio: o ultimo item de cada uma, quantos convenios tem o nome dele, e o convenio.
CREATE TEMPORARY TABLE d632_vendas ON COMMIT DROP AS
SELECT x.venda, x.item AS ultimo_item, x.convenios_do_nome, x.convenio_do_item, v.convenio AS convenio_de_antes, v.status
  FROM (SELECT i.item, i.venda, i.convenios_do_nome, i.convenio_do_item,
               ROW_NUMBER() OVER (PARTITION BY i.venda ORDER BY i.item DESC) AS ordem
          FROM (SELECT vp.id AS item, vp.venda, COUNT(c.id) AS convenios_do_nome, MIN(c.id) AS convenio_do_item
                  FROM vendas_produtos vp
                  LEFT JOIN convenios c
                    ON c.inquilino_id = vp.inquilino_id
                   AND (vp.desconto_motivo = LEFT(CONCAT('Convênio ', c.nome), 100)
                        OR LEFT(vp.desconto_motivo, CHAR_LENGTH(c.nome) + 11) = CONCAT('Convênio ', c.nome, chr(59), ' '))
                 WHERE LEFT(vp.desconto_motivo, 9) = 'Convênio '
                   AND strpos(vp.desconto_motivo, 'CUPOM VIP:') = 0
                 GROUP BY vp.id, vp.venda) i) x
  JOIN vendas v ON v.id = x.venda
 WHERE x.ordem = 1;

-- 1b. A "ultima venda" que anda (a 363 (a)): os convenios que recebem venda concluida acertada, com a data da mais
-- nova delas, quando passa da gravada. Lida antes da escrita, com a data de antes.
CREATE TEMPORARY TABLE d632_ultima_venda ON COMMIT DROP AS
SELECT c.id AS convenio, c.data_ultima_venda AS data_de_antes, n.data_nova
  FROM (
        SELECT a.convenio_do_item AS convenio,
               MAX(v.data_criacao) AS data_nova
          FROM d632_vendas a
          JOIN vendas v ON v.id = a.venda
         WHERE a.convenios_do_nome = 1 AND a.status = 1
           AND a.convenio_de_antes IS DISTINCT FROM a.convenio_do_item
         GROUP BY a.convenio_do_item) n
  JOIN convenios c ON c.id = n.convenio
 WHERE c.data_ultima_venda IS NULL OR c.data_ultima_venda < n.data_nova;

-- 2. A contagem, antes.
SELECT COUNT(*) AS vendas_com_item_do_convenio,
       COUNT(*) FILTER (WHERE convenios_do_nome = 1 AND convenio_de_antes IS NULL) AS mudam_sem_convenio,
       COUNT(*) FILTER (WHERE convenios_do_nome = 1 AND convenio_de_antes IS NOT NULL AND convenio_de_antes <> convenio_do_item) AS mudam_de_outro,
       COUNT(*) FILTER (WHERE convenios_do_nome = 1 AND convenio_de_antes = convenio_do_item) AS ja_certas,
       COUNT(*) FILTER (WHERE convenios_do_nome = 0) AS ficam_nome_que_nao_existe,
       COUNT(*) FILTER (WHERE convenios_do_nome > 1) AS ficam_nome_de_dois_convenios
  FROM d632_vendas;

-- 3. A lista do que muda, com o convenio de antes (o caminho de volta).
SELECT venda, ultimo_item, convenio_de_antes, convenio_do_item AS convenio_novo, status
  FROM d632_vendas
 WHERE convenios_do_nome = 1 AND convenio_de_antes IS DISTINCT FROM convenio_do_item
 ORDER BY venda;

-- 4. A lista a parte: as vendas que ficam, porque o nome do ultimo item nao bate com exatamente um convenio.
SELECT venda, ultimo_item, convenios_do_nome, convenio_de_antes, status
  FROM d632_vendas
 WHERE convenios_do_nome <> 1
 ORDER BY venda;

-- 4b. A lista da "ultima venda" que anda: o convenio, a data de antes e a nova (o caminho de volta).
SELECT convenio, data_de_antes, data_nova
  FROM d632_ultima_venda
 ORDER BY convenio;

-- 5. A escrita: `vendas.convenio`.
WITH acertadas AS (
    UPDATE vendas v
       SET convenio = a.convenio_do_item
      FROM d632_vendas a
     WHERE a.venda = v.id AND a.convenios_do_nome = 1 AND v.convenio IS DISTINCT FROM a.convenio_do_item
 RETURNING v.id
)
SELECT COUNT(*) AS vendas_acertadas_agora FROM acertadas;

-- 5b. A escrita da "ultima venda": so para a frente.
WITH avancados AS (
    UPDATE convenios c
       SET data_ultima_venda = u.data_nova
      FROM d632_ultima_venda u
     WHERE u.convenio = c.id AND (c.data_ultima_venda IS NULL OR c.data_ultima_venda < u.data_nova)
 RETURNING c.id
)
SELECT COUNT(*) AS convenios_com_a_ultima_venda_avancada FROM avancados;

-- 5c. A conferencia da "ultima venda". O esperado: 0 atras.
SELECT COUNT(*) AS ultima_venda_atras_depois
  FROM d632_ultima_venda u
  JOIN convenios c ON c.id = u.convenio
 WHERE c.data_ultima_venda IS NULL OR c.data_ultima_venda < u.data_nova;

DROP TABLE IF EXISTS pg_temp.d632_ultima_venda;
DROP TABLE IF EXISTS pg_temp.d632_vendas;

COMMIT;

-- 6. A conferencia, refeita do zero. O esperado: 0 a mudar.
SELECT COUNT(*) AS vendas_com_item_do_convenio_depois,
       COUNT(*) FILTER (WHERE x.convenios_do_nome = 1 AND v.convenio IS DISTINCT FROM x.convenio_do_item) AS a_mudar_depois
  FROM (SELECT i.item, i.venda, i.convenios_do_nome, i.convenio_do_item,
               ROW_NUMBER() OVER (PARTITION BY i.venda ORDER BY i.item DESC) AS ordem
          FROM (SELECT vp.id AS item, vp.venda, COUNT(c.id) AS convenios_do_nome, MIN(c.id) AS convenio_do_item
                  FROM vendas_produtos vp
                  LEFT JOIN convenios c
                    ON c.inquilino_id = vp.inquilino_id
                   AND (vp.desconto_motivo = LEFT(CONCAT('Convênio ', c.nome), 100)
                        OR LEFT(vp.desconto_motivo, CHAR_LENGTH(c.nome) + 11) = CONCAT('Convênio ', c.nome, chr(59), ' '))
                 WHERE LEFT(vp.desconto_motivo, 9) = 'Convênio '
                   AND strpos(vp.desconto_motivo, 'CUPOM VIP:') = 0
                 GROUP BY vp.id, vp.venda) i) x
  JOIN vendas v ON v.id = x.venda
 WHERE x.ordem = 1;
