public bool FindArticle(long lArticle, ref bool bFind, ref COPSDate dtArtIni, ref COPSDate dtArtEnd, ref long plArtDef, ref COPSPlate pstrVehicle, ref long plCusID)
        {
            Articles articulo = null;
            bool     fnResult = false;

            try
            {
                articulo = Data.SingleOrDefault <Articles>(w => w.ART_ID == lArticle);

                dtArtIni    = new COPSDate(articulo.ART_INIDATE);
                dtArtEnd    = new COPSDate(articulo.ART_ENDDATE);
                plArtDef    = articulo.ART_DART_ID;
                pstrVehicle = new COPSPlate(articulo.ART_VEHICLEID);
                plCusID     = articulo.ART_CUS_ID;

                fnResult = true;
            }
            catch (Exception)
            {
                fnResult = false;
            }

            bFind = fnResult;

            return(fnResult);
        }
        public bool SetInVehicleID(COPSPlate pstrVehicleID)
        {
            trace.Write(TraceLevel.Debug, "CDatM1::SetInVehicleID");
            bool fnResult = true;

            try
            {
                m_strInVehicleID = new COPSPlate(pstrVehicleID.ToString()) ?? throw new ArgumentNullException(nameof(pstrVehicleID), "Parameter NULL");
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                fnResult = false;
            }

            return(fnResult);
        }
        private bool IsVehicleIdVIP(CDatM1 m1, ref bool isVIP, long cpmArticleDef = GlobalDefs.DEF_UNDEFINED_VALUE)
        {
            trace.Write(TraceLevel.Info, ">>IsVehicleIdVIP");
            bool fnResult = true;

            try
            {
                isVIP = false;

                COPSPlate strPlate    = m1.GetInVehicleID();
                COPSDate  odDate      = m1.GetInDate().Copy();
                long      lGroup      = m1.GetInGroup();
                long      lArticleDef = GlobalDefs.DEF_UNDEFINED_VALUE;

                tariffCalculator.FillTree();
                bool isVehicleIdVIP = database.IsVehicleIdVIP(tariffCalculator.GetTree(), ref strPlate, odDate, lGroup, ref lArticleDef, ref isVIP);
                if (!isVehicleIdVIP)
                {
                    throw new InvalidOperationException("Error getting last operation group");
                }

                if (isVIP && lArticleDef != GlobalDefs.DEF_UNDEFINED_VALUE)
                {
                    m1.SetInArticleDef((int)lArticleDef);
                }
                else if (isVIP && lArticleDef == GlobalDefs.DEF_UNDEFINED_VALUE)
                {
                    isVIP = isVIP && lArticleDef == cpmArticleDef;
                }

                m1.SetOutIsVIP(isVIP);
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                fnResult = false;
            }


            trace.Write(TraceLevel.Info, "<<IsVehicleIdVIP");
            return(fnResult);
        }
        public int fnM1(string pStrIn, string pRegEntry, ref string pStrOut, ref string pStrOutM50, int nSize, bool bApplyHistory, bool bUseDefaultArticleDef)
        {
            int nRes = 1;

            try
            {
                Guard.IsNullOrEmptyString(pStrIn, nameof(pStrIn));

                LoadParams(pRegEntry);
                trace.Write(TraceLevel.Debug, $"GeneralParams.UnitId loaded  {GeneralParams.UnitId}");

                CDatM1     m1        = new CDatM1(loggerManager);
                CDatM1     m1Return  = new CDatM1(loggerManager);
                CDatM1     m1Amp     = new CDatM1(loggerManager);
                COPSPacket opsPacket = new COPSPacket(loggerManager);
                bool       exitCurrentOperationInOtherGroup = false;

                trace.Write(TraceLevel.Info, "Waiting For Unlock .....");

                //TODO : Añadir en lock toda la seccion
                trace.Write(TraceLevel.Info, "Inside Lock .....");

                if (!OpenDatabase())
                {
                    throw new InvalidOperationException("Open database has failed");
                }

                if (!InitComputeM1())
                {
                    throw new InvalidOperationException("Compute1 initialization has failed");
                }

                tariffCalculator.SetDBB(database);

                opsPacket.Parse(pStrIn);
                if (opsPacket.GetMsg(0) == null)
                {
                    throw new InvalidOperationException("OPSPacket doesn't conatin any message");
                }

                if (!m1.SetData(opsPacket.GetMsg(0)))
                {
                    throw new InvalidOperationException("M1 Extracting data from OPSPacket");
                }

                if (m1.GetInArticleDef() == GlobalDefs.DEF_UNDEFINED_VALUE)
                {
                    trace.Write(TraceLevel.Debug, $"Set M1 InArticleDef from parameters");
                    m1.SetInArticleDef(defaultArticleDef);
                }

                if (tariffCalculator == null)
                {
                    throw new InvalidOperationException("TariffCalculator is NULL");
                }

                trace.Write(TraceLevel.Info, "FnM1 ");
                m1.Trace();

                if (!database.IsOpened())
                {
                    trace.Write(TraceLevel.Info, "Database is not connected");

                    if (!database.Close())
                    {
                        trace.Write(TraceLevel.Error, "ERROR Closing Database");
                    }

                    if (!OpenDatabase())
                    {
                        throw new InvalidOperationException("Open database has failed");
                    }
                }

                if (m1.GetInOperType() == OperationDat.DEF_OPERTYPE_RETN)
                {
                    if (!m1Return.SetData(opsPacket.GetMsg(0)))
                    {
                        throw new InvalidOperationException("M1RETURN Extracting data from OPSPacket");
                    }

                    if (m1Return.GetInArticleDef() == GlobalDefs.DEF_UNDEFINED_VALUE)
                    {
                        trace.Write(TraceLevel.Debug, $"Set M1RETURN InArticleDef from parameters");
                        m1.SetInArticleDef(defaultArticleDef);
                    }

                    if (!ComputeReturn(m1Return, m1))
                    {
                        trace.Write(TraceLevel.Info, $"ERROR: Computing Return");
                    }
                }
                else
                {
                    bool isVIP      = false;
                    bool isResident = false;

                    if (!bUseDefaultArticleDef)
                    {
                        if (!IsVehicleIdVIP(m1, ref isVIP))
                        {
                            trace.Write(TraceLevel.Error, "ERROR : IsVehicleIdVIP");
                        }

                        if (!isVIP)
                        {
                            if (!IsVehicleIdResident(m1, ref isResident))
                            {
                                trace.Write(TraceLevel.Error, "ERROR : IsVehicleIdResident");
                            }
                        }
                    }

                    // Modify tariffs for abonos in Zumarraga
                    trace.Write(TraceLevel.Info, "System ID %1", GeneralParams.SystemId.ToString());
                    if (GeneralParams.SystemId == SYSTEM_IDENTIFIER_ZUMARRAGA)
                    {
                        if (m1.GetInArticleDef() >= 102 && m1.GetInArticleDef() <= 113)
                        {
                            trace.Write(TraceLevel.Info, "Modifying tariffs for Zumarraga");
                            COPSPlate strVehicleId = m1.GetInVehicleID();

                            if (!database.SetTariffDates(tariffCalculator.GetTree(), m1.GetInArticleDef(), strVehicleId))
                            {
                                throw new InvalidOperationException("Setting tariff dates before calling M1");
                            }
                        }
                    }

                    bool bM1Plus      = false;
                    int  nMaxQuantity = (int)m1.GetOutIntAcumul();

                    if (!tariffCalculator.GetM1(m1, bM1Plus, nMaxQuantity, bApplyHistory))
                    {
                        trace.Write(TraceLevel.Info, "ERROR : GetM1");
                    }

                    m1AppliedHistory  = (tariffCalculator.GetApplyVehicleHistory()) ? 1: 0;
                    m1RealCurrMinutes = (int)tariffCalculator.GetRealCurrMinutes();

                    if (lookOtherGroups)
                    {
                        m1Amp = new CDatM1(loggerManager);
                        if (m1Amp == null)
                        {
                            throw new InvalidOperationException("ERROR : pM1 is NULL");
                        }

                        if (!m1Amp.SetData(opsPacket.GetMsg(0)))
                        {
                            throw new InvalidOperationException("ERROR : pM1 Extracting data from OPSPacket");
                        }

                        if (m1Amp.GetInArticleDef() == GlobalDefs.DEF_UNDEFINED_VALUE)
                        {
                            m1Amp.SetInArticleDef(defaultArticleDef);
                        }


                        if (!ComputeAmpliation(m1Amp, ref exitCurrentOperationInOtherGroup))
                        {
                            trace.Write(TraceLevel.Info, "ERROR : Computing Ampliation");
                        }
                    }
                }

                m1.Trace();

                string szOutMessage;
                string szOutMessageM50;

                //// Format Result Message
                szOutMessage = FormatOutMessage(m1, true, "A");
                if (exitCurrentOperationInOtherGroup && m1Amp != null)
                {
                    szOutMessage = FormatOutMessage(m1Amp, false, "B");
                }

                szOutMessageM50 = FormatOutMessageM50(m1);

                trace.Write(TraceLevel.Info, $"Message {szOutMessage}");
                trace.Write(TraceLevel.Info, $"Message 50 {szOutMessageM50}");

                pStrOut    = szOutMessage;
                pStrOutM50 = szOutMessageM50;

                ////// Format Result Message
                //XmlDocument xmlMessage = FormatOutMessage(m1, true, "A");
                //if (exitCurrentOperationInOtherGroup && m1Amp != null)
                //{
                //    xmlMessage = FormatOutMessage(m1Amp, false, "B", xmlMessage);
                //}

                //szOutMessage = xmlMessage.InnerXml;
                //xmlMessage.RemoveAll();

                //xmlMessage = FormatOutMessageM50(m1);
                //szOutMessageM50 = xmlMessage.InnerXml;

                //trace.Write(TraceLevel.Info, $"Message {szOutMessage}");
                //trace.Write(TraceLevel.Info, $"Message 50 {szOutMessageM50}");

                //pStrOut = szOutMessage;
                //pStrOutM50 = szOutMessageM50;
            }
            catch (LoadParametersException error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                nRes = -3;
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                nRes = -1;
            }
            finally
            {
                if (!database.Close())
                {
                    trace.Write(TraceLevel.Error, "ERROR Closing Database");
                }
            }

            return(nRes);
        }
        public override bool SetData(COPSMsg message)
        {
            bool result = true;

            trace.Write(TraceLevel.Debug, "CDatM1::SetData");

            try
            {
                if (message == null)
                {
                    throw new ArgumentNullException(nameof(message), "Invalid input parameter");
                }

                base.SetData(message);

                m_strInVehicleID = message.GetElm().GetOPSPlate("m");
                m_dtInDate       = message.GetElm().GetOPSDate("d", m_dtInDate);
                m_iInOperType    = message.GetElm().GetInt("o", m_iInOperType);
                m_iInArticleDef  = message.GetElm().GetInt("ad", m_iInArticleDef);
                m_iInArticle     = message.GetElm().GetInt("a", m_iInArticle);
                m_iInGroup       = message.GetElm().GetInt("g", m_iInGroup);
                m_lOutImportAcc  = message.GetElm().GetLong("q", m_lOutImportAcc);
                m_iPaymentType   = message.GetElm().GetInt("pt", m_iPaymentType);
                m_dtInMaxDate    = message.GetElm().GetOPSDate("d2", m_dtInMaxDate);

                int iInComputeTimeLimits = 0;
                iInComputeTimeLimits   = message.GetElm().GetInt("cdl", iInComputeTimeLimits);
                m_bInComputeTimeLimits = (iInComputeTimeLimits == 1);

                int iRoundMoney = 1;
                iRoundMoney   = message.GetElm().GetInt("rmon", iRoundMoney);
                m_bRoundMoney = (iRoundMoney == 1);

                m_lInMaxTime = message.GetElm().GetLong("t", m_lInMaxTime);

                int iInHistOnlyWithSamePaymentType = 0;
                iInHistOnlyWithSamePaymentType   = message.GetElm().GetInt("spt", iInHistOnlyWithSamePaymentType);
                m_bInHistOnlyWithSamePaymentType = (iInHistOnlyWithSamePaymentType == 1);

                int iMinEqMax = 0;
                iMinEqMax   = message.GetElm().GetInt("mineqmax", iMinEqMax);
                m_bMinEqMax = (iMinEqMax == 1);

                m_lInAddFreeMinutesQuantity = message.GetElm().GetLong("aft", m_lInAddFreeMinutesQuantity);
                m_lInAddFreeMoneyQuantity   = message.GetElm().GetLong("afm", m_lInAddFreeMoneyQuantity);

                int iTemp = 0;
                iTemp = message.GetElm().GetInt("ctst", iTemp);
                m_bInCalculateTimeSteps = (iTemp != 0);
                iTemp = 0;
                iTemp = message.GetElm().GetInt("cqst", iTemp);
                m_bInCalculateQuantitySteps = (iTemp != 0);
                if (m_bInCalculateQuantitySteps)
                {
                    m_bInCalculateTimeSteps = false;
                }

                m_iInCalculateSteps_StepValue = message.GetElm().GetInt("stv", m_iInCalculateSteps_StepValue);
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
            }

            return(result);
        }
        public void Copy(CDatM1 pDatM1)
        {
            trace.Write(TraceLevel.Debug, "CDatM1::Copy");

            try
            {
                base.Copy(pDatM1);

                pDatM1.m_szInGroupDesc.CopyTo(0, m_szInGroupDesc.ToCharArray(), 0, pDatM1.m_szInGroupDesc.Length);
                pDatM1.m_szInArticleDefDesc.CopyTo(0, m_szInArticleDefDesc.ToCharArray(), 0, pDatM1.m_szInArticleDefDesc.Length);
                m_strInVehicleID                 = pDatM1.m_strInVehicleID;
                m_dtInDate                       = pDatM1.m_dtInDate.Copy();
                m_iInOperType                    = pDatM1.m_iInOperType;
                m_iInArticle                     = pDatM1.m_iInArticle;
                m_iInArticleDef                  = pDatM1.m_iInArticleDef;
                m_iInGroup                       = pDatM1.m_iInGroup;
                m_iPaymentType                   = pDatM1.m_iPaymentType;
                m_lInMoney                       = pDatM1.m_lInMoney;
                m_dtInMaxDate                    = pDatM1.m_dtInMaxDate.Copy();
                m_bInComputeTimeLimits           = pDatM1.m_bInComputeTimeLimits;
                m_lInMaxTime                     = pDatM1.m_lInMaxTime;
                m_bInHistOnlyWithSamePaymentType = pDatM1.m_bInHistOnlyWithSamePaymentType;
                m_lInIntervalOffsetMinutes       = pDatM1.m_lInIntervalOffsetMinutes;
                m_lInIntervalOffsetMoney         = pDatM1.m_lInIntervalOffsetMoney;
                m_bRoundMoney                    = pDatM1.m_bRoundMoney;
                m_iInCheckArticle                = pDatM1.m_iInCheckArticle;
                m_lInOperationID                 = pDatM1.m_lInOperationID;
                m_lInCurrRotation                = pDatM1.m_lInCurrRotation;
                m_lInAddFreeMinutesQuantity      = pDatM1.m_lInAddFreeMinutesQuantity;
                m_lInAddFreeMoneyQuantity        = pDatM1.m_lInAddFreeMoneyQuantity;

                //Out
                m_iOutResult                     = pDatM1.m_iOutResult;
                m_lOutMinImport                  = pDatM1.m_lOutMinImport;
                m_lOutMaxImport                  = pDatM1.m_lOutMaxImport;
                m_lOutMinTime                    = pDatM1.m_lOutMinTime;
                m_lOutMaxTime                    = pDatM1.m_lOutMaxTime;
                m_nOutEfMaxTime                  = pDatM1.m_nOutEfMaxTime;
                m_lOutStepImport                 = pDatM1.m_lOutStepImport;
                m_lOutRetImport                  = pDatM1.m_lOutRetImport;
                m_lOutImportAcc                  = pDatM1.m_lOutImportAcc;
                m_dtOutOperDate                  = pDatM1.m_dtOutOperDate.Copy();
                m_dtOutOperDateIni               = pDatM1.m_dtOutOperDateIni.Copy();
                m_dtOutOperDateEnd               = pDatM1.m_dtOutOperDateEnd.Copy();
                m_dtOutOperDateIni0              = pDatM1.m_dtOutOperDateIni0.Copy();
                m_dtOutMinOperDate               = pDatM1.m_dtOutMinOperDate.Copy();
                m_dtOutMaxOperDate               = pDatM1.m_dtOutMaxOperDate.Copy();
                m_lOutAcummImport                = pDatM1.m_lOutAcummImport;
                m_lOutAcummImportAllGroup        = pDatM1.m_lOutAcummImportAllGroup;
                m_nOutAcummTime                  = pDatM1.m_nOutAcummTime;
                m_nOutAcummTimeAllGroup          = pDatM1.m_nOutAcummTimeAllGroup;
                m_iOutWholeOperationWithChipCard = pDatM1.m_iOutWholeOperationWithChipCard;
                m_iOutWholeOperationWithMobile   = pDatM1.m_iOutWholeOperationWithMobile;
                m_dtOutOperDateRealIni           = pDatM1.m_dtOutOperDateRealIni.Copy();
                m_lOutRealAcummImport            = pDatM1.m_lOutRealAcummImport;
                m_nOutRealAcummTime              = (int)pDatM1.m_lOutRealAcummImport;
                m_iOutPostPay                    = pDatM1.m_iOutPostPay;
                m_iOutIsResident                 = pDatM1.m_iOutIsResident;
                m_iOutIsVIP = pDatM1.m_iOutIsVIP;
                m_iOutRemainingMinutesWithZeroValue = pDatM1.m_iOutRemainingMinutesWithZeroValue;
                m_szVAOCardID1          = String.Copy(pDatM1.m_szVAOCardID1);
                m_szVAOCardID2          = String.Copy(pDatM1.m_szVAOCardID2);
                m_szVAOCardID3          = String.Copy(pDatM1.m_szVAOCardID3);
                m_iCurNumPhotos         = pDatM1.m_iCurNumPhotos;
                m_iOutNumPhotosReceived = pDatM1.m_iOutNumPhotosReceived;

                int i = 0;
                for (i = 0; i < m_iCurNumPhotos; i++)
                {
                    m_OutPhotoStorage[i] = pDatM1.m_OutPhotoStorage[i];
                }

                for (i = 0; i < MAX_NUM_USR_MSGS; i++)
                {
                    m_szOutUserMsgs[i] = String.Copy(pDatM1.m_szOutUserMsgs[i]);
                }


                for (i = 0; i < MAX_DYN_TARIFF_PARS; i++)
                {
                    m_OutDynTariffParameters[i] = pDatM1.m_OutDynTariffParameters[i];
                }

                m_bMinEqMax = pDatM1.m_bMinEqMax;

                m_lOutAddFreeMinutesQuantity = pDatM1.m_lOutAddFreeMinutesQuantity;
                m_lOutAddFreeMoneyQuantity   = pDatM1.m_lOutAddFreeMoneyQuantity;

                m_szOutFineNumber   = String.Copy(pDatM1.m_szOutFineNumber);
                m_iOutFineResult    = pDatM1.m_iOutFineResult;
                m_bFineAlreadyPayed = pDatM1.m_bFineAlreadyPayed;

                m_iNumMoneyOffDiscounts = pDatM1.m_iNumMoneyOffDiscounts;
                for (i = 0; i < MAX_MONEYOFF_DISCOUNTS; i++)
                {
                    //_tcscpy(m_stMoneyOffDiscounts[i].szCode, pDatM1.m_stMoneyOffDiscounts[i].szCode);
                    m_stMoneyOffDiscounts[i].ulId    = pDatM1.m_stMoneyOffDiscounts[i].ulId;
                    m_stMoneyOffDiscounts[i].lResult = pDatM1.m_stMoneyOffDiscounts[i].lResult;
                }

                m_bHistFreeMoneyUsed = pDatM1.m_bHistFreeMoneyUsed;

                m_bInCalculateTimeSteps        = pDatM1.m_bInCalculateTimeSteps;
                m_bInCalculateQuantitySteps    = pDatM1.m_bInCalculateQuantitySteps;
                m_iInCalculateSteps_StepValue  = pDatM1.m_iInCalculateSteps_StepValue;
                m_strOutStepsCalculationString = pDatM1.m_strOutStepsCalculationString;
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
            }
        }