BomItemReplacer

*BomItemReplacer*

using Bartech.SGCore.Base;
using Bartech.SGCore.Base.Web;
using Bartech.SGCore.Helpers;
using Bartech.SGCore.Local.Services;
using Bartech.SGCore.Model;
using Bartech.SGCore.Model.API.Request;
using Bartech.SGCore.Model.API.Request.Common;
using Bartech.SGCore.Model.API.Response;
using Bartech.SGCore.Model.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using xTrace03_SG_Data;

namespace Bartech.SGCore.Local
{
    [XModule("BOM_Item_Replacer", "Modul pro výměnu nebo doplnění komponent", ModuleGroupType.Part)]
    public class SGBomItemReplacer : SGModuleLocal
    {
        #region konstruktor
        public SGBomItemReplacer(SGSession session)
            : base(session)
        {
            m_inputBatchService = Session.Resolve<InputBatchService>();
            m_componentCheckSvc = Session.Resolve<ComponentCheckService>();
            m_dxSession = Session.Resolve<SGDxSessionLocker>();
            AllowedInDevs = new SGDeviceType[] { SGDeviceType.Scanner, SGDeviceType.API };
            m_currentComponentList = new List<BusItem>();
        }
        #endregion
        #region privatni promenne
        private bool m_useBlocker;
        private int m_ioBlockDefinition;
        /// <summary>
        /// su prase, ale nebyl cas na prepsani metod/kontrol do InputBatchService
        /// </summary>
        private InputBatchService m_inputBatchService;
        private ComponentCheckService m_componentCheckSvc;
        private SGDxSessionLocker m_dxSession;
        private BusItem m_CurrentComponent;
        private BusItem m_componentToBeRemoved;
        private List<BusItem> m_currentComponentList;
        private bool m_isBatch;
        private ReplacingState State;
        private LogMessage tmp_message = null;
        private bool m_onlyOneComponent = false;
        private bool m_isSecondSlotRequested = false;
        private string compCD;
        private string batch;
        private string sn;
        private bool isCodeDefnull;
        private List<long> m_positionsToBeSaved;
        private SGLMState m_actionAfterReplace = SGLMState.ResetIndex;
        public enum ReplacingState
        {
            WaitingForComponent,
            WaitingForComponentToBeRemoved,
            WaitingForSlotToBeRemoved,
            WaitingForSlotToBeSaved
        }
        #endregion
        #region public property
        private volatile bool m_replacingMode;
        public bool ReplacingMode
        {
            get { return m_replacingMode; }
            set
            {
                if (value == false && WasCollectionChanged)
                {
                    // odeslat zpravu do eteru
                    Session.Messenger.Send<InputBatchGroupChangedMessage>(new InputBatchGroupChangedMessage());
                }
                m_replacingMode = value;
                RaisePropertyChanged(nameof(ReplacingMode));
            }
        }
        private bool m_wasCollectionChanged;
        /// <summary>
        /// Pokud dojde ke zmene kolekce Session.CycleContext.Components => TRUE
        /// </summary>
        public bool WasCollectionChanged { get { return m_wasCollectionChanged; } set { Set(() => WasCollectionChanged, ref m_wasCollectionChanged, value); } }
        #endregion

        #region overridey modulu
        protected override bool OnSetParameters()
        {
            //m_useBlocker = Session.SysParams.GetBoolean(this, "UseBlocker", true, "Určuje, zda má modul má modul nastavovat blokaci pracoviště");
            //m_ioBlockDefinition = Session.SysParams.GetInt32(this, "IOBlockDefinition", 1, "Určuje, která definice blokování v modulu IOPortBlockerService se má použít (1=BlockState, 2=BlockState2)");
            m_isBatch = Session.SysParams.GetBoolean(this, "IsBatch", false, "Je-li true, tak nedochází k mazání načtených komponent pří výměně");
            m_onlyOneComponent = Session.SysParams.GetBoolean(this, "OnlyOneComponent", true, "Je=li true, tak po zkontrolování jedné komponenty se vypne režim doplňování");
            m_isSecondSlotRequested = Session.SysParams.GetBoolean(this, "IsSecondSlotRequested", false, "Je-li true, tak je pro odnačtení komponenty potřeba načíst slot, na který dávam materiál");
            m_actionAfterReplace = Session.SysParams.GetEnum(this, "ActionAfterReplace", m_actionAfterReplace, "ResetIndex - zůstane na stejné úrovni, ResetLevel - projde skript pracoviště od začátku (určené pro lasery)");

            return base.OnSetParameters();
        }

