Esempio n. 1
0
        /// <summary>
        ///     Find the automated pre-product warehouse command with the highest priority.
        /// </summary>
        /// <returns></returns>
        public IList <TX50_PrePdtWhsCmd> FindPendingPreProductCommands()
        {
            // Initiate unit of work instance.
            using (var context = new KCSGDbContext())
                using (var unitOfWork = new UnitOfWork(context))
                {
                    var autoWarehousePreProduct = PreProductAutoWarehouseDeviceCode;
                    if (autoWarehousePreProduct == null)
                    {
                        return(null);
                    }

                    var autoWarehousePreProductDevice = unitOfWork.DeviceRepository.GetById(autoWarehousePreProduct);
                    if (!"0".Equals(autoWarehousePreProductDevice.F14_DeviceStatus))
                    {
                        throw new Exception("Automated warehouse pre-product is offline.");
                    }

                    var pendingCommands = unitOfWork.PreProductWarehouseCommandRepository.GetAll();
                    pendingCommands = pendingCommands.Where(i => i.F50_Status.Trim().Equals("0") ||
                                                            i.F50_Status.Trim().Equals("1") ||
                                                            i.F50_Status.Trim().Equals("2") ||
                                                            i.F50_Status.Trim().Equals("4") ||
                                                            i.F50_Status.Trim().Equals("5"))
                                      .OrderByDescending(i => i.F50_Priority)
                                      .ThenByDescending(i => i.F50_Status);
                    return(pendingCommands.ToList());
                }
        }
 /// <summary>
 ///     Check whether auto warehouse controller is enabled or not.
 /// </summary>
 /// <param name="autoWarehouseDevice"></param>
 /// <returns></returns>
 public bool IsAutoWarehouseOnline(string autoWarehouseDevice)
 {
     using (var context = new KCSGDbContext())
         using (var unitOfWork = new UnitOfWork(context))
         {
             var autoWarehouseMaterialDevice = unitOfWork.DeviceRepository.GetById(autoWarehouseDevice);
             return(AutoControllerStatus.Online.Equals(autoWarehouseMaterialDevice.F14_DeviceStatus));
         }
 }
