Relatorio de Compra e Venda de produtos por Período

02/02/2023

0

Bom dia.
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

Luiz Braga

Responder

Posts

02/02/2023

Arthur Heinrich

Nem sempre é possível misturar compras e vendas. Uma compra pode incluir várias unidades de determinado produto, que serão vendidos em múltiplas vendas.
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.
Responder

03/02/2023

Frank Hosaka

Eu uso o método da tentativa e erro:
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?
Responder

03/02/2023

Frank Hosaka

Eu uso o método da tentativa e erro:
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?
Responder

03/02/2023

Emerson Nascimento

tente neste formato:
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
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar