public override void ExecuteResult(ControllerContext context) { var Response = context.HttpContext.Response; Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "filename=foo.pdf"); var c = new ContributionStatements { FamilyId = FamilyId, FromDate = FromDate, PeopleId = PeopleId, SpouseId = SpouseId, ToDate = ToDate, typ = typ }; IEnumerable <ContributorInfo> q = null; switch (typ) { case 1: SpouseId = DbUtil.Db.People.Single(p => p.PeopleId == PeopleId).SpouseId.ToInt(); q = APIContribution.contributors(DbUtil.Db, FromDate, ToDate, PeopleId, SpouseId, 0, noaddressok, useMinAmt); break; case 2: FamilyId = DbUtil.Db.People.Single(p => p.PeopleId == PeopleId).FamilyId; q = APIContribution.contributors(DbUtil.Db, FromDate, ToDate, 0, 0, FamilyId, noaddressok, useMinAmt); break; case 3: q = APIContribution.contributors(DbUtil.Db, FromDate, ToDate, 0, 0, 0, noaddressok, useMinAmt); break; } c.Run(Response.OutputStream, DbUtil.Db, q); }
private void writeContributions(ContributorInfo c) { string hdrContributions = " Date Fund Name Amount Date Fund Name Amount\n\n"; rWrite(hdrContributions); var q2 = APIContribution.contributions(Db, c, fd, td); var contrib = new List <string>(); foreach (var ci in q2) { contrib.Add("{0:MM/dd/yyyy} {1,-16}{2,11:N2}" .Fmt(ci.ContributionDate, ci.Fund, ci.ContributionAmount)); } var n = contrib.Count; var nrows = n / 32 * 16; var remainder = n % 32; if (remainder < 16) { nrows += remainder; } else { nrows += 16; } int row, c1; for (row = 0, c1 = 0; row < nrows; row++, c1++) { if (row % 16 == 0) { c1 = row * 2; } var line = contrib[c1]; var c2 = c1 + 16; if (c2 < n) { line += " " + contrib[c2]; } if (row > 0 && row % 16 == 0) { pageStatement += 1; writeHeader(c); rWrite(hdrContributions); rWrite("\n"); } rWrite(line + "\n"); } if (nrows > 0) { rWrite("\n"); } }
public void DoWork() { Db = new CMSDataContext(Util.GetConnectionString(Host)); Db.Host = Host; Db.CommandTimeout = 1200; var noaddressok = Db.Setting("RequireAddressOnStatement", "true") == "false"; var qc = APIContribution.contributors(Db, fd, td, 0, 0, 0, noaddressok, useMinAmt: true, startswith: StartsWith); var runningtotals = Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.Count = qc.Count(); Db.SubmitChanges(); if (PDF) { var c = new ContributionStatements { FromDate = fd, ToDate = td, typ = 3 }; using (var stream = new FileStream(OutputFile, FileMode.Create)) c.Run(stream, Db, qc); LastSet = c.LastSet(); var sets = c.Sets(); foreach (var set in sets) { using (var stream = new FileStream(Output(OutputFile, set), FileMode.Create)) c.Run(stream, Db, qc, set); } runningtotals = Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.LastSet = LastSet; runningtotals.Sets = string.Join(",", sets); runningtotals.Completed = DateTime.Now; Db.SubmitChanges(); } else { textStream = new StreamWriter(OutputFile); foreach (var c in qc) { pageStatement = 1; writeHeader(c); writeContributions(c); string hdrGift = " Date Fund Name Description of Gift-in-Kind Given as of {0:d}\n\n".Fmt(td); rWrite(hdrGift); writeSummary(c); runningtotals.Processed += 1; Db.SubmitChanges(); } textStream.Close(); runningtotals = Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.Completed = DateTime.Now; Db.SubmitChanges(); } }
public ActionResult ContributionStatements(DateTime?fromDate, DateTime?endDate, string startswith, string sort, int?tagid, bool excludeelectronic, string customstatement = null, bool exportcontributors = false) { if (!fromDate.HasValue || !endDate.HasValue) { return(Content("<h3>Must have a Startdate and Enddate</h3>")); } var runningtotals = new ContributionsRun { Started = DateTime.Now, Count = 0, Processed = 0 }; var cs = Models.Report.ContributionStatements.GetStatementSpecification(customstatement); if (!startswith.HasValue()) { startswith = null; } if (exportcontributors) { var db = DbUtil.Db; var noaddressok = !db.Setting("RequireAddressOnStatement", true); const bool useMinAmt = true; if (tagid == 0) { tagid = null; } var qc = APIContribution.Contributors(db, fromDate.Value, endDate.Value, 0, 0, 0, cs.Funds, noaddressok, useMinAmt, startswith, sort, tagid: tagid, excludeelectronic: excludeelectronic); return(ExcelExportModel.ToDataTable(qc.ToList()).ToExcel("Contributors.xlsx")); } DbUtil.Db.ContributionsRuns.InsertOnSubmit(runningtotals); DbUtil.Db.SubmitChanges(); var cul = DbUtil.Db.Setting("Culture", "en-US"); var host = Util.Host; var output = Output(); if (tagid == 0) { tagid = null; } HostingEnvironment.QueueBackgroundWorkItem(ct => { Thread.CurrentThread.CurrentUICulture = new CultureInfo(cul); Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cul); var m = new ContributionStatementsExtract(host, fromDate.Value, endDate.Value, output, startswith, sort, tagid, excludeelectronic); m.DoWork(cs); }); return(Redirect("/Statements/Progress")); }
private void writeSummary(ContributorInfo c) { string hdr1Pledge = " Pledge History Current Year Summary ({0:MM/dd/yyyy})\n".Fmt(td); string hdr2Pledge = " Fund Name Pledge Given Fund Name Amount This Year\n\n"; var recPledges = new List <string>(); decimal Total = 0; rWrite(hdr1Pledge + hdr2Pledge); foreach (var p in APIContribution.pledges(Db, c, td)) { if (p.Fund != null) { recPledges.Add("{0,-16}{1,12:N2} {2,12:N2} ".Fmt(p.Fund, p.PledgeAmount, p.ContributionAmount)); } } foreach (var ci in APIContribution.quarterlySummary(Db, c, fd, td)) { Total += ci.ContributionAmount.Value; if (recPledges != null && recPledges.Count > 0 && countRec < recPledges.Count) { recPledges[countRec] += "{0,-20}{1,14:N2} ".Fmt(ci.Fund, ci.ContributionAmount); } else { recPledges.Add("{0,43}{1,-20}{2,14:N2} ".Fmt("", ci.Fund, ci.ContributionAmount)); } countRec++; } countRec = 0; foreach (var s in recPledges) { countRec++; if (countRec > 6 && (countRec % 6) == 1) { pageStatement++; writeHeader(c); rWrite(hdr1Pledge + hdr2Pledge); } rWrite(s + "\n"); } if (countRec != 0) { rWrite("\n"); } rWrite(totalLine + Total.ToString("C").PadLeft(25) + "\n"); countRec = 0; }
public override void ExecuteResult(ControllerContext context) { var response = context.HttpContext.Response; response.ContentType = "application/pdf"; var filename = $"Statement-{ToDate:d}".SlugifyString("-", false); response.AddHeader("content-disposition", $"filename={filename}.pdf"); var cs = ContributionStatementsExtract.GetStatementSpecification(CurrentDatabase, statementType ?? "all"); var c = new ContributionStatements { FamilyId = FamilyId, FromDate = FromDate, PeopleId = PeopleId, SpouseId = SpouseId, ToDate = ToDate, typ = typ, //TODO: once we switch to entirely html-based statement templates we won't need to check for these options NumberOfColumns = showCheckNo || showNotes ? 1 : 2, ShowCheckNo = showCheckNo, ShowNotes = showNotes }; IEnumerable <ContributorInfo> q = null; switch (typ) { case 1: q = APIContribution.Contributors(CurrentDatabase, FromDate, ToDate, PeopleId, SpouseId, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 2: FamilyId = CurrentDatabase.People.Single(p => p.PeopleId == PeopleId).FamilyId; q = APIContribution.Contributors(CurrentDatabase, FromDate, ToDate, 0, 0, FamilyId, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 3: q = APIContribution.Contributors(CurrentDatabase, FromDate, ToDate, 0, 0, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; } c.Run(response.OutputStream, CurrentDatabase, q, cs); }
public void Run(Stream stream, CMSDataContext Db, IEnumerable <ContributorInfo> q, int set = 0) { pageEvents.set = set; IEnumerable <ContributorInfo> contributors = q; var toDate = ToDate.Date.AddHours(24).AddSeconds(-1); PdfContentByte dc; var font = FontFactory.GetFont(FontFactory.HELVETICA, 11); var boldfont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 11); var doc = new Document(PageSize.LETTER); doc.SetMargins(36f, 30f, 24f, 36f); var w = PdfWriter.GetInstance(doc, stream); w.PageEvent = pageEvents; doc.Open(); dc = w.DirectContent; int prevfid = 0; var runningtotals = Db.ContributionsRuns.OrderByDescending(mm => mm.Id).FirstOrDefault(); runningtotals.Processed = 0; Db.SubmitChanges(); var count = 0; foreach (var ci in contributors) { if (set > 0 && pageEvents.FamilySet[ci.PeopleId] != set) { continue; } var contributions = APIContribution.contributions(Db, ci, FromDate, toDate).ToList(); var pledges = APIContribution.pledges(Db, ci, toDate).ToList(); var giftsinkind = APIContribution.GiftsInKind(Db, ci, FromDate, toDate).ToList(); var nontaxitems = Db.Setting("DisplayNonTaxOnStatement", "false").ToBool() ? APIContribution.NonTaxItems(Db, ci, FromDate, toDate).ToList() : new List <ContributionInfo>(); if ((contributions.Count + pledges.Count + giftsinkind.Count + nontaxitems.Count) == 0) { runningtotals.Processed += 1; runningtotals.CurrSet = set; Db.SubmitChanges(); if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } continue; } doc.NewPage(); if (prevfid != ci.FamilyId) { prevfid = ci.FamilyId; pageEvents.EndPageSet(); } if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } count++; var css = @" <style> h1 { font-size: 24px; font-weight:normal; margin-bottom:0; } h2 { font-size: 11px; font-weight:normal; margin-top: 0; } p { font-size: 11px; } </style> "; //----Church Name var t1 = new PdfPTable(1); t1.TotalWidth = 72f * 5f; t1.DefaultCell.Border = Rectangle.NO_BORDER; string html1 = Db.ContentHtml("StatementHeader", Resource1.ContributionStatementHeader); string html2 = Db.ContentHtml("StatementNotice", Resource1.ContributionStatementNotice); var mh = new MyHandler(); using (var sr = new StringReader(css + html1)) XMLWorkerHelper.GetInstance().ParseXHtml(mh, sr); var cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } //cell.FixedHeight = 72f * 1.25f; t1.AddCell(cell); t1.AddCell("\n"); var t1a = new PdfPTable(1); t1a.TotalWidth = 72f * 5f; t1a.DefaultCell.Border = Rectangle.NO_BORDER; var ae = new PdfPTable(1); ae.DefaultCell.Border = Rectangle.NO_BORDER; ae.WidthPercentage = 100; var a = new PdfPTable(1); a.DefaultCell.Indent = 25f; a.DefaultCell.Border = Rectangle.NO_BORDER; a.AddCell(new Phrase(ci.Name, font)); foreach (var line in ci.MailingAddress.SplitLines()) { a.AddCell(new Phrase(line, font)); } cell = new PdfPCell(a) { Border = Rectangle.NO_BORDER }; //cell.FixedHeight = 72f * 1.0625f; ae.AddCell(cell); cell = new PdfPCell(t1a.DefaultCell); cell.AddElement(ae); t1a.AddCell(ae); //-----Notice var t2 = new PdfPTable(1); t2.TotalWidth = 72f * 3f; t2.DefaultCell.Border = Rectangle.NO_BORDER; t2.AddCell(new Phrase($"\nPrint Date: {DateTime.Now:d} (id:{ci.PeopleId} {ci.CampusId})", font)); t2.AddCell(""); var mh2 = new MyHandler(); using (var sr = new StringReader(css + html2)) XMLWorkerHelper.GetInstance().ParseXHtml(mh2, sr); cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh2.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } t2.AddCell(cell); // POSITIONING OF ADDRESSES //----Header var yp = doc.BottomMargin + Db.Setting("StatementRetAddrPos", "10.125").ToFloat() * 72f; t1.WriteSelectedRows(0, -1, doc.LeftMargin - 0.1875f * 72f, yp, dc); yp = doc.BottomMargin + Db.Setting("StatementAddrPos", "8.3375").ToFloat() * 72f; t1a.WriteSelectedRows(0, -1, doc.LeftMargin, yp, dc); yp = doc.BottomMargin + 10.125f * 72f; t2.WriteSelectedRows(0, -1, doc.LeftMargin + 72f * 4.4f, yp, dc); //----Contributions doc.Add(new Paragraph(" ")); doc.Add(new Paragraph(" ") { SpacingBefore = 72f * 2.125f }); doc.Add(new Phrase($"\n Period: {FromDate:d} - {toDate:d}", boldfont)); var pos = w.GetVerticalPosition(true); var ct = new ColumnText(dc); float gutter = 20f; float colwidth = (doc.Right - doc.Left - gutter) / 2; var t = new PdfPTable(new[] { 10f, 24f, 10f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase("Contributions\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; var total = 0m; foreach (var c in contributions) { t.AddCell(new Phrase(c.ContributionDate.ToShortDateString(), font)); t.AddCell(new Phrase(c.Fund, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString("N2"), font); t.AddCell(cell); total += (c.ContributionAmount); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase("Total Contributions for period", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(total.ToString("N2"), font); t.AddCell(cell); ct.AddElement(t); //------Pledges if (pledges.Count > 0) { t = new PdfPTable(new float[] { 16f, 12f, 12f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase("\n\nPledges\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Pledge", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Given", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; foreach (var c in pledges) { t.AddCell(new Phrase(c.Fund, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.PledgeAmount.ToString2("N2"), font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString2("N2"), font); t.AddCell(cell); } ct.AddElement(t); } //------Gifts In Kind if (giftsinkind.Count > 0) { t = new PdfPTable(new float[] { 12f, 18f, 20f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase("\n\nGifts in Kind\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase("Fund", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase("Description", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; foreach (var c in giftsinkind) { t.AddCell(new Phrase(c.ContributionDate.ToShortDateString(), font)); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase(c.Fund, font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase(c.Description, font); t.AddCell(cell); } ct.AddElement(t); } //-----Summary t = new PdfPTable(new float[] { 29f, 9f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase("\n\nPeriod Summary\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; foreach (var c in APIContribution.quarterlySummary(Db, ci, FromDate, toDate)) { t.AddCell(new Phrase(c.Fund, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString("N2"), font); t.AddCell(cell); } t.DefaultCell.Border = Rectangle.TOP_BORDER; t.AddCell(new Phrase("Total contributions for period", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(total.ToString("N2"), font); t.AddCell(cell); ct.AddElement(t); //------NonTax if (nontaxitems.Count > 0) { t = new PdfPTable(new float[] { 10f, 24f, 10f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase("\n\nNon Tax-Deductible Items\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; var ntotal = 0m; foreach (var c in nontaxitems) { t.AddCell(new Phrase(c.ContributionDate.ToShortDateString(), font)); t.AddCell(new Phrase(c.Fund, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString("N2"), font); t.AddCell(cell); ntotal += (c.ContributionAmount); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase("Total Non Tax-Deductible Items for period", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(ntotal.ToString("N2"), font); t.AddCell(cell); ct.AddElement(t); } var col = 0; var status = 0; while (ColumnText.HasMoreText(status)) { if (col == 0) { ct.SetSimpleColumn(doc.Left, doc.Bottom, doc.Left + colwidth, pos); } else if (col == 1) { ct.SetSimpleColumn(doc.Right - colwidth, doc.Bottom, doc.Right, pos); } status = ct.Go(); ++col; if (col > 1) { col = 0; pos = doc.Top; doc.NewPage(); } } runningtotals.Processed += 1; runningtotals.CurrSet = set; Db.SubmitChanges(); } if (count == 0) { doc.NewPage(); doc.Add(new Paragraph("no data")); var a = new Anchor("see this help document docs.touchpointsoftware.com/Finance/ContributionStatements.html") { Reference = "http://docs.touchpointsoftware.com/Finance/ContributionStatements.html#troubleshooting" }; doc.Add(a); } doc.Close(); if (set == LastSet()) { runningtotals.Completed = DateTime.Now; } Db.SubmitChanges(); }
private void HtmlToPdfMethod(Stream stream, CMSDataContext db, IEnumerable <ContributorInfo> q, StatementSpecification cs, int set) { IConverter converter = GetConverter(); string nameOfChurch = db.Setting("NameOfChurch", "Name of Church"); string startAddress = db.Setting("StartAddress", "Start Address"); string churchPhone = db.Setting("ChurchPhone", "(000) 000-0000"); string html = cs.Template ?? db.Content("StatementTemplate", Resource1.ContributionStatementTemplate, ContentTypeCode.TypeText).Body; string bodyHtml = cs.TemplateBody ?? db.Content("StatementTemplateBody", Resource1.ContributionStatementTemplateBody, ContentTypeCode.TypeText).Body; string header = cs.Header ?? db.Content("StatementHeader", string.Format(Resource1.ContributionStatementHeader, nameOfChurch, startAddress, churchPhone), ContentTypeCode.TypeHtml).Body; string notice = cs.Notice ?? db.Content("StatementNotice", string.Format(Resource1.ContributionStatementNotice, nameOfChurch), ContentTypeCode.TypeHtml).Body; string footer = cs.Footer ?? db.Content("StatementTemplateFooter", "", ContentTypeCode.TypeText).Body; ContributionsRun runningtotals = db.ContributionsRuns.Where(mm => mm.UUId == UUId).SingleOrDefault(); StatementOptions options; if (!GetStatementOptions(bodyHtml, out options)) { GetStatementOptions(html, out options); } var toDate = ToDate.Date.AddHours(24).AddSeconds(-1); var document = new HtmlToPdfDocument { GlobalSettings = { DocumentTitle = (cs.Description ?? "Contribution Statement {date}").Replace("{date}", $"{toDate:d}"), Margins = options.Margins.Settings, PaperSize = options.PaperSize, ProduceOutline = false, } }; var familiesInSet = pageEvents.FamilySet.Where(k => k.Value == set).Select(k => k.Key); var contributors = q.Where(c => set == 0 || familiesInSet.Contains(c.FamilyId)); var count = contributors.Count(); if (count == 0) { document.Objects.Add(new ObjectSettings { HtmlText = @"<p>no data</p> <a href=""https://docs.touchpointsoftware.com/Finance/ContributionStatements.html#troubleshooting""> See this help document docs.touchpointsoftware.com/Finance/ContributionStatements.html </a>" }); var bytes = converter.Convert(document); stream.Write(bytes, 0, bytes.Length); return; } if (runningtotals != null) { runningtotals.Processed = 0; } db.SubmitChanges(); Document combinedPDF = new Document(); var combinedPDFName = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.pdf"); using (FileStream combinedStream = new FileStream(combinedPDFName, FileMode.Create)) { using (PdfCopy writer = new PdfCopy(combinedPDF, combinedStream)) { combinedPDF.Open(); var lastFamilyId = 0; foreach (var contributor in contributors) { if (runningtotals != null) { runningtotals.Processed += 1; runningtotals.CurrSet = set; db.SubmitChanges(); } if (lastFamilyId != contributor.FamilyId) { lastFamilyId = contributor.FamilyId; if (set == 0) { pageEvents.FamilySet[contributor.FamilyId] = 0; } } var contributions = APIContribution.Contributions(db, contributor, FromDate, toDate, cs.Funds).ToList(); var pledges = APIContribution.Pledges(db, contributor, toDate, cs.Funds).ToList(); var giftsinkind = APIContribution.GiftsInKind(db, contributor, FromDate, toDate, cs.Funds).ToList(); var nontaxitems = APIContribution.NonTaxItems(db, contributor, FromDate, toDate, cs.Funds).ToList(); if ((contributions.Count + pledges.Count + giftsinkind.Count + nontaxitems.Count) > 0) { contributor.MailingAddress = string.Join("<br/>", contributor.MailingAddress.SplitLines()); var taxSummary = SumByFund(contributions); var nontaxSummary = SumByFund(nontaxitems.Select(i => new NormalContribution(i)).ToList()); if (options.CombinedTaxSummary) { taxSummary.Combine(SumByFund(giftsinkind.Select(i => new NormalContribution(i)).ToList())); } var data = new StatementContext { fromDate = FromDate, toDate = toDate, header = "", notice = "", now = DateTime.Now, body = "", footer = "", contributor = contributor, envelopeNumber = Convert.ToString(Person.GetExtraValue(db, contributor.PeopleId, "EnvelopeNumber")?.IntValue), contributions = new ListOfNormalContributions(contributions), pledges = pledges, giftsinkind = giftsinkind, nontaxitems = nontaxitems, taxSummary = taxSummary, nontaxSummary = nontaxSummary, totalGiven = taxSummary.Total + nontaxSummary.Total }; data.header = db.RenderTemplate(header, data); data.notice = db.RenderTemplate(notice, data); data.body = db.RenderTemplate(bodyHtml, data); data.footer = db.RenderTemplate(footer, data); var htmlDocument = db.RenderTemplate(html, data); document.Objects.Clear(); document.Objects.Add(new ObjectSettings { CountPages = true, FooterSettings = options.Footer.Settings, HeaderSettings = options.Header.Settings, HtmlText = htmlDocument, WebSettings = new WebSettings { EnableJavascript = false, PrintBackground = true }, LoadSettings = new LoadSettings { BlockLocalFileAccess = true } }); } else { continue; } var bytes = converter.Convert(document); var pageCount = 0; using (PdfReader reader = new PdfReader(bytes)) { pageCount = reader.NumberOfPages; for (int p = 0; p < pageCount; p++) { var page = writer.GetImportedPage(reader, p + 1); writer.AddPage(page); } } if (set == 0) { pageEvents.FamilySet[contributor.FamilyId] += pageCount; } } } } using (var combined = File.OpenRead(combinedPDFName)) { combined.CopyTo(stream); } }
public void StandardMethod(Stream stream, CMSDataContext db, IEnumerable <ContributorInfo> q, StatementSpecification cs, int set = 0) { pageEvents.set = set; pageEvents.PeopleId = 0; var contributors = q; var toDate = ToDate.Date.AddHours(24).AddSeconds(-1); var font = FontFactory.GetFont(FontFactory.HELVETICA, 11); var boldfont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 11); var doc = new Document(PageSize.LETTER); doc.SetMargins(36f, 30f, 24f, 36f); var w = PdfWriter.GetInstance(doc, stream); w.PageEvent = pageEvents; doc.Open(); var dc = w.DirectContent; var prevfid = 0; var runningtotals = UUId.HasValue ? db.ContributionsRuns.Where(mm => mm.UUId == UUId).SingleOrDefault() : null; if (runningtotals != null) { runningtotals.Processed = 0; db.SubmitChanges(); } var count = 0; foreach (var ci in contributors) { if (set > 0 && pageEvents.FamilySet[ci.PeopleId] != set) { continue; } var contributions = APIContribution.Contributions(db, ci, FromDate, toDate, cs.Funds).ToList(); var pledges = APIContribution.Pledges(db, ci, toDate, cs.Funds).ToList(); var giftsinkind = APIContribution.GiftsInKind(db, ci, FromDate, toDate, cs.Funds).ToList(); var nontaxitems = db.Setting("DisplayNonTaxOnStatement", "false").ToBool() ? APIContribution.NonTaxItems(db, ci, FromDate, toDate, cs.Funds).ToList() : new List <NonTaxContribution>(); if ((contributions.Count + pledges.Count + giftsinkind.Count + nontaxitems.Count) == 0) { if (runningtotals != null) { runningtotals.Processed += 1; runningtotals.CurrSet = set; db.SubmitChanges(); } if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } continue; } pageEvents.NextPeopleId = ci.PeopleId; doc.NewPage(); if (prevfid != ci.FamilyId) { prevfid = ci.FamilyId; pageEvents.EndPageSet(); pageEvents.PeopleId = ci.PeopleId; } if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } count++; var css = @" <style> h1 { font-size: 24px; font-weight:normal; margin-bottom:0; } h2 { font-size: 11px; font-weight:normal; margin-top: 0; } p { font-size: 11px; } </style> "; //----Church Name var t1 = new PdfPTable(1) { TotalWidth = 72f * 5f }; t1.DefaultCell.Border = Rectangle.NO_BORDER; string nameOfChurch = db.Setting("NameOfChurch", "Name of Church"); string startAddress = db.Setting("StartAddress", "Start Address"); string churchPhone = db.Setting("ChurchPhone", "(000) 000-0000"); var html1 = cs.Header ?? db.ContentHtml("StatementHeader", string.Format(Resource1.ContributionStatementHeader, nameOfChurch, startAddress, churchPhone)); var html2 = cs.Notice ?? db.ContentHtml("StatementNotice", string.Format(Resource1.ContributionStatementNotice, nameOfChurch)); var mh = new MyHandler(); using (var sr = new StringReader(css + html1)) { XMLWorkerHelper.GetInstance().ParseXHtml(mh, sr); } var cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } t1.AddCell(cell); t1.AddCell("\n"); var t1a = new PdfPTable(1) { TotalWidth = 72f * 5f }; t1a.DefaultCell.Border = Rectangle.NO_BORDER; var ae = new PdfPTable(1); ae.DefaultCell.Border = Rectangle.NO_BORDER; ae.WidthPercentage = 100; var a = new PdfPTable(1); a.DefaultCell.Indent = 25f; a.DefaultCell.Border = Rectangle.NO_BORDER; a.AddCell(new Phrase(ci.Name, font)); foreach (var line in ci.MailingAddress.SplitLines()) { a.AddCell(new Phrase(line, font)); } cell = new PdfPCell(a) { Border = Rectangle.NO_BORDER }; ae.AddCell(cell); cell = new PdfPCell(t1a.DefaultCell); cell.AddElement(ae); t1a.AddCell(ae); //-----Notice var t2 = new PdfPTable(1) { TotalWidth = 72f * 3f }; t2.DefaultCell.Border = Rectangle.NO_BORDER; var envno = ""; if (db.Setting("PrintEnvelopeNumberOnStatement")) { var ev = Person.GetExtraValue(db, ci.PeopleId, "EnvelopeNumber"); var s = Util.PickFirst(ev.Data, ev.IntValue.ToString(), ev.StrValue); if (s.HasValue()) { envno = $"env: {s}"; } } t2.AddCell(db.Setting("NoPrintDateOnStatement") ? new Phrase($"\nid:{ci.PeopleId}{envno} {ci.CampusId}", font) : new Phrase($"\nprinted: {DateTime.Now:d} id:{ci.PeopleId}{envno} {ci.CampusId}", font)); t2.AddCell(""); var mh2 = new MyHandler(); using (var sr = new StringReader(css + html2)) { XMLWorkerHelper.GetInstance().ParseXHtml(mh2, sr); } cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh2.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } t2.AddCell(cell); // POSITIONING OF ADDRESSES //----Header var yp = doc.BottomMargin + db.Setting("StatementRetAddrPos", "10.125").ToFloat() * 72f; t1.WriteSelectedRows(0, -1, doc.LeftMargin - 0.1875f * 72f, yp, dc); yp = doc.BottomMargin + db.Setting("StatementAddrPos", "8.3375").ToFloat() * 72f; t1a.WriteSelectedRows(0, -1, doc.LeftMargin, yp, dc); yp = doc.BottomMargin + 10.125f * 72f; t2.WriteSelectedRows(0, -1, doc.LeftMargin + 72f * 4.4f, yp, dc); //----Contributions doc.Add(new Paragraph(" ")); doc.Add(new Paragraph(" ") { SpacingBefore = 72f * 2.125f }); doc.Add(new Phrase($"\n Period: {FromDate:d} - {toDate:d}", boldfont)); var pos = w.GetVerticalPosition(true); var ct = new ColumnText(dc); var gutter = 20f; if (NumberOfColumns == 1) { gutter = 0; } var colwidth = (doc.Right - doc.Left - gutter) / NumberOfColumns; var t = (NumberOfColumns == 2) ? new PdfPTable(new[] { 18f, 24f, 15f }) : new PdfPTable(new[] { 18f, 25f, 15f, 15f, 30f }) { WidthPercentage = 100 }; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 2) ? 3 : 5, Phrase = new Phrase("Contributions\n", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase("Amount", boldfont) }; t.AddCell(cell); if (NumberOfColumns == 1) { cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_CENTER, Phrase = ShowCheckNo ? new Phrase("Check No", boldfont) : new Phrase("", boldfont) }; t.AddCell(cell); t.AddCell(ShowNotes ? new Phrase("Notes", boldfont) : new Phrase("", boldfont)); } t.DefaultCell.Border = Rectangle.NO_BORDER; var total = 0m; foreach (var c in contributions) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); t.AddCell(new Phrase(GetFundDisplayText(db, () => c.FundName, () => c.FundDescription), font)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(c.ContributionAmount.ToString2("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_CENTER, Phrase = ShowCheckNo ? new Phrase(c.CheckNo, font) : new Phrase("", font) }; t.AddCell(cell); t.AddCell(ShowNotes ? new Phrase(c.Description?.Trim() ?? "", font) : new Phrase("", font)); } total += (c.ContributionAmount ?? 0); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell) { Colspan = 2, Phrase = new Phrase("Total Contributions for period", boldfont) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(total.ToString("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { cell = new PdfPCell(t.DefaultCell) { Colspan = 2, Phrase = new Phrase("") }; t.AddCell(cell); } ct.AddElement(t); //------Pledges if (pledges.Count > 0) { t = new PdfPTable((NumberOfColumns == 1) ? new[] { 25f, 15f, 15f, 15f, 30f } : new[] { 16f, 12f, 12f }) { WidthPercentage = 100, HeaderRows = 2, }; t.DefaultCell.Border = Rectangle.NO_BORDER; cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 1) ? 5 : 3, Phrase = new Phrase("\n\nPledges\n", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase("Pledge", boldfont) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase("Given", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } foreach (var c in pledges) { t.AddCell(new Phrase(GetFundDisplayText(db, () => c.FundName, () => c.FundDescription), font)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(c.Pledged.ToString2("N2"), font) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(c.Given.ToString2("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } } ct.AddElement(t); } //------Gifts In Kind if (giftsinkind.Count > 0) { t = new PdfPTable((NumberOfColumns == 1) ? new[] { 18f, 25f, 15f, 15f, 30f } : new[] { 12f, 18f, 20f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; // Headers cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 1) ? 5 : 3, Phrase = new Phrase("\n\nGifts in Kind\n", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); cell = new PdfPCell(t.DefaultCell) { Phrase = new Phrase("Fund", boldfont) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { Phrase = new Phrase("Description", boldfont) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } t.DefaultCell.Border = Rectangle.NO_BORDER; foreach (var c in giftsinkind) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); cell = new PdfPCell(t.DefaultCell) { Phrase = new Phrase(GetFundDisplayText(db, () => c.FundName, () => c.FundDescription), font) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 1) ? 3 : 1, Phrase = new Phrase(c.Description, font) }; t.AddCell(cell); } ct.AddElement(t); } //-----Summary t = new PdfPTable((NumberOfColumns == 1) ? new[] { 40f, 15f, 45f } : new[] { 29f, 9f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 1) ? 3 : 2, Phrase = new Phrase("\n\nPeriod Summary\n", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase("Amount", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); } foreach (var c in APIContribution.GiftSummary(db, ci, FromDate, toDate, cs.Funds)) { t.AddCell(new Phrase(GetFundDisplayText(db, () => c.FundName, () => c.FundDescription), font)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(c.Total.ToString2("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); } } t.DefaultCell.Border = Rectangle.TOP_BORDER; t.AddCell(new Phrase("Total contributions for period", boldfont)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(total.ToString("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { cell = new PdfPCell(t.DefaultCell) { Phrase = new Phrase("") }; t.AddCell(cell); } ct.AddElement(t); //------NonTax if (nontaxitems.Count > 0) { t = new PdfPTable((NumberOfColumns == 1) ? new[] { 18f, 25f, 15f, 15f, 30f } : new[] { 18f, 24f, 15f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell) { Colspan = (NumberOfColumns == 1) ? 5 : 3, Phrase = new Phrase("\n\nNon Tax-Deductible Items\n", boldfont) }; t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase("Amount", boldfont) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } t.DefaultCell.Border = Rectangle.NO_BORDER; var ntotal = 0m; foreach (var c in nontaxitems) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); t.AddCell(new Phrase(GetFundDisplayText(db, () => c.FundName, () => c.FundDescription), font)); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(c.ContributionAmount.ToString2("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(ShowNotes ? new Phrase(c.Description, font) : new Phrase("", font)); } ntotal += (c.ContributionAmount ?? 0); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell) { Colspan = 2, Phrase = new Phrase("Total Non Tax-Deductible Items for period", boldfont) }; t.AddCell(cell); cell = new PdfPCell(t.DefaultCell) { HorizontalAlignment = Element.ALIGN_RIGHT, Phrase = new Phrase(ntotal.ToString("N2"), font) }; t.AddCell(cell); if (NumberOfColumns == 1) { t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } ct.AddElement(t); } var col = 0; var status = 0; while (ColumnText.HasMoreText(status)) { switch (col) { case 0: ct.SetSimpleColumn(doc.Left, doc.Bottom, doc.Left + colwidth, pos); break; case 1: ct.SetSimpleColumn(doc.Right - colwidth, doc.Bottom, doc.Right, pos); break; } status = ct.Go(); if (NumberOfColumns == 2) { ++col; if (col <= 1) { continue; } col = 0; } pos = doc.Top; doc.NewPage(); } if (runningtotals != null) { runningtotals.Processed += 1; runningtotals.CurrSet = set; db.SubmitChanges(); } } if (count == 0) { doc.NewPage(); doc.Add(new Paragraph("no data")); var a = new Anchor("see this help document docs.touchpointsoftware.com/Finance/ContributionStatements.html") { Reference = "https://docs.touchpointsoftware.com/Finance/ContributionStatements.html#troubleshooting" }; doc.Add(a); } doc.Close(); if (set == LastSet() && runningtotals != null) { runningtotals.Completed = DateTime.Now; } db.SubmitChanges(); }
public override void ExecuteResult(ControllerContext context) { var response = context.HttpContext.Response; response.ContentType = "application/pdf"; response.AddHeader("content-disposition", "filename=foo.pdf"); var cs = ContributionStatements.GetStatementSpecification(statementType ?? "all"); if (showCheckNo || showNotes) { var c = new ContributionStatementsExtra { FamilyId = FamilyId, FromDate = FromDate, PeopleId = PeopleId, SpouseId = SpouseId, ToDate = ToDate, typ = typ, ShowCheckNo = showCheckNo, ShowNotes = showNotes }; IEnumerable <ContributorInfo> q = null; switch (typ) { case 1: q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, PeopleId, SpouseId, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 2: FamilyId = DbUtil.Db.People.Single(p => p.PeopleId == PeopleId).FamilyId; q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, 0, 0, FamilyId, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 3: q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, 0, 0, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; } c.Run(response.OutputStream, DbUtil.Db, q, cs); } else { var c = new ContributionStatements { FamilyId = FamilyId, FromDate = FromDate, PeopleId = PeopleId, SpouseId = SpouseId, ToDate = ToDate, typ = typ }; IEnumerable <ContributorInfo> q = null; switch (typ) { case 1: q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, PeopleId, SpouseId, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 2: FamilyId = DbUtil.Db.People.Single(p => p.PeopleId == PeopleId).FamilyId; q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, 0, 0, FamilyId, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; case 3: q = APIContribution.Contributors(DbUtil.Db, FromDate, ToDate, 0, 0, 0, cs.Funds, noaddressok, useMinAmt, singleStatement: singleStatement); break; } c.Run(response.OutputStream, DbUtil.Db, q, cs); } }
public void Run(Stream stream, CMSDataContext db, IEnumerable <ContributorInfo> q, ContributionStatements.StatementSpecification cs, int set = 0) { pageEvents.set = set; pageEvents.PeopleId = 0; var contributors = q; PdfContentByte dc; var font = FontFactory.GetFont(FontFactory.HELVETICA, 11); var boldfont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 11); var doc = new Document(PageSize.LETTER); doc.SetMargins(36f, 30f, 24f, 36f); var w = PdfWriter.GetInstance(doc, stream); w.PageEvent = pageEvents; doc.Open(); dc = w.DirectContent; var prevfid = 0; var runningtotals = db.ContributionsRuns.OrderByDescending(mm => mm.Id).FirstOrDefault(); runningtotals.Processed = 0; db.SubmitChanges(); var count = 0; foreach (var ci in contributors) { if (set > 0 && pageEvents.FamilySet[ci.PeopleId] != set) { continue; } var contributions = APIContribution.Contributions(db, ci, FromDate, ToDate, cs.Funds).ToList(); var pledges = APIContribution.Pledges(db, ci, ToDate, cs.Funds).ToList(); var giftsinkind = APIContribution.GiftsInKind(db, ci, FromDate, ToDate, cs.Funds).ToList(); var nontaxitems = db.Setting("DisplayNonTaxOnStatement", "false").ToBool() ? APIContribution.NonTaxItems(db, ci, FromDate, ToDate, cs.Funds).ToList() : new List <NonTaxContribution>(); if ((contributions.Count + pledges.Count + giftsinkind.Count + nontaxitems.Count) == 0) { runningtotals.Processed += 1; runningtotals.CurrSet = set; db.SubmitChanges(); if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } continue; } pageEvents.NextPeopleId = ci.PeopleId; doc.NewPage(); if (prevfid != ci.FamilyId) { prevfid = ci.FamilyId; pageEvents.EndPageSet(); pageEvents.PeopleId = ci.PeopleId; } if (set == 0) { pageEvents.FamilySet[ci.PeopleId] = 0; } count++; var css = @" <style> h1 { font-size: 24px; font-weight:normal; margin-bottom:0; } h2 { font-size: 11px; font-weight:normal; margin-top: 0; } p { font-size: 11px; } </style> "; //----Church Name var t1 = new PdfPTable(1); t1.TotalWidth = 72f * 5f; t1.DefaultCell.Border = Rectangle.NO_BORDER; var mh = new MyHandler(); using (var sr = new StringReader(css + cs.Header)) XMLWorkerHelper.GetInstance().ParseXHtml(mh, sr); var cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } //cell.FixedHeight = 72f * 1.25f; t1.AddCell(cell); t1.AddCell("\n"); var t1a = new PdfPTable(1); t1a.TotalWidth = 72f * 5f; t1a.DefaultCell.Border = Rectangle.NO_BORDER; var ae = new PdfPTable(1); ae.DefaultCell.Border = Rectangle.NO_BORDER; ae.WidthPercentage = 100; var a = new PdfPTable(1); a.DefaultCell.Indent = 25f; a.DefaultCell.Border = Rectangle.NO_BORDER; a.AddCell(new Phrase(ci.Name, font)); foreach (var line in ci.MailingAddress.SplitLines()) { a.AddCell(new Phrase(line, font)); } cell = new PdfPCell(a) { Border = Rectangle.NO_BORDER }; //cell.FixedHeight = 72f * 1.0625f; ae.AddCell(cell); cell = new PdfPCell(t1a.DefaultCell); cell.AddElement(ae); t1a.AddCell(ae); //-----Notice var t2 = new PdfPTable(1); t2.TotalWidth = 72f * 3f; t2.DefaultCell.Border = Rectangle.NO_BORDER; var envno = ""; if (db.Setting("PrintEnvelopeNumberOnStatement")) { var ev = Person.GetExtraValue(db, ci.PeopleId, "EnvelopeNumber"); var s = Util.PickFirst(ev.Data, ev.IntValue.ToString(), ev.StrValue); if (s.HasValue()) { envno = $" env: {Util.PickFirst(ev.Data, ev.IntValue.ToString(), ev.StrValue)}"; } } t2.AddCell(db.Setting("NoPrintDateOnStatement") ? new Phrase($"\nid:{ci.PeopleId}{envno} {ci.CampusId}", font) : new Phrase($"\nprinted: {DateTime.Now:d} id:{ci.PeopleId}{envno} {ci.CampusId}", font)); t2.AddCell(""); var mh2 = new MyHandler(); using (var sr = new StringReader(css + cs.Notice)) XMLWorkerHelper.GetInstance().ParseXHtml(mh2, sr); cell = new PdfPCell(t1.DefaultCell); foreach (var e in mh2.elements) { if (e.Chunks.Count > 0) { cell.AddElement(e); } } t2.AddCell(cell); // POSITIONING OF ADDRESSES //----Header var yp = doc.BottomMargin + db.Setting("StatementRetAddrPos", "10.125").ToFloat() * 72f; t1.WriteSelectedRows(0, -1, doc.LeftMargin - 0.1875f * 72f, yp, dc); yp = doc.BottomMargin + db.Setting("StatementAddrPos", "8.3375").ToFloat() * 72f; t1a.WriteSelectedRows(0, -1, doc.LeftMargin, yp, dc); yp = doc.BottomMargin + 10.125f * 72f; t2.WriteSelectedRows(0, -1, doc.LeftMargin + 72f * 4.4f, yp, dc); //----Contributions doc.Add(new Paragraph(" ")); doc.Add(new Paragraph(" ") { SpacingBefore = 72f * 2.125f }); doc.Add(new Phrase($"\n Period: {FromDate:d} - {ToDate:d}", boldfont)); var pos = w.GetVerticalPosition(true); var ct = new ColumnText(dc); var colwidth = (doc.Right - doc.Left); var t = new PdfPTable(new[] { 15f, 25f, 15f, 15f, 30f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 5; cell.Phrase = new Phrase("Contributions\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_CENTER; if (ShowCheckNo) { cell.Phrase = new Phrase("Check No", boldfont); } else { cell.Phrase = new Phrase("", boldfont); } t.AddCell(cell); if (ShowNotes) { t.AddCell(new Phrase("Notes", boldfont)); } else { t.AddCell(new Phrase("", boldfont)); } t.DefaultCell.Border = Rectangle.NO_BORDER; var total = 0m; foreach (var c in contributions) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); t.AddCell(new Phrase(c.FundName, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString2("N2"), font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_CENTER; if (ShowCheckNo) { cell.Phrase = new Phrase(c.CheckNo, font); } else { cell.Phrase = new Phrase("", font); } t.AddCell(cell); if (ShowNotes) { t.AddCell(new Phrase(c.Description.trim(), font)); } else { t.AddCell(new Phrase("", font)); } total += (c.ContributionAmount ?? 0); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase("Total Contributions for period", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(total.ToString("N2"), font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase(""); t.AddCell(cell); ct.AddElement(t); //------Pledges if (pledges.Count > 0) { t = new PdfPTable(new[] { 25f, 15f, 15f, 15f, 30f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 5; cell.Phrase = new Phrase("\n\nPledges\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Pledge", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Given", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); foreach (var c in pledges) { t.AddCell(new Phrase(c.FundName, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.Pledged.ToString2("N2"), font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.Given.ToString2("N2"), font); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); } ct.AddElement(t); } //------Gifts In Kind if (giftsinkind.Count > 0) { t = new PdfPTable(new[] { 15f, 25f, 15f, 15f, 30f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; // Headers cell = new PdfPCell(t.DefaultCell); cell.Colspan = 5; cell.Phrase = new Phrase("\n\nGifts in Kind\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase("Fund", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase("Description", boldfont); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); t.DefaultCell.Border = Rectangle.NO_BORDER; foreach (var c in giftsinkind) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase(c.FundName, font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase(c.Description, font); t.AddCell(cell); } ct.AddElement(t); } //-----Summary t = new PdfPTable(new[] { 40f, 15f, 45f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 3; cell.Phrase = new Phrase("\n\nPeriod Summary\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Fund", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.NO_BORDER; t.AddCell(new Phrase("", boldfont)); foreach (var c in APIContribution.GiftSummary(db, ci, FromDate, ToDate, cs.Funds)) { t.AddCell(new Phrase(c.FundName, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.Total.ToString2("N2"), font); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); } t.DefaultCell.Border = Rectangle.NO_BORDER; cell = new PdfPCell(t.DefaultCell); cell.Border = Rectangle.TOP_BORDER; cell.Colspan = 1; cell.Phrase = new Phrase("Total Contributions for period", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Border = Rectangle.TOP_BORDER; cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(total.ToString("N2"), font); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.Phrase = new Phrase(""); t.AddCell(cell); ct.AddElement(t); //------NonTax if (nontaxitems.Count > 0) { t = new PdfPTable(new[] { 15f, 25f, 15f, 15f, 30f }); t.WidthPercentage = 100; t.DefaultCell.Border = Rectangle.NO_BORDER; t.HeaderRows = 2; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 5; cell.Phrase = new Phrase("\n\nNon Tax-Deductible Items\n", boldfont); t.AddCell(cell); t.DefaultCell.Border = Rectangle.BOTTOM_BORDER; t.AddCell(new Phrase("Date", boldfont)); t.AddCell(new Phrase("Description", boldfont)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase("Amount", boldfont); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); t.DefaultCell.Border = Rectangle.NO_BORDER; var ntotal = 0m; foreach (var c in nontaxitems) { t.AddCell(new Phrase(c.ContributionDate.ToString2("d"), font)); t.AddCell(new Phrase(c.FundName, font)); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(c.ContributionAmount.ToString2("N2"), font); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); if (ShowNotes) { t.AddCell(new Phrase(c.Description, font)); } else { t.AddCell(new Phrase("", font)); } ntotal += (c.ContributionAmount ?? 0); } t.DefaultCell.Border = Rectangle.TOP_BORDER; cell = new PdfPCell(t.DefaultCell); cell.Colspan = 2; cell.Phrase = new Phrase("Total Non Tax-Deductible Items for period", boldfont); t.AddCell(cell); cell = new PdfPCell(t.DefaultCell); cell.HorizontalAlignment = Element.ALIGN_RIGHT; cell.Phrase = new Phrase(ntotal.ToString("N2"), font); t.AddCell(cell); t.AddCell(new Phrase("", boldfont)); t.AddCell(new Phrase("", boldfont)); ct.AddElement(t); } var status = 0; while (ColumnText.HasMoreText(status)) { ct.SetSimpleColumn(doc.Left, doc.Bottom, doc.Left + colwidth, pos); status = ct.Go(); pos = doc.Top; doc.NewPage(); } runningtotals.Processed += 1; runningtotals.CurrSet = set; db.SubmitChanges(); } if (count == 0) { doc.NewPage(); doc.Add(new Paragraph("no data")); var a = new Anchor("see this help document docs.touchpointsoftware.com/Finance/ContributionStatements.html") { Reference = "http://docs.touchpointsoftware.com/Finance/ContributionStatements.html#troubleshooting" }; doc.Add(a); } doc.Close(); if (set == LastSet()) { runningtotals.Completed = DateTime.Now; } db.SubmitChanges(); }
public void DoWork(ContributionStatements.StatementSpecification cs) { Db = DbUtil.Create(Host); DbUtil.Db.CommandTimeout = 1200; var noaddressok = !DbUtil.Db.Setting("RequireAddressOnStatement", true); showCheckNo = DbUtil.Db.Setting("RequireCheckNoOnStatement"); showNotes = DbUtil.Db.Setting("RequireNotesOnStatement"); const bool UseMinAmt = true; var qc = APIContribution.Contributors(DbUtil.Db, fd, td, 0, 0, 0, cs.Funds, noaddressok, UseMinAmt, StartsWith, Sort, tagid: TagId, excludeelectronic: ExcludeElectronic); var runningtotals = DbUtil.Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.Count = qc.Count(); DbUtil.Db.SubmitChanges(); if (showCheckNo || showNotes) { var c = new ContributionStatementsExtra { FromDate = fd, ToDate = td, typ = 3, ShowCheckNo = showCheckNo, ShowNotes = showNotes }; using (var stream = new FileStream(OutputFile, FileMode.Create)) { c.Run(stream, Db, qc, cs); } LastSet = c.LastSet(); var sets = c.Sets(); foreach (var set in sets) { using (var stream = new FileStream(Output(OutputFile, set), FileMode.Create)) { c.Run(stream, Db, qc, cs, set); } } runningtotals = DbUtil.Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.LastSet = LastSet; runningtotals.Sets = string.Join(",", sets); runningtotals.Completed = DateTime.Now; DbUtil.Db.SubmitChanges(); } else { var c = new ContributionStatements { FromDate = fd, ToDate = td, typ = 3 }; using (var stream = new FileStream(OutputFile, FileMode.Create)) { c.Run(stream, Db, qc, cs); } LastSet = c.LastSet(); var sets = c.Sets(); foreach (var set in sets) { using (var stream = new FileStream(Output(OutputFile, set), FileMode.Create)) { c.Run(stream, Db, qc, cs, set); } } runningtotals = DbUtil.Db.ContributionsRuns.OrderByDescending(mm => mm.Id).First(); runningtotals.LastSet = LastSet; runningtotals.Sets = string.Join(",", sets); runningtotals.Completed = DateTime.Now; DbUtil.Db.SubmitChanges(); } }
public ActionResult ContributionStatements(DateTime?fromDate, DateTime?endDate, string startswith, string sort, int?tagid, bool excludeelectronic, string customstatement = null, bool exportcontributors = false) { if (!fromDate.HasValue || !endDate.HasValue) { return(Content("<h3>Must have a Startdate and Enddate</h3>")); } if (fromDate.Value > endDate.Value) { return(Content("<h3>The Startdate must be earlier than the Enddate</h3>")); } var spec = ContributionStatementsExtract.GetStatementSpecification(CurrentDatabase, customstatement); if (!startswith.HasValue()) { startswith = null; } var noaddressok = !CurrentDatabase.Setting("RequireAddressOnStatement", true); const bool useMinAmt = true; if (tagid == 0) { tagid = null; } var qc = APIContribution.Contributors(CurrentDatabase, fromDate.Value, endDate.Value, 0, 0, 0, spec.Funds, noaddressok, useMinAmt, startswith, sort, tagid: tagid, excludeelectronic: excludeelectronic); var contributors = qc.ToList(); if (exportcontributors) { return(ExcelExportModel.ToDataTable(contributors).ToExcel("Contributors.xlsx")); } var statementsRun = new ContributionsRun { Started = DateTime.Now, Count = contributors.Count, Processed = 0, UUId = Guid.NewGuid(), UserId = CurrentDatabase.UserId, }; CurrentDatabase.ContributionsRuns.InsertOnSubmit(statementsRun); CurrentDatabase.SubmitChanges(); var cul = CurrentDatabase.Setting("Culture", "en-US"); var host = CurrentDatabase.Host; var id = $"{statementsRun.UUId:n}"; var output = Output(host, id); if (tagid == 0) { tagid = null; } var showCheckNo = CurrentDatabase.Setting("RequireCheckNoOnStatement"); var showNotes = CurrentDatabase.Setting("RequireNotesOnStatement"); var statements = new ContributionStatements { UUId = Guid.Parse(id), FromDate = fromDate.Value, ToDate = endDate.Value, typ = 3, //TODO: once we switch to entirely html-based statement templates we won't need to check for these options NumberOfColumns = showCheckNo || showNotes ? 1 : 2, ShowCheckNo = showCheckNo, ShowNotes = showNotes, }; if (CurrentDatabase.Setting("UseNewStatementsFormat")) { // Must do this before entering the background worker because it relies on the Application context statements.GetConverter(); } var elmah = Elmah.ErrorLog.GetDefault(System.Web.HttpContext.Current); HostingEnvironment.QueueBackgroundWorkItem(ct => { Thread.CurrentThread.CurrentUICulture = new CultureInfo(cul); Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cul); try { var m = new ContributionStatementsExtract(host, fromDate.Value, endDate.Value, output, startswith, sort, tagid, excludeelectronic) { id = id }; m.DoWork(statements, spec, contributors); } catch (Exception e) { elmah.Log(new Elmah.Error(e)); var db = CMSDataContext.Create(host); var run = db.ContributionsRuns.Single(c => c.UUId == Guid.Parse(id)); run.Error = e.Message; run.Completed = DateTime.Now; db.SubmitChanges(); } }); return(Redirect($"/Statements/Progress/{id}")); }