using System; using System.Drawing.Printing; using System.Windows.Forms; using System.IO; using System.Web.UI; using System.Linq; using Pechkin; using AdvertisingProfitControlData; namespace AdvertsingProfitControl { internal class FrontPageGenerator { /// /// Generates the front page of the report, Advertising Profit Control, as a single PDF file. /// /// public void GenerateFrontPage(DateTime date) { var stringWriter = new StringWriter(); var writer = new HtmlTextWriter(stringWriter); BuildReportFrontPage(date, ref writer); if (!Enum.TryParse(Properties.Settings.Default.ReportPaperKind, out PaperKind paperKind)) { //TODO: Report this error to the user. paperKind = PaperKind.A4; } var frontPage = new SimplePechkin(new GlobalConfig().SetPaperOrientation(true).SetPaperSize(paperKind)).Convert(stringWriter.ToString()); // using (var fs = new FileStream(GlobalClasses.LogFilePath + "Front.pdf", FileMode.Create, FileAccess.Write)) { fs.Write(frontPage, 0, frontPage.Length); } } /// /// Generates the HTML code for the front page, Advertising Profit Control. /// /// /// private void BuildReportFrontPage(DateTime date, ref HtmlTextWriter writer) { var db = new AdvertisingProfitControlDbContext(); var dateRecord = db.WeekEndingDates.SingleOrDefault(x => x.EndingDate == date); if (dateRecord == null) { MessageBox.Show("Failed"); return; } writer.Write("\n"); writer.RenderBeginTag(HtmlTextWriterTag.Html); writer.RenderBeginTag(HtmlTextWriterTag.Head); writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css"); //Set the global style for the data cells. writer.RenderBeginTag(HtmlTextWriterTag.Style); writer.Write("td{margins:0; padding:2px; border:1px solid black; font-size:" + Properties.Settings.Default.ApcFontSize + "; text-align:center; vertical-align:bottom}"); writer.RenderEndTag();// end style writer.RenderEndTag(); // end Head //writer.AddAttribute(HtmlTextWriterAttribute.Style, "width:11in; height:8in"); writer.RenderBeginTag(HtmlTextWriterTag.Body); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none; border-collapse: collapse; margin-top:1in; " + Properties.Settings.Default.ApcReportWidth + "; " + Properties.Settings.Default.ApcReportHeight); //style for the table writer.RenderBeginTag(HtmlTextWriterTag.Table); //Begin rendering the top rows, the form name, store, department and date fields. writer.RenderBeginTag(HtmlTextWriterTag.Tr);//begin first row writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none; font-size:30px"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "20"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Advertising Profit Control v" + Application.ProductVersion + ""); writer.RenderEndTag();//end product cell. writer.RenderEndTag(); //End of first row writer.RenderBeginTag(HtmlTextWriterTag.Tr); //begin second row writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:left; border:none"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "9"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin store name cell writer.Write("Store Name: Allen's of Hastings"); writer.RenderEndTag();//end store name cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:right; border:none"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "11"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //begin date and department cell writer.Write("Week Ending: " + date.ToString("d") + "
Department: Produce"); writer.RenderEndTag();//End date and department cell writer.RenderEndTag();// second row writer.RenderBeginTag(HtmlTextWriterTag.Tr);//begin label row writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.RenderEndTag(); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "6"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//projections label cell writer.Write("Projection"); writer.RenderEndTag();//end projections label cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "10"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//actual label cell writer.Write("Actual"); writer.RenderEndTag();//end actual label cell writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "3"); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border:none"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//cost analysis label cell writer.Write("Cost Analysis"); writer.RenderEndTag();//end cost analysis label cell writer.RenderEndTag();//end label row (third row) writer.RenderBeginTag(HtmlTextWriterTag.Tr); //Begin building the header row. writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-left:none; border-right:double"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Ad Items"); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Sold"); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Sale
Price"); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Total
Sales"); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Cost"); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("$
Prof.
Retn."); writer.RenderEndTag(); //th writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9; border-right:double"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Total
$
Prof.
Retn."); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Beg.
Inv."); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Rec'd"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Total"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("End.
Inv."); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Sold"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Sale
Price"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Total
Sales"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Cost"); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("$
Prof.
Retn."); writer.RenderEndTag(); //th writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Total
$
Prof.
Retn."); writer.RenderEndTag(); //th //Department Sales //Grab the department sales from the database var departmentRecord = db.WeeklySales.SingleOrDefault(x => x.FkDateId == dateRecord.Id); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:double; font-size:9px"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin number cell writer.Write("1"); writer.RenderEndTag();//end number cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:none"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin department sales cell writer.Write("Department
Sales"); writer.RenderEndTag();//end department sales cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:none"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//department sales total sales column writer.AddAttribute(HtmlTextWriterAttribute.Style, "margin:0px; border-left:1px solid black; border-top:1px dashed black; text-align:right"); writer.RenderBeginTag(HtmlTextWriterTag.P);//begin department sales paragraph tag; used because the borders of the element are flush with that of the cell's. writer.Write(departmentRecord == null ? "$0.00" : $"{departmentRecord.TotalSales:C}"); writer.RenderEndTag();//end department sales paragraph tag writer.RenderEndTag();//department sales total sales column writer.RenderEndTag();//End of header row code. //Profit Analysis values. var projections = db.Projections.Where(x => x.FkDateId == dateRecord.Id).OrderBy(x => x.RowPosition).ToList(); var inventory = db.Inventories.Where(x => x.FkDateId == dateRecord.Id).OrderBy(x => x.RowPosition).ToList(); var actualSales = db.ActualSales.Where(x => x.FkDateId == dateRecord.Id).OrderBy(x => x.RowPosition).ToList(); var comments = db.Notes.SingleOrDefault(x => x.FkDateId == dateRecord.Id); var projectionA = projections.Sum(x => x.TotalSales); var projectionB = projections.Sum(x => x.TotalProfitReturn); var actualA = actualSales.Sum(x => x.TotalSales); var actualB = actualSales.Sum(x => x.TotalProfitReturn); var adSpecialIndex = -1; for (var i = 0; i < 25; i++) { if (i < projections.Count) { if (projections[i].FkAdSpecialId != null) { if (adSpecialIndex == -1) { writer.RenderBeginTag(HtmlTextWriterTag.Tr); //ad special table row writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-left:none; border-right:double"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "17"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write(projections[i].AdSpecial.Name); writer.RenderEndTag(); //ad special cell SelectCostAnalysisCell(i, ref writer, actualA, actualB, departmentRecord, comments); writer.RenderEndTag(); //end ad special row } adSpecialIndex = i; } writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-left:none; border-right:double; text-align:left"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //ad item cell writer.Write(projections[i].AdItem.Name); writer.RenderEndTag(); //end ad item cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection sold writer.Write(projections[i].Sold); writer.RenderEndTag(); //end projection sold writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection sale price writer.Write(projections[i].SalePrice); writer.RenderEndTag(); //end projection sale price writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection total sales writer.Write($"{projections[i].TotalSales:N2}"); writer.RenderEndTag(); //end projection total sales writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection cost writer.Write($"{projections[i].Cost:N2}"); writer.RenderEndTag(); //end projection cost writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection profit return writer.Write($"{projections[i].ProfitReturn:N2}"); writer.RenderEndTag(); //end projection profit return writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9; border-right:double"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //projection total profit return writer.Write($"{projections[i].TotalProfitReturn:N2}"); writer.RenderEndTag(); //end projection total profit return writer.RenderBeginTag(HtmlTextWriterTag.Td); //inventory beginning writer.Write(inventory[i].BeginningInventory); writer.RenderEndTag(); //end inventory beginning writer.RenderBeginTag(HtmlTextWriterTag.Td); //inventory received writer.Write(inventory[i].Recieved); writer.RenderEndTag(); //end inventory received writer.RenderBeginTag(HtmlTextWriterTag.Td); //inventory total writer.Write(inventory[i].TotalInventory); writer.RenderEndTag(); //end inventory total writer.RenderBeginTag(HtmlTextWriterTag.Td); //inventory ending writer.Write(inventory[i].EndingInventory); writer.RenderEndTag(); //end inventory ending writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales sold writer.Write(actualSales[i].Sold); writer.RenderEndTag(); //end actual sales sold writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales sale price writer.Write(actualSales[i].SalePrice); writer.RenderEndTag(); //end actual sales sale price writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales total sales writer.Write($"{actualSales[i].TotalSales:N2}"); writer.RenderEndTag(); //end actual sales total sales writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales cost writer.Write($"{actualSales[i].Cost:N2}"); writer.RenderEndTag(); //end actual sales cost writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales profit return writer.Write($"{actualSales[i].ProfitReturn:N2}"); writer.RenderEndTag(); //end actual sales profit return writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:double"); writer.RenderBeginTag(HtmlTextWriterTag.Td); //actual sales total profit return writer.Write($"{actualSales[i].TotalProfitReturn:N2}"); writer.RenderEndTag(); //end actual sales total profit return } else { //Pad AppendPaddingRow(ref writer); } SelectCostAnalysisCell(adSpecialIndex != -1 ? i + 1 : i, ref writer, actualA, actualB, departmentRecord, comments); writer.RenderEndTag();//tr } //Create the totals row writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-left:none; border-right:double"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//empty cell writer.RenderEndTag();//end padding writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:right"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//projections total label cell writer.Write("TOTAL"); writer.RenderEndTag();//end projections total label cell writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//projections A (total sales) writer.Write("(A) " + $"{projectionA:N2}"); writer.RenderEndTag();//end projections A (total sales) writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:double"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//projections B (total profit return) writer.Write("(B) " + $"{projectionB:N2}"); writer.RenderEndTag();//end projections B (total profit return) writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "5"); writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:right"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//actual sales total label cell writer.Write("TOTAL"); writer.RenderEndTag();//end actual sales total label cell writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//actual sales A (total sales) writer.Write("(A) " + $"{actualA:N2}"); writer.RenderEndTag();//end actual sales A (total sales) writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin empty cell writer.RenderEndTag();//end empty cell writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:double"); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//actual sales B (total profit return) writer.Write("(B) " + $"{actualB:N2}"); writer.RenderEndTag();//end actual sales A (total profit return) writer.RenderEndTag();//end totals row //end totals row writer.RenderEndTag();//table writer.RenderEndTag();//body writer.RenderEndTag();//html } private void RenderCostsAnalysisCell(CostAnalysisCells cell, ref HtmlTextWriter writer, decimal? value, string rowSpan) { var number = string.Empty; var labelText = string.Empty; switch (cell) { case CostAnalysisCells.DepartmentSales: number = "1"; labelText = "Department
Sales"; break; case CostAnalysisCells.SalesProduced: number = "2"; labelText = "Sales Produced
by
Ad Items (A)"; break; case CostAnalysisCells.RemainingSales: number = "3"; labelText = "Remaining
Sales
(Line 1 minus
Line 2)"; break; case CostAnalysisCells.ProfitReturnFromAdItems: number = "4"; labelText = "Total $ Profit
Return From Ad
Items (B)"; break; case CostAnalysisCells.ProfitReturnFromRemainingSales: number = "5"; labelText = "Total $ Profit Return
From Remaining Sales"; break; case CostAnalysisCells.TotalProfitReturn: number = "6"; labelText = "Total $ Profit
Return
Line 4 Plus Line 5"; break; case CostAnalysisCells.CrossProfitInfoCell: break; case CostAnalysisCells.Comments: break; default: throw new ArgumentOutOfRangeException(nameof(cell), cell, null); } writer.AddAttribute(HtmlTextWriterAttribute.Rowspan, rowSpan); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:double; font-size:14px; width:25px"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin number cell writer.Write(number); writer.RenderEndTag();//end number cell writer.AddAttribute(HtmlTextWriterAttribute.Rowspan, rowSpan); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:none; width:200px"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//begin department sales cell writer.Write(labelText); writer.RenderEndTag();//end department sales cell writer.AddAttribute(HtmlTextWriterAttribute.Rowspan, rowSpan); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; border-left:none; width:75px"); writer.RenderBeginTag(HtmlTextWriterTag.Td);//department sales total sales column writer.AddAttribute(HtmlTextWriterAttribute.Style, "margin:0px; border-left:1px solid black; border-top:1px dashed black; text-align:right"); writer.RenderBeginTag(HtmlTextWriterTag.P);//begin department sales paragraph tag; used because the borders of the element are flush with that of the cell's. writer.Write($"{value:C}"); writer.RenderEndTag();//end department sales paragraph tag writer.RenderEndTag();//department sales total sales column } private void RenderCostsAnalysisCell(CostAnalysisCells cell, ref HtmlTextWriter writer, string value = "") { writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "3"); switch (cell) { case CostAnalysisCells.CrossProfitInfoCell: writer.AddAttribute(HtmlTextWriterAttribute.Rowspan, "3"); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; text-align:left"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("To Find Gross Profit % Divide
Total Profit Return By Dept.
Weekly Retail Sales"); break; case CostAnalysisCells.Comments: writer.AddAttribute(HtmlTextWriterAttribute.Rowspan, "5"); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:none; text-align:left; vertical-align:top"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("Comments: " + value); break; } writer.RenderEndTag(); } private void SelectCostAnalysisCell(int rowIndex, ref HtmlTextWriter writer, decimal? actualA, decimal? actualB, WeeklySale departmentRecord, Note comments) { if (actualA == null) { actualA = 0; } if (actualB == null) { actualB = 0; } if (comments == null) { comments = new Note { Remark = string.Empty }; } if (departmentRecord == null) { departmentRecord = new WeeklySale {TotalSales = 0}; } switch (rowIndex) { case 0: RenderCostsAnalysisCell(CostAnalysisCells.SalesProduced, ref writer, actualA, "3"); break; case 3: RenderCostsAnalysisCell(CostAnalysisCells.RemainingSales, ref writer, departmentRecord.TotalSales - actualA, "4"); break; case 7: RenderCostsAnalysisCell(CostAnalysisCells.ProfitReturnFromAdItems, ref writer, actualB, "3"); break; case 10: //get cross profit return var s = (decimal) 0.3; //0.3 is the shrink TODO:Change the shrink into a variable. RenderCostsAnalysisCell(CostAnalysisCells.ProfitReturnFromRemainingSales, ref writer, s * (departmentRecord.TotalSales - actualA), "5"); break; case 15: var x = (decimal) 0.3 * (departmentRecord.TotalSales - actualA); //0.3 is the shrink RenderCostsAnalysisCell(CostAnalysisCells.TotalProfitReturn, ref writer, x + actualB, "4"); break; case 19: RenderCostsAnalysisCell(CostAnalysisCells.CrossProfitInfoCell, ref writer); break; case 22: RenderCostsAnalysisCell(CostAnalysisCells.Comments, ref writer, comments.Remark); break; } } private void AppendPaddingRow(ref HtmlTextWriter writer) { var cellCount = 0; writer.RenderBeginTag(HtmlTextWriterTag.Tr); while (cellCount < 17) { switch (cellCount) { case 0: writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-left:none; border-right:double"); break; case 6: writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:double; background-color:#e9e9e9"); break; case 16: writer.AddAttribute(HtmlTextWriterAttribute.Style, "border-right:double"); break; } if (cellCount > 0 && cellCount < 6) { writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#e9e9e9"); } writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write("
"); writer.RenderEndTag(); cellCount++; } } private enum CostAnalysisCells { DepartmentSales = 0, SalesProduced = 1, RemainingSales = 2, ProfitReturnFromAdItems = 3, ProfitReturnFromRemainingSales = 4, TotalProfitReturn = 5, CrossProfitInfoCell = 6, Comments = 7 } } }