/// <summary> /// Restituisce l'elenco delle azioni iniziali da aggiungere ad una richiesta. L'azione si /// limita alla composizione partenza, poiché ogni azione, all'atto della sua esecuzione, /// restituisce l'azione successiva da eseguire. /// </summary> /// <param name="richiesta">La richiesta alla quale aggiungere l'azione</param> /// <param name="parcoMezzi">Il parco mezzi sul quale insistono le richieste</param> /// <returns>L'elenco delle azioni da aggiungere</returns> private IEnumerable <IAzioneSuRichiesta> GetAzioni(RichiestaConParametri richiesta, ParcoMezzi parcoMezzi) { foreach (var parametriMezzo in richiesta.Parametri.ParametriMezzi) { yield return(new AggiungiComposizionePartenza( richiesta.Parametri.DataSegnalazione.AddSeconds(parametriMezzo.SecondiComposizione), richiesta, parametriMezzo, parcoMezzi)); } }
/// <summary> /// Genera le richieste secondo i parametri specificati nel costruttore della classe. /// </summary> /// <returns>Le richieste pseudo-random</returns> public IEnumerable <RichiestaAssistenza> Genera() { var fakerGeolocalizzazione = new Faker <Punto>() .StrictMode(true) .RuleFor(g => g.Latitudine, f => f.Address.Latitude()) .RuleFor(g => g.Longitudine, f => f.Address.Longitude()); //Questi Faker sono messi qui perchè contengono dei dati comuni a più proprietà Faker generaFaker = new Faker("it"); string indirizzo = generaFaker.Address.StreetAddress(); string NoteLocalita = generaFaker.Lorem.Sentence(); var zoneEmergenza = new[] { "Sisma Gotham City", "Alluvione Smallville", "Uragano Metropolis" }.ToList(); var fakerRichiesteAssistenza = new Faker <RichiestaAssistenza>("it") .StrictMode(true) .RuleFor(ra => ra.Id, f => f.UniqueIndex.ToString()) .RuleFor(ra => ra.Codice, f => f.IndexGlobal.ToString()) .RuleFor(ra => ra.CodiceUnitaOperativaCompetente, f => this.codiceUnitaOperativa) .RuleFor(ra => ra.Operatore, f => GeneraOperatore()) .RuleFor(ra => ra.CodiciUnitaOperativeAllertate, f => new HashSet <string> { this.codiceUnitaOperativa }) .RuleFor(ra => ra.Geolocalizzazione, f => GeneraCoordinateLocalita()) .RuleFor(ra => ra.Tipologie, f => this.GeneraTipologie()) .RuleFor(ra => ra.IstanteChiusura, f => null) .RuleFor(ra => ra.Indirizzo, f => indirizzo) .RuleFor(ra => ra.NoteLocalita, f => NoteLocalita) .RuleFor(ra => ra.ZoneEmergenza, f => f.Random.Float() < 0.001 ? new[] { f.Random.ListItem(zoneEmergenza) } : new string[0]) .RuleFor(ra => ra.Descrizione, f => f.Lorem.Sentence()) .RuleFor(ra => ra.Richiedente, f => new Richiedente(f.Name.FirstName(), f.Name.LastName(), f.Company.CompanyName(), f.Phone.Locale)) .RuleFor(ra => ra.NumeroRichiedente, f => f.Phone.PhoneNumber()) .RuleFor(ra => ra.CodiciUOCompetenza, f => new[] { f.Address.StateAbbr(), f.Address.StateAbbr(), f.Address.StateAbbr() }) .RuleFor(ra => ra.ListaPartenze, f => GeneraListaPartenze()) .RuleFor(ra => ra.Localita, f => new Localita(GeneraCoordinateLocalita(), indirizzo, NoteLocalita)) .RuleFor(ra => ra.Competenze, f => GeneraCompetenze()) .Ignore(ra => ra.Tags); var fakerTelefonata = new Faker <Telefonata>() .StrictMode(true) .RuleFor(t => t.CodiceSchedaContatto, f => f.Random.Replace("??###")) .RuleFor(t => t.CognomeChiamante, f => f.Name.LastName()) .RuleFor(t => t.Esito, f => "Avente seguito") //.RuleFor(t => t.Geolocalizzazione, f => fakerGeolocalizzazione.Generate()) .RuleFor(t => t.Motivazione, f => f.Lorem.Text()) .RuleFor(t => t.NomeChiamante, f => f.Name.FirstName()) .RuleFor(t => t.NotePrivate, f => f.Lorem.Sentence(10)) .RuleFor(t => t.NotePubbliche, f => f.Lorem.Sentence(10)) .RuleFor(t => t.NumeroTelefono, f => f.Phone.PhoneNumber()) .RuleFor(t => t.RagioneSociale, f => f.Company.CompanyName()); var numeroInterventi = (int)(this.dataMax.Subtract(this.dataMin).TotalDays *this.richiesteMedieAlGiorno); var richiesteConParametri = (from intervento in Enumerable.Range(1, numeroInterventi) let parametri = ParametriRichiesta.GetParametriFake( this.dataMin, this.dataMax, this.pesiNumeroMezziPartecipanti, new Gaussiana(this.mediaSecondiPartenzaDallaSedeSuccessive, this.mediaSecondiPartenzaDallaSedeSuccessive / 3), new Gaussiana(this.mediaSecondiArrivoSulPosto, this.mediaSecondiArrivoSulPosto / 3), new Gaussiana(this.mediaSecondiDurataIntervento, this.mediaSecondiDurataIntervento / 3), new Gaussiana(this.mediaSecondiRientroInSede, this.mediaSecondiRientroInSede / 3)) select new RichiestaConParametri { Richiesta = fakerRichiesteAssistenza.Generate(), Parametri = parametri, MezziAncoraDaInviare = parametri.ParametriMezzi.Length }).ToList(); // Aggiunta eventi telefonata in base ai parametri selezionati per ogni richiesta foreach (var r in richiesteConParametri) { var t = fakerTelefonata .CustomInstantiator(f => new Telefonata(r.Richiesta, f.Random.Replace("??###"), r.Parametri.DataSegnalazione, "FonteTelefonata")) .Generate(); } var parcoMezzi = new ParcoMezzi(this.numeroMezzi, this.codiceUnitaOperativa); var azioni = richiesteConParametri .SelectMany(r => this.GetAzioni(r, parcoMezzi)) .Where(a => a.IstantePrevisto <= this.dataMax) .OrderBy(a => a.IstantePrevisto) .ToList(); var dataSimulata = this.dataMin; var simulazioneTerminata = false; while (azioni.Any(a => !a.Eseguita()) && !simulazioneTerminata) { for (int i = 0; i < azioni.Count; i++) { simulazioneTerminata = true; if (!azioni[i].Eseguita()) { var azione = azioni[i]; if (azione.IstantePrevisto > dataSimulata) { dataSimulata = azione.IstantePrevisto; } azioni.AddRange(azione.Esegui(dataSimulata).Where(a => a.IstantePrevisto <= this.dataMax)); if (azione.Eseguita()) { simulazioneTerminata = false; break; } } } azioni = azioni .Where(a => !a.Eseguita()) .OrderBy(a => a.IstantePrevisto) .ToList(); } return(richiesteConParametri.Select(r => r.Richiesta)); }