using System.Collections.Generic;
public static void Main()
var documentos = Documento.MockDocumentos().Where(x => x.Fechamento <= DateTime.UtcNow.Date);
var conveniados = documentos.Select(x => x.Conveniado).Distinct();
foreach(var conveniado in conveniados)
var documentosPorConveniado = documentos.Where(x => x.Conveniado == conveniado).ToList();
Console.WriteLine($"Iniciando processamento do conveniado {conveniado}.");
Console.WriteLine($"Conveniado {conveniado} possui {documentosPorConveniado.Count()} documentos para processamento.");
var documentosAgrupados = documentosPorConveniado.GroupBy(x => new {x.Produto, x.RepassePorPraca, x.IdDaPraca});
Console.WriteLine($"Foram criados grupos por produto, repasse por praca e Id da praca. Total de {documentosAgrupados.Count()} grupos.");
var itemsOtherDate = new List<Documento>();
var itemsToUpdate = new List<DocuemntoParaFechar>();
foreach(var documentoAgrupadoItem in documentosAgrupados)
Console.WriteLine("====================================================================================================================================");
var pdc = documentoAgrupadoItem.FirstOrDefault();
Console.WriteLine($"Conveniado: {pdc.Conveniado} | Transacao: {pdc.Produto} | Repasse por praca: {pdc.RepassePorPraca} | | Qtd Docs: {documentoAgrupadoItem.Count()} | Valor Total: {documentoAgrupadoItem.Sum(x => x.Valor)}");
var documentosDoGrupoOrdenado = documentoAgrupadoItem.OrderBy(x => x.Vencimento);
foreach(var dcItem in documentosDoGrupoOrdenado)
var grossAmout = itemsOtherDate.Sum(x => x.Valor) + dcItem.Valor;
itemsOtherDate.Add(dcItem);
Console.WriteLine($"---- Id: {dcItem.Id} | Valor: {dcItem.Valor} | Data Fechamento: {dcItem.Fechamento:dd-MM-yyyy}| Data Vencimento: {dcItem.Vencimento:dd-MM-yyyy} | ==> não fecha");
itemsToUpdate.Add(new DocuemntoParaFechar(dcItem, dcItem.Id));
itemsToUpdate.AddRange(itemsOtherDate.Select(x => new DocuemntoParaFechar(x, dcItem.Id)));
Console.WriteLine($"---- Id: {dcItem.Id} | Valor: {dcItem.Valor} | Data Fechamento: {dcItem.Fechamento:dd-MM-yyyy}| Data Vencimento: {dcItem.Vencimento:dd-MM-yyyy} | ==> fecha e com os items de mais {itemsOtherDate.Count()} documento");
Console.WriteLine($"---- Id: {dcItem.Id} | Valor: {dcItem.Valor} | Data Fechamento: {dcItem.Fechamento:dd-MM-yyyy}| Data Vencimento: {dcItem.Vencimento:dd-MM-yyyy} | ==> fecha");
itemsOtherDate = new List<Documento>();
Console.WriteLine("====================================================================================================================================");
Console.WriteLine("-----------------------------------------------------------");
Console.WriteLine("----------------------Resultado Final----------------------");
Console.WriteLine($"---Total: {documentosPorConveniado.Count()} -------Sucesso: {itemsToUpdate.Count()} ---------Não fecha: {documentosPorConveniado.Count() - itemsToUpdate.Count()} ------");
Console.WriteLine("-----------------------------------------------------------");
foreach(var dc in itemsToUpdate.OrderBy(x => x.Documento.Fechamento))
var dcItem = dc.Documento;
if(dc.DocumentoIdChave == dc.Documento.Id)
Console.WriteLine($"---- Id: {dcItem.Id} | Valor: {dcItem.Valor} | Data Fechamento: {dcItem.Fechamento:dd-MM-yyyy}| Data Vencimento: {dcItem.Vencimento:dd-MM-yyyy} | ==> fecha");
Console.WriteLine($"---- Id: {dcItem.Id} | Valor: {dcItem.Valor} | Data Fechamento: {dcItem.Fechamento:dd-MM-yyyy}| Data Vencimento: {dcItem.Vencimento:dd-MM-yyyy} | ==> faz merge com o documento {dc.DocumentoIdChave}");
Console.WriteLine("====================================================================================================================================");
public class DocuemntoParaFechar
public DocuemntoParaFechar(Documento documento, Guid documentoIdChave)
this.Documento = documento;
DocumentoIdChave = documentoIdChave;
public Documento Documento{get;set;}
public Guid DocumentoIdChave{get;set;}
public Documento(bool repassePorPraca, string conveniado, int produto, DateTime fechamento, decimal valor, DateTime vencimento, Guid? idDaPraca = default)
RepassePorPraca = repassePorPraca;
public Guid Id {get; set;}
public bool RepassePorPraca{get;set;}
public string Conveniado{get;set;}
public int Produto{get;set;}
public DateTime Fechamento{get;set;}
public DateTime Vencimento{get;set;}
public decimal Valor{get;set;}
public Guid? IdDaPraca {get;set;}
public static List<Documento> MockDocumentos()
var conveniadoDois = "Dois";
var praca = new List<Guid>();
praca.Add(Guid.NewGuid());
praca.Add(Guid.NewGuid());
praca.Add(Guid.NewGuid());
praca.Add(Guid.NewGuid());
var documentos = new List<Documento>()
new Documento(true, conveniadoUm, 1, new DateTime(2022, 08, 24), 15m, new DateTime(2022, 08, 27), praca[0]),
new Documento(true, conveniadoUm, 1, new DateTime(2022, 08, 25), -10m, new DateTime(2022, 08, 26), praca[0]),
new Documento(true, conveniadoUm, 2, new DateTime(2022, 08, 24), -10m, new DateTime(2022, 08, 26), praca[0]),
new Documento(true, conveniadoUm, 2, new DateTime(2022, 08, 25), -5m, new DateTime(2022, 08, 27), praca[0]),
new Documento(false, conveniadoUm, 3, new DateTime(2022, 08, 24), 10m, new DateTime(2022, 08, 26)),
new Documento(false, conveniadoUm, 3, new DateTime(2022, 08, 25), -10m, new DateTime(2022, 08, 27)),
new Documento(false, conveniadoUm, 4, new DateTime(2022, 08, 24), 10m, new DateTime(2022, 08, 26)),
new Documento(false, conveniadoUm, 4, new DateTime(2022, 08, 25), -20m, new DateTime(2022, 08, 27)),
new Documento(true, conveniadoDois, 1, new DateTime(2022, 08, 24), -5m, new DateTime(2022, 08, 26), praca[1]),
new Documento(true, conveniadoDois, 1, new DateTime(2022, 08, 25), 10m, new DateTime(2022, 08, 27), praca[1]),
new Documento(true, conveniadoDois, 1, new DateTime(2022, 08, 26), 10m, new DateTime(2022, 08, 28), praca[1]),
new Documento(true, conveniadoDois, 2, new DateTime(2022, 08, 24), 15m, new DateTime(2022, 08, 27), praca[2]),
new Documento(true, conveniadoDois, 2, new DateTime(2022, 08, 25), -10m, new DateTime(2022, 08, 26)),
new Documento(false, conveniadoDois, 3, new DateTime(2022, 08, 24), 10m, new DateTime(2022, 08, 26)),
new Documento(false, conveniadoDois, 3, new DateTime(2022, 08, 25), 10m, new DateTime(2022, 08, 27)),
new Documento(false, conveniadoDois, 3, new DateTime(2022, 08, 26), 10m, new DateTime(2022, 08, 28)),
new Documento(false, conveniadoDois, 4, new DateTime(2022, 08, 25), 10m, new DateTime(2022, 08, 27)),
new Documento(false, conveniadoDois, 4, new DateTime(2022, 08, 26), 10m, new DateTime(2022, 08, 28)),
new Documento(true, conveniadoDois, 4, new DateTime(2022, 08, 25), -10m, new DateTime(2022, 08, 27), praca[2]),
new Documento(true, conveniadoDois, 4, new DateTime(2022, 08, 26), 10m, new DateTime(2022, 08, 28), praca[3]),