Páginas filhas
  • DDVENDAS - 41003 - DT - API PREÇO - Preço Base da PCTABPR.


01. DADOS GERAIS

Produto:

TOTVS Distribuição e Varejo

Linha de Produto:

Linha Winthor

Segmento:

Distribuição

Módulo:

Winthor Anywhere

Função:Atualização de objetos de banco de dados
País:Brasil
Requisito/Story/Issue:DDVENDAS-41003


02. SITUAÇÃO/REQUISITO

Criar uma API que retorna o preço por cliente para uma determinada filial.

Essa API deve ser um método único, quebrado em métodos menores para facilitar a manutenção. Por exemplo, faremos o primeiro método para capturar o preço base. Esse método deve ser isolado. No próximo aplicaremos os acréscimos. Ao invés de editar o método do preço base, passaremos um novo método logo abaixo e receberemos o preço do primeiro método como parâmetro. O segundo método calculará um novo preço de venda, e assim por diante. Uma arquitetura semelhante à PKG_LIMITECREDITO.

O primeiro método é para encontrar o preço base da PCTABPR. Para isso serão necessários os seguintes parâmetros de entrada:

CODFILIAL (Obrigatório)
CODCLI (Obrigatório)
CODPROD (Obrigatório)
CODPLPAG (Obrigatório)

CODFILIALNF (Opcional)
QT (Opcional)

Os select's são os seguintes:

&CODFILIALNF = NVL(:CODFILIALNF,SELECT CODFILIALNF FROM PCCLIENT WHERE CODCLI = :CODCLI)

// Se a variável &CODFILIALNF ficar nula após a consulta acima, NÃO EXECUTE o SELECT abaixo. Se estiver preenchida, execute.
Armazenar na variável NUMREGIAO

SELECT NUMREGIAO FROM PCTABPRCLI WHERE CODCLI = :CODCLI AND CODFILIAL = :CODFILIALNF

// Se a consulta acima não retornar nada ou não tiver sido executada pela ausência da variável &CODFILIALNF, consultar a região padrão de acordo com a praça do cliente
Armazenar na variável NUMREGIAO

SELECT NUMREGIAO FROM PCPRACA WHERE CODPRACA IN (SELECT CODPRACA FROM PCCLIENT WHERE CODCLI = :CODCLI)

// Obtendo a região, vamos identificar se o cliente usa precificação por atacado e varejo
Armazenar na variável TIPOPRECIFICACAO

SELECT PARAMFILIAL.OBTERCOMOVARCHAR2('FIL_TIPOPRECIFICACAO',:CODFILIAL) FROM DUAL

// Armazenar a coluna de preços de acordo com o plano de pagamento
Armazenar na variável COLUNAPRECO

SELECT NUMPR FROM PCPLPAG WHERE CODPLPAG = :CODPLPAG


Utilize a variável COLUNAPRECO para saber qual coluna da PCTABPR deve ser buscada. Existem 7 colunas por região, com os seguintes nomes: PVENDA1, PVENDA2, PVENDA3... Até o preço 7. A variável COLUNAPRECO serve para identificar qual desses preços deve ser utilizado. Se a COLUNAPRECO for 1, então deve ser carregado o PVENDA1. Se a COLUNAPRECO for 5, deve ser o PVENDA5, e assim por diante.

A variável TIPOPRECIFICACAO identifica se o preço deve ser carregado da tabela de varejo ou de atacado. Existem dois campos na PCTABPR para cada coluna de preço. PVENDA1 e PVENDAATAC1, PVENDA2 e PVENDAATAC2, e assim por diante. Essa variável vai determinar de qual campo deve ser carregado. A validação é em cima do campo QTMINIMAATACADO, que pode estar na PCPRODUT ou PCPRODFILIAL. Abaixo vou listar qual é lógica da consulta utilizada para determinar o QTMINIMAATACADO. Ela precisa ser tratada para retornar em um SELECT simples, mas a ideia está aqui:

 DECODE (( SELECT COUNT (*)
                             FROM pcprodfilial
                             WHERE codprod = :CODPROD
                             AND codfilial = :CODFILIAL)
                            ,0, DECODE (NVL (pcprodut.qtminimaatacado, 0)
                            ,0, 1
                            ,pcprodut.qtminimaatacado
                            )
                            ,NVL ((SELECT qtminimaatacado
                                   FROM pcprodfilial
                                   WHERE codprod = :CODPROD
                                   AND codfilial = :CODFILIAL)
                            ,DECODE (NVL (pcprodut.qtminimaatacado, 0)
                            ,0, 1
                            ,pcprodut.qtminimaatacado
                             ))
                   ) qtminimaatacado

