/// <summary> /// Realiza a conversão dos dados de rentabilidade do ambiente para um /// registro de rentabilidade. /// </summary> /// <param name="ambienteRentabilidade"></param> /// <returns></returns> private IRegistroRentabilidade ConverterParaRegistroRentabilidade(Data.Model.AmbientePedidoEspelhoRentabilidade ambienteRentabilidade) { var tipo = (TipoRegistroRentabilidade)ambienteRentabilidade.Tipo; return(new RegistroRentabilidade(ambienteRentabilidade.IdRegistro, ProvedorDescritoresRegistro.ObterDescritor(tipo, ambienteRentabilidade.IdRegistro), tipo, ambienteRentabilidade.Valor)); }
/// <summary> /// Realiza a conversão dos dados de rentabilidade do ambiente para um /// registro de rentabilidade. /// </summary> /// <param name="produtoPedidoRentabilidade"></param> /// <returns></returns> private IRegistroRentabilidade ConverterParaRegistroRentabilidade(Data.Model.ProdutoPedidoEspelhoRentabilidade produtoPedidoRentabilidade) { var tipo = (TipoRegistroRentabilidade)produtoPedidoRentabilidade.Tipo; return(new RegistroRentabilidade(produtoPedidoRentabilidade.IdRegistro, ProvedorDescritoresRegistro.ObterDescritor(tipo, produtoPedidoRentabilidade.IdRegistro), tipo, produtoPedidoRentabilidade.Valor)); }
/// <summary> /// Realiza a conversão dos dados de rentabilidade da nota fiscal para um /// registro de rentabilidade. /// </summary> /// <param name="notaFiscalRentabilidade"></param> /// <returns></returns> private IRegistroRentabilidade ConverterParaRegistroRentabilidade(Data.Model.NotaFiscalRentabilidade notaFiscalRentabilidade) { var tipo = (TipoRegistroRentabilidade)notaFiscalRentabilidade.Tipo; return(new RegistroRentabilidade(notaFiscalRentabilidade.IdRegistro, ProvedorDescritoresRegistro.ObterDescritor(tipo, notaFiscalRentabilidade.IdRegistro), tipo, notaFiscalRentabilidade.Valor)); }
/// <summary> /// Recupera o item da rentabilidade para o custo do produto da nota fiscal. /// </summary> /// <param name="sessao"></param> /// <param name="produtoNf"></param> /// <param name="produtoNfCusto"></param> /// <param name="prazoMedio"></param> /// <param name="produto"></param> /// <returns></returns> private IItemRentabilidade <Data.Model.ProdutoNfCusto> ObterItemProdutoNfCusto( GDA.GDASession sessao, Data.Model.ProdutosNf produtoNf, Data.Model.ProdutoNfCusto produtoNfCusto, int prazoMedio, Data.Model.Produto produto) { var registros = new Lazy <IList <Data.Model.ProdutoNfCustoRentabilidade> >( () => Data.DAL.ProdutoNfCustoRentabilidadeDAO.Instance.ObterPorProdutoNf(sessao, produtoNfCusto.IdProdNfCusto)); var criarRegistro = new CriadorRegistroRentabilidade( (tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { registro = new Data.Model.ProdutoNfCustoRentabilidade { IdProdNfCusto = produtoNfCusto.IdProdNfCusto, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); // Calcula o custo do produto var custoProd = Glass.Global.CalculosFluxo.CalcTotaisItemProdFast(sessao, produto.TipoCalculo, produtoNf.Altura, produtoNf.Largura, produtoNf.Qtde, produtoNf.TotM, produtoNfCusto.CustoCompra, produtoNf.AlturaBenef.GetValueOrDefault(2), produtoNf.LarguraBenef.GetValueOrDefault(2)); var preceoVendaSemIPIUnitario = (produtoNf.Total + produtoNf.ValorIcmsSt) / (decimal)produtoNf.Qtde; return(new ItemRentabilidade <Data.Model.ProdutoNfCusto, Data.Model.ProdutoNfCustoRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, produtoNfCusto, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Produto [{produtoNfCusto.Qtde}] ({produto?.CodInterno}) {produto?.Descricao}", PrecoVendaSemIPI = preceoVendaSemIPIUnitario * produtoNfCusto.Qtde, PrecoCusto = custoProd, PrazoMedio = prazoMedio, PercentualICMSCompra = (decimal)(produtoNfCusto.AliqIcmsCompra ?? 0) / 100m, PercentualICMSVenda = (decimal)produtoNf.AliqIcms / 100m, FatorICMSSubstituicao = 0m, PercentualIPICompra = (decimal)(produtoNfCusto.AliqIpiCompra ?? 0) / 100m, PercentualIPIVenda = (decimal)produtoNf.AliqIpi / 100m, PercentualComissao = produtoNf.PercComissao / 100m, CustosExtras = 0m, PercentualRentabilidade = produtoNfCusto.PercentualRentabilidade / 100m, RentabilidadeFinanceira = produtoNfCusto.RentabilidadeFinanceira }); }
/// <summary> /// Recupera o item de rentabilidade para o ambiente do pedido. /// </summary> /// <param name="sessao"></param> /// <param name="ambiente"></param> /// <returns></returns> private IItemRentabilidade ObterItemAmbientePedido( GDA.GDASession sessao, Data.Model.AmbientePedidoEspelho ambiente, int prazoMedio, IEnumerable <IItemRentabilidade <Data.Model.ProdutosPedidoEspelho> > produtos) { var registros = new Lazy <IList <Data.Model.AmbientePedidoEspelhoRentabilidade> >( () => Data.DAL.AmbientePedidoEspelhoRentabilidadeDAO.Instance.ObterPorAmbiente(sessao, ambiente.IdAmbientePedido)); var criarRegistro = new CriadorRegistroRentabilidade((tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { // Cria o registro da rentabilidade do ambiente do pedido registro = new Data.Model.AmbientePedidoEspelhoRentabilidade { IdAmbientePedido = (int)ambiente.IdAmbientePedido, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); var produtosAmbiente = produtos.Select(f => f.Proprietario); // Calcula os valores dos produtos do ambiente var valorProdutos = produtosAmbiente.Sum(f => f.Total + f.ValorBenef); var valorDescontoAtual = produtosAmbiente.Sum(f => f.ValorDescontoProd); // Calcula o total do ambiente var total = valorProdutos - (!Glass.Configuracoes.PedidoConfig.RatearDescontoProdutos ? valorDescontoAtual : 0); var percentualComissao = 0m; if (Glass.Configuracoes.PedidoConfig.Comissao.UsarComissaoPorProduto) { decimal percComissao = 0; if (total > 0) { foreach (var prod in produtosAmbiente) { percComissao += ((prod.Total * 100) / total) * (prod.PercComissao / 100); } } percentualComissao = percComissao / 100m; } return(new ItemRentabilidadeContainer <Data.Model.AmbientePedidoEspelho, Data.Model.AmbientePedidoEspelhoRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, ambiente, produtos, f => true, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Ambiente {ambiente.Ambiente}", PrecoVendaSemIPI = total, // Na atualiza configuração do sistema o total do ambiente não possui o valor do IPI PrazoMedio = prazoMedio, PercentualComissao = percentualComissao, PercentualRentabilidade = ambiente.PercentualRentabilidade / 100m, RentabilidadeFinanceira = ambiente.RentabilidadeFinanceira }); }
/// <summary> /// Recupera o item da rentabilidade para o pedido informado. /// </summary> /// <param name="session"></param> /// <param name="idPedido"></param> /// <returns></returns> private IItemRentabilidade ObterItemPedido(GDA.GDASession sessao, Data.Model.PedidoEspelho pedido) { var registros = new Lazy <IList <Data.Model.PedidoEspelhoRentabilidade> >( () => Data.DAL.PedidoEspelhoRentabilidadeDAO.Instance.ObterPorPedido(sessao, pedido.IdPedido)); var criarRegistro = new CriadorRegistroRentabilidade((tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { // Cria o registro da rentabilidade do pedido registro = new Data.Model.PedidoEspelhoRentabilidade { IdPedido = (int)pedido.IdPedido, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); int prazoMedio = CalcularPrazoMedioPedido(sessao, pedido.IdPedido); // Recupera os itens associados com todos os produtos do pedido var produtos = new LazyItemRentabilidadeEnumerable(ObterItensProdutosPedido(sessao, pedido, prazoMedio)); // Recupera os ambientes do pedido var ambientes = new LazyItemRentabilidadeEnumerable(ObterItensAmbientesPedido(sessao, pedido, prazoMedio, produtos.OfType <IItemRentabilidade <Data.Model.ProdutosPedidoEspelho> >())); var itens = produtos.Concat(ambientes); // Cria o filtro que recupera os itens para serem usados nos calculos var filtroItensParaCalculo = new Func <IItemRentabilidade, bool>((item) => { if (item is IItemRentabilidade <Data.Model.AmbientePedidoEspelho> ) { // Calcula a rentabilidade somente de ambientes com produtos return(((IItemRentabilidadeContainer)item).Itens.Any()); } var produtoPedido = (item as IItemRentabilidade <Data.Model.ProdutosPedidoEspelho>)?.Proprietario; return(produtoPedido != null && !produtoPedido.InvisivelFluxo && !produtoPedido.IdAmbientePedido.HasValue); }); decimal percentualComissao = 0; if (Glass.Configuracoes.PedidoConfig.Comissao.UsarComissaoPorProduto) { decimal percComissao = 0; var total = (pedido.Total - pedido.ValorIpi - pedido.ValorIcms) - pedido.ValorEntrega; if (total > 0) { foreach (var item in itens.Where(filtroItensParaCalculo)) { percComissao += ((item.PrecoVendaSemIPI * 100) / total) * (item.PercentualComissao); } } percentualComissao = percComissao / 100m; } else { percentualComissao = (decimal)Data.DAL.PedidoDAO.Instance.ObterPercentualComissao(sessao, (int)pedido.IdPedido) / 100m; } return(new ItemRentabilidadeContainer <Data.Model.PedidoEspelho, Data.Model.PedidoEspelhoRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, pedido, itens, filtroItensParaCalculo, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Pedido {pedido.IdPedido}", PrecoVendaSemIPI = (pedido.Total - pedido.ValorIpi - pedido.ValorIcms) - pedido.ValorEntrega, PrazoMedio = prazoMedio, PercentualComissao = percentualComissao, CustosExtras = pedido.ValorEntrega, PercentualRentabilidade = pedido.PercentualRentabilidade / 100m, RentabilidadeFinanceira = pedido.RentabilidadeFinanceira }); }
/// <summary> /// Recupera um item de rentabilidade para o produto pedido informado. /// </summary> /// <param name="sessao"></param> /// <param name="produtoPedido"></param> /// <param name="prazoMedio"></param> /// <param name="produtos"></param> /// <param name="produtosPedidoFilhos">Relação dos produtos do pedidos filhos do produto informado.</param> /// <returns></returns> private IItemRentabilidade <Data.Model.ProdutosPedidoEspelho> ObterItemProdutoPedido( GDA.GDASession sessao, Data.Model.ProdutosPedidoEspelho produtoPedido, int prazoMedio, IEnumerable <Data.Model.Produto> produtos, IEnumerable <Data.Model.ProdutosPedidoEspelho> produtosPedidoFilhos) { var registros = new Lazy <IList <Data.Model.ProdutoPedidoEspelhoRentabilidade> >( () => Data.DAL.ProdutoPedidoEspelhoRentabilidadeDAO.Instance.ObterPorProdutoPedido(sessao, produtoPedido.IdProdPed)); var criarRegistro = new CriadorRegistroRentabilidade((tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { registro = new Data.Model.ProdutoPedidoEspelhoRentabilidade { IdProdPed = (int)produtoPedido.IdProdPed, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); // Carrega o produto associado var produto = produtos.First(f => f.IdProd == produtoPedido.IdProd); // Calculao custo do produto var custoProd = Global.CalculosFluxo.CalcTotaisItemProdFast(sessao, produto.TipoCalculo, produtoPedido.Altura, produtoPedido.Largura, produtoPedido.Qtde, produtoPedido.TotM, produto.CustoCompra, produtoPedido.AlturaBenef.GetValueOrDefault(2), produtoPedido.LarguraBenef.GetValueOrDefault(2)); if (produtosPedidoFilhos.Any()) { // Recupera os itens dos produtos filhos var itens = produtosPedidoFilhos.Select(produtoPedido1 => ObterItemProdutoPedido(sessao, produtoPedido1, prazoMedio, produtos, new Data.Model.ProdutosPedidoEspelho[0])) .ToList(); return(new ItemRentabilidadeContainer <Data.Model.ProdutosPedidoEspelho, Data.Model.ProdutoPedidoEspelhoRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, produtoPedido, itens, f => true, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Produto ({produto?.CodInterno}) {produto?.Descricao}", PrecoVendaSemIPI = produtoPedido.Total + produtoPedido.ValorBenef, PrazoMedio = prazoMedio, PercentualComissao = produtoPedido.PercComissao / 100m, PercentualRentabilidade = produtoPedido.PercentualRentabilidade / 100m, RentabilidadeFinanceira = produtoPedido.RentabilidadeFinanceira }); } else { return new ItemRentabilidade <Data.Model.ProdutosPedidoEspelho, Data.Model.ProdutoPedidoEspelhoRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, produtoPedido, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Produto ({produto.CodInterno}) {produto.Descricao}", PrecoVendaSemIPI = produtoPedido.Total + produtoPedido.ValorBenef, // Na atualiza configuração do sistema o total do produto não possui o valor do IPI PrecoCusto = custoProd, PrazoMedio = prazoMedio, PercentualICMSVenda = (decimal)produtoPedido.AliqIcms / 100m, FatorICMSSubstituicao = 0m, PercentualIPICompra = 0m, //(decimal)(produto?.AliqIPI ?? 0) / 100m, PercentualIPIVenda = (decimal)produtoPedido.AliqIpi / 100m, PercentualComissao = produtoPedido.PercComissao / 100m, CustosExtras = 0M, PercentualRentabilidade = produtoPedido.PercentualRentabilidade / 100m, RentabilidadeFinanceira = produtoPedido.RentabilidadeFinanceira } }; }
/// <summary> /// Recupera o item da rentabilidade para a nota fiscal informado. /// </summary> /// <param name="sessao"></param> /// <param name="notaFiscal"></param> /// <returns></returns> private IItemRentabilidade ObterItemNotaFiscal(GDA.GDASession sessao, Data.Model.NotaFiscal notaFiscal) { var registros = new Lazy <IList <Data.Model.NotaFiscalRentabilidade> >( () => Data.DAL.NotaFiscalRentabilidadeDAO.Instance.ObterPorPedido(sessao, notaFiscal.IdNf)); var criarRegistro = new CriadorRegistroRentabilidade((tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { // Cria o registro da rentabilidade da nota fiscal registro = new Data.Model.NotaFiscalRentabilidade { IdNf = (int)notaFiscal.IdNf, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); var prazoMedio = CalcularPrazoMedioNotaFiscal(sessao, notaFiscal.IdNf); // Recupera os itens associados com todos os produtos da nota var itens = new LazyItemRentabilidadeEnumerable(ObterItensProdutosNf(sessao, notaFiscal, prazoMedio)); decimal percentualComissao = 0; if (Glass.Configuracoes.PedidoConfig.Comissao.UsarComissaoPorProduto) { decimal percComissao = 0; var total = notaFiscal.TotalNota - notaFiscal.ValorIpi; if (total > 0) { foreach (var item in itens) { percComissao += ((item.PrecoVendaSemIPI * 100) / total) * (item.PercentualComissao); } } percentualComissao = percComissao / 100m; } return(new ItemRentabilidadeContainer <Data.Model.NotaFiscal, Data.Model.NotaFiscalRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, notaFiscal, itens, f => true, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Nota Fiscal {notaFiscal.IdNf}", PrecoVendaSemIPI = notaFiscal.TotalNota - notaFiscal.ValorIpi, PrazoMedio = prazoMedio, PercentualComissao = percentualComissao, CustosExtras = notaFiscal.OutrasDespesas + notaFiscal.ValorSeguro + notaFiscal.ValorFrete, PercentualRentabilidade = notaFiscal.PercentualRentabilidade / 100m, RentabilidadeFinanceira = notaFiscal.RentabilidadeFinanceira }); }
/// <summary> /// Recupera um item de rentabilidade para o produto pedido informado. /// </summary> /// <param name="sessao"></param> /// <param name="produtoNf"></param> /// <param name="produtoNfCustos">Custos associados.</param> /// <param name="prazoMedio"></param> /// <param name="produtos"></param> /// <returns></returns> private IItemRentabilidade <Data.Model.ProdutosNf> ObterItemProdutoNf( GDA.GDASession sessao, Data.Model.ProdutosNf produtoNf, IEnumerable <Data.Model.ProdutoNfCusto> produtoNfCustos, int prazoMedio, IEnumerable <Data.Model.Produto> produtos) { var registros = new Lazy <IList <Data.Model.ProdutoNfRentabilidade> >( () => Data.DAL.ProdutoNfRentabilidadeDAO.Instance.ObterPorProdutoNf(sessao, produtoNf.IdProdNf)); var criarRegistro = new CriadorRegistroRentabilidade( (tipo, nome, valor) => { var idRegistro = ProvedorDescritoresRegistro.ObterRegistro(tipo, nome); var registro = registros.Value.FirstOrDefault(f => f.Tipo == (int)tipo && f.IdRegistro == idRegistro); if (registro == null) { registro = new Data.Model.ProdutoNfRentabilidade { IdProdNf = (int)produtoNf.IdProdNf, IdRegistro = idRegistro, Tipo = (int)tipo, Valor = valor }; registros.Value.Add(registro); } else { registro.Valor = valor; } return(ConverterParaRegistroRentabilidade(registro)); }); // Carrega o produto associado var produto = produtos.FirstOrDefault(f => f.IdProd == produtoNf.IdProd); if (!produtoNfCustos.Any()) { produtoNfCustos = new[] { new Data.Model.ProdutoNfCusto { IdProdNf = produtoNf.IdProdNf, IdProdNfEntrada = 0, Qtde = (int)produtoNf.Qtde, CustoCompra = produto.CustoCompra } } } ; var qtdeProdutoNfCustos = produtoNfCustos.Count(); if (qtdeProdutoNfCustos > 1) { var itens = produtoNfCustos.Select(produtoNfCusto => ObterItemProdutoNfCusto(sessao, produtoNf, produtoNfCusto, prazoMedio, produto)); return(new ItemRentabilidadeContainer <Data.Model.ProdutosNf, Data.Model.ProdutoNfRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, produtoNf, itens, f => true, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Produto ({produto?.CodInterno}) {produto?.Descricao}", PrecoVendaSemIPI = produtoNf.Total + produtoNf.ValorIcmsSt, PrazoMedio = prazoMedio, PercentualComissao = produtoNf.PercComissao / 100m, PercentualRentabilidade = produtoNf.PercentualRentabilidade / 100m, RentabilidadeFinanceira = produtoNf.RentabilidadeFinanceira }); } else { var custoCompra = qtdeProdutoNfCustos == 1 ? produtoNfCustos.First().CustoCompra : produto.CustoCompra; // Calcula o custo do produto var custoProd = Glass.Global.CalculosFluxo.CalcTotaisItemProdFast(sessao, produto.TipoCalculo, produtoNf.Altura, produtoNf.Largura, produtoNf.Qtde, produtoNf.TotM, custoCompra, produtoNf.AlturaBenef.GetValueOrDefault(2), produtoNf.LarguraBenef.GetValueOrDefault(2)); return(new ItemRentabilidade <Data.Model.ProdutosNf, Data.Model.ProdutoNfRentabilidade>( ProvedorIndicadoresFinanceiro, criarRegistro, produtoNf, registros, ConverterParaRegistroRentabilidade) { Descricao = $"Produto ({produto?.CodInterno}) {produto?.Descricao}", PrecoVendaSemIPI = produtoNf.Total + produtoNf.ValorIcmsSt, // Não atualizar a configuração do sistema o total do produto não possui o valor do IPI PrecoCusto = custoProd, PrazoMedio = prazoMedio, PercentualICMSCompra = (decimal)(produtoNfCustos.FirstOrDefault()?.AliqIcmsCompra ?? 0f) / 100m, PercentualICMSVenda = (decimal)produtoNf.AliqIcms / 100m, FatorICMSSubstituicao = 0m, PercentualIPICompra = (decimal)(produtoNfCustos.FirstOrDefault()?.AliqIpiCompra ?? 0f) / 100m, PercentualIPIVenda = (decimal)produtoNf.AliqIpi / 100m, PercentualComissao = produtoNf.PercComissao / 100m, CustosExtras = 0m, PercentualRentabilidade = produtoNf.PercentualRentabilidade / 100m, RentabilidadeFinanceira = produtoNf.RentabilidadeFinanceira }); } }