Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            EmailHandler emailServices = new EmailHandler();

            try
            {
                //throw new System.Exception("TEST ERROR");
                // Core data is stored within APIHandler
                APIHandler apiHandler = new APIHandler();
                // Creates CredentialManager and APIData objects
                // Credential Manager reads config Parameters based on Environment
                // APIData uses Environment Data to determine where to populate API Data Resources and Skill
                try
                {
                    apiHandler.Init();
                }
                catch (Exception e)
                {
                    Console.Clear();
                    Console.WriteLine("########## ERROR OCCURRED DURING INIT ##########");
                    Thread.Sleep(30000);
                    apiHandler.Init();
                    apiHandler.cm.LogMessage($"Error occurred during Init: {e.Message.ToString()}");
                    apiHandler.cm.LogMessage($"{e.StackTrace.ToString()}");
                }

                // Prints all Data pulled from the API
                //apiHandler.apiData.Info();
                //Console.ReadKey();


                // ExcelData is comprised of the updated info pulled from WFM Excel Sheet
                // Reads Agents and their desired Queue
                // Reads Queues and the required skills to be added to the Queue
                ExcelData excelData = new ExcelData();
                try
                {
                    excelData.Init(apiHandler.cm);
                }
                catch (Exception e)
                {
                    apiHandler.cm.BeginLog();
                    apiHandler.cm.LogMessage($"Error occurred during ExcelData Init Sequence: {e.Message.ToString()}");
                    apiHandler.cm.LogMessage($"{e.StackTrace.ToString()}");
                    apiHandler.cm.EndLog();
                    Thread.Sleep(15000);
                    excelData.Init(apiHandler.cm);
                }


                //Logs all the skills and their corresponding Role in the Excel Sheet Reference that do not exist in the UCCX Skills API
                try
                {
                    apiHandler.cm.BeginLog();
                    apiHandler.cm.LogMessage("");
                    apiHandler.cm.LogMessage("###############################################################################");
                    apiHandler.cm.LogMessage("## SKILLS THAT ARE NOT AVAILABLE WITHIN THE UCCX SKILLS API ARE LISTED BELOW ##");
                    apiHandler.cm.LogMessage("###############################################################################");
                    apiHandler.cm.LogMessage("");
                    string strPad = "[Role]";
                    apiHandler.cm.LogMessage($"{strPad.PadRight(35, ' ')} >Skill");
                    apiHandler.cm.LogMessage($"-------------------------------------------------------------------------------------------");
                    foreach (ExcelSkill sk in excelData.excelSkills)
                    {
                        foreach (KeyValuePair <string, int> kvp in sk.SkillsAdded)
                        {
                            //Console.WriteLine(kvp.Key + $"({kvp.Value.ToString()})");
                            if (!apiHandler.apiData.SkillsData.Skill.Any(x => x.SkillName.Equals(kvp.Key)))
                            {
                                strPad = "[" + sk.Name + "]";
                                apiHandler.cm.LogMessage($"{strPad.PadRight(35, ' ')} >{kvp.Key}");
                                //Console.WriteLine($"Issue with Role: {sk.Name}");
                                //Console.WriteLine($"\tSkill: {kvp.Key} does not exist in the API Skill Data.");
                                //Console.WriteLine();
                            }
                        }
                    }
                    apiHandler.cm.EndLog();
                }
                catch (Exception e)
                {
                    apiHandler.cm.BeginLog();
                    apiHandler.cm.LogMessage("An error occurred while attempting to log the invalid skills within the Excel Reference Sheet.");
                    apiHandler.cm.LogMessage($"{e.Message.ToString()}");
                    apiHandler.cm.LogMessage($"{e.StackTrace.ToString()}");
                    apiHandler.cm.EndLog();
                }


                try
                {
                    List <string> uccxSkills = new List <string>();
                    uccxSkills.Add("Skill ID, UCCX API Skill Name");
                    string uccxSnapshotFile = apiHandler.cm.Configuration.GetSection("UCCXAPISnapshot")["SnapshotFileLocation"].Replace("<DATETIME>", System.DateTime.Now.ToString("yyyy-mm-dd--HH-mm-ss"));
                    foreach (Skill sk in apiHandler.apiData.SkillsData.Skill)
                    {
                        uccxSkills.Add($"{sk.SkillId.ToString()},{sk.SkillName}");
                        //Console.WriteLine($"{sk.SkillName}");
                        //Console.WriteLine($"[{sk.SkillId.ToString()}] {sk.SkillName}");
                    }
                    string[] uccxSkillsArr = uccxSkills.ToArray();
                    System.IO.File.WriteAllLines(uccxSnapshotFile, uccxSkillsArr);
                    apiHandler.cm.BeginLog();
                    apiHandler.cm.LogMessage($"Current UCCX Skills API Data written to file located at: {uccxSnapshotFile}");
                    apiHandler.cm.EndLog();
                }
                catch (Exception e)
                {
                    apiHandler.cm.BeginLog();
                    apiHandler.cm.LogMessage("An error occurred while attempting to write to file the current snapshot of Skills available via the UCCX Skills API.");
                    apiHandler.cm.LogMessage($"{e.Message.ToString()}");
                    apiHandler.cm.LogMessage($"{e.StackTrace.ToString()}");
                    apiHandler.cm.EndLog();
                }
                //excelData.Info();
                // Prints Excel Data
                //foreach(ExcelSkill sk in excelData.excelSkills)
                //{
                //    if(sk.SkillResourceGroup != null && sk.SkillTeam != null)
                //    {
                //        Console.WriteLine($"{sk.Name} -- RG: {sk.SkillResourceGroup} -- T: {sk.SkillTeam}");
                //    }
                //    else if (sk.SkillResourceGroup != null)
                //    {
                //        Console.WriteLine($"{sk.Name} -- RG: {sk.SkillResourceGroup}");
                //    }
                //    else
                //    {
                //        Console.WriteLine($"{sk.Name}");
                //    }
                //}

                // Takes in ExcelData Object to determine skills required to update each user via API PUT Request
                // Tries Twice -- only known issue is a rare error involving Server rejecting Auth due to too many requests that occurred during testing
                try
                {
                    apiHandler.ExcelQueueUpdate(excelData);
                }
                catch (Exception e)
                {
                    apiHandler.cm.LogMessage("");
                    apiHandler.cm.LogMessage($"Error occurred during ExcelQueueUpdate Sequence: {e.Message.ToString()}");
                    apiHandler.cm.LogMessage($"{e.StackTrace.ToString()}");
                    apiHandler.cm.EndLog();
                    Thread.Sleep(120000);
                    try
                    {
                        apiHandler.ExcelQueueUpdate(excelData);
                    }
                    catch (Exception y)
                    {
                        apiHandler.cm.LogMessage("");
                        apiHandler.cm.LogMessage("");
                        apiHandler.cm.LogMessage("----------------------------------- END OF PROCESS REPORT ------------------------------------");
                        apiHandler.cm.LogMessage("ERROR -- WFM Queue Update has encountered an unrecoverable error");
                        apiHandler.cm.LogMessage($">Tasked with updating {excelData.excelAgents.Count.ToString()} agents.");
                        apiHandler.cm.LogMessage($">Successfully Updated 0/{excelData.excelAgents.Count.ToString()} agents.");
                        apiHandler.cm.LogMessage(y.Message.ToString());
                        apiHandler.cm.LogMessage(y.StackTrace.ToString());
                        apiHandler.cm.EndLog();
                    }
                }


                // This override is used to remove all skills from the Agents in the Excel Sheet
                //apiHandler.ExcelQueueUpdate(excelData, true);

                // Reports email to users in Workforce Management with a report detailing the App's actions
                if (apiHandler.failedLogging.Count > 0)
                {
                    //string addFailedQueues = "";
                    if (apiHandler.failedLogging.Count > 0)
                    {
                        string appendReporting = "";
                        appendReporting = "\n\nThe following Agent/Queues were found to be invalid:";
                        foreach (string str in apiHandler.failedLogging)
                        {
                            appendReporting += $"\n{str}";
                        }
                        apiHandler.reportingMessage = appendReporting + "\n\n" + apiHandler.reportingMessage;
                    }
                    emailServices.BuildEmail(false, apiHandler.reportingMessage, apiHandler.cm.LogPath, apiHandler.cm.LogHeader, true);
                }
                else
                {
                    emailServices.BuildEmail(false, apiHandler.reportingMessage, apiHandler.cm.LogPath, apiHandler.cm.LogHeader, false);
                }

                // Print Info that will be uploaded to Reporting Sandbox Database
                //int count = 1;
                //foreach(System.Data.DataRow dr in apiHandler.AgentsUpdatedDT.Rows)
                //{
                //    var dataArray = dr.ItemArray;
                //    Console.WriteLine($"[{count++}] {dataArray[0]} -- {dataArray[1]}");
                //}

                // Clearly defines console output end
                Console.WriteLine("\n");
                for (int i = 0; i < Console.WindowWidth; ++i)
                {
                    Console.Write("-");
                }
                Console.WriteLine("\n");
            }
            catch (Exception f)
            {
                try
                {
                    emailServices.BuildEmail(true, String.Empty, String.Empty, String.Empty, false);
                    APIHandler apiHandlerLog = new APIHandler();
                    apiHandlerLog.Init();
                    apiHandlerLog.cm.LogMessage($"FATAL ERROR: {f.Message.ToString()}");
                    apiHandlerLog.cm.LogMessage($"{f.StackTrace.ToString()}");
                }
                catch (Exception m)
                {
                    Console.WriteLine(m);
                }
            }
        }
        // Method used to update agent queues based on the results of the Excel File built by WFM
        public void ExcelQueueUpdate(ExcelData excelData, bool wipeData = false)
        {
            failedLogging = new List <string>();
            long totalTime = 0;

            UpdateConsoleStep("WFM Agent Queue Update Process using the UCCX API...");
            // Variables to track for logging/reporting
            int numFailed          = 0;
            int numAgentsProcessed = 0;

            Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop + 1);
            UpdateConsoleStep("\t>Agents Processed: " + numAgentsProcessed.ToString() + "/" + excelData.excelAgents.Count.ToString());
            cm.BeginLog();
            cm.LogMessage("Beginning WFM Agent Queue Update Process using the UCCX API.");
            cm.LogMessage("");

            // Begin iterating through each agent to build and update skillmaps
            foreach (ExcelAgent excelAgent in excelData.excelAgents)
            {
                try
                {
                    Stopwatch isw = new Stopwatch();
                    try
                    {
                        isw.Start();
                    }
                    catch (Exception n)
                    {
                        cm.LogMessage($"Error occurred starting StopWatch object: {n.Message.ToString()} -- {n.StackTrace.ToString()}");
                    }
                    // Determine Agent URL via apiData.ResourcesData
                    string agentUserId = apiData.ResourcesData.Resource.Where(p => p.FirstName + " " + p.LastName == excelAgent.agentName).First().UserID;
                    string agentUrl    = $"{cm.RootURL}/resource/{agentUserId}";
                    cm.LogMessage($"Updating {excelAgent.agentName}");
                    //// DEBUG -- Prints the built Agent URL for verification ###############################################
                    //Console.WriteLine(agentUrl);
                    ////#####################################################################################################

                    // Determine which Resource from APIData.ResourcesData corresponds to the current excelAgent being processed
                    Resource agentInfo = apiData.ResourcesData.Resource.Where(p => p.FirstName + " " + p.LastName == excelAgent.agentName).First();
                    // Serialize XML related to the current excelAgent being processed using Resource Object
                    XmlDocument xml = SerializeXml(agentInfo);

                    //Console.WriteLine(xml.OuterXml);
                    //Console.ReadKey();
                    // Isolate Old skillMap Node
                    XmlNode node = xml.SelectSingleNode("/resource/skillMap");

                    // Determine Agent's desired Queue
                    ExcelSkill newQueue = excelData.excelSkills.Where(p => p.Name == excelAgent.Queue).First();

                    // Build Skill Map XML to replace current using Agent's desired Queue
                    XmlDocument xmlSkillMap    = new XmlDocument();
                    string      skillMapString = BuildSkillMap(newQueue);

                    // BuildSkillMap() Returns "ERROR" if the skill was unable to be found
                    if (skillMapString != "ERROR")
                    {
                        xmlSkillMap.LoadXml(skillMapString);

                        // Create new XmlNode object to replace old skillMap with
                        XmlNode newNode = xmlSkillMap.SelectSingleNode("/skillMap");
                        //// DEBUG -- Prints the updated Skill Map XML ##########################################################
                        //Console.WriteLine("########################### NEW SKILL MAP ###########################\n" + node.OuterXml + "\n\n");
                        ////#####################################################################################################

                        // If wipeData == True, remove all skills from Agents
                        if (wipeData == false)
                        {
                            // Replace skillMap Node with new skillMap Node
                            node.InnerXml = newNode.InnerXml;
                        }
                        else
                        {
                            // Remove all skills from Agents
                            node.InnerXml = "";
                        }
                        if (newQueue.SkillResourceGroup != null)
                        {
                            cm.LogMessage($"Updating Resource Group of {excelAgent.agentName} ({agentUserId}) to {newQueue.SkillResourceGroup}.");
                            xml = UpdateResourceGroup(xml, newQueue);
                        }
                        if (newQueue.SkillTeam != null)
                        {
                            cm.LogMessage($"Updating Team of {excelAgent.agentName} ({agentUserId}) to {newQueue.SkillTeam}.");
                            xml = UpdateTeam(xml, newQueue);
                        }
                        try
                        {
                            // Call Method to make PUT Request to API to update Agent skillMap and Log Action/Results
                            cm.LogMessage($"Attempting to update {excelAgent.agentName} ({agentUserId}) to new Queue: {excelAgent.Queue} -- Agent refURL: {agentUrl}");
                            HttpWebResponse requestResponse = UpdateAgentResource(xml.OuterXml, agentUrl);
                            cm.LogMessage($"Status Code Returned: {requestResponse.StatusCode} -- {requestResponse.StatusDescription}\n");
                            //// DEBUG -- Prints HttpWebResponse from PUT Request ###################################################
                            //Console.WriteLine($"{requestResponse.StatusCode}: {requestResponse.StatusDescription}");
                            ////#####################################################################################################
                        }
                        catch (Exception e)
                        {
                            numFailed += 1;
                            // Log Error and update Console
                            LogConsoleAndLogFile($"ERROR: {e.Message.ToString()}", 5);
                            cm.LogMessage($"Source: {e.Source.ToString()}");
                            cm.LogMessage($"Stack Trace: {e.StackTrace.ToString()}");
                            if (e.Message.ToString().Contains("SSL"))
                            {
                                throw new System.Exception("SSL Error", e);
                            }
                        }
                    }
                    else
                    {
                        cm.LogMessage($"Unable to successfully update {excelAgent.agentName}, moving to the next Agent if available.");
                        numFailed += 1;
                    }
                    numAgentsProcessed += 1;
                    if (isw != null)
                    {
                        if (isw.IsRunning)
                        {
                            isw.Stop();
                            totalTime += isw.ElapsedMilliseconds;
                            // End Process Console Output
                            UpdateConsoleStep($"\t>Agents Processed: {numAgentsProcessed.ToString()}/{excelData.excelAgents.Count.ToString()} ({isw.ElapsedMilliseconds.ToString()}ms, {totalTime.ToString()}ms Total)");
                            LogConsoleAndLogFile($"\t>Successfully updated: {(numAgentsProcessed - numFailed).ToString()}.", 1, false, false);
                            LogConsoleAndLogFile($"\t>Failed to Update: {numFailed.ToString()}.", 2, false, false);
                            cm.LogMessage($"Time Elapsed: {isw.ElapsedMilliseconds.ToString()}ms, Total Time Elapsed: {totalTime.ToString()}ms");
                        }
                    }
                    else
                    {
                        totalTime += 5000;
                        UpdateConsoleStep($"\t>Agents Processed: {numAgentsProcessed.ToString()}/{excelData.excelAgents.Count.ToString()} (N/A ms, {totalTime.ToString()}ms Total)");
                        LogConsoleAndLogFile($"\t>Successfully updated: {(numAgentsProcessed - numFailed).ToString()}.", 1, false, false);
                        LogConsoleAndLogFile($"\t>Failed to Update: {numFailed.ToString()}.", 2, false, false);
                        cm.LogMessage($"Time Elapsed: N/A ms, Total Time Elapsed: {totalTime.ToString()}ms");
                    }
                }
                catch (Exception e)
                {
                    numAgentsProcessed += 1;
                    numFailed          += 1;
                    cm.LogMessage($"Error Occurred Updating Agent: {excelAgent.agentName} -- {e.Message.ToString()}");
                    cm.LogMessage($"Source: {e.Source.ToString()}");
                    cm.LogMessage($"Stack Trace: {e.StackTrace.ToString()}");
                    if (e.Message.ToString().Contains("SSL"))
                    {
                        throw new System.Exception("SSL Error", e);
                    }
                    else
                    {
                        failedLogging.Add($"{excelAgent.agentName} - {excelAgent.Queue}");
                    }
                }
                cm.LogMessage("");
            }
            updatesFailed = numFailed;
            cm.LogMessage("");
            cm.LogMessage("");
            cm.LogMessage("----------------------------------- END OF PROCESS REPORT ------------------------------------");
            EndConsoleLog(excelData.excelAgents.Count, numFailed, totalTime);
            cm.EndLog();
            reportingMessage  = $"------------- WFM Queue Update has completed -------------";
            reportingMessage += $"\n|\t>Agents Processed: {numAgentsProcessed.ToString()}/{excelData.excelAgents.Count.ToString()} (Total Elapsed Time: {totalTime.ToString()}ms)";
            reportingMessage += $"\n|\t>Successfully updated: {(numAgentsProcessed - numFailed).ToString()}.";
            reportingMessage += $"\n|\t>Failed to Update: {numFailed.ToString()}.";
            reportingMessage += $"\n----------------------------------------------------------------------------------------------";
        }