/// <summary> /// Localiza as naturezas de operação para os produtos informados, /// com base no cliente e loja. /// </summary> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="produtos"></param> /// <returns>Relação da natureza de operação para cada produto.</returns> public IEnumerable <Entidades.NaturezaOperacao> Buscar( Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, IEnumerable <Global.Negocios.Entidades.Produto> produtos) { var idsProduto = produtos.Select(f => f.IdProd); var produtosNaturezaOperacao = new Dictionary <int, int?>(); using (var session = new GDA.GDASession()) { // Carrega a relação dos produtos com a natureza de operação associada foreach (var i in idsProduto.Distinct() .Select(idProd => new { IdProd = idProd, IdNaturezaOperacao = (int?)Data.DAL.RegraNaturezaOperacaoDAO.Instance .BuscaNaturezaOperacao(session, (uint?)loja?.IdLoja, (uint?)cliente?.IdCli, idProd) })) { produtosNaturezaOperacao.Add(i.IdProd, i.IdNaturezaOperacao); } } IEnumerable <Entidades.NaturezaOperacao> naturezasOperacao; var idsNaturezaOperacao = produtosNaturezaOperacao .Where(f => f.Value.HasValue) .Select(f => f.Value.Value) .Distinct() .ToList(); if (idsNaturezaOperacao.Any()) { // Carrega os dados completos das naturezas de operação encontradas naturezasOperacao = SourceContext.Instance.CreateQuery() .From <Data.Model.NaturezaOperacao>() .Where($"IdNaturezaOperacao IN ({string.Join(",", idsNaturezaOperacao)})") .ProcessLazyResult <Entidades.NaturezaOperacao>() .ToList(); } else { naturezasOperacao = new Entidades.NaturezaOperacao[0]; } foreach (var idProd in idsProduto) { var idNaturezaOperacao = produtosNaturezaOperacao[idProd]; if (idNaturezaOperacao.HasValue) { yield return(naturezasOperacao.FirstOrDefault(f => f.IdNaturezaOperacao == idNaturezaOperacao.Value)); } else { yield return(null); } } }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="container"></param> /// <param name="resultadoInterno"></param> /// <param name="loja"></param> /// <param name="cliente"></param> public Resultado( IItemImpostoContainer container, ICalculoImpostoResultado resultadoInterno, Global.Negocios.Entidades.Loja loja, Global.Negocios.Entidades.Cliente cliente) { Container = container; ResultadoInterno = resultadoInterno; Loja = loja; Cliente = cliente; }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="orçamento"></param> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="itens"></param> public OrcamentoImpostoContainer( Data.Model.Orcamento orcamento, Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, IEnumerable <IItemImposto> itens) { Orcamento = orcamento; Cliente = cliente; Loja = loja; Itens = itens; }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="pedido"></param> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="itens"></param> public PedidoImpostoContainer( Data.Model.Pedido pedido, Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, IEnumerable <IItemImposto> itens) { Pedido = pedido; Cliente = cliente; Loja = loja; Itens = itens; }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="notaFiscal"></param> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="fornecedor"></param> /// <param name="itens"></param> public NotaFiscalImpostoContainer( Data.Model.NotaFiscal notaFiscal, Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, Global.Negocios.Entidades.Fornecedor fornecedor, IEnumerable <IItemImposto> itens) { NotaFiscal = notaFiscal; Cliente = cliente; Loja = loja; Fornecedor = fornecedor; Itens = itens; }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="produtoPedido"></param> /// <param name="loja"></param> /// <param name="cliente"></param> /// <param name="naturezaOperacao"></param> /// <param name="produto"></param> /// <param name="mva"></param> /// <param name="descontoRateadoImpostos"></param> /// <param name="codValorFiscal"></param> public ProdutoPedidoItemImposto( Data.Model.ProdutosPedido produtoPedido, Global.Negocios.Entidades.Loja loja, Global.Negocios.Entidades.Cliente cliente, Entidades.NaturezaOperacao naturezaOperacao, Global.Negocios.Entidades.Produto produto, float mva, decimal descontoRateadoImpostos, IProvedorCodValorFiscal provedorCodValorFiscal) { ProdutoPedido = produtoPedido; Loja = loja; Cliente = cliente; NaturezaOperacao = naturezaOperacao; Produto = produto; Mva = mva; DescontoRateadoImpostos = descontoRateadoImpostos; ProvedorCodValorFiscal = provedorCodValorFiscal; }
/// <summary> /// Recupera o container dos itens de impostos da nota fiscal. /// </summary> /// <param name="notaFiscal"></param> /// <param name="itens"></param> /// <returns></returns> private IItemImpostoContainer ObterContainer(Data.Model.NotaFiscal notaFiscal, IEnumerable <Data.Model.ProdutosNf> produtosNf) { Global.Negocios.Entidades.Cliente cliente = null; Global.Negocios.Entidades.Loja loja = null; Global.Negocios.Entidades.Fornecedor fornecedor = null; IEnumerable <Global.Negocios.Entidades.Produto> produtos = null; IEnumerable <IItemImposto> itens = null; var consultas = SourceContext.Instance.CreateMultiQuery() .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Cliente>() .Where("IdCli=?id") .Add("?id", notaFiscal.IdCliente), (sender, query, result) => cliente = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Cliente>(result, SourceContext.Instance) .FirstOrDefault()) .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Loja>() .Where("IdLoja=?id") .Add("?id", notaFiscal.IdLoja), (sender, query, result) => loja = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Loja>(result, SourceContext.Instance) .FirstOrDefault()) .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Fornecedor>() .Where("IdFornec=?id") .Add("?id", notaFiscal.IdFornec), (sender, query, result) => fornecedor = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Fornecedor>(result, SourceContext.Instance) .FirstOrDefault()); if (produtosNf == null) { // Consulta os produtos da nota consultas // Consulta os produtos dos produtos da nota .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Produto>() .Where("IdProd IN ?subProdutos") .Add("?subProdutos", SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosNf>() .Where("IdNf=?idNf") .Add("?idNf", notaFiscal.IdNf) .SelectDistinct("IdProd")), (sender, query, result) => produtos = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Produto>(result, SourceContext.Instance) .ToList()) .Add <Data.Model.ProdutosNf>(SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosNf>() .Where("IdNf=?id") .Add("?id", notaFiscal.IdNf), (sender, query, result) => itens = ObterItensImposto(notaFiscal, result.ToList(), produtos).ToList()) .Execute(); } else { var idsProd = string.Join(",", produtosNf.Select(f => f.IdProd).Distinct()); if (!string.IsNullOrEmpty(idsProd)) { consultas .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Produto>() .Where($"IdProd IN ({idsProd})"), (sender, query, result) => produtos = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Produto>(result, SourceContext.Instance) .ToList()); } consultas.Execute(); itens = ObterItensImposto(notaFiscal, produtosNf, produtos).ToList(); } var pedidoImposto = new NotaFiscalImpostoContainer(notaFiscal, cliente, loja, fornecedor, itens); return(pedidoImposto); }
/// <summary> /// Recupera os itens de impostos com base nos produtos do orçamento. /// </summary> /// <param name="orcamento">Orçamento pai.</param> /// <param name="produtosOrcamento"></param> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="produtos"></param> /// <param name="ambientes">Ambientes.</param> /// <returns></returns> private IEnumerable <IItemImposto> ObterItensImposto( Data.Model.Orcamento orcamento, IEnumerable <Data.Model.ProdutosOrcamento> produtosOrcamento, Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, IEnumerable <Global.Negocios.Entidades.Produto> produtos, IEnumerable <Data.Model.ProdutosOrcamento> produtosAmbienteOrcamento) { var naturezasOperacao = LocalizadorNaturezaOperacao.Buscar(cliente, loja, produtos); var mvas = ProvedorMvaProdutoUf.ObterMvaPorProdutos(produtos, loja, null, cliente, true); var produtosNaturezaOperacao = new Dictionary <int, Tuple <Global.Negocios.Entidades.Produto, Entidades.NaturezaOperacao> >(); var produtosMva = new Dictionary <int, float>(); // Carrega a natureza de operação e o mva dos produtos using (var produtoEnumerator = produtos.GetEnumerator()) using (var naturezasOperacaoEnumerator = naturezasOperacao.GetEnumerator()) using (var mvaEnumerator = mvas.GetEnumerator()) while (produtoEnumerator.MoveNext()) { if (naturezasOperacaoEnumerator.MoveNext()) { produtosNaturezaOperacao.Add(produtoEnumerator.Current.IdProd, new Tuple <Global.Negocios.Entidades.Produto, Entidades.NaturezaOperacao>( produtoEnumerator.Current, naturezasOperacaoEnumerator.Current)); } if (mvaEnumerator.MoveNext()) { produtosMva.Add(produtoEnumerator.Current.IdProd, mvaEnumerator.Current); } } var totalOrcamentoSemDesconto = new Lazy <decimal>(() => { return(Data.DAL.OrcamentoDAO.Instance.ObterTotalSemDesconto(null, (int)orcamento.IdOrcamento, orcamento.Total)); }); foreach (var produtoOrcamento in produtosOrcamento) { var descontoRateadoImpostos = 0m; var descontoAmbienteRateadoImpostos = 0m; if (!Configuracoes.PedidoConfig.RatearDescontoProdutos) { if (orcamento.Desconto != 0m) { if (orcamento.TipoDesconto == 1) { descontoRateadoImpostos += (produtoOrcamento.Total.GetValueOrDefault() + produtoOrcamento.ValorBenef) * orcamento.Desconto / 100m; } else { descontoRateadoImpostos += (produtoOrcamento.Total.GetValueOrDefault() + produtoOrcamento.ValorBenef) * (orcamento.Desconto / Math.Max(totalOrcamentoSemDesconto.Value, 1)); } } var produtoAmbienteOrcamento = produtoOrcamento.IdProdParent > 0 ? produtosAmbienteOrcamento.FirstOrDefault(f => f.IdProd == produtoOrcamento.IdProdParent.Value) : null; if (produtoAmbienteOrcamento?.IdProd > 0) { produtoAmbienteOrcamento.TotalProdutos = (produtosOrcamento?.Where(f => f.IdProdParent == produtoAmbienteOrcamento.IdProd)?.Sum(f => f.Total + f.ValorBenef)).GetValueOrDefault(); } if (produtoAmbienteOrcamento?.Desconto > 0) { if (produtoAmbienteOrcamento.TipoDesconto == 1) { descontoAmbienteRateadoImpostos += (produtoOrcamento.Total.GetValueOrDefault() + produtoOrcamento.ValorBenef) * (produtoAmbienteOrcamento.Desconto / 100m); } else { descontoAmbienteRateadoImpostos += (produtoOrcamento.Total.GetValueOrDefault() + produtoOrcamento.ValorBenef) * (produtoAmbienteOrcamento.Desconto / (produtoAmbienteOrcamento.TotalProdutos + produtoAmbienteOrcamento.ValorDescontoAtualAmbiente)); } } } var produtoNateruzaOperacao = produtosNaturezaOperacao[(int)produtoOrcamento.IdProduto]; yield return(new ProdutoOrcamentoItemImposto( produtoOrcamento, loja, cliente, produtoNateruzaOperacao.Item2, produtoNateruzaOperacao.Item1, produtosMva[(int)produtoOrcamento.IdProduto], descontoRateadoImpostos, ProvedorCodValorFiscal)); } }
/// <summary> /// Recupera o container dos itens de impostos do orçamento. /// </summary> /// <param name="orçamento"></param> /// <param name="loja">Instancia da loja associada com o orçamento.</param> /// <param name="cliente">Instancia do cliente associado com o orçamento.</param> /// <returns></returns> private IItemImpostoContainer ObterContainer(Data.Model.Orcamento orcamento, out Global.Negocios.Entidades.Loja loja, out Global.Negocios.Entidades.Cliente cliente) { Global.Negocios.Entidades.Cliente cliente1 = null; Global.Negocios.Entidades.Loja loja1 = null; IEnumerable <Global.Negocios.Entidades.Produto> produtos = null; IEnumerable <Data.Model.ProdutosOrcamento> produtosAmbienteOrcamento = null; IEnumerable <Data.Model.ProdutosOrcamento> produtosOrcamento = null; IEnumerable <IItemImposto> itens = null; produtosAmbienteOrcamento = SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosOrcamento>() .Where("IdOrcamento=?id AND (IdProdParent IS NULL OR IdProdParent = 0)") .Add("?id", orcamento.IdOrcamento) .Execute <Data.Model.ProdutosOrcamento>().ToList(); produtosOrcamento = SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosOrcamento>() .Where("IdOrcamento=?id AND IdProdParent IS NOT NULL AND IdProdParent > 0 AND (IdProdOrcamentoParent IS NULL OR IdProdOrcamentoParent = 0)") .Add("?id", orcamento.IdOrcamento) .Execute <Data.Model.ProdutosOrcamento>().ToList(); SourceContext.Instance.CreateMultiQuery() .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Cliente>() .Where("IdCli=?id") .Add("?id", orcamento.IdCliente), (sender, query, result) => cliente1 = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Cliente>(result, SourceContext.Instance) .FirstOrDefault()) .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Loja>() .Where("IdLoja=?id") .Add("?id", orcamento.IdLoja), (sender, query, result) => loja1 = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Loja>(result, SourceContext.Instance) .FirstOrDefault()) // Consulta os produtos dos produtos do orçamento .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Produto>() .Where("IdProd IN ?subProdutos") .Add("?subProdutos", SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosOrcamento>() .Where("IdOrcamento=?idOrcamento") .Add("?idOrcamento", orcamento.IdOrcamento) .SelectDistinct("IdProduto")), (sender, query, result) => produtos = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Produto>(result, SourceContext.Instance) .ToList()) .Execute(); itens = ObterItensImposto(orcamento, produtosOrcamento, cliente1, loja1, produtos, produtosAmbienteOrcamento).ToList(); var orcamentoImposto = new OrcamentoImpostoContainer(orcamento, cliente1, loja1, itens); loja = loja1; cliente = cliente1; return(orcamentoImposto); }
/// <summary> /// Recupera os itens de impostos com base nos produtos do pedido. /// </summary> /// <param name="pedido">Pedido pai.</param> /// <param name="produtosPedido"></param> /// <param name="cliente"></param> /// <param name="loja"></param> /// <param name="produtos"></param> /// <param name="ambientes">Ambientes.</param> /// <returns></returns> private IEnumerable <IItemImposto> ObterItensImposto( Data.Model.Pedido pedido, IEnumerable <Data.Model.ProdutosPedido> produtosPedido, Global.Negocios.Entidades.Cliente cliente, Global.Negocios.Entidades.Loja loja, IEnumerable <Global.Negocios.Entidades.Produto> produtos, IEnumerable <Data.Model.AmbientePedido> ambientes) { var naturezasOperacao = LocalizadorNaturezaOperacao.Buscar(cliente, loja, produtos); var mvas = ProvedorMvaProdutoUf.ObterMvaPorProdutos(produtos, loja, null, cliente, true); var produtosNaturezaOperacao = new Dictionary <int, Tuple <Global.Negocios.Entidades.Produto, Entidades.NaturezaOperacao> >(); var produtosMva = new Dictionary <int, float>(); // Carrega a natureza de operação e o mva dos produtos using (var produtoEnumerator = produtos.GetEnumerator()) using (var naturezasOperacaoEnumerator = naturezasOperacao.GetEnumerator()) using (var mvaEnumerator = mvas.GetEnumerator()) while (produtoEnumerator.MoveNext()) { if (naturezasOperacaoEnumerator.MoveNext()) { produtosNaturezaOperacao.Add(produtoEnumerator.Current.IdProd, new Tuple <Global.Negocios.Entidades.Produto, Entidades.NaturezaOperacao>( produtoEnumerator.Current, naturezasOperacaoEnumerator.Current)); } if (mvaEnumerator.MoveNext()) { produtosMva.Add(produtoEnumerator.Current.IdProd, mvaEnumerator.Current); } } var totalPedidoSemDesconto = new Lazy <decimal>(() => { var percFastDelivery = 1f; if (Configuracoes.PedidoConfig.Pedido_FastDelivery.FastDelivery && pedido.FastDelivery) { percFastDelivery = 1 + (Configuracoes.PedidoConfig.Pedido_FastDelivery.TaxaFastDelivery / 100f); } return(Data.DAL.PedidoDAO.Instance.GetTotalSemDesconto(null, pedido.IdPedido, (pedido.Total / (decimal)percFastDelivery))); }); foreach (var produtoPedido in produtosPedido) { var descontoRateadoImpostos = 0m; if (!Configuracoes.PedidoConfig.RatearDescontoProdutos) { if (pedido.Desconto != 0m) { descontoRateadoImpostos = (pedido.TipoDesconto == 1 ? pedido.Desconto / 100m : pedido.Desconto / Math.Max(totalPedidoSemDesconto.Value, 1)) * (produtoPedido.Total + produtoPedido.ValorBenef); } var ambiente = produtoPedido.IdAmbientePedido.HasValue ? ambientes.FirstOrDefault(f => f.IdAmbientePedido == produtoPedido.IdAmbientePedido.Value) : null; if (ambiente != null && ambiente.Desconto > 0) { descontoRateadoImpostos += (ambiente.TipoDesconto == 1 ? ambiente.Desconto / 100m : ambiente.Desconto / (ambiente.TotalProdutos + ambiente.ValorDescontoAtual)) * (produtoPedido.Total + produtoPedido.ValorBenef); } } var produtoNateruzaOperacao = produtosNaturezaOperacao[(int)produtoPedido.IdProd]; yield return(new ProdutoPedidoItemImposto( produtoPedido, loja, cliente, produtoNateruzaOperacao.Item2, produtoNateruzaOperacao.Item1, produtosMva[(int)produtoPedido.IdProd], descontoRateadoImpostos, ProvedorCodValorFiscal)); } }
/// <summary> /// Recupera o container dos itens de impostos do pedido. /// </summary> /// <param name="pedido"></param> /// <param name="loja">Instancia da loja associada com o pedido.</param> /// <param name="cliente">Instancia do cliente associado com o pedido.</param> /// <returns></returns> private IItemImpostoContainer ObterContainer(Data.Model.Pedido pedido, out Global.Negocios.Entidades.Loja loja, out Global.Negocios.Entidades.Cliente cliente) { Global.Negocios.Entidades.Cliente cliente1 = null; Global.Negocios.Entidades.Loja loja1 = null; IEnumerable <Global.Negocios.Entidades.Produto> produtos = null; IEnumerable <Data.Model.AmbientePedido> ambientes = null; IEnumerable <IItemImposto> itens = null; SourceContext.Instance.CreateMultiQuery() .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Cliente>() .Where("IdCli=?id") .Add("?id", pedido.IdCli), (sender, query, result) => cliente1 = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Cliente>(result, SourceContext.Instance) .FirstOrDefault()) .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Loja>() .Where("IdLoja=?id") .Add("?id", pedido.IdLoja), (sender, query, result) => loja1 = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Loja>(result, SourceContext.Instance) .FirstOrDefault()) // Consulta os produtos dos produtos do pedido .Add(SourceContext.Instance.CreateQuery() .From <Data.Model.Produto>() .Where("IdProd IN ?subProdutos") .Add("?subProdutos", SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosPedido>() .Where("IdPedido=?idPedido") .Add("?idPedido", pedido.IdPedido) .SelectDistinct("IdProd")), (sender, query, result) => produtos = EntityManager.Instance .ProcessLazyResult <Global.Negocios.Entidades.Produto>(result, SourceContext.Instance) .ToList()) .Add <Data.Model.AmbientePedido>(SourceContext.Instance.CreateQuery() .From <Data.Model.AmbientePedido>() .Where("IdPedido=?id") .Add("?id", pedido.IdPedido), (sender, query, result) => ambientes = result.ToList()) // Consulta os produtos do pedido que serão usados para o cálculo .Add <Data.Model.ProdutosPedido>(SourceContext.Instance.CreateQuery() .From <Data.Model.ProdutosPedido>() .Where("IdPedido=?id AND InvisivelPedido=0 AND InvisivelFluxo=0 AND IdProdPedParent IS NULL") .Add("?id", pedido.IdPedido), (sender, query, result) => itens = ObterItensImposto(pedido, result, cliente1, loja1, produtos, ambientes).ToList()) .Execute(); var pedidoImposto = new PedidoImpostoContainer(pedido, cliente1, loja1, itens); loja = loja1; cliente = cliente1; return(pedidoImposto); }