#define PROD_ /* * Created by D Macintosh * Date: 11/14/2025 * Time: 9:32 PM * */ using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Reflection; using System.Net; using System.Text.RegularExpressions; using ClosedXML.Excel; using System.Data; using System.Security.Principal; //using DocumentFormat.OpenXml; using System.Linq; using bdf; using DocumentFormat.OpenXml.Wordprocessing; //using DocumentFormat.OpenXml.Drawing.Charts; //using DocumentFormat.OpenXml.Xml; namespace bdf { class bdf { public static string product = "BDF"; public static string version = "2.0.1"; public static string fullUser = WindowsIdentity.GetCurrent().Name; // \\DOMAIN\User.Id for NTLM auth for Megatool public static int debug = 0; public static int mode = 1; public static int major_errs = 0; public static int MAX_RETRY = 3; public static int month_offset = 1; // by default prep the bill for the upcoming bill cycle, ie end of current month is invoice date public static int webMaxWait = 1; //max wait time in minutes for webaccess public static bool logappend = true; public static string logname = "logfile.txt"; public static StreamWriter outfile; public static string domain = "RCI"; public static string username = ""; public static string password = ""; public static string dirpath = "." + Path.DirectorySeparatorChar; public static string base_path = "." + Path.DirectorySeparatorChar; public static Dictionary ToDo = new Dictionary { }; public static string token = ""; public static string filename = "output.xlsx"; //we'll change this later to be month specific public static string InsisSuffix = "_Megatool.xlsx"; public static string overrideSuffix = "_override.txt"; public static bool reuse = false; public static List todo = new List { }; public static StringBuilder adminLog = new StringBuilder(); public static StringBuilder auditLog = new StringBuilder(); public static int adlvl = 2; /* see https://denhamcoder.net/2018/08/25/embedding-net-assemblies-inside-net-assemblies/ */ // still needs external copy during compilation! // Loads NewtonsoftJson lib into memory as .dll public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string name = new AssemblyName(args.Name).Name; string embname = "other"; if (name == "ClosedXML") { embname = "BDF.Embedded.ClosedXML.dll"; } else if (name == "ClosedXML.Parser") { embname = "BDF.Embedded.ClosedXML.Parser.dll"; } else if (name == "DocumentFormat.OpenXml") { embname = "BDF.Embedded.DocumentFormat.OpenXml.dll"; } else if (name == "DocumentFormat.OpenXml.Framework") { embname = "BDF.Embedded.DocumentFormat.OpenXml.Framework.dll"; } else if (name == "ExcelDataReader.DataSet") { embname = "BDF.Embedded.ExcelDataReader.DataSet.dll"; } else if (name == "ExcelDataReader") { embname = "BDF.Embedded.ExcelDataReader.dll"; } else if (name == "ExcelNumberFormat") { embname = "BDF.Embedded.ExcelNumberFormat.dll"; } else if (name == "Microsoft.Bcl.HashCode") { embname = "BDF.Embedded.Microsoft.Bcl.HashCode.dll"; } else if (name == "RBush") { embname = "BDF.Embedded.RBush.dll"; } else if (name == "SixLabors.Fonts") { embname = "BDF.Embedded.SixLabors.Fonts.dll"; } else if (name == "System.Buffers") { embname = "BDF.Embedded.System.Buffers.dll"; } else if (name == "System.IO") { embname = "BDF.Embedded.System.IO.dll"; } else if (name == "System.Memory") { embname = "BDF.Embedded.System.Memory.dll"; } else if (name == "System.Numerics.Vectors") { embname = "BDF.Embedded.System.Numerics.Vectors.dll"; } else if (name == "System.Formats.Asn1") { embname = "BDF.Embedded.System.Formats.Asn1.dll"; } else if (name == "System.Memory") { embname = "BDF.Embedded.System.Memory.dll"; } else if (name == "System.Numerics.Vectors") { embname = "BDF.Embedded.System.Numerics.Vectors.dll"; } else if (name == "System.Runtime.CompilerServices.Unsafe") { embname = "BDF.Embedded.System.Runtime.CompilerServices.Unsafe.dll"; } else if (name == "System.Runtime") { embname = "BDF.Embedded.System.Runtime.dll"; } else if (name == "System.Security.Cryptography.Algorithms") { embname = "BDF.Embedded.System.Security.Cryptography.Algorithms.dll"; } else if (name == "System.Security.Cryptography.Encoding") { embname = "BDF.Embedded.System.Security.Cryptography.Encoding.dll"; } else if (name == "System.Security.Cryptography.Primitives") { embname = "BDF.Embedded.System.Security.Cryptography.Primitives.dll"; } else if (name == "System.Security.Cryptography.X509Certificates") { embname = "BDF.Embedded.System.Security.Cryptography.X509Certificates.dll"; } else if (name == "System.Text.Encoding.CodePages") { embname = "BDF.Embedded.System.Text.Encoding.CodePages.dll"; } else if (name == "System.Text.RegularExpressions") { embname = "BDF.Embedded.System.Text.RegularExpressions.dll"; } else { embname = "something_bad"; } Logger.Log(5, "returning assy: {0}", name); try { using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embname)) { var assemblyData = new Byte[stream.Length]; stream.Read(assemblyData, 0, assemblyData.Length); return Assembly.Load(assemblyData); } } catch (Exception e) { Console.WriteLine("EXCemb: {0}:{1}.", e.Message, e.InnerException.Message); return null; } } public static void Main(string[] args) { // Load Embedded Resources try { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; } catch (Exception e) { Console.WriteLine("DLL: {0}:{1}.", e.Message, e.InnerException.Message); } //foreach (var resource in Assembly.GetExecutingAssembly().GetManifestResourceNames()) Console.WriteLine("Resource: " + resource); Main2(args); } public static async void Main2(string[] args) { // Enforce TLS1.2 Sep2017 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768 | (SecurityProtocolType)192; // Logging file outfile = new StreamWriter(@"" + logname, logappend); outfile.AutoFlush = true; string ban2 = product + " v" + version + " (c) 2025 Doug Macintosh"; ban2 = "\u2551 " + ban2 + " \u2551"; string ban1 = "\u2554"; for (int i = 2; i < ban2.Length; i++) { ban1 += "\u2550"; } ban1 += "\u2557"; string ban3 = "\u255a"; for (int i = 2; i < ban2.Length; i++) { ban3 += "\u2550"; } ban3 += "\u255d"; Logger.Log(ban1); Logger.Log(ban2); Logger.Log(ban3); Logger.Log("--- call (613)697-9178 for support ---"); Arguments myargs = new Arguments(args); CookieContainer cookiejar = new CookieContainer(); if (myargs.Exists("help") || myargs.Exists("h")) { // Environment.GetCommandLineArgs() or Environment.ProcessPath. You can then use System.IO.Path.GetFileName(Environment.GetCommandLineArgs()); Logger.Log(" usage: " + System.IO.Path.GetFileName(Environment.GetCommandLineArgs()[0]) + " [-options]"); //Console.WriteLine("retry: -retries n"); //Logger.Log("--- UNLICENSED, FOR EVALUATION USE ONLY ---"); Logger.Log(" login: -u user -p passwd"); Logger.Log(" detail files: -all OR any combo of -ldf -wav -sip"); Logger.Log(" output path: -path " + (Path.DirectorySeparatorChar.ToString() == "\\" ? "C:" : "") + "/directory/subdir"); Logger.Log(" SO basepath: -so C:\\Users\\us.er\\OneDrive\\path\\"); Logger.Log(" subdirs: -ldfdir .\\LDF\\ | -wavdir .\\WAV\\ | -sipdir .\\SIP\\"); Logger.Log(" inv offset: -month=x [x = +/- 6, default is coming bill cycle, ie '1']"); Logger.Log(" reuse: -reuse"); Logger.Log(" redo: -redo"); Logger.Log(" verbose: -v"); //Logger.Log(" debug: -debug n"); return; } //WebProxy proxyObject = null; if (myargs.Exists("debug")) { debug = int.Parse(myargs.Single("debug")); Logger.Log(5, "Setting debug level to {0}", debug); } if (myargs.Exists("v")) { debug += 1; Logger.Log(0, "Logging verbosity increased."); } // Start User cred { if (!fullUser.StartsWith("RCI")) { Logger.Log(0, "Your current userid ({0}) must be a member of RCI to proceed.", fullUser); if ( (debug < 2) && !(fullUser == "doug")) { return; } else username = fullUser; } else { domain = fullUser.Split('\\')[0]; username = fullUser.Split('\\')[1]; Logger.Log(4, "Using credentials for ({0})", username); } if ((myargs.Exists("u")) && (myargs.Exists("p"))) { username = myargs.Single("u"); password = myargs.Single("p"); Logger.Log(5, "Setting authorized account to: {0}", username); } else if (myargs.Exists("p")) { password = myargs.Single("p"); Logger.Log(5, "Setting password for {0}", username); } } // end User cred // SO Type defs below { if (myargs.Exists("all")) { todo.Add("LDF"); todo.Add("WAV"); todo.Add("SIP"); } if (myargs.Exists("ldf")) { todo.Add("LDF"); } if (myargs.Exists("wav")) { todo.Add("WAV"); } if (myargs.Exists("sip")) { todo.Add("SIP"); } if (todo.Count == 0) { todo.Add("LDF"); // default } string todos = ""; foreach (string t in todo) { todos += t + " "; } Logger.Log(0, "Generating Bill Detail files for: {0}", todos); if (myargs.Exists("so")) { if (myargs.Single("so") != "") base_path = myargs.Single("so"); if (!base_path.EndsWith(Path.DirectorySeparatorChar.ToString())) { base_path += Path.DirectorySeparatorChar.ToString(); } } else { base_path = "C:\\Users\\" + username + "\\OneDrive - Rogers Communications Inc\\Jeff Hawthorne's files - GCNS Stream 5 - Dark Fibre - Billing BDF Files\\"; } Logger.Log(0, "SO Base Path: {0}", base_path); } ToDo["LDFprefix"] = "GCNSLDF"; ToDo["WAVprefix"] = "GCNSWAV"; ToDo["SIPprefix"] = "SSCGPAS"; ToDo["LDFpath"] = "." + Path.DirectorySeparatorChar + "Dark Fibre Service Orders" + Path.DirectorySeparatorChar; ToDo["WAVpath"] = "." + Path.DirectorySeparatorChar + "Wavelength Service Orders" + Path.DirectorySeparatorChar; ToDo["SIPpath"] = "." + Path.DirectorySeparatorChar + "SIP Service Orders" + Path.DirectorySeparatorChar; { if (myargs.Exists("ldfdir")) { if (myargs.Single("ldfdir") != "") ToDo["LDFpath"] = myargs.Single("ldfdir"); ; if (!ToDo["LDFpath"].EndsWith(Path.DirectorySeparatorChar.ToString())) { ToDo["LDFpath"] += Path.DirectorySeparatorChar.ToString(); } } if (todo.Contains("LDF")) Logger.Log(0, " LDF SO files expected in sub-directory: {0}", ToDo["LDFpath"]); if (myargs.Exists("wavdir")) { if (myargs.Single("wavdir") != "") ToDo["WAVpath"] = myargs.Single("wavdir"); ; if (!ToDo["WAVpath"].EndsWith(Path.DirectorySeparatorChar.ToString())) { ToDo["WAVpath"] += Path.DirectorySeparatorChar.ToString(); } } if (todo.Contains("WAV")) Logger.Log(0, " WAV SO files expected in sub-directory: {0}", ToDo["WAVpath"]); if (myargs.Exists("sipdir")) { if (myargs.Single("sipdir") != "") ToDo["SIPpath"] = myargs.Single("sipdir"); ; if (!ToDo["SIPpath"].EndsWith(Path.DirectorySeparatorChar.ToString())) { ToDo["SIPpath"] += Path.DirectorySeparatorChar.ToString(); } } if (todo.Contains("SIP")) Logger.Log(0, " SIP SO files expected in sub-directory: {0}", ToDo["SIPpath"]); } //end SO Type defs if (myargs.Exists("path")) { dirpath = myargs.Single("path"); if (dirpath == "") dirpath = "."; if (!dirpath.EndsWith(Path.DirectorySeparatorChar.ToString())) { dirpath += Path.DirectorySeparatorChar.ToString(); } } else { dirpath = "." + Path.DirectorySeparatorChar.ToString(); } Logger.Log(5, "Setting filestore root path to {0}", dirpath); if ((username == "") && !reuse) { Logger.Log(0, "No valid login credentials found. Exiting."); return; } if (myargs.Exists("month")) { // if (myargs.Exists("1")) offset = -1; int offset = Int32.Parse(myargs.Single("month")); if ((offset >= -6) && (offset <= 12)) month_offset = offset; } // ***MAIN ------------------------------------------------------------------------------------------------------------------------------- var updates = new Dictionary { { "October", "November" } // change date /* { "31", "30" }, // change amount { "10312025", "11302025" } , // change invoice number { "$42,008.75", "$10,000.00" } // change amount */ }; PDF.doPDF2( "test.pdf", "updated.pdf", updates ); return; //-------- bool LoggedIn = false; // are we authenticated to Megatool? foreach (string task in todo) // tasks are some combination of LDF/WAV/SIP { Logger.Log(0, "Starting to process the {0} BDF...", task); if (myargs.Exists("redo")) { if (System.IO.File.Exists(dirpath + Path.DirectorySeparatorChar + task + InsisSuffix)) { if (!SafeDeleteFile(dirpath + Path.DirectorySeparatorChar + task + InsisSuffix)) { Logger.Log(0, "Unable to delete existing {0}, is it open in Excel?", task + InsisSuffix); reuse = false; } else { Logger.Log(1, " -deleted existing {0} intermediate file.", task + InsisSuffix); } } } if (myargs.Exists("reuse")) { if (!System.IO.File.Exists(dirpath + Path.DirectorySeparatorChar + task + InsisSuffix)) { Logger.Log(0, "Did not find an existing {0} Forcing rebuild...", task + InsisSuffix); reuse = false; } else { reuse = true; } } // Megatool subsection, gets mapping between SO's and SCHEDA's, create "(task)_Megatool.xlsx" var wbk = new XLWorkbook(); // Add a worksheet var insisMap = wbk.AddWorksheet(task+InsisSuffix.Split('.')[0]); // add empty worksheet 'InsisMap' string path = dirpath + task + InsisSuffix; //If less than 24h old, or -old switch used, use an existing map file if ((System.IO.File.Exists(path)) && (System.IO.File.GetLastWriteTime(path).DayOfYear == DateTime.Today.DayOfYear) || reuse) { try { Logger.Log(0, "Loading previous Megatool mapping file ({0})...", path); wbk = new XLWorkbook(path); } catch { Logger.Log(0, "Please verify you do not have ({0}) open in Excel and retry.", path); return; } } else { if (!LoggedIn) //authenticate to Megatool { int tries = 1; // Megatool login procedure do { Logger.Log(0, "Initiating connection..."); tries++; Logger.Log("** Password is required to access Megatool. You must be on the Corporate Lan/VPN.**"); while (password == "") { Logger.Log(0, "Please enter the password for ({0}) and hit Return.", fullUser); password = ReadPassword(); } try { LoggedIn = MegaT.Auth(username, password, ref cookiejar); if (!LoggedIn) { Logger.Log(1, " retrying {0}", tries); } } catch (Exception) { Logger.Log("Exception attempting to login to MegaTool"); if (!LoggedIn) { Logger.Log(1, " retrying {0}", tries); } } } while (!LoggedIn && (tries <= MAX_RETRY)); if (!LoggedIn) { Logger.Log("Exiting due to inability to login to MegaTool website"); return; } } // ***SO Files ------------------------------------------------------------------------------------------------------------------------------- List active = new List { }; Dictionary sch2mrr = new Dictionary { }; List scheds = new List { }; // GET ALL GCNSLDFXXX SCHEDS FROM INSIS MegaT.GetSchedAs( ToDo[(task+"prefix")], ref scheds, ref cookiejar); Logger.Log(1, "Found {0} candidate {1} SCHEDAs", scheds.Count, ToDo[(task + "prefix")] ); // FILTER OUT ALL XL/DISCONNECTED SCHEDS foreach (string sched in scheds) { bool inactive = MegaT.SchedXL(sched, ref cookiejar); if (!inactive) { active.Add(sched); sch2mrr.Add(sched, MegaT.getMRR(sched, ref cookiejar)); // for each active SCH, get current MRR from main page } else { Logger.Log(5, " {0} ({1})", sched, inactive ? "inactive" : "active"); } } Logger.Log(0, "Found {0} active {1}xxx SCHEDAs", active.Count, ToDo[(task + "prefix")]); if (active.Count == 0) // no valid SCHEDs so we're done here! { Logger.Log(0, "ERROR: No active {0} SCHEDAs found. Exiting as no point proceding further.", task); return; } // OBTAIN DETAIL INFORMATION FOR ALL ACTIVE SCHEDS FROM 'SCHEDULE', SO MOST IMPORTANT, BUT GRAB CONTRACT, TA ETC AS NEEDED var dt = new DataTable(); // Create intermediate file columns based on dictionary keys coming from GetParms /* dt.Columns.Add("SO", typeof(String)); dt.Columns.Add("TA", typeof(String)); dt.Columns.Add("COP", typeof(String)); dt.Columns.Add("PRID", typeof(String)); dt.Columns.Add("CONTRACT", typeof(String)); dt.Columns.Add("SCHED", typeof(String)); // Cell(6) SCHED dt.Columns.Add("BSD", typeof(String)); // Cell(7) BSD dt.Columns.Add("MRR", typeof(String)); // Cell(8) MRR dt.Columns.Add("NRC", typeof(String)); // Cell(9) NRC */ // Build our dictionary with a dummy call for parms, this is extensible for coding, we can add/remove parms as needed foreach( var k in MegaT.GetParms("dummy", ref cookiejar)) { dt.Columns.Add( k.Key, typeof(String) ); // order of entry is important when referencing by row/cell //Console.WriteLine("Adding: " + k.Key); } // Look for override data in _override.txt Dictionary overrides = getOverrides(task); //todo should rework this to use SCHED as key, not SO foreach (string sched in active) { Dictionary parms = MegaT.GetParms(sched, ref cookiejar); // scrape megatool for current SCHEDA // Create a new row var row = dt.NewRow(); row["SCHED"] = sched; // Fill row with dictionary values foreach (var kvp in parms) { //Console.WriteLine(" * s={0} p={1} v={2}", sched, kvp.Key, kvp.Value); if (kvp.Value.Length >= 3) { if ((kvp.Value.Substring(0, 3)) == "R00") { row["TA"] = kvp.Value ?? ""; } else if ((kvp.Value.Substring(0, 3)) == "K00") { row["CONTRACT"] = kvp.Value ?? ""; } else { row[kvp.Key] = kvp.Value ?? ""; } } else { row[kvp.Key] = kvp.Value ?? ""; } } //Console.WriteLine("c r:{0} s:{1}+", row["MRR"], sched); if (sch2mrr[sched] != 0) { if ((row["MRR"].ToString() != "XXX") && (Double.Parse(row["MRR"].ToString()) != sch2mrr[sched])) { Logger.Log(0, " -MRR discrepancy for {2} between SchedA {0} and Schedule {1} MRRs", sch2mrr[sched], row["MRR"], sched); } row["MRR"] = sch2mrr[sched]; } foreach (var kvp in parms) { string ivalue = ""; if (overrides.ContainsKey(parms["SCHED"] + kvp.Key)) //if (overrides.TryGetValue(parms["SO"] + kvp.Key, out ivalue)) { } // key not found, move on { ivalue = overrides[(parms["SCHED"] + kvp.Key)]; Logger.Log(0, " >REPLACE {0}-{1} (was:{2} now:{3})", parms["SCHED"], kvp.Key, kvp.Value, ivalue); row[kvp.Key] = ivalue; } } dt.Rows.Add(row); } // end of foreach SCHED // Now dump out the INSIS data into the intermediate file //using (var wb = new XLWorkbook()) { // Insert the DataTable starting at cell A1 insisMap.Cell(1, 1).InsertTable(dt); insisMap.Columns().AdjustToContents(); //ws.RangeUsed().Sort("A"); var used = insisMap.RangeUsed(); // Define a range that excludes the header row (row 1) var dataRange = used.Range(2, 1, used.RowCount(), used.ColumnCount()); // Sort by column A inside that range (currently SO, thinking SCHED is a better idea) dataRange.Sort("A"); // Save to file (_Megatool mapping) try { wbk.SaveAs(path); } catch { Logger.Log(0, "Ensure you do not have ({0}) already open!", path); return; } } } // *** ------------------------------------------------------------------------------------------------------------------------------- //Date string 202511 DateTime d = DateTime.Now; //string CurrentYearMonth = d.ToString("yyyyMM"); int current = Int32.Parse(d.AddMonths(month_offset).ToString("yyyyMM")); // Go to the first day of this month, then subtract 1 day DateTime lastDayPrevMonth = new DateTime(d.Year, d.Month, 1).AddMonths(month_offset).AddDays(-1); // Format as yyyymmdd string invDate = lastDayPrevMonth.ToString("yyyyMMdd"); //string effDate = (new DateTime(d.Year, d.Month, 1)).ToString("yyyyMMdd"); Logger.Log(0, "Beginning actual BDF processing ({0})", current); bdf.filename = "BDF_" + task + "_" + current.ToString() + ".xlsx"; //Load and convert all XLS? files that start with 'ROGERS_(task)_SO*' in the (task) subdirectory File.getXLS(task, (base_path + ToDo[(task + "path")]) ); Logger.Log(0, "{0} Service Order Workbooks returned.", File.ServiceOrders.Count); // BDF Workbook - create the correct format based on task var workbook = BDF.CreateBDF(task); // bdf2 is link to 2nd Tab with the individual connection details, all sheets have Type 2 var bdf2 = workbook.Worksheet(2); //var bdf2 = workbook.Worksheet("BDF Type 2"); // make an empty list of type BDF.Rows to be added to BDF worksheet#2 at end // Type 2 is common across all 3 task types, but last row not used for SIP var rows = new List { }; // Type 2 try { //Process each line in each SO for unique SOs -- UPDATED TO ONLY DO 1 LINE PER SO FILE plus a BUILD line if present int k = 1; foreach (XLWorkbook wb in File.ServiceOrders) // List of XL workbooks passed from XLImport { // Two tabs, LDF specific details below // /1.LDFONS_Service_Order_V2 and // 2.LDFONS_SDP_data_V2 //IXLWorksheet ws1 = wb.Worksheet("LDFONS_Service_Order_V2"); IXLWorksheet ws1 = wb.Worksheet(1); //generic 1st worksheet //IXLWorksheet ws2 = wb.Worksheet("LDFONS_SDP_data_V2"); IXLWorksheet ws2 = wb.Worksheet(2); //generic 2nd worksheet string _so = ws2.Cell("A2").Value.ToString(); // This is our SO# Logger.Log(1, "Ingesting {0} ({1}/{2})...", _so, k++, File.ServiceOrders.Count); List sos = new List { }; //UPDATED USE 1 entry per SO found, expect 1 SO per file string C = ws1.Cell("A2").Value.ToString(); //ROGERS string CCI = (string)ws1.Cell("G2").Value.ToString(); // R000XXXXXX //Format CCI as R + 9 digits, left zero padded string _cci = CCI; _cci = ("000000000" + Int32.Parse(_cci.Substring(1))); CCI = "R" + _cci.Substring(_cci.Length - 9); // var _rows = wbk.Worksheet(task+InsisSuffix.Split('.')[0]).RangeUsed().RowsUsed(); // _Megatool intermediate sheet foreach (var row in ws2.RowsUsed()) // go through Tab#2 of SO { var r = new Row { Row_Number = (rows.Count + 1), Contractor = C, Canada_Contract_Identifier = CCI }; ////if ( task == "SIP") // var r_nrc = new Row { Row_Number = (rows.Count + 1), Contractor = C, Canada_Contract_Identifier = CCI }; // only used if NRC present var r_nrc = BDF.CopyRow(r); if (row.RowNumber() != 1) // skip column titles { //Process contents of a new row for the Type 2 tab if (!sos.Contains(_so)) //UPDATED TO ONLY ENTER 1 LINE PER SO { //tcids.Add(ws2.Cell("AF" + row.RowNumber()).Value.ToString()); sos.Add(_so); // UPDATED TO ADD THE SO# INSTEAD OF UNIQUE SERVICE r.Canada_Contract_Identifier = CCI; r.SSC_Order_Number = Int32.Parse(ws2.Cell("A" + row.RowNumber()).Value.ToString()); r.SSC_Version = (Int32)ws2.Cell("B" + row.RowNumber()).Value; r.SDPID = ws2.Cell("S" + row.RowNumber()).Value.ToString(); r.Department = ws2.Cell("F" + row.RowNumber()).Value.ToString(); r.Prov = ws2.Cell("AQ" + row.RowNumber()).Value.ToString(); r.Billing_End_Date = Int32.Parse(ws2.Cell("M" + row.RowNumber()).Value.ToString().Replace("/", "")); r.SCID = ws2.Cell("AB" + row.RowNumber()).Value.ToString(); r.TCID = ws2.Cell("AF" + row.RowNumber()).Value.ToString(); r.TA_Number = CCI; r.Invoice_Period = current; r.Period_of_Service = current; //Add in Megatool and maybe EWP? data like SCHEDA //Get matching InsisMap row# //int i = 0; int so_row = 0; int r0_row = 0; int max = wbk.Worksheet(task + InsisSuffix.Split('.')[0]).RowsUsed().Count(); IXLRangeRow _srow = null; IXLRangeRow _rrow = null; try { // Match by SO# (preferred) or TA/Contract# (backup) so we get the right SCHEDA for data foreach (var _row in _rows) { if ((string.Equals(_row.Cell(1).GetString(), r.SSC_Order_Number.ToString(), StringComparison.OrdinalIgnoreCase))) { so_row = _row.RowNumber(); _srow = _row; } else if (string.Equals(_row.Cell(2).GetString(), r.TA_Number.ToString(), StringComparison.OrdinalIgnoreCase)) { r0_row = _row.RowNumber(); _rrow = _row; } //Console.WriteLine("sr={0} rr={1} max={2} cur={3}",so_row, r0_row, max, _row.RowNumber()); if ((so_row != 0) || ((r0_row != 0) && (_row.RowNumber() == max))) // prefer SO match, take R000 otherwise { //_srow = _row; if (so_row == 0) // No SO match { //i = r0_row; _srow = _rrow; } //i= _row.RowNumber(); // Now add Megatool data if it exists, and we always have a SchedA! string schA = _srow.Cell(6).GetString(); r.CI_Name = schA; if (_srow.Cell(1).GetString() == "XXX") //SO not defined { Logger.Log(5, " {0}-SO not found in InsisMap! Linking SO ({1}) by TA/Contract", r.SSC_Order_Number, schA); } string mrc = _srow.Cell(8).GetString(); if (mrc != "XXX") { calcTaxes(mrc, "0", ref r); } else { Logger.Log(0, " {0}-MRR not found ({1}) ", r.SSC_Order_Number, schA); } //Fix up Billing Effective Date as there are some customs, return as INT23 string bef = _srow.Cell(7).GetString(); if (bef == "XXX") { Logger.Log(1, " -- Bill Start Date not found in INSIS for {0}, retrieving from exceptions.", r.CI_Name); r.Billing_Effective_Date = getBEF(r.CI_Name); } else { r.Billing_Effective_Date = Int32.Parse(bef); } // Logic to determine if we need to add an extra row for an NRC item string nrc = _srow.Cell(9).GetString(); if (nrc != "XXX") { double _nrc = Double.Parse(nrc + "0"); if (_nrc != 0) { string billMonth = r.Billing_Effective_Date.ToString(); billMonth = billMonth.Substring(0, (billMonth.Length - 2)); Logger.Log(2, "Billing for {0} and BEF is {1}", current, billMonth); if (current.ToString() == billMonth) { Logger.Log(0, " >SO{1} ADD NRC={0:0.00} charge to current BDF ({2})", _nrc, r.SSC_Order_Number, r.CI_Name); r_nrc = BDF.CopyRow(r); calcTaxes("0", nrc, ref r_nrc); int build_row = 0; foreach (var nrc_row in ws2.RowsUsed()) { try { if (ws2.Cell("AB" + nrc_row.RowNumber().ToString()).Value.ToString().ToUpper().Contains("BUILD")) { build_row = nrc_row.RowNumber(); r_nrc.SSC_Seq_No = Int32.Parse(ws2.Cell("U" + nrc_row.RowNumber().ToString()).Value.ToString()); r_nrc.SCID = ws2.Cell("AB" + nrc_row.RowNumber().ToString()).Value.ToString(); break; } } catch (Exception e) { Logger.Log(0, "nrc {0}:{1}", e.Message, e.InnerException.Message); } } if (build_row == 0) { Logger.Log(0, "WARNING - No 'Build' row in SO-{0} found for this charge, using '* MANUAL *' ({1})", r.SSC_Order_Number, r.CI_Name); r_nrc.SSC_Seq_No = 0; r_nrc.SCID = "* MANUAL *"; } } else if (current >= Int32.Parse(billMonth)) { Logger.Log(0, " >SO{1} SKIP NRC={0:0.00} as presumed already billed ({2})", _nrc, r.SSC_Order_Number, r.CI_Name); } else { Logger.Log(0, " >SO{1} SKIP NRC={0:0.00} as it is a future billing ({2})", _nrc, r.SSC_Order_Number, r.CI_Name); } } } break; } // end of if scheda match } // end of row interations in InsisMap } catch (Exception e) { Logger.Log(0, "InsisMap Exc: {0}:{1}", e.Message, e.InnerException.Message); } //Now add row(s) as needed try { if ((so_row + r0_row) == 0) { Logger.Log(0, "Megatool InsisMap : Row not found: {0}", r.SSC_Order_Number); } if (r.Billing_Effective_Date > (current * 100 + 1)) { Logger.Log(0, " >SO{0} SKIP as it doesn't start billing until {2} ({1})", r.SSC_Order_Number, r.CI_Name, r.Billing_Effective_Date); } else { rows.Add(r); if (r_nrc.Non_recurring_Charges_for_the_Month != 0) rows.Add(r_nrc); } } catch (Exception e) { Logger.Log(0, "Exc:add {0}:{1}", e.Message, e.InnerException.Message); } // End row adds } } // End of first row in SO (default for billing) } // End of SO rows processing } // End of current SO Workbook try { BDF.InsertData(bdf2, rows); bdf2.Range(2, 21, bdf2.LastRowUsed().RowNumber(), 31).Style.NumberFormat.Format = "#0.00"; } catch (Exception e) { Logger.Log(0, "Exc:add2 {0}:{1}", e.Message, e.InnerException.Message); } } catch (Exception e) { Logger.Log(0, "Exception Rows: {0}:{1} ", e.Message, e.InnerException); } //End of SO Workbooks Logger.Log("Finalizing..."); Dictionary Invoice = new Dictionary { }; InvoiceCell ic = new InvoiceCell { }; // finalize the totals on first sheet //var bdf1 = workbook.Worksheet("BDF Type 1"); var bdf1 = workbook.Worksheet(1); if (task != "SIP") { var row2s = new List { new Row2 { Invoice_Period = current, Invoice_Date = int.Parse(invDate), Contractor_Name = "ROGERS", Canada_Contract_Identifier = "K00019754" } }; try { // 1 Record Type | 2 Invoice Date | 3 Invoice Period | 4 CCI | 5 Contractor Name BDF.InsertData(bdf1, row2s); bdf1.Row(2).Cell(6).Value = sumCol(22, ref bdf2); //Tot Recur Chgs Month bdf1.Row(2).Cell(7).Value = sumCol(24, ref bdf2); //Tot Non-Recur Chgs Month bdf1.Row(2).Cell(8).Value = (double)bdf1.Row(2).Cell(6).Value + (double)bdf1.Row(2).Cell(7).Value; //Total Chgs Excl Tax bdf1.Row(2).Cell(9).Value = sumCol(26, ref bdf2); //Tot Other Charge/Cred bdf1.Row(2).Cell(10).Value = sumCol(25, ref bdf2); //tot Service Credits bdf1.Row(2).Cell(11).Value = 0; //Tot Late Pmt Amt bdf1.Row(2).Cell(12).Value = sumCol(27, ref bdf2); //tot GST bdf1.Row(2).Cell(13).Value = sumCol(28, ref bdf2); //tot HST bdf1.Row(2).Cell(14).Value = sumCol(29, ref bdf2); //tot QST bdf1.Row(2).Cell(15).Value = sumCol(30, ref bdf2); //tot taxes bdf1.Row(2).Cell(16).Value = sumCol(31, ref bdf2); //tot amt incl tax if (task != "SIP") { bdf1.LastColumnUsed().Delete(); // get rid of total usage summary col } } catch (Exception e) { Logger.Log(0, "Error creating totals for Tab 1", e.Message); } try // Create Custom Invoice from template { Invoice.Add( ic.Account , "Account PO2-" + "857412"); //bdf2 C2 Invoice.Add( ic.Date , dateFormal(row2s.Invoice_Date); Invoice.Add( ic.Invoice , "10312025" ); //mmddyyyy FIXME Invoice.Add( ic.Total_Charges , bdf1.Row(2).Cell(16).Value.ToString() ); Invoice.Add( ic.Account2 , Invoice[ic.Account]); Invoice.Add( ic.Date2 , Invoice[ic.Date]); Invoice.Add( ic.Invoice2 , Invoice[ic.Invoice]); Invoice.Add( ic.Total_Charges2 , Invoice[ic.Total_Charges]); Invoice.Add( ic.CCI , row2s.Canada_Contract_Identifier ); Invoice.Add( ic.PaperFee , "0" ); Invoice.Add( ic.LateCharge , "0" ); Invoice.Add( ic.Service_Charges , String.Format("{0}", int.Parse(Invoice[ic.PaperFee]) + int.Parse(Invoice[ic.LateCharge]) ); Invoice.Add( ic.UsageCharges , "0"); Invoice.Add( ic.TotalUsageCharges , "0"); Invoice.Add( ic.DataMonthlyCharges , bdf1.Row(2).Cell(6).Value.ToString() ); Invoice.Add( ic.DataNon_RecurringCharges , bdf1.Row(2).Cell(7).Value.ToString() ); Invoice.Add( ic.DataTotalOtherCharges , bdf1.Row(2).Cell(9).Value.ToString() ); Invoice.Add( ic.Data_Services , ( bdf1.Row(2).Cell(8).Value + bdf1.Row(2).Cell(9).Value - bdf1.Row(2).Cell(10).Value).ToString() ); //Invoice.Add( ic.TaxON_PST , bdf1.Row(2).Cell(9).Value Invoice.Add( ic.TaxON_GST , bdf1.Row(2).Cell(12).Value.ToString()); Invoice.Add( ic.TaxON_HST , bdf1.Row(2).Cell(13).Value.ToString()); Invoice.Add( ic.TaxPQ_PST , bdf1.Row(2).Cell(14).Value.ToString()); Invoice.Add( ic.TaxPQ_GST , "0"); FIXME Invoice.Add( ic.TaxPQ_HST , "0"); Invoice.Add( ic.Taxes , bdf1.Row(2).Cell(15).Value.ToString()); Excel2PDF.Program.customInvoie(task, ref Invoice); } catch (Exception e) { Logger.Log(0, "Error Invoice Cells for Tab 1", e.Message); } } else // SIP BDF { var row2s = new List { new Row2 { Invoice_Period = current, Invoice_Date = int.Parse(invDate), Contractor_Name = "ROGERS", Canada_Contract_Identifier = "K00019754" } }; try { BDF.InsertData(bdf1, row2s); bdf1.Row(2).Cell(6).Value = sumCol(22, ref bdf2); bdf1.Row(2).Cell(7).Value = sumCol(24, ref bdf2); bdf1.Row(2).Cell(8).Value = (double)bdf1.Row(2).Cell(6).Value + (double)bdf1.Row(2).Cell(7).Value; bdf1.Row(2).Cell(9).Value = sumCol(26, ref bdf2); bdf1.Row(2).Cell(10).Value = sumCol(25, ref bdf2); bdf1.Row(2).Cell(11).Value = 0; bdf1.Row(2).Cell(12).Value = sumCol(27, ref bdf2); bdf1.Row(2).Cell(13).Value = sumCol(28, ref bdf2); bdf1.Row(2).Cell(14).Value = sumCol(29, ref bdf2); bdf1.Row(2).Cell(15).Value = sumCol(30, ref bdf2); bdf1.Row(2).Cell(16).Value = sumCol(31, ref bdf2); bdf1.Row(2).Cell(17).Value = 0; //sumCol(32, ref bdf2); //Total Usage Charges (SIP only) } catch (Exception e) { Logger.Log(0, "Error creating totals for SIP Tab 1", e.Message); } // Create the header-only TAB3 for SIP var bdf3 = workbook.Worksheet(3); var row3 = new List { new Row3 { } }; try { BDF.InsertData(bdf3, row3); } catch (Exception e) { Logger.Log(0, "Error creating totals for SIP Tab 3", e.Message); } } //DateTime dd = DateTime.Now; string traceable = ""; try { if ( username.Contains(".")) { traceable = bdf.filename.Split('.')[0] + "_" + username.Split('.')[0].Substring(0, 1) + username.Split('.')[1].Substring(0, 1) + "_" + d.ToString("yyyyMMdd") + ".xlsx"; } else { traceable = bdf.filename.Split('.')[0] + "_" + username + "_" + d.ToString("yyyyMMdd") + ".xlsx"; } } catch (Exception e) { Logger.Log(0, "traceable: ", e.Message); } try { bdf1.Range(2, 6, bdf1.LastRowUsed().RowNumber(), 17).Style.NumberFormat.Format = "#0.00"; workbook.SaveAs(traceable); Logger.Log(0, "Excel file populated! ({0})", traceable); } catch (Exception e) { Logger.Log(0, "Error formatting and saving Workbook ({0})", traceable); Logger.Log(0, "({0})", e.Message); Logger.Log(0, "Please close the workbook ({0}) if you currently have it open in Excel and then retry.", traceable); } File.ServiceOrders.RemoveRange(0, File.ServiceOrders.Count); } // end of MAIN() } // end of todo loop // END OF MAIN2 public static Dictionary getOverrides(string task) //returns with SCHEDA prefix { Dictionary o = new Dictionary { }; if (System.IO.File.Exists(task + overrideSuffix)) { Logger.Log(0, "Found Overrides file ({0}), parsing it...", task + overrideSuffix); foreach (var line in System.IO.File.ReadLines(task + overrideSuffix)) { if (string.IsNullOrWhiteSpace(line)) continue; // Split by spaces: first token is the index word string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 2) { Logger.Log(0, " -Skipping: Invalid override line format: {0}", line); continue; } string indexWord = parts[0]; // convert from SO to SCHEDA // Validate numeric range //if (!int.TryParse(indexWord, out int indexNum) || // indexNum < 100000 || indexNum > 999999) Match match = Regex.Match( indexWord , @"^[A-Za-z]{7}[0-9]{3}", System.Text.RegularExpressions.RegexOptions.None); if (!match.Success) { Logger.Log(0, " -Skipping: Invalid SCHEDA '{0}' in line: {1}", indexWord, line); continue; } // Dictionary for key=value pairs Dictionary pairs = new Dictionary(); // Parse remaining tokens for (int i = 1; i < parts.Length; i++) { var kv = parts[i].Split('='); if (kv.Length != 2) { Logger.Log(0, " -Skipping: Malformed override entry format: {0}", parts[i]); continue; } string key = kv[0].Trim(); string value = kv[1].Trim(); pairs[key] = value; } // Validate overrides, SO was already checked // SO TA COP PRID CONTRACT SCHED BSD MRR NRC // 124111 R000137538 333754 3050 GCNSLDF047 XXX 900 0 // //foreach (string Parm in new string[] { "COP", "PRID", "SCHED", "BSD", "MRR", "NRC" }) // checklist try { string ivalue = ""; if (!pairs.TryGetValue("COP", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num)) if (!(num >= 100000 && num <= 999999)) //invalid COP { Logger.Log(0, " >{1} SKIP invalid override for COP of {0}", ivalue, indexWord); pairs.Remove("COP"); } if (!pairs.TryGetValue("PRID", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num2)) if (!(num2 >= 1000 && num2 <= 9999)) //invalid PRID { Logger.Log(0, " >{1} SKIP invalid override for PRID of {0}", ivalue, indexWord); pairs.Remove("PRID"); } if (!pairs.TryGetValue("SO", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num3)) if (!(num3 >= 100000 && num3 <= 999999)) //invalid SO { Logger.Log(0, " >{1} SKIP invalid override for SO of {0}", ivalue, indexWord); pairs.Remove("SO"); } if (!pairs.TryGetValue("BSD", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num4)) if (!(num4 >= 20200000 && num4 <= 20300000)) //invalid COP { Logger.Log(0, " >{1} SKIP invalid override for BSD of {0}", ivalue, indexWord); pairs.Remove("BSD"); } if (!pairs.TryGetValue("MRR", out ivalue)) { } // key not found, move on else if (double.TryParse(ivalue, out double num5)) if (!(num5 >= 0 && num5 <= 99999)) //invalid MRR { Logger.Log(0, " >{1} SKIP invalid override for MRR of {0}", ivalue, indexWord); pairs.Remove("MRR"); } if (!pairs.TryGetValue("NRC", out ivalue)) { } // key not found, move on else if (double.TryParse(ivalue, out double num6)) if (!(num6 >= 0 && num6 <= 99999)) //invalid MRR { Logger.Log(0, " >{1} SKIP invalid override for NRC of {0}", ivalue, indexWord); pairs.Remove("NRC"); } } catch (Exception e) { Logger.Log(0, "Overrides Exc: {0}:{1}", e.Message, e.InnerException.Message); } string so_overrides = ""; { foreach (var p in pairs) { so_overrides += (String.Format(" {0} = {1}", p.Key, p.Value)); o.Add(indexWord + p.Key, p.Value); } Logger.Log(1, " - {0} : {1}", indexWord, so_overrides); } } } else { Logger.Log(1, " Override file ({0}) not found. Skipping Overrides.", task + overrideSuffix); } return o; } public static Dictionary getOverrides_so(string task) { Dictionary o = new Dictionary { }; if (System.IO.File.Exists(task+overrideSuffix)) { Logger.Log(0, "Found Overrides file ({0}), parsing it...", task + overrideSuffix); foreach (var line in System.IO.File.ReadLines(task + overrideSuffix)) { if (string.IsNullOrWhiteSpace(line)) continue; // Split by spaces: first token is the index word string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length< 2) { Logger.Log(0, " -Skipping: Invalid override line format: {0}", line); continue; } string indexWord = parts[0]; // Validate numeric range if (!int.TryParse(indexWord, out int indexNum) || indexNum< 100000 || indexNum> 999999) { Logger.Log(0, " -Skipping: Invalid SO# '{0}' in line: {1}", indexWord, line); continue; } // Dictionary for key=value pairs Dictionary pairs = new Dictionary(); // Parse remaining tokens for (int i = 1; i < parts.Length; i++) { var kv = parts[i].Split('='); if (kv.Length != 2) { Logger.Log(0, " -Skipping: Malformed override entry format: {0}", parts[i]); continue; } string key = kv[0].Trim(); string value = kv[1].Trim(); pairs[key] = value; } // Validate overrides, SO was already checked // SO TA COP PRID CONTRACT SCHED BSD MRR NRC // 124111 R000137538 333754 3050 GCNSLDF047 XXX 900 0 // //foreach (string Parm in new string[] { "COP", "PRID", "SCHED", "BSD", "MRR", "NRC" }) // checklist try { string ivalue = ""; if (!pairs.TryGetValue("COP", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num)) if (!(num >= 100000 && num <= 999999)) //invalid COP { Logger.Log(0, " >SO{1} SKIP invalid override for COP of {0}", ivalue, indexWord); pairs.Remove("COP"); } if (!pairs.TryGetValue("PRID", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num2)) if (!(num2 >= 1000 && num2 <= 9999)) //invalid PRID { Logger.Log(0, " >SO{1} SKIP invalid override for PRID of {0}", ivalue, indexWord); pairs.Remove("PRID"); } if (!pairs.TryGetValue("SCHED", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue.Substring(7), out int num3)) if (!(num3 >= 1 && num3 <= 999)) //invalid SCHED { Logger.Log(0, " >SO{1} SKIP invalid override for SCHED of {0}", ivalue, indexWord); pairs.Remove("SCHED"); } if (!pairs.TryGetValue("BSD", out ivalue)) { } // key not found, move on else if (int.TryParse(ivalue, out int num4)) if (!(num4 >= 20200000 && num4 <= 20300000)) //invalid COP { Logger.Log(0, " >SO{1} SKIP invalid override for BSD of {0}", ivalue, indexWord); pairs.Remove("BSD"); } if (!pairs.TryGetValue("MRR", out ivalue)) { } // key not found, move on else if (double.TryParse(ivalue, out double num5)) if (!(num5 >= 0 && num5 <= 99999)) //invalid MRR { Logger.Log(0, " >SO{1} SKIP invalid override for MRR of {0}", ivalue, indexWord); pairs.Remove("MRR"); } if (!pairs.TryGetValue("NRC", out ivalue)) { } // key not found, move on else if (double.TryParse(ivalue, out double num6)) if (!(num6 >= 0 && num6 <= 99999)) //invalid MRR { Logger.Log(0, " >SO{1} SKIP invalid override for NRC of {0}", ivalue, indexWord); pairs.Remove("NRC"); } } catch (Exception e) { Logger.Log(0, "Overrides Exc: {0}:{1}", e.Message, e.InnerException.Message); } string so_overrides = ""; { foreach (var p in pairs) { so_overrides += (String.Format(" {0} = {1}", p.Key, p.Value)); o.Add(indexWord + p.Key, p.Value); } Logger.Log(1, " -SO{0} : {1}", indexWord, so_overrides); } } } return o; } public static string dateFormal(int dateInt) { //int dateInt = 20251130; string dateString = dateInt.ToString(); // 1. Define the input format ("yyyyMMdd") string inputFormat = "yyyyMMdd"; // 2. Parse the string into a DateTime object DateTime dateTimeObject = DateTime.ParseExact( dateString, inputFormat, CultureInfo.InvariantCulture ); // 3. Define the desired output format ("MMMM dd, yyyy") // MMMM = Full month name // dd = Day of the month // yyyy = Year string outputFormat = "MMMM dd, yyyy"; string result = dateTimeObject.ToString(outputFormat); //Console.WriteLine(result); // Output: November 30, 2025 return result; } public static void calcTaxes( string mrc, string nrc, ref Row r) { r.Recurring_Charges_for_the_Month = Double.Parse(mrc); r.Total_Recurring_Charges_for_the_Month = r.Recurring_Charges_for_the_Month; r.Non_recurring_Charges_for_the_Month = Double.Parse(nrc); r.Total_Non_recurring_Charges_for_the_Month = r.Non_recurring_Charges_for_the_Month; r.Total_Service_Credits = 0; r.Total_Other_Charges_and_Credits = 0; double taxable = (r.Total_Recurring_Charges_for_the_Month + r.Total_Non_recurring_Charges_for_the_Month - r.Total_Other_Charges_and_Credits); if (r.Prov == "QC") { r.Total_GST_Amount = Math.Round((0.05) * taxable, 2); r.Total_HST_Amount = 0; r.Total_QST_Amount = Math.Round((0.09975) * taxable, 2); } else if (r.Prov == "ON") { r.Total_GST_Amount = 0; r.Total_HST_Amount = Math.Round((0.13) * taxable, 2); r.Total_QST_Amount = 0; } else if (r.Prov == "NS") { r.Total_GST_Amount = 0; r.Total_HST_Amount = Math.Round((0.14) * taxable, 2); r.Total_QST_Amount = 0; } else if ( (r.Prov == "AB") || (r.Prov == "NWT") || (r.Prov == "NU") || (r.Prov == "YK")) { r.Total_GST_Amount = Math.Round((0.05) * taxable, 2); r.Total_HST_Amount = 0; r.Total_QST_Amount = 0; } else if ( (r.Prov == "BC") || (r.Prov == "MB")) { r.Total_GST_Amount = Math.Round((0.05) * taxable, 2); //r.Total_PST_Amount = Math.Round((0.07) * taxable, 2); r.Total_HST_Amount = 0; r.Total_QST_Amount = Math.Round((0.07) * taxable, 2); } else if ((r.Prov == "NB") || (r.Prov == "NFLD") || (r.Prov == "PEI")) { r.Total_GST_Amount = 0; r.Total_HST_Amount = Math.Round((0.15) * taxable, 2); r.Total_QST_Amount = 0; } else if ( (r.Prov == "SK") ) { r.Total_GST_Amount = Math.Round((0.05) * taxable, 2); //r.Total_PST_Amount = Math.Round((0.06) * taxable, 2); r.Total_HST_Amount = 0; r.Total_QST_Amount = Math.Round((0.06) * taxable, 2); } r.Total_Taxes = r.Total_GST_Amount + r.Total_HST_Amount + r.Total_QST_Amount; r.Total_Amount_including_taxes = r.Total_Taxes + taxable; } public static Int32 getBEF(string sch) { Dictionary lookup = new Dictionary { {"GCNSLDF007" , 20250815} , {"GCNSLDF008" , 20250613} , {"GCNSLDF009" , 20250506} , {"GCNSLDF013" , 20250108} , {"GCNSLDF014" , 20250411} , {"GCNSLDF027" , 20251101} , {"GCNSLDF028" , 20250701} , {"GCNSLDF029" , 20251001} , {"GCNSLDF030" , 20250901} , {"GCNSLDF034" , 20251101} , {"GCNSLDF041" , 20251001} , {"GCNSLDF047" , 20251101} }; if ( lookup.ContainsKey(sch) ) { return lookup[sch]; } else { Logger.Log(0, " ERROR: Bill Start Date Exception not found for ({0})", sch); return 0; } } public static double sumCol(int col, ref IXLWorksheet ws) { //IXLWorksheet ws = wbk.Worksheet("BDF Type 2"); int lastRow = ws.LastRowUsed().RowNumber(); double total = 0; for (int row = 2; row <= lastRow; row++) { var cellValue = ws.Cell(row, col).GetDouble(); total += cellValue; } return total; } public static string ReadPassword() { // Using StringBuilder is a good balance between security and ease of use in console apps StringBuilder passwordBuilder = new StringBuilder(); ConsoleKeyInfo key; Console.Write(">>>>>>>>>>>>>>>>>>>>>>> "); do { // Read the key, but do not display it (intercept = true) key = Console.ReadKey(true); // Handle standard characters if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter) { passwordBuilder.Append(key.KeyChar); Console.Write("*"); // Display an asterisk or other mask character } // Handle backspace else if (key.Key == ConsoleKey.Backspace && passwordBuilder.Length > 0) { passwordBuilder.Remove(passwordBuilder.Length - 1, 1); Console.Write("\b \b"); // Erase the last character from the console } } // Stop when the Enter key is pressed while (key.Key != ConsoleKey.Enter); Console.WriteLine(); // Add a new line after the password entry is complete return passwordBuilder.ToString(); } public static bool SafeDeleteFile(string filePath) { try { // Validate input if (string.IsNullOrWhiteSpace(filePath)) return false; // Normalize path (removes illegal characters, etc.) string fullPath = System.IO.Path.GetFullPath(filePath); // Make sure file exists if (!System.IO.File.Exists(fullPath)) return false; // Remove read-only attribute if necessary System.IO.FileAttributes attrs = System.IO.File.GetAttributes(fullPath); if ((attrs & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) { System.IO.File.SetAttributes(fullPath, System.IO.FileAttributes.Normal); } // Attempt deletion System.IO.File.Delete(fullPath); // Verify deletion return !System.IO.File.Exists(fullPath); } catch (System.Exception) { // Could log the exception if needed return false; } } } // bdf class public static class IDictionaryExtensions { public static TKey FindKeyByValue(this IDictionary dictionary, TValue value) { if (dictionary == null) throw new ArgumentNullException("dictionary"); foreach (KeyValuePair pair in dictionary) if (value.Equals(pair.Value)) return pair.Key; throw new Exception("the value is not found in the dictionary"); } } }