        public override void Clear()
        {
            m_CurrentComponent = null;
            compCD = null;
            batch = null;
            sn = null;
            isCodeDefnull = false;
            State = ReplacingState.WaitingForComponent;
            base.Clear();
        }

        public override SGLMState HandlePortData(SGTreeModuleData mdata, SGReceivedData data)
        {
            SGLMState s = SGLMState.NotHandled;
            if (mdata.LevelState == SGLevelState.Echo)
            {
                if (ReplacingMode)
                {
                    switch (State)
                    {
                        case ReplacingState.WaitingForComponent:
                            Message = Log(LogMsg.BOMITEM_REPLACER_WaitingForNewComponent);
                            break;
                        case ReplacingState.WaitingForComponentToBeRemoved:
                            Message = Log(LogMsg.BOMITEM_REPLACER_WaitingForOriginalComponent);
                            break;
                        case ReplacingState.WaitingForSlotToBeRemoved:
                            Message = Log(LogMsg.BOMITEM_REPLACER_WaitingForOriginalSlot);
                            break;
                        case ReplacingState.WaitingForSlotToBeSaved:
                            Message = Log(LogMsg.BOMITEM_REPLACER_WaitingForNewSlot);
                            break;
                    }

                    s = SGLMState.Handled;
                }
            }
            else
            {
                #region API
                if (data.DeviceType == SGDeviceType.API)
                {
                    //nejedna se o API command
                    if (!(data.Data is ApiRequestDataCommand))
                    {
                        if (data.Data is ApiRequestDataComponentToReplace)
                        {
                            ApiRequestDataComponentToReplace httpApiRequestDataComponentToReplace = data.Data as ApiRequestDataComponentToReplace;
                            if (httpApiRequestDataComponentToReplace == null)
                                return SGLMState.NotHandled;

                            s = HandleComponentData(httpApiRequestDataComponentToReplace.ComponentCD, State);
                            ApiResponse(s);
                        }
                        else if (data.Data is ApiRequestDataSlotToBeRemoved)
                        {
                            ApiRequestDataSlotToBeRemoved httpApiRequestDataSlotToBeRemoved = data.Data as ApiRequestDataSlotToBeRemoved;
                            if (httpApiRequestDataSlotToBeRemoved == null)
                                return SGLMState.NotHandled;

                            s = HandleRemovingSlotData(httpApiRequestDataSlotToBeRemoved.SlotToBeRemoved);
                            ApiResponse(s);
                        }
                        else if (data.Data is ApiRequestDataSlotToBeSaved)
                        {
                            ApiRequestDataSlotToBeSaved httpApiRequestDataSlotToBeSaved = data.Data as ApiRequestDataSlotToBeSaved;
                            if (httpApiRequestDataSlotToBeSaved == null)
                                return SGLMState.NotHandled;

                            s = HandleSavingSlotData(httpApiRequestDataSlotToBeSaved.SlotToBeSaved);
                            ApiResponse(s);
                        }
                        else if (mdata.GotControl && data.Data is ApiRequestDataCheckActualStep)
                        {
                            SendActualStep();
                            return SGLMState.Handled;
                        }
                    }
                    //API command
                    else if (data.Data is ApiRequestDataCommand)
                    {
                        ApiRequestDataCommand httpApiRequestDataCommand = data.Data as ApiRequestDataCommand;
                        if (httpApiRequestDataCommand == null)
                            return SGLMState.NotHandled;

                        if (Session.SysCommands.IsSysCommand(this, httpApiRequestDataCommand.CommandBD, SGSysCommandType.ReplaceComponent) && !ReplacingMode)
                        {
                            ReplacingMode = true;
                            Message = Log(LogMsg.BOMITEM_REPLACER_Activated);
                            s = SGLMState.Handled | SGLMState.OK;
                            Session.Messenger.Send(new HttpApiResponseMessage(ApiResponseData.GetOKResponse()));
                        }
                        else if (Session.SysCommands.IsSysCommand(this, httpApiRequestDataCommand.CommandBD, SGSysCommandType.ReplaceComponent) && ReplacingMode)
                        {
                            ReplacingMode = false;
                            State = ReplacingState.WaitingForComponent;
                            Message = Log(LogMsg.BOMITEM_REPLACER_Deactivated);
                            s = SGLMState.Handled | SGLMState.OK | SGLMState.ResetIndex;
                            Session.Messenger.Send(new HttpApiResponseMessage(ApiResponseData.GetOKResponse()));
                        }
                    }
                }
                #endregion
                #region normalni vstup
                else if (data.DataType != DataType.Command)
                {
                    //vetev vymeny materialu
                    if (ReplacingMode)
                    {
                        if (data.DeviceType != SGDeviceType.API && (data.DataType == DataType.InputBatch || new Regex(Session.BomItem.SlotRegex).Match(data.Text).Success))
                        {
                            switch (State)
                            {
                                case ReplacingState.WaitingForComponent:
                                case ReplacingState.WaitingForComponentToBeRemoved:
                                    s = HandleComponentData(data.Text, State);
                                    break;
                                case ReplacingState.WaitingForSlotToBeRemoved:
                                    s = HandleRemovingSlotData(data.Text);
                                    break;
                                case ReplacingState.WaitingForSlotToBeSaved:
                                    s = HandleSavingSlotData(data.Text);
                                    break;
                            }
                        }
                    }
                }
                else if (data.DataType == DataType.Command)
                {
                    if (Session.SysCommands.IsSysCommand(this, data, SGSysCommandType.ReplaceComponent))
                    {
                        if (ReplacingMode)
                        {
                            ReplacingMode = false;
                            m_CurrentComponent = null;
                            compCD = null;
                            batch = null;
                            sn = null;
                            isCodeDefnull = false;
                            State = ReplacingState.WaitingForComponent;
                            Message = Log(LogMsg.BOMITEM_REPLACER_Deactivated);
                            s = SGLMState.Handled | SGLMState.OK | SGLMState.ResetIndex;
                        }
                        else
                        {
                            ReplacingMode = true;
                            Message = Log(LogMsg.BOMITEM_REPLACER_Activated);
                            s = SGLMState.Handled | SGLMState.OK;
                        }
                    }
                }
                #endregion
            }
            return s;

        }