Esempio n. 3
0
        /// <summary>
        ///     Find the automated material warehouse command with highest priority.
        /// </summary>
        /// <returns></returns>
        public IList <TX34_MtrWhsCmd> FindPendingMaterialCommands()
        {
            // Initiate unit of work instance.
            using (var context = new KCSGDbContext())
                using (var unitOfWork = new UnitOfWork(context))
                {
                    var pendingCommands = unitOfWork.MaterialWarehouseCommandRepository.GetAll();
                    pendingCommands = pendingCommands.Where(i => i.F34_Status.Trim().Equals("0") ||
                                                            i.F34_Status.Trim().Equals("1") ||
                                                            i.F34_Status.Trim().Equals("2") ||
                                                            i.F34_Status.Trim().Equals("4") ||
                                                            i.F34_Status.Trim().Equals("5"))
                                      .OrderByDescending(i => i.F34_Priority)
                                      .ThenByDescending(i => i.F34_Status);

                    return(pendingCommands.ToList());
                }
        }
 /// <summary>
 ///     Set automated warehouse to offline mode.
 /// </summary>
 /// <param name="deviceCode"></param>
 public void SetAutoWarehouseOffline(string deviceCode)
 {
     using (var context = new KCSGDbContext())
         using (var unitOfWork = new UnitOfWork(context))
         {
             var device = unitOfWork.DeviceRepository.GetByDeviceCode(deviceCode);
             if (device != null)
             {
                 device.F14_DeviceStatus = "1";
                 device.F14_UpdateDate   = DateTime.Now;
                 unitOfWork.DeviceRepository.Update(device);
                 Message.InitiateMessage(DateTime.Now, MessageType.Error, "Autoware House is at error status..");
             }
             else
             {
                 Message.InitiateMessage(DateTime.Now, MessageType.Error, "Set Device Status failed");
             }
             unitOfWork.Commit();
         }
 }
        /// <summary>
        /// Check whether screen is locked by another terminal or not.
        /// </summary>
        /// <param name="screen"></param>
        /// <returns></returns>
        private bool IsAccessLocked(string terminalNo)
        {
            // No screen is specified, therefore every terminal can access to 'em at any time.
            if (_screens == null)
            {
                return(false);
            }

            using (var context = new KCSGDbContext())
                using (var unitOfWork = new UnitOfWork(context))
                {
                    // More than one screen is specified.
                    // If one of them is access by another terminal. Block the access of the current one.
                    var terminalStatuses       = unitOfWork.TermStatusRepository.GetAll();
                    var conflictTerminalStatus =
                        terminalStatuses.FirstOrDefault(
                            x =>
                            !x.F17_TermNo.Equals(terminalNo) && _screens.Contains(x.F17_InUsePictureNo) &&
                            (x.F17_LastRequest != null));
                    if (conflictTerminalStatus != null && conflictTerminalStatus.F17_LastRequest != null &&
                        DateTime.Now.Subtract(conflictTerminalStatus.F17_LastRequest.Value) < TimeSpan.FromSeconds(10))
                    {
                        return(true);
                    }

                    // Screen is not blocked by any terminals at the request time.
                    var accesses = unitOfWork.AccessRepository.GetAll();
                    accesses = accesses.Where(x => _screens.Contains(x.F18_LockedPicture));

                    // Whether screen is locked by another terminal.
                    return((from terminalStatus in terminalStatuses
                            from access in accesses
                            where terminalStatus.F17_InUsePictureNo.Equals(access.F18_LockPicture) &&
                            !terminalStatus.F17_TermNo.Equals(terminalNo)
                            select terminalStatus).Any());
                }
        }
        /// <summary>
        ///     This function is for parsing cookie, querying database and decide whether user can access the function or not.
        /// </summary>
        /// <param name="authorizationContext"></param>
        public void OnAuthorization(AuthorizationContext authorizationContext)
        {
#if !UNAUTHORIZED_DEBUG
            using (var context = new KCSGDbContext())
                using (var unitOfWork = new UnitOfWork(context))
                {
                    try
                    {
                        var loginDomain = new LoginDomain(unitOfWork);

                        // Initiate authentication result.
                        var authenticationResult = new AuthenticationResult();

                        #region Authentication cookie & ticket validation

                        var formAuthenticationCookie =
                            authorizationContext.RequestContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

                        if (formAuthenticationCookie == null)
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            FormsAuthentication.SignOut();

                            authorizationContext.Result = new HttpUnauthorizedResult();
                            Log.Error("Authentication cookie is invalid.");

                            return;
                        }

                        //Cookie value is invalid
                        if (string.IsNullOrWhiteSpace(formAuthenticationCookie.Value))
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();
                            Log.Error("Authentication cookie value is invalid.");
                            return;
                        }

                        // Decrypt the authentication cookie value to authentication ticket instance.
                        var formAuthenticationTicket = FormsAuthentication.Decrypt(formAuthenticationCookie.Value);

                        // Ticket is invalid.
                        if (formAuthenticationTicket == null)
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error("Authentication ticket is not valid.");
                            return;
                        }

                        // User data is invalid.
                        if (string.IsNullOrWhiteSpace(formAuthenticationTicket.UserData))
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error("Authentication ticket's user data is invalid.");
                            return;
                        }

                        #endregion

                        #region IP Address validation

                        // Find the user data in the ticket.
                        var loginViewModel = JsonConvert.DeserializeObject <LoginItem>(formAuthenticationTicket.UserData);

                        // User data is invalid.
                        if (loginViewModel == null)
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error("Authentication ticket information is invalid.");
                            return;
                        }

                        // Find IP Address of request.
                        var requestIpAddress = loginDomain.FindRequestIpAddress(authorizationContext.HttpContext);

                        // Cookie doesn't come from the same origin.
                        if (string.IsNullOrEmpty(requestIpAddress) || !requestIpAddress.Equals(loginViewModel.IpAddress))
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error(string.Format("Cookie doesn't come from the same origin as the request (Source: {0} - Target: {1})", loginViewModel.IpAddress, loginViewModel.Password));
                            return;
                        }

                        #endregion

                        #region Passsword

                        // No password is included in cookie.
                        if (string.IsNullOrEmpty(loginViewModel.Password))
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error("No password is included in the cookie.");
                            return;
                        }

                        // Find password setting.
                        var passwordSetting = loginDomain.FindPasswordSetting(loginViewModel.Password);
                        if (passwordSetting == null)
                        {
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error(string.Format("Password {0}", loginViewModel.Password));
                            return;
                        }

                        // Find the password level.
                        authenticationResult.PasswordLevel = passwordSetting.F16_PswdLevel;

                        #endregion

                        #region Terminal

                        // Analyze client ip address.
                        var ips = loginDomain.AnalyzeIpAddress(requestIpAddress);

                        // Find terminal by searching ip address.
                        var terminal = loginDomain.FindTerminalFromIpAddress(ips);

                        // No terminal has been found in the request.
                        if (terminal == null)
                        {
                            // Unauthenticated request is allowed to access function.
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Sign the user out to clear the cookie.
                            FormsAuthentication.SignOut();

                            // Treat the request as unauthorized.
                            authorizationContext.Result = new HttpUnauthorizedResult();

                            Log.Error(string.Format("No terminal has been found with IP : {0}", requestIpAddress));
                            return;
                        }

                        // Update authentication result.
                        authenticationResult.TerminalNo = terminal.F06_TerminalNo;

                        #endregion

                        #region Cookie authentication

                        // Find the current system time on the server.
                        var systemTime = DateTime.Now;

                        // Login is successful, save the information in the cookie for future use.
                        formAuthenticationTicket = new FormsAuthenticationTicket(1, loginDomain.AuthenticationTicketName, systemTime,
                                                                                 systemTime.AddMinutes(30), true, JsonConvert.SerializeObject(loginViewModel));

                        // Initialize cookie contain the authorization ticket.
                        var httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName,
                                                        FormsAuthentication.Encrypt(formAuthenticationTicket));
                        authorizationContext.HttpContext.Response.Cookies.Add(httpCookie);

                        // Set credential for the HttpContext.
                        var claimIdentity = new ClaimsIdentity(null, loginDomain.AuthenticationClaimName);
                        claimIdentity.AddClaim(new Claim(ClientIdentities.TerminalNo, authenticationResult.TerminalNo));
                        claimIdentity.AddClaim(new Claim(ClientIdentities.IpAddress, requestIpAddress));
                        claimIdentity.AddClaim(new Claim(ClientIdentities.PasswordLevel, authenticationResult.PasswordLevel));

                        #endregion

                        #region Accessible screens

                        // Find list of accessible screens by using terminal functions & functions management.
                        var availableScreens = loginDomain.FindAccessibleScreens(authenticationResult.TerminalNo,
                                                                                 authenticationResult.PasswordLevel);

                        // No screen has been found.
                        if (availableScreens == null || availableScreens.Count < 1)
                        {
                            // Unauthenticated request is allowed to access function.
                            if (IsAnonymousAllowed(authorizationContext))
                            {
                                return;
                            }

                            // Treat the request as forbidden.
                            authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);

                            Log.Error(string.Format("No available screen has been found for terminal {0}", authenticationResult.TerminalNo));
                            return;
                        }

                        // Update available screens list to the terminal.
                        authenticationResult.AccessibleScreens = availableScreens;

                        // Identity update.
                        claimIdentity.AddClaim(new Claim(ClientIdentities.AccessibleScreens, string.Join(",", authenticationResult.AccessibleScreens)));

                        if (_screens != null)
                        {
                            claimIdentity.AddClaim(new Claim(ClientIdentities.AccessingScreen, string.Join(",", _screens)));
                        }

                        var claimsPrincipal = new ClaimsPrincipal(claimIdentity);
                        authorizationContext.HttpContext.User = claimsPrincipal;

                        // At least one screen has been specified to the target controller/action.
                        if (_screens != null && _screens.Length > 0)
                        {
                            // Check whether terminal can access to screen or not.
                            var isScreenAccessible = availableScreens.Any(x => _screens.Any(y => x.Equals(y)));
                            if (!isScreenAccessible)
                            {
                                // Treat the request as forbidden.
                                authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);

                                Log.Error(string.Format("Terminal {0} cannot access to screens : {1}", authenticationResult.TerminalNo, string.Join(",", _screens)));
                            }
                        }

                        // Access of terminal to screen is locked.
                        if (IsAccessLocked(terminal.F06_TerminalNo))
                        {
                            var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
                            authorizationContext.Result = new RedirectResult(urlHelper.Action("Index", "Home", new { Area = "", @isLockScreen = true }));
                        }


                        #endregion
                    }
                    catch (UnauthorizedAccessException)
                    {
                        authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
                    }
                }
