//AJOUT D'UNE PROPOSITION
        public async Task AddStatement(string observationId, ObservationCreationModel newStatement, string userId)
        {
            var existingObservation = await this.GetUserObservationbyId(observationId);

            if (existingObservation == null)
            {
                throw new BusinessException("Ce relevé n'existe pas");
            }

            var statement = new ObservationStatement();

            statement.Id = Guid.NewGuid().ToString("N");

            statement.UserId = userId;
            statement.Date   = DateTime.UtcNow;

            if (!string.IsNullOrEmpty(newStatement.Genus))
            {
                var s = (await this.SpeciesManager
                         .GetSpeciesByGenusAsync(newStatement.Genus))
                        .FirstOrDefault();
                statement.CommonGenus = s?.CommonGenus;
                statement.Genus       = s?.Genus;
            }

            if (!string.IsNullOrEmpty(newStatement.Species))
            {
                Species species = await this.SpeciesManager
                                  .GetSpeciesByNameAsync(newStatement.Species);

                statement.CommonSpeciesName = species?.CommonSpeciesName;
                statement.SpeciesName       = species.SpeciesName;
                statement.TelaBotanicaTaxon = species?.TelaBotanicaTaxon;
                statement.Expertise         = await this.CalculateUserSpeciesExpertise(userId, newStatement.Species);
            }

            if (existingObservation.ObservationStatements.Any(s => s.SpeciesName == statement.SpeciesName && s.Genus == statement.Genus))
            {
                throw new BusinessException("Une proposition identique existe déjà");
            }
            statement.TotalScore = statement.CalculateReliabilityStatement();
            statement.Order      = existingObservation.ObservationStatements.Count() + 1;

            statement.TotalScore = statement.CalculateReliabilityStatement();
            existingObservation.ObservationStatements.Add(statement);
            await this.DataContext.Observations.FindOneAndReplaceAsync(o => o.Id == existingObservation.Id, existingObservation);

            await this.CalculateKnowledegePoints(observationId, statement.Id, null);

            await this.CheckObservationIsIdentify(existingObservation.Id);

            User user = await this.UsersManager.SelectAsync(userId);

            var validator = await MissionValidatorFactory.GetValidator(this.ServiceProvider, user);

            if (validator != null)
            {
                await validator?.UpdateMissionProgression(existingObservation, statement, ActionType.CreateStatement);
            }
        }
        //POUR VALIDER UNE PROPOSITION EXISTANTE
        public async Task ConfirmStatement(string observationId, string statementId, string userId, bool isOnlyGenus)
        {
            var existingObservation = await this.GetUserObservationbyId(observationId);

            if (existingObservation == null)
            {
                throw new BusinessException("Ce relevé n'existe pas");
            }

            var statement = existingObservation.ObservationStatements.FirstOrDefault(x => x.Id == statementId);

            if (statement == null)
            {
                throw new BusinessException("Cette propostion n'existe pas");
            }

            if (existingObservation.ObservationStatements.Any(s => s.ObservationStatementConfirmations != null && s.ObservationStatementConfirmations.Any(c => c.UserId == userId)))
            {
                throw new BusinessException("Vous avez déjà validé une proposition pour ce relevé");
            }

            if (statement.ObservationStatementConfirmations == null)
            {
                statement.ObservationStatementConfirmations = new List <ObservationStatementConfirmation>();
            }

            var confirmation = new ObservationStatementConfirmation()
            {
                Id          = Guid.NewGuid().ToString("N"),
                Date        = DateTime.UtcNow,
                UserId      = userId,
                Expertise   = !isOnlyGenus ? await this.CalculateUserSpeciesExpertise(userId, statement.SpeciesName) : await this.CalculateUserGenusExpertise(userId, statement.Genus),
                IsOnlyGenus = isOnlyGenus
            };

            statement.ObservationStatementConfirmations.Add(confirmation);
            statement.TotalScore        = statement.CalculateReliabilityStatement();
            statement.TotalScoreSpecies = statement.CalculateSpeciesReliabilityStatement();
            await this.DataContext.Observations.FindOneAndReplaceAsync(o => o.Id == existingObservation.Id, existingObservation);

            await this.CalculateKnowledegePoints(observationId, statementId, confirmation.Id);

            await this.CheckObservationIsIdentify(existingObservation.Id);

            User user = await this.UsersManager.SelectAsync(userId);

            var validator = await MissionValidatorFactory.GetValidator(this.ServiceProvider, user);

            if (validator != null)
            {
                await validator?.UpdateMissionProgression(existingObservation, statement, ActionType.ConfirmStatement);
            }
        }
        public async Task <bool> UpdateMissionProgression([FromBody] ObservationCreationModel identification, string observationId)
        {
            User user = await this.UsersManager.SelectAsync(this.User.Identity.Name);

            Mission mission = await this.MissionsManager.GetMissionById(user.MissionProgress.MissionId);

            ObservationStatement os = new ObservationStatement
            {
                Genus       = identification.Genus,
                SpeciesName = identification.Species
            };
            var result    = false;
            var validator = await MissionValidatorFactory.GetValidator(this.ServiceProvider, user);

            if (validator != null)
            {
                result = await((IdentifyMissionValidator)validator).UpdateIdentifyMissionProgression(observationId, mission, os, user.OsmId);
            }
            return(result);
        }
        public async Task TimerIsEnd(string missionId)
        {
            User user = await this.UsersManager.SelectAsync(this.User.Identity.Name);

            var validator = await MissionValidatorFactory.GetValidator(this.ServiceProvider, user);

            var result = false;

            if (validator != null)
            {
                result = await validator.IsMissionValid(missionId, user);
            }

            if (result)
            {
                await this.UsersManager.EndCurrentMission(user.OsmId, user.MissionProgress.History);
            }
            else
            {
                await this.UsersManager.StartMissionAsync(null, user.OsmId);
            }
        }
        public async Task <Observation> CreateObservationAsync(string speciesName, string genus, string userid, Entities.Enums.Confident confident, double latitude, double longitude, string[] pictures, int?treeSize)
        {
            Observation newObservation = new Observation();

            try
            {
                newObservation.Id       = Guid.NewGuid().ToString("N");
                newObservation.Pictures = new List <string>();
                newObservation.Date     = DateTime.UtcNow;

                var statement = new ObservationStatement();
                statement.Id = Guid.NewGuid().ToString("N");
                User user = await this.UsersManager.SelectAsync(userid);

                newObservation.UserId                = user.OsmId;
                statement.UserId                     = user.OsmId;
                newObservation.AuthorName            = user?.Name;
                newObservation.ObservationStatements = new List <ObservationStatement>();

                newObservation.Coordinates = new GeoJsonPoint <GeoJson2DGeographicCoordinates>(new GeoJson2DGeographicCoordinates(longitude, latitude));
                newObservation.TreeSize    = (TreeSize?)treeSize;


                if (!string.IsNullOrEmpty(genus))
                {
                    var s = (await this.SpeciesManager
                             .GetSpeciesByGenusAsync(genus))
                            .FirstOrDefault();
                    statement.CommonGenus = s?.CommonGenus;
                    statement.Genus       = s?.Genus;
                    if (string.IsNullOrEmpty(speciesName))
                    {
                        statement.Expertise = await this.CalculateUserGenusExpertise(user.OsmId, statement.Genus);
                    }
                }

                if (!string.IsNullOrEmpty(speciesName))
                {
                    Species species = await this.SpeciesManager
                                      .GetSpeciesByNameAsync(speciesName);

                    statement.CommonSpeciesName = species?.CommonSpeciesName;
                    statement.SpeciesName       = species.SpeciesName;
                    statement.TelaBotanicaTaxon = species?.TelaBotanicaTaxon;
                    statement.Expertise         = await this.CalculateUserSpeciesExpertise(user.OsmId, speciesName);
                }
                statement.Date              = DateTime.UtcNow;
                statement.TotalScore        = statement.CalculateReliabilityStatement();
                statement.TotalScoreSpecies = statement.CalculateSpeciesReliabilityStatement();
                statement.Order             = 1;
                statement.Confident         = confident;
                newObservation.ObservationStatements.Add(statement);

                if (pictures != null)
                {
                    foreach (string picture in pictures?.Where(p => !string.IsNullOrEmpty(p)))
                    {
                        newObservation.Pictures.Add(await this.FileManager.SaveDataUrlAsFileAsync("observations", picture));
                    }
                }

                await this.DataContext.Observations.InsertOneAsync(newObservation);

                await this.AddExplorationPointsForNewObservation(newObservation);


                var validator = await MissionValidatorFactory.GetValidator(this.ServiceProvider, user);

                if (validator != null)
                {
                    await validator?.UpdateMissionProgression(newObservation, statement, ActionType.CreateObservation);
                }
            }
            catch (Exception e)
            {
                throw;
            }


            return(newObservation);
        }