        public override SGLMState ModuleChecker(SGTreeModuleData mdata)
        {
            //pokud je zapnuty
            return !mdata.GotControl && ReplacingMode ? SGLMState.Handled : SGLMState.NotHandled;
        }

        public override void StartLevel(SGTreeModuleData mdata)
        {
            base.StartLevel(mdata);
            ReplacingMode = false;
        }
        protected override void SendActualStep()
        {
            Session.Messenger.Send(new HttpApiResponseMessage(new ApiResponseDataCheckActualStepReplacer
            {
                ActualStep = this.ModuleCD,
                State = State.ToString()
            }));
        }
        #endregion

        #region pomocne funkce
        private void ChangeItemInCollection(BusItem component)
        {
            Session.GlobalContext.BOMComponents.Where(x => x.ComponentID == component.ComponentID).Select(x => { x.InputBatchCD = component.InputBatchCD; x.ComponentID = component.ComponentID; return x; }).FirstOrDefault();
        }
        private void ApiResponse(SGLMState s)
        {
            if ((s & SGLMState.OK) == SGLMState.OK)
            {
                Session.Messenger.Send(new HttpApiResponseMessage(new ApiResponseData()
                {
                    Result = "",
                    Text = ""
                }));
            }
            else
            {
                Session.Messenger.Send(new HttpApiResponseMessage(new ApiResponseData()
                {
                    Result = "error",
                    Text = Message == null ? "Neznámá chyba" : Message.TextFormatted,
                }));
            }
        }
        private bool RegexInputBatchCheck(string data, out string compCD, out string batch, out string sn, out bool isCodeDefNull)
        {
            SGCodeDef codeDef = Session.Data.GetCodeDef(data);
            compCD = null;
            batch = null;
            sn = null;
            isCodeDefNull = false;

            if (codeDef == null)
            {
                isCodeDefNull = true;
                Message = Log(LogMsg.LOCALMANAGER_UnhandledData, data);
                return false;
            }

            string regexText = codeDef.RegexText;
            var regx = new Regex(regexText).Match(data);
            if (regx.Success)
            {
                // NVCZ kod se musi optimalizovat do lepsi podoby aby to bylo unoverzalni
                compCD = regx.Groups["MATCD"].Value.TrimEnd();
                batch = regx.Groups["BATCHCD"].Value.Trim();
                sn = regx.Groups["BATCHSN"].Value.Trim();
                return true;
            }
            return false;
        }
        private SGLMState HandleComponentData(string data, ReplacingState replacingState = ReplacingState.WaitingForComponent)
        {
            SGLMState s = SGLMState.Handled | SGLMState.ResetIndex;


            RegexInputBatchCheck(data, out compCD, out batch, out sn, out isCodeDefnull);
            if (isCodeDefnull)
            {
                Message = Log(LogMsg.LOCALMANAGER_UnhandledData, data);
                return s | SGLMState.Fail;
            }
            else if (!string.IsNullOrEmpty(compCD))
            {
                bool pbSnOnly = string.IsNullOrEmpty(batch) && !string.IsNullOrEmpty(sn);
                bool pbBatchAndSn = !string.IsNullOrEmpty(batch) && !string.IsNullOrEmpty(sn);
                bool pbCompAndBatch = !string.IsNullOrEmpty(compCD) && !string.IsNullOrEmpty(batch);

                BusInputBatchSerial bibSn = null;
                BusInputBatch bib = null;

                // tady by se melo osetrit co nacitam za kod. pokud sn tak najdu prvni inputbatchsn a inputbatch abych vedel soucastku, pokud kod soucastku a sarze tak musim hledat prvni soucastku v kusovniku a pak dotahovat sarzi

                // pokud by me dosla v kodu sarze a sn nebo sn sarze mel bych prvni hledat sarzi a sn a potom se divat na komponentu

                // najdi soucastku v ciseliku
                if (replacingState == ReplacingState.WaitingForComponent)
                {
                    //za druhe m_positionsToBeSaved mi vraci vice pozic, nez se realne ma prepisovat
                    m_currentComponentList = Session.GlobalContext.BOMComponents.Where(x => x.ComponentCD == compCD).ToList();
                    m_CurrentComponent = m_currentComponentList.ElementAtOrDefault(0);
                    m_positionsToBeSaved = Session.BomItem.GetAllPositionsForCode(compCD);
                    if (SetError(m_CurrentComponent != null, LogMsg.SMT_ComponentUnwanted, true, sn, batch, compCD))
                    {
                        m_CurrentComponent = m_CurrentComponent.Clone();
                        bool addtoCollection = false;
                        s = Session.BomItem.CheckComponent(m_CurrentComponent, out addtoCollection);
                        if ((s & SGLMState.OK) == SGLMState.OK)
                        {
                            bib = m_inputBatchService.GetInputBatch(m_dxSession, batch, m_CurrentComponent.ComponentID, true);
                            //pokud sarze komponenty jiz musi existovat
                            if (bib == null && m_CurrentComponent.BatchMustExist)
                            {
                                Message = Log(LogMsg.DRYER_BatchNotFound, batch);
                                return SGLMState.Handled | SGLMState.Fail;
                            }

                            if (bib == null && Session.BomItem.CreateInputBatch(batch, m_CurrentComponent.ComponentID))
                                bib = m_inputBatchService.GetInputBatch(m_dxSession, batch, m_CurrentComponent.ComponentID, true);

                            if (bib.IsBlocked)
                            {
                                Message = Log(LogMsg.INPUTBATCH_IsBlocked, bib.BatchCD, bib.ComponentCD, bib.BlockedMessage);
                                m_CurrentComponent = null;
                                bib = null;
                                return SGLMState.Handled | SGLMState.Fail;
                            }

                            var inputBatchSN = new BusInputBatchSerial(m_inputBatchService);
                            if (SetError(bib != null, LogMsg.BATCH_BatchSnNotFound, true, data, batch, sn) && m_componentCheckSvc.CanUseComponent(this, m_dxSession, inputBatchSN, bib, SetError, Log, ref tmp_message))
                            {
                                if (m_CurrentComponent.IsSlotNeeded)
                                    State = ReplacingState.WaitingForSlotToBeRemoved;
                                //existuje jiz nacteny material stejny jako material, ktery nacitam
                                else if (Session.CycleContext.Components.Any(x => x.ComponentCD == m_CurrentComponent.ComponentCD))
                                {
                                    m_CurrentComponent.SetInputBatch(batch, sn);
                                    foreach (var position in m_positionsToBeSaved)
                                    {
                                        BusItem component;
                                        component = Session.GlobalContext.BOMComponents.Where(x => x.PositionID == position && x.ComponentCD == m_CurrentComponent.ComponentCD).FirstOrDefault();
                                        Session.CycleContext.Components.Remove(component);
                                        component.SetInputBatch(batch, sn);
                                        component.SetInputBatchID(bib.OID);
                                        component.SetAsMatched();
                                        Session.BomItem.SetGlobalCollectionItem(component);
                                        Session.CycleContext.Components.Add(component);
                                    }
                                    WasCollectionChanged = true;
                                    Message = Log(LogMsg.BOMITEM_REPLACER_ComponentRefilled, m_CurrentComponent.ComponentCD, m_CurrentComponent.InputBatchCD);
                                    ReplacingMode = !m_onlyOneComponent;
                                    if (m_onlyOneComponent)
                                        s |= m_actionAfterReplace;
                                }
                                else
                                    State = ReplacingState.WaitingForComponentToBeRemoved;
                                // nastav sarzi do komponenty
                                m_CurrentComponent.SetInputBatch(batch, sn);
                            }
                            else if (tmp_message != null)
                            {
                                Message = tmp_message;
                                return SGLMState.Handled | SGLMState.Fail;
                            }
                        }
                    }
                }
                else if (replacingState == ReplacingState.WaitingForComponentToBeRemoved)
                {
                    m_componentToBeRemoved = Session.BomItem.GetComponentFromBom(compCD);
                    if (SetError(m_CurrentComponent != null, LogMsg.SMT_ComponentUnwanted, true, sn, batch, compCD))
                    {
                        bool addtoCollection = false;
                        s = Session.BomItem.CheckComponent(m_CurrentComponent, out addtoCollection);
                        if ((s & SGLMState.OK) == SGLMState.OK)
                        {
                            bib = m_inputBatchService.GetInputBatch(m_dxSession, batch, m_CurrentComponent.ComponentID, true);
                            //pokud uz musi sarze eexistovat
                            if (bib == null && m_CurrentComponent.BatchMustExist)
                            {
                                Message = Log(LogMsg.DRYER_BatchNotFound, batch);
                                return SGLMState.Handled | SGLMState.Fail;
                            }
                            if (bib == null && Session.BomItem.CreateInputBatch(batch, m_CurrentComponent.ComponentID))
                                bib = m_inputBatchService.GetInputBatch(m_dxSession, batch, m_CurrentComponent.ComponentID, true);

                            if (SetError(bib != null, LogMsg.BATCH_BatchSnNotFound, true, data, batch, sn))
                            {
                                m_componentToBeRemoved.SetInputBatch(batch, sn);
                                foreach (long positionID in m_positionsToBeSaved)
                                {
                                    Session.CycleContext.Components.Remove(Session.CycleContext.Components.Where(x => x.InputBatchCD == m_componentToBeRemoved.InputBatchCD && x.PositionID == positionID).FirstOrDefault());
                                }
                                Session.CycleContext.Components.Add(m_CurrentComponent);
                                WasCollectionChanged = true;
                                State = ReplacingState.WaitingForComponent;
                                ReplacingMode = !m_onlyOneComponent;
                                if (m_onlyOneComponent)
                                    s |= SGLMState.ResetIndex;
                            }
                        }
                    }
                }
            }
            LogResult();
            return s;
        }

