/// <summary>
        /// Verifica si se cumple alguna condicion de activacion para un request activo.
        /// Estas condiciones son:
        ///   * La fecha actual es mayor a la de inicio. (Si la fecha de inicio esta especificada)
        ///   * La distancia al port o portfacility es menor o igual que la especificada. (Si AccessType=3)
        /// </summary>
        /// <param name="aspr"></param>
        /// <param name="UtcNow"></param>
        /// <returns></returns>
        private bool RequestReadyToActive(ActiveShipPositionRequest aspr, DateTime UtcNow)
        {
            var ddpm       = new DDPVersionManager();
            var currentDDP = ddpm.GetCurrentDDPVersion();

            var spr = aspr.ShipPositionRequest;
            var spm = new ShipPositionManager();

            if (ShipPositionRequestHelper.IsOneTimePoll(spr.RequestType) == true)
            {
                return(true);
            }

            if (spr.AccessType != 3 && spr.StartTimeSpecified != 0 && UtcNow >= spr.StartTime)
            {
                return(true);
            }

            if (spr.AccessType == 3 && spm.IsShipInArea(spr.IMONum, spr.Item, double.Parse(spr.Distance), currentDDP.Id) == true)
            {
                return(true);
            }

            return(false);
        }
        private string SendShipPositionRequest(Message msg)
        {
            DataCenterLogic.DataCenterTypesIDE.ShipPositionRequestType shipPositionRequest = (DataCenterLogic.DataCenterTypesIDE.ShipPositionRequestType)(msg.Body);

            //Send to IDE
            if (System.Configuration.ConfigurationManager.AppSettings["send2servers"] != "False")
            {
                shipPositionRequest.test = DataCenterLogic.DataCenterTypesIDE.testType.Item0;
                ideClient.ShipPositionRequest(shipPositionRequest);
                log.Info("SendShipPositionRequest: shipPositionRequest sent to IDE");
            }

            if (ShipPositionRequestHelper.IsPeriodicRequest(shipPositionRequest.RequestType))
            {
                //Es periodico, y pedimos sacarlo de la frecuencia estandard 6hs (RequestType==6), y no es SAR (msgtype==5)?
                //Debemos imputarnos la presunta reprogramacion PRICING
                if (shipPositionRequest.RequestType != DataCenterLogic.DataCenterTypesIDE.requestTypeType.Item6 &&
                    shipPositionRequest.MessageType == DataCenterLogic.DataCenterTypesIDE.messageTypeType1.Item5)
                {
                    /************************************************/
                    var     pmgr  = new PricingManager();
                    decimal?price = pmgr.AddASPReprogrMessage(0, shipPositionRequest.DataUserRequestor, shipPositionRequest.DataUserProvider);
                    log.Info(string.Format("SendShipPositionRequest: Reprogramacion presunta par {0} => precio={1}", shipPositionRequest.MessageId, price));
                    /************************************************/
                }
            }

            //Guarda el mensaje en la base de datos
            using (var dao = new ShipPositionRequestDataAccess())
            {
                dao.Create(TypeHelper.Map2DB(shipPositionRequest), 1);
            }
            log.Info("ShipPositionRequest stored");
            return(shipPositionRequest.MessageId);
        }
 /// <summary>
 /// Retorna el periodo minimo de poleo para un barco determinado en minutos
 /// </summary>
 /// <param name="IMONum">ship IMO number</param>
 /// <param name="sprId">Id del Ship Position Request, que debe ser omitido para hacer la verificacion</param>
 /// <returns>Periodo minimo para el barco, o menor que cero si no hay nada configurado</returns>
 public int GetMinPeriodForShip(string IMONum, int sprId)
 {
     log.Debug("Obteniendo el periodo minimo del barco");
     using (ActiveShipPositionRequestDataAccess da = new ActiveShipPositionRequestDataAccess())
     {
         int minReqType = da.GetMinPeriodicRequestTypeForShip(IMONum, sprId);
         return(ShipPositionRequestHelper.GetMinutes(minReqType));
     }
 }
        /// <summary>
        /// Valida la combinacion de accesType y requestType para un ShipPositionRequest.
        /// Si hay algun error esta funcion envia un Receipt al requisitor, informandole el problema.
        /// </summary>
        /// <param name="shipPositionRequest">El mensaje ShipPositionRequest a ser analizado.</param>
        /// <returns>Verdadero, si el mensaje es valido, False otra cosa</returns>
        private bool ValidateShipPositionRequest(DataCenterLogic.DataCenterTypes.ShipPositionRequestType shipPositionRequest)
        {
            var ddpm       = new DDPVersionManager();
            var ddpVersion = ddpm.GetCurrentDDPVersion();

            log.Info("Validando SPR");
            #region Port state with time trigger could not be used with RequestType 1,7 or 9:
            //log.Debug("Port state with time trigger could not be used with RequestType 1,7 or 9");
            if (shipPositionRequest.AccessType == DataCenterLogic.DataCenterTypes.accessTypeType.Item3 &&
                (shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item1 ||
                 shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item7 ||
                 shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item9))
            {
                log.Error("Validacion erronea, se envia receipt");
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Invalid request parameters: Port could not be used with RequestType 1,7 or 9"));
                return(false);
            }
            #endregion
            #region Access type 0 only with message 4 and request 0
            //log.Debug("AccessType 0 (reset) solo valido con RT 0 y MS 4");
            if (shipPositionRequest.AccessType == DataCenterLogic.DataCenterTypes.accessTypeType.Item0 || shipPositionRequest.RequestType == requestTypeType.Item0)
            {
                //Invalid request parameters: AccessType 0 only valid with MessageType 4
                if (shipPositionRequest.MessageType != DataCenterLogic.DataCenterTypes.messageTypeType1.Item4)
                {
                    ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                               string.Format("Invalid request parameters: AccessType 0 only valid with MessageType 4"));
                    log.Error("Validacion erronea, se envia receipt");
                    return(false);
                }

                // Invalid request parameters: AccessType 0 only valid with RequestType 0
                if (shipPositionRequest.RequestType != DataCenterLogic.DataCenterTypes.requestTypeType.Item0 || shipPositionRequest.AccessType != DataCenterLogic.DataCenterTypes.accessTypeType.Item0)
                {
                    ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                               string.Format("Invalid request parameters: AccessType 0 only valid with RequestType 0"));
                    log.Info("Validacion erronea, se envia receipt");
                    return(false);
                }
            }
            #endregion
            #region REVISAR

            /*
             * log.Debug("Port State");
             * //Invalid request parameters: Port state and RequestTypes 1,7 and 9 only valid with AccessType 5
             * if( shipPositionRequest.ItemElementName == DataCenterLogic.DataCenterTypes.ItemChoiceType.Port ||
             *  shipPositionRequest.ItemElementName == DataCenterLogic.DataCenterTypes.ItemChoiceType.PortFacility
             *  && ( shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item1 ||
             *       shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item7 ||
             *       shipPositionRequest.RequestType == DataCenterLogic.DataCenterTypes.requestTypeType.Item9 )
             *  && shipPositionRequest.AccessType != DataCenterLogic.DataCenterTypes.accessTypeType.Item5 )
             * {
             * ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
             *  string.Format("Invalid request parameters: Port state and RequestTypes 1,7 and 9 only valid with AccessType 5"));
             *
             * return false;
             * } */
            #endregion
            #region Invalid request parameters: RequestTypes 1,7 and 9 are the only valid for MessageType 5
            //log.Debug("Si es mensaje de tipo 5 (Sar) RT solo puede ser 1 o 9");
            if (shipPositionRequest.MessageType == DataCenterLogic.DataCenterTypes.messageTypeType1.Item5 &&
                shipPositionRequest.RequestType != DataCenterLogic.DataCenterTypes.requestTypeType.Item1 &&
                shipPositionRequest.RequestType != DataCenterLogic.DataCenterTypes.requestTypeType.Item7 &&
                shipPositionRequest.RequestType != DataCenterLogic.DataCenterTypes.requestTypeType.Item9)
            {
                log.Error("Validacion erronea, se envia receipt");
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Invalid request parameters: RequestTypes 1,7 and 9 are the only valid for MessageType 5"));
                return(false);
            }
            #endregion
            #region Distance is only valid with access type 3
            log.Debug("Distance is only valid with access type 3");
            if (shipPositionRequest.Distance != "0" && shipPositionRequest.AccessType != DataCenterLogic.DataCenterTypes.accessTypeType.Item3)
            {
                log.Info("Validacion erronea, se envia receipt");
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Invalid request parameters: Distance is only valid with access type 3"));
                return(false);
            }
            #endregion
            #region Request Duration not valid for one time poll
            log.Debug("Request Duration not valid for one time poll");
            if (ShipPositionRequestHelper.IsOneTimePoll(shipPositionRequest.RequestType) &&
                (shipPositionRequest.RequestDuration != null && (shipPositionRequest.RequestDuration.startTimeSpecified == true || shipPositionRequest.RequestDuration.stopTimeSpecified == true)))
            {
                log.Info("Validacion erronea, se envia receipt");
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Invalid request parameters: Request Duration not valid for one time poll"));
                return(false);
            }
            #endregion
            #region Port State
            log.Debug("Validacion Para PortStates");
            if (shipPositionRequest.AccessType == DataCenterLogic.DataCenterTypes.accessTypeType.Item3 ||
                shipPositionRequest.AccessType == DataCenterLogic.DataCenterTypes.accessTypeType.Item5)
            {
                if (shipPositionRequest.ItemElementName != ItemChoiceType.Port && shipPositionRequest.ItemElementName != ItemChoiceType.PortFacility)
                {
                    log.Info("invalid fields for port state request, ItemElementName not port or portfacility");
                    ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                               string.Format("Invalid fields for port state request, ItemElementName not port or portfacility"));
                    return(false);
                }
                string portName = shipPositionRequest.Item.ToString();
                using (var pda = new PlaceDataAccess())
                {
                    if (pda.PortExists(portName, ddpVersion.Id) == false && pda.PortFacilityExists(portName, ddpVersion.Id) == false)
                    {
                        log.Info("invalid fields for port state request, Item" + shipPositionRequest.Item.ToString() + " doesn't exists");
                        ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                                   string.Format("invalid fields for port state request, Item" + shipPositionRequest.Item.ToString() + " doesn't exists")
                                                   );
                        return(false);
                    }
                }
            }
            #endregion
            #region AccessType2
            log.Debug("Validacion Para AccessType2");
            if (shipPositionRequest.AccessType == DataCenterLogic.DataCenterTypes.accessTypeType.Item2 &&
                shipPositionRequest.RequestType != requestTypeType.Item7)
            {
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Access type 2 only valid for archived data"));
                return(false);
            }
            #endregion
            //Verifica si existe el Data User que requiere la información
            var cgm = new ContractingGovermentManager();

            var contractingGoverment = cgm.GetContractingGovermentByLRITId(shipPositionRequest.DataUserRequestor, ddpVersion.Id);
            if (contractingGoverment == null)
            {
                string strError = string.Format("Specified LDU '{0}' does not exist", shipPositionRequest.DataUserRequestor);

                //Arma mensaje de Recibo
                DataCenterLogic.DataCenterTypes.ReceiptType receipt = new DataCenterLogic.DataCenterTypes.ReceiptType();

                var cmgr = new ConfigurationManager();

                receipt.DDPVersionNum = DDPVersionManager.currentDDP();
                receipt.Destination   = shipPositionRequest.DataUserRequestor;
                receipt.Message       = strError;
                receipt.MessageId     = MessageIdManager.Generate();
                receipt.MessageType   = DataCenterLogic.DataCenterTypes.messageTypeType3.Item7;
                receipt.Originator    = cmgr.Configuration.DataCenterID;
                receipt.ReceiptCode   = DataCenterLogic.DataCenterTypes.receiptCodeType.Item7;
                receipt.ReferenceId   = shipPositionRequest.MessageId;
                receipt.schemaVersion = decimal.Parse(cmgr.Configuration.SchemaVersion);
                receipt.test          = DataCenterLogic.DataCenterTypes.testType.Item1;
                receipt.TimeStamp     = DateTime.UtcNow;

                Message msgout = new Message(receipt);
                msgout.Label = "receipt";

                //Encola mensaje
                QueueManager.Instance().EnqueueOut(msgout);

                log.Error(strError);
                return(false);
            }

            log.Info("Validacion Ok");
            return(true);
        }
        /// <summary>
        /// Procesa un mensaje de tipo ShipPositionRequest
        /// </summary>
        /// <param name="msg">Mensaje de la cola con ShipPositionRequest en el body</param>
        public void ProcessShipPositionRequest(ShipPositionRequestType shipPositionRequest)
        {
            log.Info("Procesando ShipPositionRequest");
            try
            {
                if (ValidateShipPositionRequest(shipPositionRequest) != true)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Debug(ex);
            }

            Ship ship = null;

            using (var sdao = new ShipDataAccess())
            {
                log.Debug("Verifica si existe el barco en la base de datos");
                ship = sdao.getByIMONum(shipPositionRequest.IMONum);

                if (ship == null)
                {
                    //The ship is not in our system, send receipt CODE 7
                    log.Debug("el barco no esta en nuestro sistema, se envia recibo codigo 7");
                    ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                               string.Format("The ship {0} is not registered", shipPositionRequest.IMONum));
                    return;
                }
            }

            //Save ship position request to obtain id
            log.Debug("Guardando SPR en base de datos para obtener id");
            var shipPositionRequestDB = TypeHelper.Map2DB(shipPositionRequest);

            try
            {
                using (var spreq = new ShipPositionRequestDataAccess())
                {
                    spreq.Create(shipPositionRequestDB, 0);
                }
            }
            catch (Exception ex)
            {
                log.Error("Hubo un problema al guardar el mensaje");
                log.Debug(ex);
                return;
            }



            //log.Debug("Verificando si ya hay un request activo para el barco");

            //using (var asprDa = new ActiveShipPositionRequestDataAccess())
            //{
            //  List<ActiveShipPositionRequest> asprlist = asprDa.GetAll();
            //  foreach (ActiveShipPositionRequest aspr in asprlist)
            //  {
            //    if (shipPositionRequest.IMONum == aspr.ShipPositionRequest.IMONum &&
            //        Convert.ToInt32(shipPositionRequest.AccessType) == aspr.ShipPositionRequest.AccessType &&
            //        shipPositionRequest.DataUserRequestor == aspr.ShipPositionRequest.DataUserRequestor
            //       )
            //    {
            //      log.Debug("Se reemplaza request del barco:" + shipPositionRequest.IMONum);
            //      asprDa.Remove(aspr);
            //    }
            //  }
            //}

            #region Historics position report
            log.Debug("Verificando si es un request para datos archivados");
            if (ShipPositionRequestHelper.IsHistoricRequest(shipPositionRequest.RequestType))
            {
                ProcessHistoricShipPositionRequest(shipPositionRequest, ship);
                return;
            }
            #endregion
            #region Periodic position report
            log.Debug("Verificando si es un request periodico");
            if (ShipPositionRequestHelper.IsPeriodicRequest(shipPositionRequest.RequestType))
            {
                ActiveShipPositionRequestManager asprManager = new ActiveShipPositionRequestManager();
                asprManager.AddOrReplace(shipPositionRequestDB);
                log.Debug("ASPR REPLACED: Barco:" + shipPositionRequest.IMONum);
                log.Debug("Requestor: " + shipPositionRequest.DataUserRequestor);
                log.Debug("Access-Request Type: " + shipPositionRequest.AccessType + "-" + shipPositionRequest.RequestType);


                //Es periodico, y nos saca de la frecuencia estandard 6hs (RequestType==6), y no es SAR (msgtype==5)?
                //Debemos cobrarle la presunta reprogramacion PRICING
                if (shipPositionRequest.RequestType != requestTypeType.Item6 &&
                    shipPositionRequest.MessageType == messageTypeType1.Item5)
                {
                    /************************************************/
                    var     pmgr  = new PricingManager();
                    decimal?price = pmgr.AddASPReprogrMessage(0, shipPositionRequest.DataUserRequestor, shipPositionRequest.DataUserProvider);
                    log.Info(string.Format("ProcessShipPositionRequest: Reprogramacion presunta par {0} => precio={1}", shipPositionRequest.MessageId, price));
                    /************************************************/
                }

                return;
            }
            #endregion
            #region One Time poll
            log.Debug("Verificando si es un request para unica vez");
            if (ShipPositionRequestHelper.IsOneTimePoll(shipPositionRequest.RequestType))
            {
                ActiveShipPositionRequestManager asprManager = new ActiveShipPositionRequestManager();
                //Crea Active
                asprManager.AddNew(shipPositionRequestDB.Id);
                log.Debug("ASPR ADDED: Barco:" + shipPositionRequest.IMONum);
                log.Debug("Requestor: " + shipPositionRequest.DataUserRequestor);
                log.Debug("Access-Request Type: " + shipPositionRequest.AccessType + "-" + shipPositionRequest.RequestType);
            }
            #endregion
            #region Reset Request
            log.Debug("Verificando si es un request reset");
            if (ShipPositionRequestHelper.IsResetRequest(shipPositionRequest.RequestType))
            {
                var asprManager = new ActiveShipPositionRequestManager();
                asprManager.RemoveAllForRequestor(shipPositionRequestDB);
            }
            #endregion
            #region Stop Request
            log.Debug("Verificando si es un request Stop");
            if (ShipPositionRequestHelper.IsStopRequest(shipPositionRequest.RequestType))
            {
                ActiveShipPositionRequestManager asprManager = new ActiveShipPositionRequestManager();
                asprManager.AddOrReplace(shipPositionRequestDB);
                log.Debug("ASPR REPLACED: Barco:" + shipPositionRequest.IMONum);
                log.Debug("Requestor: " + shipPositionRequest.DataUserRequestor);
                log.Debug("Access-Request Type: " + shipPositionRequest.AccessType + "-" + shipPositionRequest.RequestType);
            }
            #endregion

            return;
        }
        /// <summary>
        /// Procesa un pedido de posicion historica.
        /// Los pedidos de posicion historicas son RequestType 7 y RequestType 9
        /// </summary>
        /// <param name="shipPositionRequest">Mensaje de ShipPositionRequest</param>
        /// <param name="ship">Barco al que se hace referencia</param>
        private void ProcessHistoricShipPositionRequest(DataCenterLogic.DataCenterTypes.ShipPositionRequestType shipPositionRequest, Ship ship)
        {
            log.Info("Procesando ShipPositionRequest Historico");
            log.Debug("Obteniendo CgId de LRITId");

            //Obtener Contracting goverment ID
            ContractingGovermentManager cgmgr = new ContractingGovermentManager();
            var ddpm       = new DDPVersionManager();
            var currentDDP = ddpm.GetCurrentDDPVersion();

            var contractingGoverment = cgmgr.GetContractingGovermentByLRITId(shipPositionRequest.DataUserRequestor, currentDDP.Id);

            if (contractingGoverment == null)
            {
                log.Info("CGID no válido se envia recibo");
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Invalid Contracting Government ID"));
                return;
            }

            ShipPositionManager spm = new ShipPositionManager();

            List <ShipPosition> positions = new List <ShipPosition>();

            log.Debug("Verificando si se pide ultima posicion");
            if (ShipPositionRequestHelper.IsMostRecentPosition(shipPositionRequest.RequestType))
            {
                ShipPosition pos = spm.GetLastShipPosition(shipPositionRequest.IMONum);
                if (pos != null)
                {
                    positions.Add(pos);
                }
            }
            else
            {
                log.Debug("No, se piden mas posiciones");
                log.Debug("Verificando titulacion");
                positions = spm.GetShipPositionHistory(shipPositionRequest.IMONum,
                                                       shipPositionRequest.RequestDuration.startTime,
                                                       shipPositionRequest.RequestDuration.stopTime);
            }

            if (positions.Count == 0)
            {
                log.Info("No hay posiciones");
                //The ship didnt send message in that period
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item6,
                                           string.Format("No archived data for the request"));
                return;
            }

            var configMgr = new ConfigurationManager();

            log.Debug("Procesando Posiciones");

            int not_entitled_count = 0;

            var ddpVersion = ddpm.DDPFromDate(DateTime.UtcNow);
            var cgOld      = cgmgr.GetContractingGovermentByLRITId(shipPositionRequest.DataUserRequestor, ddpVersion.Id);

            foreach (ShipPosition position in positions)
            {
                bool verifyWatersOf = true;
                if (shipPositionRequest.AccessType == accessTypeType.Item3 || shipPositionRequest.AccessType == accessTypeType.Item5)
                {
                    verifyWatersOf = false;
                }

                //Solo valido titulacion si el access type es distinto a 6 (SAR)
                if (shipPositionRequest.AccessType != accessTypeType.Item6 && (ddpVersion == null || cgmgr.IsEntitled(cgOld, position, ddpVersion, verifyWatersOf) == false))
                {
                    not_entitled_count++;
                    continue;
                }

                var sprm = new ShipPositionReportManager();

                if (ShipPositionRequestHelper.IsMostRecentPosition(shipPositionRequest.RequestType))
                {
                    sprm.SendReport(shipPositionRequest.DataUserRequestor, position, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.responseTypeType.Item4, DataCenterLogic.DataCenterTypesIDE.messageTypeType.Item3);
                }
                else
                {
                    if (shipPositionRequest.AccessType == accessTypeType.Item3 || shipPositionRequest.AccessType == accessTypeType.Item5)
                    {
                        sprm.SendReport(shipPositionRequest.DataUserRequestor, position, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.responseTypeType.Item3, DataCenterLogic.DataCenterTypesIDE.messageTypeType.Item1);
                    }
                    else if (shipPositionRequest.AccessType == accessTypeType.Item1)
                    {
                        sprm.SendReport(shipPositionRequest.DataUserRequestor, position, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.responseTypeType.Item1, DataCenterLogic.DataCenterTypesIDE.messageTypeType.Item1);
                    }
                    else if (shipPositionRequest.AccessType == accessTypeType.Item2)
                    {
                        sprm.SendReport(shipPositionRequest.DataUserRequestor, position, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.responseTypeType.Item2, DataCenterLogic.DataCenterTypesIDE.messageTypeType.Item1);
                    }
                    else
                    {
                        sprm.SendReport(shipPositionRequest.DataUserRequestor, position, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.responseTypeType.Item4, DataCenterLogic.DataCenterTypesIDE.messageTypeType.Item1);
                    }
                }

                log.Debug("Report Enviado");
            }

            //Hubo alguna posicion para la que no tuvo permiso
            if (not_entitled_count != 0)
            {
                ReceiptManager.SendReceipt(shipPositionRequest.DataUserRequestor, shipPositionRequest.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                           string.Format("Not entitled to recieve {0} positions", not_entitled_count));
                log.Debug("Receipt Enviado");
            }

            return;
        }
        /// <summary>
        /// Esta es la funcion principal del manejador de pedidos activos.
        /// Itera y procesa todos los pedidos activo.
        /// Es encargada de enviar (cuando se cumplan las condiciones) los mensajes a la cola de salida.
        /// </summary>
        public void Process(int hour, int mins) //hora: 0-23, minutes={0, 15, 30, 45}
        {
            //log.Info("Procesando Active Ship Position Request");
            using (var asprda = new ActiveShipPositionRequestDataAccess())
            {
                List <ActiveShipPositionRequest> asprlist = asprda.GetAll();
                foreach (ActiveShipPositionRequest aspr in asprlist)
                {
                    try
                    {
                        //Verifica si el tiempo de inicio ya paso
                        var      spm    = new ShipPositionManager();
                        var      spr    = aspr.ShipPositionRequest;
                        DateTime UtcNow = DateTime.UtcNow;
                        //log.Debug("Verificando estado del ASPR");
                        if (aspr.Status == 0)
                        {
                            //Condicion para activar el envio
                            if (RequestReadyToActive(aspr, UtcNow) == true)
                            {
                                if (TryReprog(spr) == true)
                                {
                                    asprda.Update(aspr.Id, 1, UtcNow);
                                    log.Debug("Reprogramado OK ==> estado ACTIVO");
                                }
                                else
                                {
                                    log.Error("Reprogramado ERROR");
                                }
                            }
                        }
                        else
                        {
                            //Status = 1
                            if (spr.StopTime != null && UtcNow >= spr.StopTime)
                            {
                                var IMONum         = aspr.ShipPositionRequest.IMONum;
                                var currentReqType = ShipPositionRequestHelper.GetMinutes(aspr.ShipPositionRequest.RequestType);
                                var minReqType     = GetMinPeriodForShip(IMONum, 0);

                                log.Debug("Se cumplio Stop Time del request eliminando request activo");

                                asprda.Remove(aspr);

                                //Verifica si el request tiene frecuencia distinta a la actual y reprograma si es necesario
                                //si el request caduco reprograma para que reporte cada 6 horas
                                log.Debug("Verificando si hay que reprogramar el equipo");
                                if (minReqType == currentReqType)
                                {
                                    using (var sda = new ShipDataAccess())
                                    {
                                        int newMinPeriod = GetMinPeriodForShip(IMONum, 0);

                                        if (newMinPeriod == -1)
                                        {
                                            newMinPeriod = 360;
                                        }

                                        //Reprogram ASP
                                        try
                                        {
                                            var aspman = new AspManager();
                                            aspman.CreatePollMessage(DateTime.UtcNow.AddMinutes(8), newMinPeriod, sda.getByIMONum(spr.IMONum), PollAction.Reprogram);
                                        }
                                        catch (Exception ex)
                                        {
                                            ShipManager.ChangeShipStatus(ShipStatus.Error, sda.getByIMONum(spr.IMONum));
                                            log.Error("Hubo un error en la reprogramacion del barco" + Environment.NewLine + Environment.NewLine + ex + Environment.NewLine + Environment.NewLine);
                                        }
                                    }
                                }
                                //log.Debug("ASPR " + aspr.Id + " REMOVED: Status: " + aspr.Status + " Barco:" + spr.IMONum);
                                //log.Debug("Requestor: " + spr.DataUserRequestor);
                                //log.Debug("Access-Request Type: " + spr.AccessType + "-" + spr.RequestType);
                                continue;
                            }

                            //log.Debug("Verificando si es request de unica vez");
                            //ONE TIME POLL
                            if (ShipPositionRequestHelper.IsOneTimePoll(spr.RequestType) == true)
                            {
                                //log.Debug("verificando si hay nueva posicion registrada");
                                ShipPosition spos = spm.GetLastShipPosition(spr.IMONum);
                                if (spos != null && spos.TimeStamp > aspr.LastTime)
                                {
                                    log.Debug("Nueva posicion con fecha > LastTime ... verificando titulacion");
                                    CheckEntitlementAndSendReportOrReceipt(spr, spos);
                                    asprda.Remove(aspr);
                                    ShipManager.ChangeShipStatus(ShipStatus.Ok, ShipManager.getByIMONum(spr.IMONum));
                                    log.Debug("ASPR " + aspr.Id + " REMOVED: Status: " + aspr.Status + " Barco:" + spr.IMONum);
                                    log.Debug("Requestor: " + spr.DataUserRequestor);
                                    log.Debug("Access-Request Type: " + spr.AccessType + "-" + spr.RequestType);
                                    continue;
                                }
                            }
                            //PERIODIC REPORT
                            else if (ShipPositionRequestHelper.IsPeriodicRequest(spr.RequestType) == true)
                            {
                                if (spr.RequestType == 2 && new int[] { 0, 15, 30, 45 }.Contains(mins) == false) //15 minute periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 3 && new int[] { 0, 30 }.Contains(mins) == false) //30 minute periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 4 && mins != 0) //1 hour periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 5 && (new int[] { 0, 3, 6, 9, 12, 15, 18, 21 }.Contains(hour) == false || mins != 0)) //3 hour periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 6 && (new int[] { 0, 6, 12, 18 }.Contains(hour) == false || mins != 0)) //6 hour periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 10 && (new int[] { 0, 12 }.Contains(hour) == false || mins != 0)) //12 hour periodic rate
                                {
                                    continue;
                                }
                                if (spr.RequestType == 11 && (hour != 0 || mins != 0)) //24 hour periodic rate
                                {
                                    continue;
                                }

                                int minutes = ShipPositionRequestHelper.GetMinutes(spr.RequestType);
                                log.Debug("Procesando requerimiento periodico de " + minutes + " minutos");

                                //TimeSpan delta = TimeSpan.FromMinutes(minutes);
                                //if (DCDebug == "true")
                                //  delta = TimeSpan.FromSeconds(minutes);
                                //if (UtcNow >= aspr.LastTime.AddSeconds(delta.TotalSeconds))
                                //{

                                //log.Debug("se cumplio el periodo");
                                ShipPosition spos = spm.GetLastShipPosition(spr.IMONum);
                                if (spos != null)
                                {
                                    //La ultima posicion para el barco es mas nueva que la ultima que mande?
                                    if (spos.TimeStamp > aspr.LastTime)
                                    {
                                        CheckEntitlementAndSendReportOrReceipt(spr, spos);
                                        ShipManager.ChangeShipStatus(ShipStatus.Ok, ShipManager.getByIMONum(spr.IMONum));
                                    }
                                    else
                                    if (spos.TimeStamp < aspr.LastTime)
                                    {
                                        //Feature-add: +30' estados del Active Ship Position Report
                                        log.Info("No new position since last report");
                                        ReceiptManager.SendReceipt(spr.DataUserRequestor, spr.MessageId, DataCenterLogic.DataCenterTypesIDE.receiptCodeType.Item7,
                                                                   string.Format("No new position since last report"));
                                        return;
                                    }
                                    asprda.Update(aspr.Id, 1, spos.TimeStamp);
                                    log.Debug("ASPR " + aspr.Id + " UPDATED: Status: " + aspr.Status + " Barco:" + spr.IMONum);
                                    log.Debug("Requestor: " + spr.DataUserRequestor);
                                    log.Debug("Access-Request Type: " + spr.AccessType + "-" + spr.RequestType);
                                }
                                else
                                {
                                    log.Error("Hubo un problema al verificar la titulacion y enviar la respuesta");
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Error procesando ASPR", ex);
                    }
                } //foreach
            }
        }
        public bool TryReprog(ShipPositionRequest spr)
        {
            bool reprogOk = true;

            /**************************************************************************************************/

            if (ShipPositionRequestHelper.IsOneTimePoll(spr.RequestType) == true)
            {
                var ship = ShipManager.getByIMONum(spr.IMONum);

                try
                {
                    var aspman = new AspManager();
                    // El 8 asegura un start frame posterior a la hora actual
                    aspman.CreatePollMessage(DateTime.UtcNow.AddMinutes(8), 0, ship, PollAction.Report);
                    log.Debug("Solitud Enviada (OneTimePoll) a IMO:" + ship.IMONum);
                }
                catch (Exception ex)
                {
                    log.Error("Error al enviar la solicitud" + Environment.NewLine + Environment.NewLine + ex + Environment.NewLine + Environment.NewLine);
                    reprogOk = false;
                }

                return(reprogOk);
            }

            /**************************************************************************************************/

            int requestPeriod = ShipPositionRequestHelper.GetMinutes(spr.RequestType);

            log.Debug("Request de " + requestPeriod + " minutos");

            //Get faster active request in minutes
            int minPeriod = GetMinPeriodForShip(spr.IMONum, spr.Id);

            log.Debug("Request activo mas frecuente del barco de " + minPeriod + " minutos");


            //See if we need to reprogram the equipment on ship
            log.Debug("Verificando si es necesario reprogramar el equipo");
            if (requestPeriod < minPeriod || minPeriod == -1)
            {
                using (var sdao = new ShipDataAccess())
                {
                    var ship = sdao.getByIMONum(spr.IMONum);
                    //Reprogram ASP
                    log.Debug("Se envia PollMessage");
                    try
                    {
                        var aspman = new AspManager();
                        // El 8 asegura un start frame posterior a la hora actual
                        aspman.CreatePollMessage(DateTime.UtcNow.AddMinutes(8), requestPeriod, ship, PollAction.Reprogram);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Hubo un problema al enviar la solicitud" + ex);
                        reprogOk = false;
                    }
                    finally
                    {
                    }
                }
            }

            return(reprogOk);
        }