private static void WriteData(ApplicationDbContext db, bool removeCycles, Person[] people)
        {
            const string outDir = @"C:\Users\AustinWise\Dropbox\DKP";

            List <Debt> netMoney = null;

            using (Stream fs = removeCycles ? new FileStream(Path.Combine(outDir, "Info.txt"), FileMode.Create, FileAccess.Write) : Stream.Null)
            {
                using (var infoOutput = new StreamWriter(fs))
                {
                    netMoney = DebtGraph.CalculateDebts(db, people, removeCycles, infoOutput ?? Console.Out);
                }
            }
            Console.WriteLine("{0:c}", netMoney.Sum(m => m.Amount) / 100d);

            const string gvPath = @"c:\temp\graph\test.gv";

            using (var fs = new FileStream(gvPath, FileMode.Create, FileAccess.Write))
            {
                using (var sw = new StreamWriter(fs))
                {
                    DebtGraph.WriteGraph(netMoney, sw);
                }
            }

            DebtGraph.RenderGraphAsPng(gvPath, Path.Combine(outDir, removeCycles ? "current.png" : "nocycles.png"));
            if (removeCycles)
            {
                DebtGraph.RenderGraphAsPng(gvPath, Path.Combine(outDir, DateTime.Now.ToString("yyyy-MM-dd") + ".png"));
            }
        }
Exemple #2
0
        public async Task Send(int creditorId)
        {
            bool actuallySend = false;

            Console.Write("Type 'true' to actually send emails: ");
            bool.TryParse(Console.ReadLine(), out actuallySend);

            var person = mDb.Person
                         .Where(p => p.Id == creditorId)
                         .Include(p => p.PaymentIdentity).ThenInclude(p => p.PaymentMeth)
                         .Single();

            var transactions = mDb.Transaction
                               .Where(t => t.CreditorId != t.DebtorId &&
                                      (t.CreditorId == person.Id || t.DebtorId == person.Id) &&
                                      (!t.Creditor.IsDeleted && !t.Debtor.IsDeleted));

            foreach (var dontUse in PEOPLE_TO_EXCLUDE)
            {
                var p = dontUse;
                transactions = transactions.Where(t => t.DebtorId != p && t.CreditorId != p);
            }

            var netMoney = DebtGraph.CalculateDebts(mDb, transactions, true, TextWriter.Null);

            var swGraph = new StringWriter();

            DebtGraph.WriteGraph(netMoney, swGraph);
            var bytes = DebtGraph.RenderGraphAsPng(swGraph.ToString());

            var debtors = DebtGraph.GreatestDebtor(netMoney);
            var myDebt  = debtors.Where(d => d.Item1.Id == person.Id).SingleOrDefault();

            if (myDebt != null)
            {
                debtors.Remove(myDebt);
            }

            debtors = debtors.Where(tup => tup.Item2 > 1000 && !string.IsNullOrEmpty(tup.Item1.Email)).ToList();

            int sentSoFar = 0;

            foreach (var tup in debtors)
            {
                var fields = ProcessOnePerson(person, tup.Item1, tup.Item2);

                if (actuallySend)
                {
                    await mEmail.SendHtmlEmailAsync(tup.Item1.FullName, tup.Item1.Email, "DKP Invoice", fields.BODY);
                }
                Console.WriteLine(actuallySend ? "Sent {0,2}/{1,2} ({2} {3})" : "Would send: {2} {3}", ++sentSoFar, debtors.Count, tup.Item1.FirstName, tup.Item1.LastName);
            }

            Console.WriteLine();
            Console.WriteLine("Done! Press enter to exit.");
            Console.ReadLine();
        }
        public ActionResult Display(int[] peopleIds)
        {
            var people = peopleIds
                         .Select(i => dc.Person.Where(p => p.Id == i).Single())
                         .ToArray();
            var swLog    = new StringWriter();
            var netMoney = DebtGraph.CalculateDebts(dc, people, true, swLog);

            var swGraph = new StringWriter();

            DebtGraph.WriteGraph(netMoney, swGraph);
            var svg = DebtGraph.RenderGraphAsSvg(swGraph.ToString());

            var mod = new AnalyseModel();

            mod.LogOutput = swLog.ToString();
            mod.ImageSvg  = svg;
            mod.Debtors   = DebtGraph.GreatestDebtor(netMoney);
            return(View(mod));
        }