// A consulta na PCPRODUT é a seguinte: SELECT QTMINIMAATACADO FROM PCPRODUT WHERE CODPROD = :CODPROD;
// A consulta na PCPDRODFILIAL é a seguinte: SELECT QTMINIMAATACADO FROM PCPRODFILIAL WHERE CODPROD = :CODPROD AND CODFILIAL = :CODFILIAL;


// Abaixo regra para identificar qual deve ser o preço carregado de acordo com a validação dos parâmetros COLUNAPRECO e TIPOPRECIFICACAO. A essa altura já temos a variável NUMREGIAO preenchida. Se a variável QT não for enviada, considere-a como 1.
No exemplo abaixo, usei os dois pontos ":" para identificar variáveis recebidas no JSON e o caracter "&" para identificar as variáveis carregadas das consultas acima.

// Fazer a consulta na PCTABPR usando a lógica abaixo, mas passando no WHERE a variável CODPROD (Recebida no JSON de entrada) e NUMREGIAO (Armazenada nas primeiras consultas)
if ((TIPOPRECIFICACAO = 'P') OR
           (TIPOPRECIFICACAO = 'A' AND :QT >= &qtminimaatacado) OR --HIS.00185.2015
           (TIPOPRECIFICACAO = 'V' AND (:QT < &qtminimaatacado OR NVL(&qtminimaatacado,0) = 0)))
         THEN
          IF COLUNAPRECO = 1
          THEN
            PRECO_VENDA := pctabpr.pvenda1;
          ELSIF COLUNAPRECO = 2
          THEN
            PRECO_VENDA := pctabpr.pvenda2;
          ELSIF COLUNAPRECO = 3
          THEN
            PRECO_VENDA := pctabpr.pvenda3;
          ELSIF COLUNAPRECO = 4
          THEN
            PRECO_VENDA := pctabpr.pvenda4;
          ELSIF COLUNAPRECO = 5
          THEN
            PRECO_VENDA := pctabpr.pvenda5;
          ELSIF COLUNAPRECO = 6
          THEN
            PRECO_VENDA := pctabpr.pvenda6;
          ELSIF COLUNAPRECO = 7
          THEN
            PRECO_VENDA := pctabpr.pvenda7;
          END IF;
        ELSIF ((TIPOPRECIFICACAO = 'A' AND :QT < &qtminimaatacado) OR--HIS.00185.2015
              (TIPOPRECIFICACAO = 'V' AND :QT >= &qtminimaatacado))--HIS.00185.2015
        THEN
          IF COLUNAPRECO = 1
          THEN
            PRECO_VENDA := pctabpr.pvendaatac1;
          ELSIF COLUNAPRECO = 2
          THEN
            PRECO_VENDA := pctabpr.pvendaatac2;
          ELSIF COLUNAPRECO = 3
          THEN
            PRECO_VENDA := pctabpr.pvendaatac3;
          ELSIF COLUNAPRECO = 4
          THEN
            PRECO_VENDA := pctabpr.pvendaatac4;
          ELSIF COLUNAPRECO = 5
          THEN
            PRECO_VENDA := pctabpr.pvendaatac5;
          ELSIF COLUNAPRECO = 6
          THEN
            PRECO_VENDA := pctabpr.pvendaatac6;
          ELSIF COLUNAPRECO = 7
          THEN
            PRECO_VENDA := pctabpr.pvendaatac7;
          END IF;
        ELSE
          IF COLUNAPRECO = 1
          THEN
            PRECO_VENDA := pctabpr.pvenda1;
          ELSIF COLUNAPRECO = 2
          THEN
            PRECO_VENDA := pctabpr.pvenda2;
          ELSIF COLUNAPRECO = 3
          THEN
            PRECO_VENDA := pctabpr.pvenda3;
          ELSIF COLUNAPRECO = 4
          THEN
            PRECO_VENDA := pctabpr.pvenda4;
          ELSIF COLUNAPRECO = 5
          THEN
            PRECO_VENDA := pctabpr.pvenda5;
          ELSIF COLUNAPRECO = 6
          THEN
            PRECO_VENDA := pctabpr.pvenda6;
          ELSIF COLUNAPRECO = 7
          THEN
            PRECO_VENDA := pctabpr.pvenda7;
          END IF;        END IF;  

Critérios de aceitação

