/// <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) { var prazoMedio = CalcularPrazoMedioPedido(sessao, ambiente.IdPedido); var produtosAmbiente = Data.DAL.ProdutosPedidoEspelhoDAO.Instance.GetByAmbiente(sessao, ambiente.IdAmbientePedido); var produtos = Data.DAL.ProdutoDAO.Instance.ObterProdutos(sessao, produtosAmbiente.Select(f => f.IdProd).Distinct()).ToList(); // Recupera os itens de rentabilidade dos produtos do pedido var itens = new LazyItemRentabilidadeEnumerable(produtosAmbiente.Select(produtoPedido => { // Carrega os produtos filhos var filhosComposicao = Data.DAL.ProdutosPedidoEspelhoDAO.Instance.ObterFilhosComposicao(sessao, produtoPedido.IdProdPed); if (!produtos.Any(f => f.IdProd == produtoPedido.IdProd)) { var produto = Data.DAL.ProdutoDAO.Instance.GetElementByPrimaryKey(sessao, produtoPedido.IdProd); if (produto != null) { produtos.Add(produto); } } return(ObterItemProdutoPedido(sessao, produtoPedido, prazoMedio, produtos, filhosComposicao)); })); return(ObterItemAmbientePedido(sessao, ambiente, prazoMedio, itens.OfType <IItemRentabilidade <Data.Model.ProdutosPedidoEspelho> >())); }
/// <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 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 }); }