Exemple #4
0
        //
        // GET: /MyDebt/Details/5

        public ActionResult Details(int id)
        {
            var person = mData.Person.Where(p => p.Id == id).Single();

            var transactions = mData.Transaction.Include(t => t.Creditor).Include(t => t.Debtor)
                               .Where(t => t.CreditorId != t.DebtorId &&
                                      !t.Creditor.IsDeleted &&
                                      !t.Debtor.IsDeleted &&
                                      (t.CreditorId == person.Id || t.DebtorId == person.Id))
                               .ToList();

            var netMoney = DebtGraph.CalculateDebts(mData, transactions, true, TextWriter.Null);

            var swGraph = new StringWriter();

            DebtGraph.WriteGraph(netMoney, swGraph);
            var svg = DebtGraph.RenderGraphAsSvg(swGraph.ToString());

            var creditors = DebtGraph.GreatestDebtor(netMoney);
            var myDebt    = creditors.Where(d => d.Item1.Id == person.Id).SingleOrDefault();

            if (myDebt != null)
            {
                creditors.Remove(myDebt);
            }

            //change the list of debtors in to creditors
            creditors = creditors.Select(c => new Tuple <Person, int>(c.Item1, -c.Item2))
                        .Reverse()
                        .ToList();

            var mod = new MyDebtModel();

            mod.Person      = person;
            mod.ImageSvg    = svg;
            mod.Creditors   = creditors;
            mod.OverallDebt = (myDebt == null) ? 0 : myDebt.Item2;

            return(View(mod));
        }
        private static void DebtTransfer(ApplicationDbContext db, Person debtor, Person oldCreditor, Person newCreditor, DateTime when)
        {
            var netMoney = DebtGraph.CalculateDebts(db, new[] { debtor, oldCreditor }, false, null);

            if (netMoney.Count != 1)
            {
                throw new Exception("No debt to transfer.");
            }

            var theDebt = netMoney[0];

            if (theDebt.Debtor.Id != debtor.Id || theDebt.Creditor.Id != oldCreditor.Id)
            {
                throw new Exception("Debt does not go in the expected direction.");
            }

            var msg = Transaction.CreateDebtTransferString(debtor, oldCreditor, newCreditor);

            var bs = new BillSplit();

            bs.Name = msg;
            db.BillSplit.Add(bs);

            var cancelTrans = new Transaction()
            {
                Id          = Guid.NewGuid(),
                DebtorId    = oldCreditor.Id, //owes money
                CreditorId  = debtor.Id,      //owed money
                Amount      = theDebt.Amount,
                Bill        = bs,
                Description = msg,
                Created     = when
            };

            db.Transaction.Add(cancelTrans);

            var makeCreditorWholeTransaction = new Transaction()
            {
                Id          = Guid.NewGuid(),
                DebtorId    = newCreditor.Id, //owes money
                CreditorId  = oldCreditor.Id, //owed money
                Amount      = theDebt.Amount,
                Bill        = bs,
                Description = msg,
                Created     = when
            };

            db.Transaction.Add(makeCreditorWholeTransaction);

            var makeDebtorOweNewPartyTrans = new Transaction()
            {
                Id          = Guid.NewGuid(),
                DebtorId    = debtor.Id,      //owes money
                CreditorId  = newCreditor.Id, //owed money
                Amount      = theDebt.Amount,
                Bill        = bs,
                Description = msg,
                Created     = when
            };

            db.Transaction.Add(makeDebtorOweNewPartyTrans);

            db.SaveChanges();
        }
Exemple #6
0
        MyRecord ProcessOnePerson(Person creditor, Person debtor, int amount)
        {
            var q = from t in mDb.Transaction
                    where (t.CreditorId == debtor.Id && t.DebtorId == creditor.Id) ||
                    (t.CreditorId == creditor.Id && t.DebtorId == debtor.Id)
                    orderby t.Created
                    select t;
            var allTrans = q.ToList();

            foreach (var t in allTrans)
            {
                t.SetPrettyDescription(mPersonMap);
            }

            var  souceTrans = new List <Transaction>();
            Debt debt       = null;

            while (allTrans.Count != 0)
            {
                debt = DebtGraph.CalculateDebts(mDb, allTrans, false, TextWriter.Null).SingleOrDefault();
                if (debt == null)
                {
                    break; //this indicates that there is no debt between the two people
                }
                if (debt.Debtor.Id == creditor.Id)
                {
                    break; //this indicates that there is a debt owed in the opisite direction
                }
                souceTrans.Add(allTrans[allTrans.Count - 1]);
                allTrans.RemoveAt(allTrans.Count - 1);
            }

            //TODO: grenerate a pretty table, maybe
            //It seems like a duplication of effort to try to create a subset of the website's debt table here.

            double amountInDollars = Math.Round(amount / 100d, 2);


            var sb = new StringBuilder();

            sb.AppendFormat("Hi {0},", debtor.FirstName);
            sb.AppendLine("<br/>");

            sb.Append("This is a friendly, automated reminder that you currently owe a balence to me in DKP. ");
            sb.Append("Including ");
            sb.Append(souceTrans[0].Description);
            sb.Append(", our most recent time together, you owe ");
            sb.AppendFormat("{0:c}.", amountInDollars);
            sb.AppendLine("<br/>");

            sb.Append("For more information about the transaction history see <a href=\"http://dkp.awise.us/MyDebt/DebtHistory?");
            sb.AppendFormat("debtorId={0}&creditorId={1}", debtor.Id, creditor.Id);
            sb.Append("\">this table</a>. Let me know if you have any questions or concerns.");
            sb.AppendLine("<br/>");

            sb.AppendLine("Here are some handy links to send payment:<ul>");
            foreach (var payId in creditor.PaymentIdentity)
            {
                if (!payId.PaymentMeth.HasPayLink)
                {
                    continue;
                }
                sb.AppendFormat("<li><a href=\"{0}\">{1}</a></li>", payId.CreatePayLink(amount), payId.PaymentMeth.Name.Trim());
            }
            sb.Append("</ul>");
            sb.AppendLine("<br/>");

            sb.Append("Thanks,");
            sb.AppendLine("<br/>");
            sb.Append(creditor.FirstName);

            var ret = new MyRecord();

            ret.EmailAddress = debtor.Email;
            ret.BODY         = sb.ToString();
            return(ret);
        }