SET TERM ^ ;

CREATE OR ALTER PROCEDURE SPU_TRANSF_ALOCACAO_ESTOQUE (
    PEDIDO_REC INTEGER,
    PED_ITEM_ID_REC INTEGER,
    PEDIDO_PAG INTEGER,
    PED_ITEM_ID_PAG INTEGER)
AS
DECLARE VARIABLE ESTABELECIMENTO_ID INTEGER;
DECLARE VARIABLE LOCALIZACAO_ID INTEGER;
DECLARE VARIABLE PRODUTO_ID INTEGER;
DECLARE VARIABLE TAMANHO INTEGER;
DECLARE VARIABLE DATA_DISPONIVEL DATE;
DECLARE VARIABLE DATA_DISPONIVEL_REC DATE;
DECLARE VARIABLE COMANDA_ID INTEGER;
DECLARE VARIABLE CONFERENCIA_ID INTEGER;
DECLARE VARIABLE NECESSIDADE NUMERIC(15,4);
DECLARE VARIABLE DISPONIBILIDADE NUMERIC(15,4);
DECLARE VARIABLE QTD_TRANSF NUMERIC(15,4);
DECLARE VARIABLE ID INTEGER;
DECLARE VARIABLE SALDO NUMERIC(15,4);
DECLARE VARIABLE REM_STATUS CHAR(1);
DECLARE VARIABLE FLAG CHAR(1);
DECLARE VARIABLE HISTORICO VARCHAR(500);
BEGIN
  
  NECESSIDADE = 0;
  DISPONIBILIDADE = 0;

  FLAG = '0';

  FOR
  SELECT A.ESTABELECIMENTO_CODIGO,
         A.LOCALIZACAO_ID,
         A.PRODUTO_CODIGO,
         A.TAMANHO,
         B.QUANTIDADE - A.QTD_EST,
         COALESCE((SELECT FIRST 1 T.STATUS FROM TBREMESSA_ITEM_TRATAMENTO T
                    WHERE T.TABELA_ID = A.PEDIDO
                      AND T.TAB_ITEM_ID = A.CONTROLE
                      AND T.ESTABELECIMENTO_ID = A.ESTABELECIMENTO_CODIGO
                      AND T.TAMANHO = A.TAMANHO
                      AND T.STATUS = '1'),'0') REM_STATUS,
         A.DATA_DISPONIVEL,
         COALESCE((SELECT FIRST 1
                        K.ESTOQUE_DETALHE_ID
                    FROM TBESTOQUE_DETALHE_ALOCACAO K
                WHERE   K.TABELA_ID = A.PEDIDO
                AND     K.TAB_ITEM_ID = A.CONTROLE AND K.TIPO = 'P'), 0) AS COMANDA_ID,

         COALESCE((SELECT FIRST 1
                        J.CONFERENCIA_ID
                    FROM TBCONFERENCIA_ITEM J, TBCONFERENCIA C
                WHERE   J.CONFERENCIA_ID = C.ID
                AND     C.TABELA_ID = A.PEDIDO
                AND     C.TABELA = 'PED'
                AND     J.TABELA_ITEM_ID = A.CONTROLE
                AND     J.QTD_CONFERIDA > 0), 0) AS CONFERENCIA_ID

    FROM TBPEDIDO_ITEM A, TBPEDIDO_ITEM_SALDO B
   WHERE A.CONTROLE = B.PEDIDO_ITEM_CONTROLE
     AND A.PEDIDO = B.PEDIDO
     AND A.PEDIDO = :PEDIDO_REC
     AND A.CONTROLE = :PED_ITEM_ID_REC
     AND B.QUANTIDADE > 0
    INTO :ESTABELECIMENTO_ID,
         :LOCALIZACAO_ID,
         :PRODUTO_ID,
         :TAMANHO,
         :NECESSIDADE,
         :REM_STATUS,
         :DATA_DISPONIVEL_REC,
         :COMANDA_ID,
         :CONFERENCIA_ID
      DO BEGIN

      FLAG = '1';

      IF (COMANDA_ID > 0) THEN
          BEGIN
          EXCEPTION "..." 'ITEM DO PEDIDO VINCULADO A COMANDA DE ALOCACAO. OPERACAO CANCELADA!';
          END

      IF (CONFERENCIA_ID > 0) THEN
          BEGIN
          EXCEPTION "..." 'ITEM DO PEDIDO VINCULADO A CONFERENCIA DE PECAS. OPERACAO CANCELADA!';
          END

      IF (REM_STATUS = '1') THEN
          BEGIN
          EXCEPTION "..." 'ITEM DO PEDIDO DE ORIGEM BLOQUEADO PELO PPCP, GERACAO DE REMESSA EM ANDAMENTO. OPERACAO CANCELADA!';
          END

      IF (NECESSIDADE <= 0) THEN
          BEGIN
          EXCEPTION "..." 'ITEM DO PEDIDO DE ORIGEM SEM NECESSIDADE DE ALOCACAO DE ESTOQUE. OPERACAO CANCELADA!';
          END

              FOR
              SELECT A.QTD_EST, A.DATA_DISPONIVEL
                FROM TBPEDIDO_ITEM A
               WHERE A.ESTABELECIMENTO_CODIGO = :ESTABELECIMENTO_ID
                 AND A.LOCALIZACAO_ID = :LOCALIZACAO_ID
                 AND A.PEDIDO = :PEDIDO_PAG
                 AND A.CONTROLE = :PED_ITEM_ID_PAG
                 AND A.PRODUTO_CODIGO = :PRODUTO_ID
                 AND A.TAMANHO = :TAMANHO
                INTO :DISPONIBILIDADE, :DATA_DISPONIVEL
                  DO
                  BEGIN
            
                  FLAG = '2';

                  IF (DISPONIBILIDADE <= 0) THEN
                      BEGIN
                      EXCEPTION "..." 'ITEM DO PEDIDO DE DESTINO SEM DISPONIBILIDADE PARA TRANSFERIR ALOCACAO DE ESTOQUE. OPERACAO CANCELADA!';
                      END

                      IF (NECESSIDADE > DISPONIBILIDADE) THEN
                          BEGIN
                          NECESSIDADE = DISPONIBILIDADE;
                          DISPONIBILIDADE = 0;  /* RESTO DO PEDIDO DE DESTINO (PAGADOR) */
                          DATA_DISPONIVEL = NULL;
                          END ELSE
                      IF (NECESSIDADE <= DISPONIBILIDADE) THEN
                          BEGIN
                          DISPONIBILIDADE = DISPONIBILIDADE - NECESSIDADE; /* RESTO DO PEDIDO DE DESTINO (PAGADOR), ESSA QTD VOLTARÁ AO PEDIDO PAGADOR */
                          END
            
                            /* BAIXA ESTOQUE ALOCADO DA TABELA QUE VAI CEDER O SALDO */
                            UPDATE TBESTOQUE_DETALHE_ALOCACAO SET SALDO = 0
                            WHERE TABELA_ID = :PEDIDO_PAG AND TAB_ITEM_ID = :PED_ITEM_ID_PAG;
        
                            HISTORICO = 'SALDO ESTOQUE DESALOCADO PARA TRANSFERÊNCIA.'
                                      ||' *** PED/ITEM:'||:PEDIDO_PAG||'/'||:PED_ITEM_ID_PAG;

                              INSERT INTO TBHISTORICO (
                               TABELA, TABELA_ID, USUARIO, IP, HISTORICO) VALUES (
                              'TBPEDIDO_ALOCADO', :PEDIDO_PAG,
                              (SELECT FIRST 1 MON$USER FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                              (SELECT FIRST 1 MON$REMOTE_ADDRESS FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                               :HISTORICO);

                            /* TRANSFERE TALÕES EM ABERTO DA TABELA QUE VAI RECEBER O ESTOQUE PARA A TABELA QUE VAI CEDER O ESTOQUE */
                            QTD_TRANSF = NECESSIDADE;
        
                              FOR
                              SELECT A.ID, A.SALDO
                                FROM TBREMESSA_ITEM_ALOCACAO A
                               WHERE A.SALDO > 0
                                 AND A.TABELA_ID = :PEDIDO_REC
                                 AND A.TAB_ITEM_ID = :PED_ITEM_ID_REC
                                INTO :ID, :SALDO
                                  DO
                                  BEGIN
                                  IF (QTD_TRANSF > 0) THEN
                                      BEGIN
                                      IF (SALDO <= QTD_TRANSF) THEN
                                          BEGIN
                                            UPDATE TBREMESSA_ITEM_ALOCACAO SET
                                            TABELA_ID = :PEDIDO_PAG,
                                            TAB_ITEM_ID = :PED_ITEM_ID_PAG
                                            WHERE ID = :ID;
        
                                            QTD_TRANSF = :QTD_TRANSF - :SALDO;
                                          END ELSE
                                      IF (SALDO > QTD_TRANSF) THEN
                                          BEGIN
        
                                               INSERT INTO TBREMESSA_ITEM_ALOCACAO (ESTABELECIMENTO_ID,
                                                                               LOCALIZACAO_ID,
                                                                               TABELA_ID,
                                                                               TAB_ITEM_ID,
                                                                               PRODUTO_ID,
                                                                               TAMANHO,
                                                                               QUANTIDADE,
                                                                               TIPO,
                                                                               REMESSA,
                                                                               TALAO, 
                                                                               AGRUPAMENTO_ID,
                                                                               AGRUP_PED_ID, 
                                                                               SALDO,
                                                                               ORIGEM_PRODUTO_ID)
                                               SELECT ESTABELECIMENTO_ID, 
                                                      LOCALIZACAO_ID, 
                                                      0,
                                                      0,
                                                      PRODUTO_ID,
                                                      TAMANHO, 
                                                     (:SALDO - :QTD_TRANSF),
                                                      TIPO,
                                                      REMESSA,
                                                      TALAO,
                                                      AGRUPAMENTO_ID,
                                                      AGRUP_PED_ID,
                                                     (:SALDO - :QTD_TRANSF),
                                                     ORIGEM_PRODUTO_ID
                                               FROM TBREMESSA_ITEM_ALOCACAO
                                               WHERE ID = :ID;
        
                                            UPDATE TBREMESSA_ITEM_ALOCACAO SET
                                            TABELA_ID = :PEDIDO_PAG,
                                            TAB_ITEM_ID = :PED_ITEM_ID_PAG,
                                            QUANTIDADE = :QTD_TRANSF,
                                            SALDO = :QTD_TRANSF
                                            WHERE ID = :ID;
        
                                            QTD_TRANSF = 0;
                                          END
                                      END
                                  END
        
                          /* AJUSTAR PROCEDIMENTO, CRIAR LAÇO NA TABELA DE AGRUPAMENTO DETALHADO */
                          /* TRANSFERE OS AGRUPAMENTOS EM ABERTO DA TABELA QUE VAI RECEBER O ESTOQUE PARA A TABELA QUE VAI CEDER O ESTOQUE */
                          IF (QTD_TRANSF > 0) THEN
                              BEGIN
                              DELETE FROM TBAGRUPAMENTO_PEDIDO A
                               WHERE A.SALDO > 0 AND A.TABELA_ID = :PEDIDO_REC
                                 AND A.TAB_ITEM_ID = :PED_ITEM_ID_REC;

                              DELETE FROM TBPEDIDO_CONSUMO A
                               WHERE A.PEDIDO_ID = :PEDIDO_REC
                                 AND A.PEDIDO_ITEM_ID = :PED_ITEM_ID_REC;

                              /*
                              FOR SELECT A.ID, A.SALDO
                                FROM TBAGRUPAMENTO_PEDIDO A
                               WHERE A.SALDO > 0
                                 AND A.TABELA_ID = :PEDIDO_REC
                                 AND A.TAB_ITEM_ID = :PED_ITEM_ID_REC
                                INTO :ID, :SALDO
                                  DO
                                  BEGIN
                                  IF (QTD_TRANSF > 0) THEN
                                      BEGIN                                                              
                                      IF (SALDO <= QTD_TRANSF) THEN
                                          BEGIN
                                            UPDATE TBAGRUPAMENTO_PEDIDO SET
                                            TABELA_ID = :PEDIDO_PAG,
                                            TAB_ITEM_ID = :PED_ITEM_ID_PAG
                                            WHERE ID = :ID;
                                            QTD_TRANSF = :QTD_TRANSF - :SALDO;
                                          END ELSE
                                      IF (SALDO > QTD_TRANSF) THEN
                                          BEGIN
        
                                            UPDATE TBAGRUPAMENTO_PEDIDO SET
                                            TABELA_ID = :PEDIDO_PAG,
                                            TAB_ITEM_ID = :PED_ITEM_ID_PAG,
                                            QUANTIDADE = :QTD_TRANSF,
                                            SALDO = :QTD_TRANSF
                                            WHERE ID = :ID;
        
                                            QTD_TRANSF = 0;
                                          END
                                      END
                                  END */
                              END
        
                            /* ALOCA O SALDO DE ESTOQUE TRANSFERIDO NO PEDIDO DESTINO*/
                            INSERT INTO TBESTOQUE_DETALHE_ALOCACAO (
                            ESTABELECIMENTO_ID,TABELA_ID,TAB_ITEM_ID,TIPO,
                            LOCALIZACAO_ID, PRODUTO_ID, TAMANHO, QUANTIDADE,
                            SALDO) VALUES (:ESTABELECIMENTO_ID,
                            :PEDIDO_REC, :PED_ITEM_ID_REC, 'P', :LOCALIZACAO_ID,
                            :PRODUTO_ID, :TAMANHO, :NECESSIDADE, :NECESSIDADE);
            
                            HISTORICO = 'TRANSF.ALOC.ESTOQUE' 
                                      ||' QTD/TAM/LOC.'||TRUNC(:NECESSIDADE)||'/'||:TAMANHO||'/'||:LOCALIZACAO_ID
                                      ||' *** PED/ITEM:'||:PEDIDO_PAG||'/'||:PED_ITEM_ID_PAG
                                      ||' -> '||:PEDIDO_REC||'/'||:PED_ITEM_ID_REC;

                              INSERT INTO TBHISTORICO (
                               TABELA, TABELA_ID, USUARIO, IP, HISTORICO) VALUES (
                              'TBPEDIDO_ALOCADO', :PEDIDO_REC,
                              (SELECT FIRST 1 MON$USER FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                              (SELECT FIRST 1 MON$REMOTE_ADDRESS FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                               :HISTORICO);

                              INSERT INTO TBHISTORICO (
                               TABELA, TABELA_ID, USUARIO, IP, HISTORICO) VALUES (
                              'TBPEDIDO_ALOCADO', :PEDIDO_PAG,
                              (SELECT FIRST 1 MON$USER FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                              (SELECT FIRST 1 MON$REMOTE_ADDRESS FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION),
                               :HISTORICO);

                            IF (DISPONIBILIDADE > 0) THEN
                                BEGIN
                                  /* VOLTA A ALOCA DO SALDO DE ESTOQUE RESIDUAL PARA PEDIDO DE ORIGEM*/
                                  INSERT INTO TBESTOQUE_DETALHE_ALOCACAO (
                                  ESTABELECIMENTO_ID,TABELA_ID,TAB_ITEM_ID,TIPO,
                                  LOCALIZACAO_ID, PRODUTO_ID, TAMANHO, QUANTIDADE,
                                  SALDO) VALUES (:ESTABELECIMENTO_ID,
                                  :PEDIDO_PAG, :PED_ITEM_ID_PAG, 'P', :LOCALIZACAO_ID,
                                  :PRODUTO_ID, :TAMANHO, :DISPONIBILIDADE, :DISPONIBILIDADE);
                                END
        
                            /* TRANSFERE DATA DE DISPONIBILIDADE ENTRE PEDIDOS*/
                            IF (DATA_DISPONIVEL IS NOT NULL) THEN
                                BEGIN
                                  UPDATE TBPEDIDO_ITEM SET DATA_DISPONIVEL = NULL
                                   WHERE PEDIDO = :PEDIDO_PAG AND CONTROLE = :PED_ITEM_ID_PAG;

                                IF (DATA_DISPONIVEL_REC IS NULL OR DATA_DISPONIVEL_REC < :DATA_DISPONIVEL) THEN
                                    BEGIN
                                      UPDATE TBPEDIDO_ITEM SET DATA_DISPONIVEL = :DATA_DISPONIVEL
                                       WHERE PEDIDO = :PEDIDO_REC AND CONTROLE = :PED_ITEM_ID_REC;
                                    END
                                END
        
                  END
         END

  IF (FLAG = '0') THEN
      BEGIN
      EXCEPTION "..." 'ITEM DO PEDIDO DE ORIGEM NAO LOCALIZADO. OPERACAO CANCELADA!';
      END
  IF (FLAG = '1') THEN
      BEGIN
      EXCEPTION "..." 'ITEM DO PEDIDO DE DESTINO NAO LOCALIZADO. OPERACAO CANCELADA!';
      END

END
^

SET TERM ; ^

