public AllEgsResult GetDSMsAssetSkuValidationResult(string fulfillmentID = null, string CurrentUser = null, bool Email = false, string EmailList = null)
        {
            var exoResult         = new AllEgsResult();
            var exchangeOutput    = new List <AllEgsOutputModel>();
            var error             = new StringBuilder();
            var emailSubject      = "Exchange MSAsset/SKU Validation Report for FulfillmentIDs from DS - " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            var errorEmailSubject = "Error: Exchange MSAsset/SKU Validation Report for FulfillmentIDs from DS - " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

            ExecutionMode = (fulfillmentID == null) ? "S" : "U";

            if (currentExeName != null)
            {
                emailTrigger = currentExeName.IndexOf("AllEgsMsAssetSkuValidationReporting", StringComparison.OrdinalIgnoreCase) >= 0 ? true : false;
            }

            Dictionary <string, List <DSDataSet> > dsDataSet = null;

            try
            {
                dsDataSet = new DSDataSetAccess().GetInProgressExchangeDeploymentsToRTEG(fulfillmentID);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            AllEgsQc exoQc = new AllEgsQc();

            // Get FulfillmentId to DemandId mapping
            GDCOTicketStoreHandler      GDCOTicketStoreHandler = new GDCOTicketStoreHandler();
            Dictionary <string, string> FidToDemandIdMapping   = GDCOTicketStoreHandler.GetFidToDemandIdMapping(dsDataSet.Keys.ToList());

            // Get CPS FidList, it contains all of the fids which are CPS
            Dictionary <string, string> CpsFidTitleDic = GDCOTicketStoreHandler.GetCpsFidTitleDic(FidToDemandIdMapping);

            // Iterate over each DS project
            foreach (var fID in dsDataSet.Keys)
            {
                var dsTasks   = dsDataSet[fID];
                var GroupType = dsTasks.Last().GroupType;
                if (dsTasks != null && dsTasks.Any())
                {
                    var dcCode = dsTasks.Last().DeploymentDCCode;

                    var exoOpModel = exoQc.PerformAllEgsSkuMsAssetValidation(fID, dsTasks.Last().GDCOFaultDescription, dsTasks.Last().DeploymentPGName, "D", null, null, dcCode, GroupType, CpsFidTitleDic, dsTasks.Last().MDMIdList, null, true);
                    exoOpModel.GroupType = GroupType;
                    exchangeOutput.Add(exoOpModel);
                    error.AppendLine(exoOpModel.Error.ToString());
                }
            }

            // Save the exchangeOutput to QcExecutionRawResult table and to the shared path
            List <string> resultFiles = null;

            try
            {
                resultFiles = SaveResultToFile(exchangeOutput, "D");
            }
            catch (Exception ex)
            {
                error.AppendLine("Exception in saving results to the csv file. " + ex.ToString());
            }

            try
            {
                var gdcoTickets = CreateGdcoTickets(exchangeOutput, "D");

                // Create blocking ICM ticket for EXO fid
                DSDataSetAccess   dsa = new DSDataSetAccess();
                GdcoTicketHandler gdcoTicketHandler = new GdcoTicketHandler();

                foreach (var fID in dsDataSet.Keys)
                {
                    var dsTasks = dsDataSet[fID];
                    if (dsTasks != null && dsTasks.Any() && dsTasks.Last().GroupType.IndexOf("PreRack", StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        var dcCode           = dsTasks.Last().DeploymentDCCode;
                        var clusterName      = dsTasks.Last().ClusterName;
                        var currentWorkOrder = dsTasks.Last().GDCOFaultDescription;
                        var errorDescription = "Please complete manual QC for this cluster " + clusterName + "< EOM >";
                        var errorCode        = "Exo manual block ticket";
                        var errorTitle       = "NetworkProvisioning - General Investigation for Azure Networking - MOR/PRD build (Non PNaaS)";

                        if (dsa.IsInOA(dsTasks))
                        {
                            var tickets = new List <GdcoTicket.Model.GdcoTableTicket>();
                            try
                            {
                                tickets = new GdcoTicketTableHandler().GetTickets(fID, "msassetsku");
                            }
                            catch (Exception ex)
                            {
                                return(null);
                            }

                            bool             blockTicketExist = false;
                            List <DSDataSet> oaTasks          = new List <DSDataSet>();

                            if (dsDataSet.ContainsKey(fID))
                            {
                                oaTasks = dsDataSet[fID].Where(d => (d.GDCOFaultCode.Equals("124110"))).ToList();
                            }
                            foreach (var oaTask in oaTasks)
                            {
                                if (oaTask.TicketState.Equals("Created", StringComparison.OrdinalIgnoreCase) || oaTask.TicketState.Equals("InProgress", StringComparison.OrdinalIgnoreCase) ||
                                    oaTask.TicketState.Equals("Blocked", StringComparison.OrdinalIgnoreCase))
                                {
                                    // Loop through each ticket to see if manual exo blocking ticket exist under active OA task ticket
                                    foreach (var ticket in tickets)
                                    {
                                        if (ticket.GdcoTicket.IndexOf(errorTitle, StringComparison.OrdinalIgnoreCase) >= 0 &&
                                            ticket.GdcoTicket.IndexOf(oaTask.TicketId, StringComparison.OrdinalIgnoreCase) >= 0)
                                        {
                                            blockTicketExist = true;
                                            break;
                                        }
                                    }
                                }
                                if (blockTicketExist)
                                {
                                    break;
                                }
                            }

                            if (!blockTicketExist)
                            {
                                try
                                {
                                    var ExoBlockingTicket = new GdcoTicketHandler().CreateTicket(fID, currentWorkOrder,
                                                                                                 errorCode, errorTitle, errorDescription, dcCode, "oadpm", "3", "", "D", "msassetsku");
                                    gdcoTickets.Add(ExoBlockingTicket);

                                    // Assign blocking tickets' parents
                                    DSDataSet oaTask = null;

                                    if (dsDataSet.ContainsKey(fID))
                                    {
                                        oaTask = dsDataSet[fID].Where(d => ((d.GDCOFaultCode.Equals("124110")) &&
                                                                            (d.TicketState.Equals("Created", StringComparison.OrdinalIgnoreCase) || d.TicketState.Equals("InProgress", StringComparison.OrdinalIgnoreCase)))).FirstOrDefault();
                                    }
                                    if (oaTask != null && oaTask.TicketId != null)
                                    {
                                        new GdcoTicketHandler().AssignParent(Convert.ToInt64(oaTask.TicketId), ExoBlockingTicket.Id);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    SendEmail.SendExoSkuMsAssetReportEmail(Constants.serviceAccount, Constants.automationTeam, "EXO Blocking ticket failure", ex.ToString());
                                }
                            }
                        }
                    }
                }

                foreach (var gdcoTicket in gdcoTickets)
                {
                    if (!string.IsNullOrEmpty(gdcoTicket.Error))
                    {
                        error.AppendLine("Error in GDCO Ticket Creation " + gdcoTicket.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                error.AppendLine("Exception in creating GDCO Tickets. " + ex.ToString());
            }

            // Insert the record and send email
            try
            {
                exoResult.Result = exchangeOutput;
                var insertedResultId = QcExecutionRawResultHandler.InsertQcExecutionRawResult(PropertyGroup, ExecutionMode, JsonConvert.SerializeObject(exchangeOutput), DateTime.Now, resultFiles, CurrentUser);
                exoResult.Report = GetExoReport(insertedResultId, "D");
            }
            catch (Exception ex)
            {
                error.AppendLine("Error in inserting the execution result. " + ex.ToString());
            }
            exoResult.Error = error;

            // send diff email
            if (EmailBody.Length > 440)
            {
                string to      = "*****@*****.**";
                string subject = "OA CIS tickets comparision";
                EmailBody.AppendLine("</table>");
                SendEmail.SendExoSkuMsAssetReportEmail(Constants.serviceAccount, to, subject, EmailBody.ToString());
            }

            if (Email)
            {
                var    body            = new StringBuilder();
                var    dbSummaryReport = new StringBuilder();
                string dbDetailReport  = null;
                body.AppendLine("<style> table {    font-family: arial, sans-serif;    border-collapse: collapse;    width: 100%;}td, th {    border: 1px solid #dddddd;    text-align: left;    padding: 8px;}tr:nth-child(even) {    background-color: #dddddd;} h3 {    font-family: arial, sans-serif; color:#2F4F4F;}</style>");
                body.AppendLine("<p><h3>Summary Report:</h3></p>");
                body.AppendLine("<table>");
                body.AppendLine("<tr><td>MdmId</td><td>Current WO</td><td>Failed Tests</td><td>Ticket(s)/Status</td></tr>");
                foreach (var report in exoResult.Report)
                {
                    var tickets = new StringBuilder(string.Empty);
                    if (report.gdcoTickets != null && report.gdcoTickets.Any())
                    {
                        foreach (var gdcoTicket in report.gdcoTickets)
                        {
                            if (gdcoTicket.Fields.ContainsKey("GDCOTicketing.Custom.UpdateInfo") && gdcoTicket.Fields.ContainsKey("System.State"))
                            {
                                var ticketUrl  = gdcoTicket.Fields["GDCOTicketing.Custom.UpdateInfo"].ToString();
                                var firstIndex = ticketUrl.IndexOf("<a");
                                var lastIndex  = ticketUrl.IndexOf(">", firstIndex);
                                tickets.Append(ticketUrl.Substring(firstIndex, lastIndex - firstIndex + 1) + gdcoTicket.Id + "</a>" + "(" + gdcoTicket.Fields["System.State"] + ") ");
                            }
                        }
                    }
                    body.AppendLine("<tr><td>" + report.MdmId + "</td><td>" + report.WorkOrder + "</td><td>" + report.FailedTests + "</td><td>" + tickets.ToString() + "</td></tr>");
                    dbSummaryReport.Append(report.MdmId + "," + report.WorkOrder + "," + report.FailedTests + "," + tickets.ToString() + ";");
                }
                if (dbSummaryReport.Length > 0)
                {
                    dbSummaryReport.Remove(dbSummaryReport.Length - 1, 1);
                }
                body.AppendLine("</table>");
                if (exoResult.Report != null && exoResult.Report.Any())
                {
                    body.AppendLine("<p><h3>Detail Report: </h3>" + exoResult.Report.First().DetailReport + "</p>");
                    dbDetailReport = exoResult.Report.First().DetailReport;
                }
                // Save the Report to database
                try
                {
                    new ReportingHandler().SaveReport(dbSummaryReport.ToString(), dbDetailReport, "ds", "msassetsku");
                }
                catch (Exception ex)
                {
                    exoResult.Error.AppendLine(ex.ToString());
                }

                if (exoResult.Error != null && exoResult.Error.ToString().Trim().Length > 0)
                {
                    string[] errorLines = exoResult.Error.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
                    body.AppendLine("<p><h3>Errors: </h3><ol>");
                    foreach (var erroLine in errorLines)
                    {
                        if (erroLine != null && !string.IsNullOrEmpty(erroLine.Trim()))
                        {
                            body.AppendLine("<li>" + erroLine + "</li>");
                        }
                    }
                    body.AppendLine("</ol></p>");
                }
                SendEmail.SendExoSkuMsAssetReportEmail(CurrentUser, EmailList, emailSubject, body.ToString());
            }

            // Send out email to OA when no pid/mdmid found in MSAsset and no PO found for these Fids
            if (emailTrigger && error.ToString().IndexOf("MSAsset returned no output", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                // Filter the error just contains MsAsset association issues.
                string[]      sep     = { Environment.NewLine, "\n" }; // "\n" added in case you manually appended a newline
                string[]      errList = error.ToString().Split(sep, StringSplitOptions.None);
                StringBuilder sb      = new StringBuilder();
                sb.AppendLine("<p><h3>Below EXO fids don't have both MsAsset and PO Associations, please find investigate. </h3></p>");

                foreach (string line in errList)
                {
                    if (line.IndexOf("MSAsset returned no output", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        sb.AppendLine(line);
                    }
                }

                string subject = "Below EXO Fids don't have MsAsset and PO Associations";
                string to      = Constants.msAssetSupportAccount + ";" + Constants.OADPMAccount;
                SendEmail.SendExoSkuMsAssetReportEmail(Constants.serviceAccount, to, subject, sb.ToString());
            }

            return(exoResult);
        }
        public AllEgsResult GetMsAssetSkuValidationMdmIdsResult(string MdmId = null, string CurrentUser = null, bool Email = false, string EmailList = null)
        {
            var allEgsResult      = new AllEgsResult();
            var allEgsOutput      = new List <AllEgsOutputModel>();
            var error             = new StringBuilder();
            var emailSubject      = "All EGs MSAsset/SKU Validation Report for MdmIds from Cis - " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            var errorEmailSubject = "Error: All EGs MSAsset/SKU Validation Report for MdmIds from Cis - " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

            ExecutionMode = (MdmId == null) ? "S" : "U";

            if (currentExeName != null)
            {
                emailTrigger = currentExeName.IndexOf("AllEgsMsAssetSkuValidationReporting", StringComparison.OrdinalIgnoreCase) >= 0 ? true : false;
            }

            var cisAccess = new CisAccess();
            Dictionary <string, CisProject> cisProjectDictionary = new Dictionary <string, CisProject>();

            // Fetch the incoming MdmIds
            if (string.IsNullOrEmpty(MdmId))
            {
                try
                {
                    cisProjectModel = cisAccess.GetCisProjectsFromCis(true);
                }
                catch (Exception ex)
                {
                    error.AppendLine(ex.ToString());
                    allEgsResult.Error = error;
                    if (Email)
                    {
                        SendEmail.SendExoSkuMsAssetReportEmail(CurrentUser, Constants.automationTeam, errorEmailSubject, "Error in fetching Projects from Cis. " + error.ToString());
                    }
                    return(allEgsResult);
                }

                var incomingCisProjects = cisProjectModel.CisProjects.Where(c => c.UpdateAssetWorkOrderStatus.IndexOf("Finished", StringComparison.OrdinalIgnoreCase) >= 0);
                if (cisProjectModel == null || !incomingCisProjects.Any())
                {
                    error.AppendLine("No Exchange Project Found in Cis coming to OA queue.");
                    allEgsResult.Error = error;
                    if (Email)
                    {
                        SendEmail.SendExoSkuMsAssetReportEmail(CurrentUser, Constants.automationTeam, emailSubject, error.ToString());
                    }
                    return(allEgsResult);
                }

                foreach (var cisProj in incomingCisProjects)
                {
                    cisProjectDictionary[cisProj.MdmId] = cisProj;
                }
            }
            else
            {
                cisProjectDictionary[MdmId] = new CisProject
                {
                    MdmId                      = MdmId,
                    CurrentWorkOrder           = string.Empty,
                    UpdateAssetWorkOrderStatus = string.Empty
                };
            }

            AllEgsQc allEgsQc = new AllEgsQc();

            // Iterate over each Cis project
            foreach (var mdmId in cisProjectDictionary.Keys)
            {
                var cisProjectDetails = cisProjectDictionary[mdmId];
                if (cisProjectDetails != null)
                {
                    // Perform the QC
                    var allEgsOpModel = allEgsQc.PerformAllEgsSkuMsAssetValidation(mdmId, cisProjectDetails.CurrentWorkOrder, cisProjectDetails.PropertyGroupName, "M", null, null, cisProjectDetails.DatacenterCode);
                    if (allEgsOpModel != null)
                    {
                        allEgsOutput.Add(allEgsOpModel);
                        error.AppendLine(allEgsOpModel.Error.ToString());
                    }
                }
            }

            // Save the exchangeOutput to QcExecutionRawResult table and to the shared path
            List <string> resultFiles = null;

            try
            {
                resultFiles = SaveResultToFile(allEgsOutput, "M");
            }
            catch (Exception ex)
            {
                error.AppendLine("Exception in saving results to the csv file. " + ex.ToString());
            }

            try
            {
                var gdcoTickets = CreateGdcoTickets(allEgsOutput, "M");
                foreach (var gdcoTicket in gdcoTickets)
                {
                    if (!string.IsNullOrEmpty(gdcoTicket.Error))
                    {
                        error.AppendLine("Error in GDCO Ticket Creation " + gdcoTicket.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                error.AppendLine("Exception in creating GDCO Tickets. " + ex.ToString());
            }

            // Insert the record and send email
            try
            {
                allEgsResult.Result = allEgsOutput;
                allEgsResult.Report = GetExoReport(allEgsOutput, "M");
            }
            catch (Exception ex)
            {
                error.AppendLine("Error in inserting the execution result. " + ex.ToString());
            }

            // Filter out duplicate errors
            HashSet <String> set = new HashSet <String>();

            string[] delim = { Environment.NewLine, "\n" };
            string[] lines = error.ToString().Split(delim, StringSplitOptions.None);
            foreach (string line in lines)
            {
                set.Add(line);
            }
            error = new StringBuilder();
            foreach (string line in set)
            {
                error.AppendLine(line);
            }

            allEgsResult.Error = error;

            if (Email)
            {
                var    body            = new StringBuilder();
                var    dbSummaryReport = new StringBuilder();
                string dbDetailReport  = null;
                body.AppendLine("<style> table {    font-family: arial, sans-serif;    border-collapse: collapse;    width: 100%;}td, th {    border: 1px solid #dddddd;    text-align: left;    padding: 8px;}tr:nth-child(even) {    background-color: #dddddd;} h3 {    font-family: arial, sans-serif; color:#2F4F4F;}</style>");
                body.AppendLine("<p><h3>Summary Report:</h3></p>");
                body.AppendLine("<table>");
                body.AppendLine("<tr><td>PropertyGroup</td><td>MdmId</td><td>Current WO</td><td>Failed Tests</td><td>Ticket(s)/Status</td></tr>");
                foreach (var report in allEgsResult.Report)
                {
                    var tickets = new StringBuilder(string.Empty);
                    if (report.gdcoTickets != null && report.gdcoTickets.Any())
                    {
                        foreach (var gdcoTicket in report.gdcoTickets)
                        {
                            if (gdcoTicket.Fields.ContainsKey("GDCOTicketing.Custom.UpdateInfo") && gdcoTicket.Fields.ContainsKey("System.State") && gdcoTicket.Fields.ContainsKey("GDCOTicketing.Custom.SLARemaining"))
                            {
                                var ticketUrl  = gdcoTicket.Fields["GDCOTicketing.Custom.UpdateInfo"].ToString();
                                var firstIndex = ticketUrl.IndexOf("<a");
                                var lastIndex  = ticketUrl.IndexOf(">", firstIndex);
                                var assignedTo = "None";
                                if (gdcoTicket.Fields.ContainsKey("System.AssignedTo"))
                                {
                                    assignedTo = gdcoTicket.Fields["System.AssignedTo"].ToString();
                                }
                                var state = (string)gdcoTicket.Fields["System.State"];
                                if (state.IndexOf("Canceled", StringComparison.OrdinalIgnoreCase) >= 0 || state.IndexOf("Resolved", StringComparison.OrdinalIgnoreCase) >= 0)
                                {
                                    tickets.Append(ticketUrl.Substring(firstIndex, lastIndex - firstIndex + 1) + gdcoTicket.Id + "</a>" + "(" + state + ") ");
                                }
                                else
                                {
                                    tickets.Append(ticketUrl.Substring(firstIndex, lastIndex - firstIndex + 1) + gdcoTicket.Id + "</a>" + "(" + state + "|RemainingSLA: " + Math.Round(TimeSpan.FromMilliseconds(Convert.ToDouble(gdcoTicket.Fields["GDCOTicketing.Custom.SLARemaining"])).TotalHours, 1) + "H|AssignedTo:" + assignedTo + ") ");
                                }
                            }
                        }
                    }
                    body.AppendLine("<tr><td>" + report.PropertyGroupName + "</td><td>" + report.MdmId + "</td><td>" + report.WorkOrder + "</td><td>" + report.FailedTests + "</td><td>" + tickets.ToString() + "</td></tr>");
                    dbSummaryReport.Append(report.PropertyGroupName + "," + report.MdmId + "," + report.WorkOrder + "," + report.FailedTests + "," + tickets.ToString() + ";");
                }
                if (dbSummaryReport.Length > 0)
                {
                    dbSummaryReport.Remove(dbSummaryReport.Length - 1, 1);
                }
                body.AppendLine("</table>");
                if (resultFiles != null && resultFiles.Any())
                {
                    body.AppendLine("<p><h3>Detail Report: </h3>" + resultFiles.First() + "</p>");
                    dbDetailReport = resultFiles.First();
                }

                // Save the Report to database
                if (MdmId == null)
                {
                    try
                    {
                        new ReportingHandler().SaveReport(dbSummaryReport.ToString(), dbDetailReport, "cis", "allegs_msassetsku");
                    }
                    catch (Exception ex)
                    {
                        allEgsResult.Error.AppendLine(ex.ToString());
                    }
                }

                if (allEgsResult.Error != null && allEgsResult.Error.ToString().Trim().Length > 0)
                {
                    string[] errorLines = allEgsResult.Error.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
                    body.AppendLine("<p><h3>Errors: </h3><ol>");
                    foreach (var erroLine in errorLines)
                    {
                        if (erroLine != null && !string.IsNullOrEmpty(erroLine.Trim()))
                        {
                            body.AppendLine("<li>" + erroLine + "</li>");
                        }
                    }
                    body.AppendLine("</ol></p>");
                }
                SendEmail.SendExoSkuMsAssetReportEmail(CurrentUser, EmailList, emailSubject, body.ToString());
            }
            return(allEgsResult);
        }