private bool ComputeReturn(CDatM1 m1Return, CDatM1 m1)
        {
            trace.Write(TraceLevel.Debug, "ComputeReturn");
            bool   fnResult                 = true;
            CDatM1 M1ComputeTime            = null;
            CDatM1 M1ReturnWithCompleteHist = null;

            try
            {
                bool     bM1Plus      = false;
                int      nMaxQuantity = 0;
                COPSDate dt;
                COPSDate dt2;
                bool     bWholeOperationWithChipCard;
                bool     bWholeOperationWithMobile;

                M1ReturnWithCompleteHist = new CDatM1(loggerManager);
                m1Return.SetInOperType(OperationDat.DEF_OPERTYPE_PARK);
                M1ReturnWithCompleteHist.Copy(m1Return);

                m1Return.SetInHistOnlyWithSamePaymentType(true);

                if (!tariffCalculator.GetM1(m1Return, bM1Plus, nMaxQuantity))
                {
                    throw new InvalidOperationException("Error computing M1");
                }

                if (!tariffCalculator.GetM1(M1ReturnWithCompleteHist, bM1Plus, nMaxQuantity))
                {
                    throw new InvalidOperationException("Error computing M1");
                }

                if ((!m1Return.GetOutHistPostPay()) && (!M1ReturnWithCompleteHist.GetOutHistPostPay()))
                {
                    dt = m1Return.GetOutOperDateRealIni();
                    m1.SetOutOperDateIni0(dt);
                    m1.SetOutOperDateIni(dt);

                    dt2 = m1Return.GetOutOperDateIni();
                    if (dt2.GetStatus() == COPSDateStatus.Valid)
                    {
                        m1.SetOutOperDateEnd(dt2);
                    }
                    else
                    {
                        m1.SetOutOperDateEnd(dt);
                    }

                    m1.SetOutAccumulateMoney(m1Return.GetOutRealAccumulateMoney());
                    m1.SetOutAccumulateTime(m1Return.GetOutRealAccumulateTime());

                    m1.SetInIntervalOffsetMoney(M1ReturnWithCompleteHist.GetOutRealAccumulateMoney() - m1Return.GetOutRealAccumulateMoney());
                    m1.SetInIntervalOffsetMinutes(M1ReturnWithCompleteHist.GetOutRealAccumulateTime() - m1Return.GetOutRealAccumulateTime());

                    bWholeOperationWithChipCard = m1Return.GetOutWholeOperationWithChipCard() == 1;
                    bWholeOperationWithMobile   = m1Return.GetOutWholeOperationWithMobile() == 1;

                    if (!tariffCalculator.GetM1(m1, bM1Plus, nMaxQuantity))
                    {
                        throw new InvalidOperationException("Error computing Return M1");
                    }

                    if (m1.GetOutResult() <= 0)
                    {
                        m1.SetOutResult(TariffCalculator.M1_NO_RETURN);
                    }
                    else if ((m1.GetInPaymentType() != OperationDat.DEF_OPERPAY_CHIPCARD) && (m1.GetInPaymentType() != OperationDat.DEF_OPERPAY_MOBILE))
                    {
                        m1.SetOutResult(TariffCalculator.M1_NO_RETURN);
                    }
                    else if (m1.GetOutRetImport() <= 0)
                    {
                        m1.SetOutResult(TariffCalculator.M1_NO_RETURN);
                    }

                    if (m1.GetOutResult() > 0)
                    {
                        string    strUnit;
                        COPSPlate strVehicleId;

                        M1ComputeTime = new CDatM1(loggerManager);
                        M1ComputeTime.SetInUnit(m1.GetInUnit());
                        strUnit = m1.GetInUnit().ToString();
                        M1ComputeTime.SetSrc(strUnit);
                        dt = m1.GetDate();
                        M1ComputeTime.SetDate(dt);

                        M1ComputeTime.SetInOperType(OperationDat.DEF_OPERTYPE_PARK);        // DEFINES en operdat.h
                        M1ComputeTime.SetInDate(dt);

                        M1ComputeTime.SetInArticleDef(m1.GetInArticleDef());
                        M1ComputeTime.SetInGroup(m1.GetInGroup());
                        strVehicleId = m1.GetInVehicleID();
                        M1ComputeTime.SetInVehicleID(strVehicleId);

                        dt = m1Return.GetOutOperDateRealIni();

                        M1ComputeTime.SetInDate(dt);
                        M1ComputeTime.SetOutOperDateIni0(dt);
                        M1ComputeTime.SetOutOperDateIni(dt);

                        M1ComputeTime.SetOutMaxImport(m1.GetOutAccumulateMoney());
                        M1ComputeTime.SetInIntervalOffsetMoney(M1ReturnWithCompleteHist.GetOutRealAccumulateMoney() - m1Return.GetOutRealAccumulateMoney());
                        M1ComputeTime.SetInIntervalOffsetMinutes(M1ReturnWithCompleteHist.GetOutRealAccumulateTime() - m1Return.GetOutRealAccumulateTime());

                        if (!tariffCalculator.GetM1(M1ComputeTime, bM1Plus, nMaxQuantity, false))
                        {
                            throw new InvalidOperationException("Error computing Compute Time M1");
                        }

                        if (M1ComputeTime.GetOutResult() <= 0)
                        {
                            m1.SetOutResult(TariffCalculator.M1_NO_RETURN);
                        }
                        else
                        {
                            dt = M1ComputeTime.GetOutOperDateEnd();
                            m1.SetOutOperDateEnd(dt);

                            // Total parking time
                            m1.SetOutEfMaxTime(M1ComputeTime.GetOutEfMaxTime());
                        }
                    }
                }
                else
                {
                    m1.SetOutResult(TariffCalculator.M1_NO_RETURN);
                }
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                fnResult = false;
            }

            return(fnResult);
        }
        private Dictionary <string, string> ExtractM1DataToM50Message(CDatM1 m1)
        {
            trace.Write(TraceLevel.Info, ">>ExtractM1DataToM50Message");

            Dictionary <string, string> elements = new Dictionary <string, string>();

            try
            {
                elements.Add($"r", m1.GetOutResult().ToString());
                elements.Add($"q1", m1.GetOutMinImport().ToString());
                elements.Add($"q2", m1.GetOutMaxImport().ToString());
                elements.Add($"t", m1.GetOutEfMaxTime().ToString());
                elements.Add($"o", m1.GetInOperType().ToString());

                if (m1.GetOutOperDateEnd().GetStatus() != COPSDateStatus.Null)
                {
                    elements.Add($"d", m1.GetOutOperDateEnd().CopyToChar());
                }

                if (m1.GetOutOperDateIni().GetStatus() != COPSDateStatus.Null)
                {
                    elements.Add($"di", m1.GetOutOperDateIni().CopyToChar());
                }

                elements.Add($"g", m1.GetInGroup().ToString());
                elements.Add($"ad", m1.GetInArticleDef().ToString());
                elements.Add($"aq", m1.GetOutAccumulateMoney().ToString());
                elements.Add($"at", m1.GetOutAccumulateTime().ToString());
                elements.Add($"aqag", m1.GetOutAccumulateMoneyAllGroup().ToString());
                elements.Add($"atag", m1.GetOutAccumulateTimeAllGroup().ToString());

                if (m1.GetOutOperDateIni0().GetStatus() != COPSDateStatus.Null)
                {
                    elements.Add($"d0", m1.GetOutOperDateIni0().CopyToChar());
                }

                elements.Add($"q", m1.GetOutRetImport().ToString());

                if (m1.GetOutOperDateRealIni().GetStatus() != COPSDateStatus.Null)
                {
                    elements.Add($"dr0", m1.GetOutOperDateRealIni().CopyToChar());
                }

                elements.Add($"raq", m1.GetOutRealAccumulateMoney().ToString());
                elements.Add($"rat", m1.GetOutRealAccumulateTime().ToString());

                if (m1.GetOutWholeOperationWithChipCard() != 0)
                {
                    elements.Add($"chca", m1.GetOutWholeOperationWithChipCard().ToString());
                }

                if (m1.GetOutWholeOperationWithMobile() != 0)
                {
                    elements.Add($"mobi", m1.GetOutWholeOperationWithMobile().ToString());
                }

                if (m1.GetOutPostPay() != 0)
                {
                    elements.Add($"pp", m1.GetOutPostPay().ToString());
                }

                if (m1.GetOutIsResident() != 0)
                {
                    elements.Add($"resi", m1.GetOutIsResident().ToString());
                }

                if (m1.GetOutIsVIP() != 0)
                {
                    elements.Add($"vip", m1.GetOutIsVIP().ToString());
                }

                elements.Add($"his", m1AppliedHistory.ToString());
                elements.Add($"rot", m1RealCurrMinutes.ToString());
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
            }

            trace.Write(TraceLevel.Info, "<<ExtractM1DataToM50Message");

            return(elements);
        }
        private bool ComputeAmpliation(CDatM1 pM1, ref bool pExistCurrentOperationInOtherGroup)
        {
            trace.Write(TraceLevel.Debug, "ComputeAmpliation");
            bool fnResult = true;

            try
            {
                bool      bM1Plus      = false;
                int       nMaxQuantity = 0;
                COPSPlate strPlate;
                COPSDate  oDate;
                long      lCurrentArticleDef;
                long      lCurrentGroup;
                long      lAmpArticleDef = GlobalDefs.DEF_UNDEFINED_VALUE;
                long      lAmpGroup      = GlobalDefs.DEF_UNDEFINED_VALUE;
                bool      bIsVIP         = false;
                bool      bIsResident    = false;

                pExistCurrentOperationInOtherGroup = false;

                lCurrentArticleDef = pM1.GetInArticleDef();
                lCurrentGroup      = pM1.GetInGroup();
                strPlate           = pM1.GetInVehicleID();
                oDate = pM1.GetInDate().Copy();


                if (!database.GetVehicleLastOperationInfo(strPlate, oDate, ref lAmpArticleDef, ref lAmpGroup))
                {
                    throw new InvalidOperationException("Error getting last operation group");
                }

                if ((lAmpGroup != lCurrentGroup && lAmpGroup != GlobalDefs.DEF_UNDEFINED_VALUE) ||
                    (lAmpArticleDef != lCurrentArticleDef && lAmpArticleDef != GlobalDefs.DEF_UNDEFINED_VALUE)
                    )
                {
                    if (lAmpGroup != GlobalDefs.DEF_UNDEFINED_VALUE)
                    {
                        pM1.SetInGroup((int)lAmpGroup);
                    }

                    if (lAmpArticleDef != GlobalDefs.DEF_UNDEFINED_VALUE)
                    {
                        pM1.SetInArticleDef((int)lAmpArticleDef);
                    }

                    nMaxQuantity = (int)pM1.GetOutIntAcumul();

                    if (!tariffCalculator.GetM1(pM1, bM1Plus, nMaxQuantity))
                    {
                        throw new InvalidOperationException("Error computing Ampliation M1");
                    }

                    if (pM1.GetOutRealAccumulateMoney() > 0 && pM1.GetOutResult() > 0 && pM1.GetOutPostPay() == 0)
                    {
                        pExistCurrentOperationInOtherGroup = true;

                        if (!IsVehicleIdVIP(pM1, ref bIsVIP, pM1.GetInArticleDef()))
                        {
                            trace.Write(TraceLevel.Info, "ERROR : IsVehicleIdVIP");
                        }

                        if (!bIsVIP)
                        {
                            if (!IsVehicleIdResident(pM1, ref bIsResident, pM1.GetInArticleDef()))
                            {
                                trace.Write(TraceLevel.Info, "ERROR : IsVehicleIdResident");
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
                fnResult = false;
            }

            return(fnResult);
        }
        private Dictionary <string, string> ExtractM1DataToMessage(CDatM1 m1, string m1ID)
        {
            trace.Write(TraceLevel.Debug, ">>ExtractM1DataToMessage");

            Dictionary <string, string> elements = new Dictionary <string, string>();

            try
            {
                elements.Add($"{m1ID}r", m1.GetOutResult().ToString());

                if (m1.GetOutResult() > 0)
                {
                    elements.Add($"{m1ID}q1", m1.GetOutMinImport().ToString());
                    elements.Add($"{m1ID}q2", m1.GetOutMaxImport().ToString());

                    if (m1.GetInComputeTimeLimits())
                    {
                        elements.Add($"{m1ID}t1", m1.GetOutMinTime().ToString());
                        elements.Add($"{m1ID}t2", m1.GetOutMaxTime().ToString());

                        if (m1.GetOutMinOperDate().GetStatus() != COPSDateStatus.Null)
                        {
                            elements.Add($"{m1ID}d1", m1.GetOutMinOperDate().CopyToChar());
                        }

                        if (m1.GetOutMaxOperDate().GetStatus() != COPSDateStatus.Null)
                        {
                            elements.Add($"{m1ID}d2", m1.GetOutMaxOperDate().CopyToChar());
                        }
                    }

                    elements.Add($"{m1ID}t", m1.GetOutEfMaxTime().ToString());
                    elements.Add($"{m1ID}o", m1.GetInOperType().ToString());

                    if (m1.GetOutOperDateEnd().GetStatus() != COPSDateStatus.Null)
                    {
                        elements.Add($"{m1ID}d", m1.GetOutOperDateEnd().CopyToChar());
                    }

                    if (m1.GetOutOperDateIni().GetStatus() != COPSDateStatus.Null)
                    {
                        elements.Add($"{m1ID}di", m1.GetOutOperDateIni().CopyToChar());
                    }

                    elements.Add($"{m1ID}g", m1.GetInGroup().ToString());
                    elements.Add($"{m1ID}ad", m1.GetInArticleDef().ToString());
                    elements.Add($"{m1ID}aq", m1.GetOutAccumulateMoney().ToString());
                    elements.Add($"{m1ID}at", m1.GetOutAccumulateTime().ToString());
                    elements.Add($"{m1ID}aqag", m1.GetOutAccumulateMoneyAllGroup().ToString());
                    elements.Add($"{m1ID}atag", m1.GetOutAccumulateTimeAllGroup().ToString());

                    if (m1.GetOutOperDateIni0().GetStatus() != COPSDateStatus.Null)
                    {
                        elements.Add($"{m1ID}d0", m1.GetOutOperDateIni0().CopyToChar());
                    }

                    elements.Add($"{m1ID}q", m1.GetOutRetImport().ToString());

                    if (m1.GetOutOperDateRealIni().GetStatus() != COPSDateStatus.Null)
                    {
                        elements.Add($"{m1ID}dr0", m1.GetOutOperDateRealIni().CopyToChar());
                    }

                    elements.Add($"{m1ID}raq", m1.GetOutRealAccumulateMoney().ToString());
                    elements.Add($"{m1ID}rat", m1.GetOutRealAccumulateTime().ToString());

                    if (m1.GetOutWholeOperationWithChipCard() != 0)
                    {
                        elements.Add($"{m1ID}chca", m1.GetOutWholeOperationWithChipCard().ToString());
                    }

                    if (m1.GetOutWholeOperationWithMobile() != 0)
                    {
                        elements.Add($"{m1ID}mobi", m1.GetOutWholeOperationWithMobile().ToString());
                    }

                    if (m1.GetOutPostPay() != 0)
                    {
                        elements.Add($"{m1ID}pp", m1.GetOutPostPay().ToString());
                    }

                    if (m1.GetOutIsResident() != 0)
                    {
                        elements.Add($"{m1ID}resi", m1.GetOutIsResident().ToString());
                    }

                    if (m1.GetOutIsVIP() != 0)
                    {
                        elements.Add($"{m1ID}vip", m1.GetOutIsVIP().ToString());
                    }

                    string strOutStepsCalculationString = m1.GetOutStepsCalculationString();
                    if (strOutStepsCalculationString.Length > 0)
                    {
                        elements.Add($"{m1ID}cst", m1.GetOutStepsCalculationString());
                    }
                }
            }
            catch (Exception error)
            {
                trace.Write(TraceLevel.Error, error.ToLogString());
            }

            trace.Write(TraceLevel.Debug, "<<ExtractM1DataToMessage");

            return(elements);
        }