        private SGLMState HandleRemovingSlotData(string slotToBeRemoved)
        {
            SGLMState s = SGLMState.NotHandled;
            var slotToBeRemovedRegx = new Regex(Session.BomItem.SlotRegex).Match(slotToBeRemoved);
            if (SetError(slotToBeRemovedRegx.Success, LogMsg.LOCALMANAGER_UnhandledData, true, slotToBeRemoved))
            {
                string machineid = slotToBeRemovedRegx.Groups["MachineNUM"].Value.TrimEnd();
                string side = slotToBeRemovedRegx.Groups["Side"].Value.TrimEnd();
                string slot = slotToBeRemovedRegx.Groups["PosNUM"].Value.TrimEnd();
                m_componentToBeRemoved = Session.BomItem.GetComponentFromCycleContext(m_CurrentComponent.ComponentCD, machineid, side, slot);
                if (SetError(m_componentToBeRemoved != null, LogMsg.CUSTOM_WARNING_MSG, true, $"Na stroji {machineid}, straně {side} a slotu {slot} není načtena vyměňovaná komponenta ({m_CurrentComponent.ComponentCD})"))
                {
                    Message = Log(LogMsg.CUSTOM_INFO_MSG, "Komponenta úspěšně nalezena");

                    if (!m_isBatch)
                    {
                        m_positionsToBeSaved = Session.BomItem.GetAllPositionsForCode(m_componentToBeRemoved.ComponentCD, machineid, side, slot);
                        foreach (var position in m_positionsToBeSaved)
                        {
                            var component = Session.CycleContext.Components.Where(x => x.PositionID == position && x.ComponentCD == m_componentToBeRemoved.ComponentCD).FirstOrDefault();
                            if (Session.CycleContext.Components.Remove(component))
                                Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Komponenta {m_componentToBeRemoved.ComponentCD} úspěšně odstraněna z reference {position}");
                        }
                    }
                    m_CurrentComponent.SetAsMatched();
                    //pokud musi pri vymene dojit i k nacteni druheho slotu, na ktery davam material
                    if (m_isSecondSlotRequested)
                    {
                        State = ReplacingState.WaitingForSlotToBeSaved;
                        return SGLMState.Handled | SGLMState.OK;
                    }
                    else
                    {
                        foreach (var position in m_positionsToBeSaved)
                        {
                            var component = Session.GlobalContext.BOMComponents.Where(x => x.PositionID == position && x.ComponentCD == m_componentToBeRemoved.ComponentCD).FirstOrDefault();
                            component.SetInputBatch(m_CurrentComponent.InputBatchCD, sn);
                            component.SetInputBatchID(m_CurrentComponent.InputBatchID);
                            component.SetAsMatched();
                            component.SetUsedSlot(slot);
                            Session.BomItem.SetGlobalCollectionItem(component);
                            Session.CycleContext.Components.Add(component);
                        }
                        WasCollectionChanged = true;
                        Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Slot {m_CurrentComponent.UsedSlot} byl úspěšně ověřen.");
                        m_CurrentComponent = null;
                        State = ReplacingState.WaitingForComponent;
                        ReplacingMode = !m_onlyOneComponent;
                        s = SGLMState.Handled | SGLMState.OK;
                        //pokud je zapnut rezim vymeny/doplneni pouze pro jednu soucastku -> reset index aby se propsal echo prvniho modulu
                        if (m_onlyOneComponent)
                            s |= SGLMState.ResetIndex;
                    }

                    //m_CurrentComponent.SetUsedSlot(slot);
                    //if (m_CurrentComponent.SlotMatched)
                    //{
                    //    if (!m_isBatch)
                    //    {
                    //        Session.CycleContext.Components.Remove(m_componentToBeRemoved);
                    //        Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Komponenta {m_componentToBeRemoved.ComponentCD} úspěšně odstraněna");
                    //    }
                    //    m_CurrentComponent.SetAsMatched();
                    //    //pokud musi pri vymene dojit i k nacteni druheho slotu, na ktery davam material
                    //    if (m_isSecondSlotRequested)
                    //    {
                    //        State = ReplacingState.WaitingForSlotToBeSaved;
                    //        return SGLMState.Handled | SGLMState.OK;
                    //    }
                    //    else
                    //    {
                    //        Session.CycleContext.Components.Add(m_CurrentComponent.Clone());
                    //        WasCollectionChanged = true;
                    //        Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Slot {m_CurrentComponent.UsedSlot} byl úspěšně ověřen.");
                    //        m_CurrentComponent = null;
                    //        State = ReplacingState.WaitingForComponent;
                    //        ReplacingMode = !m_onlyOneComponent;
                    //        s = SGLMState.Handled | SGLMState.OK;
                    //        //pokud je zapnut rezim vymeny/doplneni pouze pro jednu soucastku -> reset index aby se propsal echo prvniho modulu
                    //        if (m_onlyOneComponent)
                    //            s |= SGLMState.ResetIndex;
                    //    }
                    //}
                    //else
                    //{
                    //    s = SGLMState.Handled | SGLMState.Fail;
                    //    Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"Slot {m_CurrentComponent.UsedSlot} nebyl ověřen");
                    //}
                }
            }
            return s;
        }

