Relatorio de Compra e Venda de produtos por Período
02/02/2023
0
Estou gerando um relatório para a contabilidade, onde contem informações de compra e vendas dos produtos vendidos em determinado periodo. (Ex: 12/2022) e as compras desde que iniciou o movimento da empresa. (EX: 01/2022). Se selecionar apenas as vendas separado, totaliza 23800 unidades vendidas. Que é o correto. Porem na consulta completa, está se tornando 238000. Alguém poderia me ajudar, por favor. Caso necessário, posso disponibilizar o banco.
**Consulta completa
select distinct cp.doccompra,cp.dtaentrada,ic.codder,d.descricaocompleta,ic.custount vr_unit_compra,ic.quanta qtd_compra,
ic.subtotbruto vr_operacao_compra,ic.baseicms,ic.valicms,(ic.valicms / ic.quanta) credito_unit, --VALOR ICMS / QUANTIDADE (NF COMPRA)
nf.numeronf,nf.dtaemissao,ni.precount vr_unit_venda,ni.quanta qtd_venda,ni.subtotbruto vr_operacao_venda,
ni.baseicms Base_icms_venda, ni.valicms val_icms_venda,ni.alqicms,
CASE
WHEN ni.percdeson = '0' and t.sgl_estado = 'MG' THEN 100 - ni.basetrib
ELSE ni.percdeson
END AS percdeson,
nf.codcidade,t.sgl_estado,
CASE
WHEN t.sgl_estado != 'MG' THEN cast(((ic.valicms / ic.quanta) * ni.quanta)AS NUMERIC(10,10))
ELSE cast((ic.valicms / ic.quanta) * ni.quanta AS NUMERIC(10,10))
END AS credito_saida, --CREDITO UNITARIO * QUANTIDADE VENDIDA
CASE
WHEN t.sgl_estado = 'MG' THEN cast(((ic.valicms / ic.quanta) * ni.quanta)*((100 - ni.basetrib) / 100) AS NUMERIC(10,10))
ELSE cast(((ic.valicms / ic.quanta) * ni.quanta) * (ni.percdeson/100)AS NUMERIC(10,10))
END AS estorno, --CREDITO SAIDA * PERC REDUCAO
CASE
WHEN t.sgl_estado != 'MG' THEN cast(((((ic.valicms / ic.quanta) * ni.quanta))-(((ic.valicms / ic.quanta) * ni.quanta) * (ni.percdeson/100)))AS NUMERIC(10,10))
ELSE cast(((ic.valicms / ic.quanta) * ni.quanta) - ((ic.valicms / ic.quanta) * ni.quanta)*((100 - ni.basetrib) / 100) AS NUMERIC(10,10))
END AS credito_restante --CREDITO SAIDA - VALOR DO ESTORNO
from tderivacao d
inner join itcompras ic on ic.codder = d.codder
inner join tnotaitem ni on ni.codder = d.codder
inner join tcompraprodutos cp on cp.seqcompra = ic.seqcompra
inner join tnotafiscal nf on nf.seqnf = ni.seqnf
inner join tcidade t on t.cod_cidade = nf.codcidade
where nf.dtaemissao >= '01.12.2022' and nf.dtaemissao <= '31.12.2022' and
cp.dtaentrada >= '01.01.2022' and cp.dtaentrada <= '31.12.2022' and nf.flagcancelada = 'N' and d.codder = '1'
order by 2,12,11
-------------------------------------------------------
**Consulta de Vendas
SELECT
'VENDAS',
LPAD(EXTRACT(MONTH FROM n.dtaemissao),2,'0')||'/'||LPAD(EXTRACT(YEAR FROM n.dtaemissao),4,'0') AS DATA,
ni.codder,d.descricaocompleta,sum(ni.quanta)
FROM tderivacao d
inner join tnotaitem ni on ni.codder = d.codder
inner join tnotafiscal n on n.seqnf = ni.seqnf
where n.dtaemissao between :di and :df and ni.codder = '1'
group by 1,2,3,4
Luiz Braga
Posts
02/02/2023
Arthur Heinrich
Também é possível que uma compra ou venda inclua múltiplos produtos. Quando misturamos tudo, ocorre um "produto cartesiano" (operação que multiplica as linhas no resultado).
Se você pensar bem, na lógica do negócio, são departamentos distintos, com funções distintas.
O departamento de compras recebe pedidos de múltiplos produtos, que geram valores a serem pagos (contas a pagar/fornecedores).
Os produtos recebidos ficam no estoque, à disposição para serem vendidos, o que requer notas de entrada e saída.
Já o departamento de vendas, vende parte do estoque, que pode ser composto de produtos de múltiplas compras, gerando valores a serem recebidos (contas a receber/clientes).
Imagine que a empresa comprou determinado produto, 5 unidades em janeiro, mais 5 em fevereiro e 5 em março. Agora, ocorreram duas vendas desse produto, sendo 8 unidades para um cliente A e 6 para um cliente B. Como você imagina que o relatório exibiria estas operações?
Da forma como você fez, utilizando um join, você está tentando misturar as 3 compras às duas vendas e, provavelmente, vai acabar com 6 linhas no resultado. E isto que eu descrevi um cenário simples.
A solução é não misturar as coisas.
Faça 3 relatórios:
- Relatório de compras
- Relatório de vendas
- Relatório do estoque
Cada um terá suas particularidades, sem que um interfira nos demais.
Para que seja possível apurar lucro, você pode controlar o custo médio do produto no estoque, que seria a média ponderada do custo de todos os produtos comprados.
Ao vender, pode informar no registro da venda o valor médio do produto (vindo do estoque) e o preço de venda, podendo apurar o ganho.
Isto é mais ou menos a mesma coisa que se faz com compra e venda de ações.
03/02/2023
Frank Hosaka
1a. tentativa: select sum(venda) as venda from tbderivacao; => resultado: 23.800,00
2a. tentativa: select sum(venda) as venda from tbderivacao, tnotitem; => resultado: 23.800,00
3a. tentativa: select sum(venda) as venda from tbderivacao, tnotitem, tnotafiscal; => resultado: 23.800,00
Conclusão: se eu consigo o valor esperado da venda só com a primeira tabela, para que preciso agregar as outras 500 tabelas?
03/02/2023
Frank Hosaka
1a. tentativa: select sum(venda) as venda from tbderivacao; => resultado: 23.800,00
2a. tentativa: select sum(venda) as venda from tbderivacao, tnotitem; => resultado: 23.800,00
3a. tentativa: select sum(venda) as venda from tbderivacao, tnotitem, tnotafiscal; => resultado: 23.800,00
Conclusão: se eu consigo o valor esperado da venda só com a primeira tabela, para que preciso agregar as outras 500 tabelas?
03/02/2023
Emerson Nascimento
select /*campos comuns*/, /*sum campos de compras/*, /*sum campos de venda/* from ( --vendas select /*campos comuns a compras e vendas*/, /*campos de venda apurados*/, /*campos de compra ZERADOS*/ from [apuracao de dados de venda] group by /*campos comuns a compras e vendas*/ union all --compras select /*campos comuns a compras e vendas*/, /*campos de venda ZERADOS*/, /*campos de compra apurados*/ from [apuracao de dados de compra] group by /*campos comuns a compras e vendas*/ ) tab group by /*campos comuns*/
algo assim:
SELECT dataapur, SUM(qtdven) vendas, SUM(qtdcom) compras FROM ( -- VENDAS SELECT LPAD(EXTRACT(MONTH FROM n.dtaemissao),2,'0')||'/'||LPAD(EXTRACT(YEAR FROM n.dtaemissao),4,'0') dataapur, ni.codder, d.descricaocompleta, sum(ni.quanta) qtdven, 0 qtdcom -- aqui é assim mesmo, atribuindo 0 FROM tderivacao d inner join tnotaitem ni on ni.codder = d.codder inner join tnotafiscal n on n.seqnf = ni.seqnf where n.dtaemissao between :di and :df and ni.codder = '1' group by LPAD(EXTRACT(MONTH FROM n.dtaemissao),2,'0')||'/'||LPAD(EXTRACT(YEAR FROM n.dtaemissao),4,'0'), ni.codder, d.descricaocompleta UNION ALL -- COMPRAS SELECT /*OBTER DATAAPUR*/, /*OBTER CODDER*/, /*OBTER DESCRICAOCOMPLETA*/, 0 qtdven, -- aqui é assim mesmo, atribuindo 0 /*OBTER QUANTIDADE COMPRAS*/ qtdcom FROM [condicao necessária para encontrar as compras] group by /*DATAAPUR*/, /*CORDDER*/, /*DESCRICAOCOMPLETA*/ ) TAB GROUP BY DATAAPUR -- aqui estou usando somente a dataapur, de modo que o totalizador será somente a data. -- se quiser saber por codder, acrescente CODDER neste group by e também na select
Clique aqui para fazer login e interagir na Comunidade :)