A API precisa retornar exatamente o mesmo preço apresentado na rotina 316, em um item que não tenha nenhum tipo de acréscimo e nenhum imposto (ST, IPI, DIFAL, etc...)

1) Testar variações de produto, cliente e plano de pagamento, usando colunas diferentes entre os planos
2) Testar processo de tabela de preço por cliente (Rotina 3314)
3) Testar precificação por atacado e varejo (Validando o parâmetro e QTMINIMAATACADO)



03. SOLUÇÃO

  • Foi criado um novo endpoint para consulta de preço

    OBS: Se o campo qt não for passado no request, será considerado o valor 1 na API

    A API segue os steps abaixo para encontrar o preço base:

    1 - Busca o tipo de precificação, se é varejo ou atacado, através do select:

    SELECT PARAMFILIAL.OBTERCOMOVARCHAR2('FIL_TIPOPRECIFICACAO',:CODFILIAL) FROM DUAL

    OBS: essa function executara a seguinte consulta:

    select valor from pcparamfilial where nome = 'FIL_TIPOPRECIFICACAO' and codfilial = :CODFILIAL;

    2 - Busca a coluna preço, que será usada para saber em qual coluna consultar o preço, usando a consulta:

    SELECT NUMPR FROM PCPLPAG WHERE CODPLPAG = :CODPLPAG

    3 - Busca a Região, usando a seguinte regra:
    3.1 - Se for enviado o codFilialNf no request, ele será usado, caso contrario, esse dado será buscado na pcclient usando o codCli, usando a consuta:

    SELECT NVL(:CODFILIALNF, CODFILIALNF) FROM PCCLIENT WHERE CODCLI = :CODCLI

    3.2 - Tendo o codFilialNf, seja ele passado como parametro, ou encontrado na PCCLIENT, será buscada a região usanod a consulta:

    SELECT NUMREGIAO FROM PCTABPRCLI WHERE CODCLI = :CODCLI AND CODFILIALNF = :CODFILIALNF

    3.3 - Caso a região não seja encontrada no select anterior(3.2), ou o codFilialNf não tenha sido encontrado no primeiro passo(3.1), será buscada a região por praça, usando a consulta:

    SELECT NUMREGIAO FROM PCPRACA WHERE CODPRACA IN (SELECT CODPRACA FROM PCCLIENT WHERE CODCLI = :CODCLI)

    4 - Busca a quantidade minima atacado, através da consulta:

    	SELECT 
    	DECODE(
    		(SELECT COUNT (*) FROM PCPRODFILIAL WHERE codprod = :CODPROD AND codfilial = :CODFILIAL),
    		0, 
    		DECODE(NVL((SELECT QTMINIMAATACADO FROM PCPRODUT WHERE CODPROD = :CODPROD), 0),
    			0,
    			1,
    			(SELECT QTMINIMAATACADO FROM PCPRODUT WHERE CODPROD = :CODPROD)
    		),
    		NVL(
    			(SELECT qtminimaatacado FROM PCPRODFILIAL WHERE codprod = :CODPROD AND codfilial = :CODFILIAL),
    			DECODE(
    				NVL((SELECT QTMINIMAATACADO FROM PCPRODFILIAL WHERE CODPROD = :CODPROD AND CODFILIAL = :CODFILIAL), 0),
    				0,
    				1,
    				(SELECT QTMINIMAATACADO FROM PCPRODFILIAL WHERE CODPROD = :CODPROD AND CODFILIAL = :CODFILIAL)
             	)
     		)
    	) qtminimaatacado FROM dual

    5 - Busca o preço de venda, usando os dados obtidos nos passos anteriores, seguindo as regras presentes na descrição da ISSUE, com as consultas:

    SELECT PVENDA1 FROM PCTABPR P WHERE P.CODPROD = :CODPROD AND P.NUMREGIAO = :REGIAO
    SELECT PVENDAATAC1 FROM PCTABPR P WHERE P.CODPROD = :CODPROD AND P.NUMREGIAO = :REGIAO

    OBS: o campo pode ser PVENDA[numero coluna preço] ou PVENDAATAC[numero coluna preço], dependendo de qual regra o conjunto de dados se adequar, conforme descrito na ISSUE


Atualizar a winthor-venda  para uma das versões abaixo ou superior:

  • 0.3.0.535


04. DEMAIS INFORMAÇÕES

Importante

As versões estarão disponíveis para download no CCW.

https://centraldecontrole.pcinformatica.com.br/


Mantenha suas rotinas sempre atualizadas!


05. ASSUNTOS RELACIONADOS