        private SGLMState HandleSavingSlotData(string slotToBeSaved)
        {
            SGLMState s = SGLMState.NotHandled;
            var slotToBeSavedRegx = new Regex(Session.BomItem.SlotRegex).Match(slotToBeSaved);
            if (SetError(slotToBeSavedRegx.Success, LogMsg.LOCALMANAGER_UnhandledData, true, slotToBeSaved))
            {
                string machineid = slotToBeSavedRegx.Groups["MachineNUM"].Value.TrimEnd();
                string side = slotToBeSavedRegx.Groups["Side"].Value.TrimEnd();
                string slot = slotToBeSavedRegx.Groups["PosNUM"].Value.TrimEnd();

                var c = Session.BomItem.GetComponentFromBom(m_CurrentComponent.ComponentCD, machineid, side, slot);
                if (SetError(c != null, LogMsg.CUSTOM_DEBUG_MSG, true, $"Komponenta {m_CurrentComponent.ComponentCD} nepatří na stroj={machineid}, strana={side}, slot={slot}"))
                {
                    var batch = m_CurrentComponent.InputBatchCD;
                    var sn = m_CurrentComponent.InputBatchSerialCD;
                    m_CurrentComponent = c;
                    m_CurrentComponent.SetInputBatch(batch, sn);
                    m_CurrentComponent.SetUsedSlot(slot);

                    if (m_CurrentComponent.SlotMatched)
                    {
                        if (!m_isBatch)
                        {
                            Session.CycleContext.Components.Remove(m_componentToBeRemoved);
                            Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Komponenta {m_componentToBeRemoved.ComponentCD} úspěšně odstraněna");
                        }

                        m_CurrentComponent.SetAsMatched();
                        Session.CycleContext.Components.Add(m_CurrentComponent.Clone());
                        WasCollectionChanged = true;
                        Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Slot {m_CurrentComponent.UsedSlot} byl úspěšně ověřen.");
                        m_CurrentComponent = null;
                        State = ReplacingState.WaitingForComponent;
                        ReplacingMode = !m_onlyOneComponent;
                        s = SGLMState.Handled | SGLMState.OK;
                        if (m_onlyOneComponent)
                            s |= SGLMState.ResetIndex;
                    }
                    else
                    {
                        s = SGLMState.Handled | SGLMState.Fail;
                        Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"Slot {m_CurrentComponent.UsedSlot} nebyl ověřen");
                    }
                }
            }
            return s;
        }


        /// <summary>
        /// mozna se bude v budoucnu blokovat pres CogiScan
        /// idealne by Block/Unblock zavolal aj CogiScan
        /// </summary>
        private void Block()
        {
            if (m_useBlocker) Session.Resolve<IOPortBlockerService>().Block(m_ioBlockDefinition);
        }

        private void Unblock()
        {
            if (m_useBlocker) Session.Resolve<IOPortBlockerService>().Unblock(m_ioBlockDefinition);
        }
        #endregion
    }
}