#elif UNAUTHORIZED_DEBUG
#endif
        }
Esempio n. 7
0
        /// <summary>
        /// Task which is used for sending status request to external terminal.
        /// </summary>
        private void SendingStatusRequestCommands()
        {
            while (true)
            {
                // Task is not allowed to run.
                if (!_isTaskRunning)
                {
                    Thread.Sleep(Setting.CommandScanTaskInterval);
                    continue;
                }

                // Wait for status request.
                _manualResetStatusRequest.WaitOne();

                var terminalMessage = new TerminalMessage();

                try
                {
                    // Maximum command sequence number.
                    var maximumCommandSeq = 1;

                    using (var context = new KCSGDbContext())
                        using (var unitOfWork = new UnitOfWork(context))
                        {
                            // Find no manage in database.
                            var noManage = unitOfWork.NoManageRepository.GetAll().FirstOrDefault();
                            if (noManage == null)
                            {
                                Thread.Sleep(Setting.CommandScanTaskInterval);
                                continue;
                            }

                            if (TerminalName.Material.Equals(_terminalSetting.Key))
                            {
                                maximumCommandSeq = noManage.F48_MtrWhsCmdNo + 1;
                                if (maximumCommandSeq > 9999)
                                {
                                    noManage.F48_MtrWhsCmdNo = 0;
                                    maximumCommandSeq        = 0;
                                }

                                noManage.F48_MtrWhsCmdNo = maximumCommandSeq;
                            }
                            else if (TerminalName.PreProduct.Equals(_terminalSetting.Key))
                            {
                                // delete off empty command
                                var preProduct = unitOfWork.PreProductWarehouseCommandRepository.GetMany(
                                    i => i.F50_From.Trim().Equals(""))
                                                 .FirstOrDefault();

                                if (preProduct != null)
                                {
                                    unitOfWork.PreProductWarehouseCommandRepository.Delete(preProduct);
                                    unitOfWork.Commit();
                                }

                                maximumCommandSeq = noManage.F48_PrePdtWhsCmdNo + 1;
                                if (maximumCommandSeq > 9999)
                                {
                                    noManage.F48_PrePdtWhsCmdNo = 0;
                                    maximumCommandSeq           = 0;
                                }
                                noManage.F48_PrePdtWhsCmdNo = maximumCommandSeq;
                            }
                            else if (TerminalName.Product.Equals(_terminalSetting.Key))
                            {
                                maximumCommandSeq = noManage.F48_PdtWhsCmdNo + 1;
                                if (maximumCommandSeq > 9999)
                                {
                                    noManage.F48_PdtWhsCmdNo = 0;
                                    maximumCommandSeq        = 0;
                                }
                                noManage.F48_PdtWhsCmdNo = maximumCommandSeq;
                            }

                            // Update no manage first.
                            unitOfWork.NoManageRepository.Update(noManage);
                            unitOfWork.Commit();
                        }

                    terminalMessage.CommandIndex    = "5000";
                    terminalMessage.CommandSequence = maximumCommandSeq.ToString("D4");

                    using (var tcpClient = new TcpClient())
                    {
                        var endpoint = new IPEndPoint(IPAddress.Parse(_terminalSetting.Value.Outgoing.Address), _terminalSetting.Value.Outgoing.Port);
                        tcpClient.Connect(endpoint);
                        //using (var stream = tcpClient.GetStream())
                        //using (var streamWriter = new StreamWriter(stream, new UTF8Encoding()))
                        //{

                        //    streamWriter.AutoFlush = true;
                        //    streamWriter.WriteLine(terminalMessage);
                        //}

                        using (var stream = tcpClient.GetStream())
                        {
                            var bytes = Encoding.UTF8.GetBytes(terminalMessage.ToString());
                            stream.Write(bytes, 0, bytes.Length);
                            stream.Flush();
                        }
                    }

                    Message.InitiateMessage(DateTime.Now, MessageType.StatusRequest, "Sent status request", terminalMessage.ToString());
                }
                catch (Exception exception)
                {
                    Message.InitiateMessage(DateTime.Now, MessageType.Error, $"Failed to send status request: {terminalMessage}");
                    Log.Debug(exception.Message, exception);
                }
                finally
                {
                    // 2017-05-15: Disabled status request message notification.
                    //Message.InitiateMessage(DateTime.Now, MessageType.Information, $"Status request will be sent after {CommandStatusTime} milliseconds");
                    Thread.Sleep(CommandStatusTime);
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        ///     Task which is used for scanning pending commands and broadcast to external terminals.
        /// </summary>
        private void SearchWarehousePendingCommands()
        {
            while (true)
            {
                // Task is not allowed to run.
                if (!_isTaskRunning)
                {
                    Thread.Sleep(Setting.CommandScanTaskInterval);
                    continue;
                }

                // Wait for signal from another thread to start this one.
                _manualResetScannerEvent.WaitOne();

                try
                {
                    // Message will be built base on the being activated automated warehouse controller.
                    var message = "";

                    #region Message construction

                    // Operating warehouse controller is material.
                    if (TerminalName.Material.Equals(_terminalSetting.Key))
                    {
                        #region Automated warehouse status validation.

                        // No material warehouse controller has been configured in application setting file.
                        if (string.IsNullOrEmpty(AutoController.MaterialAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"No material warehouse controller device code has been configured into application setting file. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for 3 secs.
                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }

                        // Material auto warehouse controller is offline.
                        if (!MaterialAutoWarehouseController.IsAutoWarehouseOnline(AutoController.MaterialAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"Material automated warehouse is offline. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for awhile.
                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }

                        #endregion

                        #region Message initialization

                        try
                        {
                            // Find pending material command in database.
                            var commands = AutoController.FindPendingMaterialCommands();

                            // Command is not valid.
                            if (commands == null || commands.Count < 1)
                            {
                                //Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                //$"No pending command has been found. Broadcaster will be restarted in {Setting.CommandScanTaskInterval} milliseconds.");

                                Thread.Sleep(Setting.CommandScanTaskInterval);
                                continue;
                            }

                            // ProceedIncommingCommand database records.
                            MaterialAutoWarehouseController.ProcessDataBase(commands, AutoController.MaterialAutoWarehouseDeviceCode, _terminalSetting.Value.Outgoing);

                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }
                        catch (Exception exception)
                        {
                            Log.Error(exception.Message, exception);
                            Message.InitiateMessage(DateTime.Now, MessageType.Error, exception.Message);

                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }

                        #endregion
                    }
                    else if (TerminalName.PreProduct.Equals(_terminalSetting.Key))
                    {
                        using (var context = new KCSGDbContext())
                            using (var unitOfWork = new UnitOfWork(context))
                            {
                                // delete off empty command
                                var preProduct = unitOfWork.PreProductWarehouseCommandRepository.GetMany(
                                    i => i.F50_From.Trim().Equals(""))
                                                 .FirstOrDefault();

                                if (preProduct != null)
                                {
                                    unitOfWork.PreProductWarehouseCommandRepository.Delete(preProduct);
                                    unitOfWork.Commit();
                                }
                            }

                        #region Automated warehouse status validation.

                        // No material warehouse controller has been configured in application setting file.
                        if (string.IsNullOrEmpty(AutoController.PreProductAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"No pre-product warehouse controller device code has been configured into application setting file. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for 3 secs.
                            Thread.Sleep(3000);
                            continue;
                        }

                        // Material auto warehouse controller is offline.
                        if (!PreProductAutoWarehouseController.IsAutoWarehouseOnline(AutoController.PreProductAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"Pre-product automated warehouse is offline. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for awhile.
                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }

                        #endregion

                        #region Pre-product initialization

                        try
                        {
                            var commands = AutoController.FindPendingPreProductCommands();
                            if (commands == null || commands.Count < 1)
                            {
                                //Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                //$"No pending command has been found. Listener will be restarted in {Setting.CommandScanTaskInterval} milliseconds.");

                                Thread.Sleep(Setting.CommandScanTaskInterval);
                                continue;
                            }

                            // ProceedIncommingCommand messages list.
                            PreProductAutoWarehouseController.ProceedMessages(commands,
                                                                              AutoController.PreProductAutoWarehouseDeviceCode, _terminalSetting.Value.Outgoing);

                            Thread.Sleep(Setting.CommandScanTaskInterval);
                        }
                        catch (Exception exception)
                        {
                            Log.Error(exception.Message, exception);
                            Message.InitiateMessage(DateTime.Now, MessageType.Error, exception.Message);
                        }

                        #endregion
                    }
                    else if (TerminalName.Product.Equals(_terminalSetting.Key))
                    {
                        #region Automated warehouse status validation.

                        // No material warehouse controller has been configured in application setting file.
                        if (string.IsNullOrEmpty(AutoController.ProductAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"No product warehouse controller device code has been configured into application setting file. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for 3 secs.
                            Thread.Sleep(3000);
                            continue;
                        }

                        // Material auto warehouse controller is offline.
                        if (!ProductAutoWarehouseController.IsAutoWarehouseOnline(AutoController.ProductAutoWarehouseDeviceCode))
                        {
                            Message.InitiateMessage(DateTime.Now, MessageType.Information,
                                                    $"Product automated warehouse is offline. Restart in {Setting.CommandScanTaskInterval} milliseconds.");

                            // Sleep the thread for awhile.
                            Thread.Sleep(Setting.CommandScanTaskInterval);
                            continue;
                        }

                        #endregion

                        #region Products initialization

                        try
                        {
                            // TODO: Disabled it at 2017-05-17 (Consider enable it back)
                            //var commands = AutoController.FindPendingProductCommands();
                            //if (commands == null || commands.Count < 1)
                            //{
                            //    //Message.InitiateMessage(DateTime.Now, MessageType.Information,
                            //    //$"No pending command has been found. Listener will be restarted in {Setting.CommandScanTaskInterval} milliseconds.");
                            //    Thread.Sleep(Setting.CommandScanTaskInterval);
                            //    continue;
                            //}
                            //ProductAutoWarehouseController.ProcessDataList(commands,
                            //    AutoController.ProductAutoWarehouseDeviceCode, _terminalSetting.Value.Outgoing);
                            //Thread.Sleep(Setting.CommandScanTaskInterval);

                            var command = AutoController.FindPendingProductCommands().FirstOrDefault();
                            if (command == null)
                            {
                                Thread.Sleep(Setting.CommandScanTaskInterval);
                                continue;
                            }

                            ProductAutoWarehouseController.ProcessDataList(new[] { command },
                                                                           AutoController.ProductAutoWarehouseDeviceCode, _terminalSetting.Value.Outgoing);
                            Thread.Sleep(Setting.CommandScanTaskInterval);
                        }
                        catch (Exception exception)
                        {
                            Log.Error(exception.Message, exception);
                            Message.InitiateMessage(DateTime.Now, MessageType.Error, exception.Message);
                        }

                        #endregion
                    }
                    else
                    {
                        Message.InitiateMessage(DateTime.Now, MessageType.Error,
                                                $"Material, Pre-Product, Product should be selected to broadcast message. Restart message broadcaster in {Setting.CommandScanTaskInterval} milliseconds.");
                        Thread.Sleep(Setting.CommandScanTaskInterval);
                        continue;
                    }

                    #endregion
                }
                catch (EntityException entityException)
                {
                    Log.Error(entityException.Message, entityException);
                    Message.ShowMessageBox(View.FindView(),
                                           "There is something wrong with database. Please check database configuration in configuration file.",
                                           "System Message", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);

                    Application.Current.Dispatcher.Invoke(() => { IsTaskRunning = false; });
                }
                catch (Exception exception)
                {
                    Log.Error(exception.Message, exception);
                }
            }
        }