Paste #N8RaJoAyS

CREATE OR REPLACE FUNCTION exe.comprar_cartelas(v_rodada_id bigint, v_ponto_id integer, v_pdv_id integer, v_user_id integer, v_cartelas_qde integer, v_identificacao text, v_autenticacao uuid, v_imprimiu boolean)
RETURNS bigint AS $$
DECLARE
    m_sala_id integer;
    m_venda_id bigint;
    m_valor_cartela numeric(15,2);
    m_proxima_cartela integer;
    m_cartela_aleatoria boolean;
    m_premio_fixo boolean;
BEGIN
    INSERT INTO bng.vendas (rodada_id, ponto_id, pdv_id, user_id , cartelas, valor_total, identificacao, autenticacao, imprimiu)
    SELECT v_rodada_id, v_ponto_id, v_pdv_id, v_user_id, v_cartelas_qde, r.valor_cartela * v_cartelas_qde, v_identificacao, v_autenticacao, v_imprimiu
    FROM bng.rodadas r WHERE r.id=v_rodada_id AND r.rodada_estado='aberta'
    RETURNING id INTO m_venda_id;

    SELECT s.id, r.proxima_cartela, s.cartela_aleatoria, r.valor_cartela, r.premio_fixo
    INTO m_sala_id, m_proxima_cartela, m_cartela_aleatoria, m_valor_cartela, m_premio_fixo
    FROM bng.salas s
    INNER JOIN bng.rodadas r ON r.sala_id=s.id
    INNER JOIN bng.pontos p ON p.sala_id=s.id
    INNER JOIN bng.pdvs pdv ON pdv.ponto_id=p.id
    WHERE pdv.deleted_user_id IS NULL AND pdv.ativo
    AND p.deleted_user_id IS NULL AND p.ativo
    AND s.deleted_user_id IS NULL AND s.ativo
    AND pdv.id=v_pdv_id AND p.id=v_ponto_id AND r.id=v_rodada_id AND r.rodada_estado='aberta'
    FOR UPDATE OF r;

    IF NOT FOUND THEN
       RAISE EXCEPTION 'rodada fechada';
    END IF;

    IF m_cartela_aleatoria THEN
        INSERT INTO bng.venda_cartelas (venda_id, rodada_id, cartela_id)
        SELECT m_venda_id, v_rodada_id,
        (SELECT ca.cartela_id FROM bng.sala_cartelas_aleatorias ca WHERE ca.id=((m_proxima_cartela + a.n - 1) % 24000) + 1 AND ca.sala_id=m_sala_id)
        FROM generate_series(0, v_cartelas_qde - 1) AS a(n)
        ORDER BY a.n;
    ELSE
        INSERT INTO bng.venda_cartelas (venda_id, rodada_id, cartela_id)
        SELECT m_venda_id, v_rodada_id,
        ((m_proxima_cartela + a.n - 1) % 24000) + 1
        FROM generate_series(0, v_cartelas_qde - 1) AS a(n)
        ORDER BY a.n;
    END IF;

    INSERT INTO bng.rodada_ponto_totais AS rpt
    (rodada_id, ponto_id, valor_cartela, cartelas, total_cartelas, falhas)
    VALUES
    (v_rodada_id, v_ponto_id, m_valor_cartela, v_cartelas_qde, v_cartelas_qde * m_valor_cartela, CASE WHEN v_imprimiu=false THEN 1 ELSE 0 END)
    ON CONFLICT (rodada_id, ponto_id)
    DO UPDATE
    SET
     cartelas = rpt.cartelas + EXCLUDED.cartelas,
     total_cartelas = rpt.total_cartelas + EXCLUDED.total_cartelas,
     falhas = rpt.falhas + EXCLUDED.falhas
     ;

    UPDATE bng.salas AS s
    SET acumulado =
    CASE WHEN s.acumulado + (m_valor_cartela * v_cartelas_qde) * s.porcentagem_premio_acumulado / 100 < acumulado_maximo
    THEN s.acumulado + (m_valor_cartela * v_cartelas_qde) * s.porcentagem_premio_acumulado / 100 ELSE acumulado_maximo END
    WHERE id = m_sala_id AND acumulado < acumulado_maximo;

    IF m_premio_fixo THEN
        UPDATE bng.rodadas
        SET cartelas_vendidas = cartelas_vendidas + v_cartelas_qde, dt_modificado=now(),
        proxima_cartela = ((m_proxima_cartela + v_cartelas_qde - 1) % 24000) + 1
        WHERE id = v_rodada_id;
    ELSE
        UPDATE bng.rodadas
        SET premio_kuadra = m_valor_cartela * (cartelas_vendidas + v_cartelas_qde) * porcentagem_premio_kuadra / 100,
            premio_kina = m_valor_cartela * (cartelas_vendidas + v_cartelas_qde) * porcentagem_premio_kina / 100,
            premio_keno = m_valor_cartela * (cartelas_vendidas + v_cartelas_qde) * porcentagem_premio_keno / 100,
            cartelas_vendidas = cartelas_vendidas + v_cartelas_qde, dt_modificado=now(),
            proxima_cartela = ((m_proxima_cartela + v_cartelas_qde - 1) % 24000) + 1
        WHERE id = v_rodada_id;
    END IF;

    RETURN m_venda_id;
END; $$
LANGUAGE PLPGSQL;