From b91303457b841ca84ae63ae70a036365daafb37b Mon Sep 17 00:00:00 2001
From: "harald.martini@student.tugraz.at" <harald.martini@student.tugraz.at>
Date: Mon, 5 Jul 2021 11:19:01 +0200
Subject: [PATCH] Check if multistage input is complete in CanBeSimulated
 property, simulate VIF after saving if input is complete

---
 .../Implementation/JobListViewModel.cs        | 47 ++++++++++++-------
 .../ViewModel/Interfaces/IJobListViewModel.cs |  2 +-
 .../MultistageJobViewModel_v0_1.cs            | 25 ++++++----
 .../ViewModelTests/ExemptedTests.cs           |  6 +--
 .../ViewModelTests/JobListViewModelTests.cs   | 14 ++----
 Vecto3GUI2020Test/ViewModelTests/VIFTests.cs  | 39 +++++++++++++--
 6 files changed, 89 insertions(+), 44 deletions(-)

diff --git a/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs b/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs
index a1aecd628f..f62a0431b1 100644
--- a/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs
+++ b/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs
@@ -237,7 +237,9 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 						Jobs.Add(result);
 					}
 					if (runSimulationAfterAdding) {
-						await RunSimulationExecute(result);
+						if (result.CanBeSimulated) {
+							await RunSimulationExecute(result);
+						}
 					}
 
 					return result;
@@ -318,9 +320,9 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 			set
 			{
 				SetProperty(ref _simulationRunning, value);
-				SimulationCommand.NotifyCanExecuteChanged();
+				SimulationCommand?.NotifyCanExecuteChanged();
 				
-				(_cancelSimulationCommand as RelayCommand).NotifyCanExecuteChanged();
+				(_cancelSimulationCommand as RelayCommand)?.NotifyCanExecuteChanged();
 			}
 		}
 
@@ -333,17 +335,27 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 
 		public async Task RunSimulationExecute(IDocumentViewModel jobToSimulate = null)
 		{
+			if (SimulationRunning) {
+				return;
+			}
 			SimulationRunning = true;
-			await Task.Run(() => RunSimulationAsync(_cancellationTokenSource.Token,
-				outputMessages: _outputMessage, 
-				progress: _progress, 
-				status: _status,
-				jobToSimulate: jobToSimulate));
-
-			_cancellationTokenSource = new CancellationTokenSource();
-			_simulationLoggingEnabled = true;
-			SimulationRunning = false;
-			_outputViewModel.Progress = 0;
+			try {
+				await Task.Run(() => RunSimulationAsync(_cancellationTokenSource.Token,
+					outputMessages: _outputMessage,
+					progress: _progress,
+					status: _status,
+					jobToSimulate: jobToSimulate));
+			} catch (Exception ex) {
+				_outputViewModel.AddMessage(new MessageEntry() {
+					Type = MessageType.ErrorMessage,
+					Message = ex.Message
+				});
+			} finally {
+				_cancellationTokenSource = new CancellationTokenSource();
+				_simulationLoggingEnabled = true;
+				SimulationRunning = false;
+				_outputViewModel.Progress = 0;
+			}
 		}
 
 		private async Task RunSimulationAsync(CancellationToken ct, 
@@ -484,7 +496,7 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 							outputMessages.Report(new MessageEntry()
 							{
 								Message = "Simulation canceled",
-								Type = MessageType.StatusMessage,
+								Type = MessageType.InfoMessage,
 							});
 							return;
 						}
@@ -557,7 +569,7 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 					outputMessages.Report(new MessageEntry()
 					{
 						Message = "Simulation canceled",
-						Type = MessageType.StatusMessage,
+						Type = MessageType.InfoMessage,
 					});
 
 					return;
@@ -624,7 +636,6 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 								Type = MessageType.StatusMessage,
 								Message = string.Format(
 									"{2} for '{0}' written to {1}", Path.GetFileName(jobEntry.DataSource.SourceFile), entry.Key, entry.Value),
-								//Link = "<XML>" + entry.Key
 								Link = entry.Key
 							});
 					}
@@ -638,7 +649,6 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 					Type = MessageType.StatusMessage,
 					Message = string.Format("Sum file written to {0}", sumFileWriter.SumFileName),
 					Link = sumFileWriter.SumFileName,
-					//Link = "<CSV>" + sumFileWriter.SumFileName
 				});
 			}
 
@@ -747,11 +757,12 @@ namespace VECTO3GUI2020.ViewModel.Implementation
 				return _cancelSimulationCommand ?? (_cancelSimulationCommand = new RelayCommand(() => {
 						_outputViewModel.AddMessage(new MessageEntry() {
 							Message="Canceling Simulation",
-							Type=MessageType.StatusMessage,
+							Type=MessageType.InfoMessage,
 						});
 						_simulationLoggingEnabled = false;
 						_cancellationTokenSource.Cancel();
 						
+						
 					},
 					() => SimulationRunning));
 			}            
diff --git a/VECTO3GUI2020/ViewModel/Interfaces/IJobListViewModel.cs b/VECTO3GUI2020/ViewModel/Interfaces/IJobListViewModel.cs
index cd1be30f07..8bb869180d 100644
--- a/VECTO3GUI2020/ViewModel/Interfaces/IJobListViewModel.cs
+++ b/VECTO3GUI2020/ViewModel/Interfaces/IJobListViewModel.cs
@@ -10,7 +10,7 @@ namespace VECTO3GUI2020.ViewModel.Interfaces
     {
 		ObservableCollection<IDocumentViewModel> Jobs { get; }
 		ICommand NewManufacturingStageFileCommand { get; }
-		Task<IDocumentViewModel> AddJobAsync(string fileName, bool runSimulationAfterAdding);
+		Task<IDocumentViewModel> AddJobAsync(string fileName, bool runSimulationAfterAdding = false);
 		void AddJob(IDocumentViewModel jobToAdd);
 	}
 }
diff --git a/VECTO3GUI2020/ViewModel/MultiStage/Implementation/MultistageJobViewModel_v0_1.cs b/VECTO3GUI2020/ViewModel/MultiStage/Implementation/MultistageJobViewModel_v0_1.cs
index ab4ca8ad98..2522d6bbd1 100644
--- a/VECTO3GUI2020/ViewModel/MultiStage/Implementation/MultistageJobViewModel_v0_1.cs
+++ b/VECTO3GUI2020/ViewModel/MultiStage/Implementation/MultistageJobViewModel_v0_1.cs
@@ -44,6 +44,13 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 		IManufacturingStageViewModel ManufacturingStageViewModel { get; }
 		bool Exempted { get; }
 		ICommand LoadVehicleDataCommand { get; }
+
+		/// <summary>
+		/// Creates a new VIF file
+		/// </summary>
+		/// <param name="outputFile"></param>
+		/// <returns>Name of the created File</returns>
+		string SaveVif(string outputFile);
 	}
 
 
@@ -78,6 +85,7 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 			_primaryVehicle = _jobInputData.PrimaryVehicle;
 			_dialogHelper = multistageDependencies.DialogHelperLazy;
 			_inputDataReader = inputDataReader;
+			_inputComplete = inputData.JobInputData.InputComplete;
 
 			_exempted = PrimaryVehicle.Vehicle.ExemptedVehicle;
 
@@ -133,11 +141,6 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 								errorMessage += auxiliariesErrorInfo.Error.Replace(",", "\n");
 							}
 
-
-							//_dialogHelper.Value.ShowMessageBox("Vehicle\n" + string.Join("\n", vehicleViewModel.Errors.Values) 
-							//												+ (vehicleViewModel.MultistageAuxiliariesViewModel.HasErrors ? ("\nAuxiliaries\n" + string.Join("\n", vehicleViewModel.MultistageAuxiliariesViewModel.Errors.Values)) : ""),
-								//"Error");
-
 							_dialogHelper.Value.ShowMessageBox(errorMessage, "Error", MessageBoxButton.OK,
 									MessageBoxImage.Error);
 							return;
@@ -179,7 +182,6 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 		/// <param name="writer"></param>
 		/// <param name="dialogHelper"></param>
 		/// <returns>Name of the created file</returns>
-
 		private string SaveVif(IMultistageVIFInputData vifData, string outputFile,
 			FileOutputVIFWriter writer = null, IDialogHelper dialogHelper = null)
 		{
@@ -217,7 +219,10 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 					} else {
 						dialogHelper?.ShowMessageBox($"Written to {writer.XMLMultistageReportFileName}", "Info",
 							MessageBoxButton.OK, MessageBoxImage.Information);
-						_jobListViewModel.AddJobAsync(writer.XMLMultistageReportFileName, true);
+
+						var runSimulation = vifData.VehicleInputData.VehicleDeclarationType ==
+											VehicleDeclarationType.final;
+						_jobListViewModel.AddJobAsync(writer.XMLMultistageReportFileName, runSimulation);
 
 						Debug.WriteLine($"Written to {writer.XMLMultistageReportFileName}");
 						return writer.XMLMultistageReportFileName;
@@ -278,8 +283,10 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation
 		{
 			get
 			{
-				return true;
-			} set => throw new NotImplementedException();
+				return InputComplete && _inputData.JobInputData.ConsolidateManufacturingStage.Vehicle.VehicleDeclarationType ==
+					VehicleDeclarationType.final;
+			}
+			set => throw new NotImplementedException();
 		}
 
 		#endregion
diff --git a/Vecto3GUI2020Test/ViewModelTests/ExemptedTests.cs b/Vecto3GUI2020Test/ViewModelTests/ExemptedTests.cs
index 772f5e0ded..7338aaa868 100644
--- a/Vecto3GUI2020Test/ViewModelTests/ExemptedTests.cs
+++ b/Vecto3GUI2020Test/ViewModelTests/ExemptedTests.cs
@@ -145,8 +145,8 @@ namespace Vecto3GUI2020Test.ViewModelTests
 
 			//Check that file was added to JobList
 			var jobListVm = _kernel.Get<IJobListViewModel>() as JobListViewModel;
-			Assert.AreEqual(1, jobListVm.Jobs.Count);
-			Assert.AreEqual(result, jobListVm.Jobs[0].DataSource.SourceFile);
+			Assert.AreEqual(2, jobListVm.Jobs.Count);
+			Assert.AreEqual(result, jobListVm.Jobs[1].DataSource.SourceFile);
 
 			var inputDataProvider = _testHelper.GetInputDataProvider(result) as IMultistageBusInputDataProvider;
 			Assert.NotNull(inputDataProvider);
@@ -170,7 +170,7 @@ namespace Vecto3GUI2020Test.ViewModelTests
 
 
 			Write("Starting simulation ...");
-			jobListVm.Jobs[0].Selected = true;
+			jobListVm.Jobs[1].Selected = true;
 			await jobListVm.RunSimulationExecute();
 
 
diff --git a/Vecto3GUI2020Test/ViewModelTests/JobListViewModelTests.cs b/Vecto3GUI2020Test/ViewModelTests/JobListViewModelTests.cs
index da049e7ca2..de49f8a9ef 100644
--- a/Vecto3GUI2020Test/ViewModelTests/JobListViewModelTests.cs
+++ b/Vecto3GUI2020Test/ViewModelTests/JobListViewModelTests.cs
@@ -103,22 +103,16 @@ namespace Vecto3GUI2020Test.ViewModelTests
 			jobListViewModel.Jobs[0].Selected = true;
 
 
-			jobListViewModel.RunSimulationExecute();
-
-
-
 			//Simulate for a while
 			var outputVm = _kernel.Get<IOutputViewModel>(); // SINGLETON
-			var constraint = Is.True.After(delayInMilliseconds: 100000, pollingInterval: 100);
-			Assert.That(() => outputVm.Progress >= 25, constraint);
-			
-
-
+			var simulationTask = jobListViewModel.RunSimulationExecute();
+			Assert.That(() => outputVm.Progress, Is.GreaterThanOrEqualTo(25).After(1 * 60 * 1000, 1),
+				() => $"Simulation reached {outputVm.Progress}%");
 
 			TestContext.Write("Canceling Simulation ... ");
 			Assert.IsTrue(jobListViewModel.SimulationRunning);
 			jobListViewModel.CancelSimulation.Execute(null);
-			Assert.That(() => jobListViewModel.SimulationRunning == false, constraint);
+			Assert.That(() => jobListViewModel.SimulationRunning, Is.False.After(20*1000, 50) );
 			TestContext.WriteLine("Done!");
 
 			watch.Stop();
diff --git a/Vecto3GUI2020Test/ViewModelTests/VIFTests.cs b/Vecto3GUI2020Test/ViewModelTests/VIFTests.cs
index 6ab3900239..7782639ece 100644
--- a/Vecto3GUI2020Test/ViewModelTests/VIFTests.cs
+++ b/Vecto3GUI2020Test/ViewModelTests/VIFTests.cs
@@ -10,7 +10,8 @@ using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.OutputData.FileIO;
 using TUGraz.VectoCore.Utils;
 using VECTO3GUI2020.Helper;
-
+using VECTO3GUI2020.ViewModel.Implementation;
+using VECTO3GUI2020.ViewModel.Interfaces;
 using VECTO3GUI2020.ViewModel.MultiStage.Implementation;
 
 namespace Vecto3GUI2020Test.ViewModelTests
@@ -18,6 +19,8 @@ namespace Vecto3GUI2020Test.ViewModelTests
 	public class VIFTests : ViewModelTestBase
 	{
 
+		public const string _finalVifReport4 = "final.VIF_Report_4.xml";
+
 		[Test]
 		public void loadPrimaryVehicleOnlyAndCreateNewVIF()
 		{
@@ -26,7 +29,7 @@ namespace Vecto3GUI2020Test.ViewModelTests
 
 			Assert.AreEqual(2, stage);
 
-			//Set Necessary Fields
+			//Set Mandatory Fields
 			var vehicle =
 				multistagevm.ManufacturingStageViewModel.Vehicle as InterimStageBusVehicleViewModel_v2_8;
 			vehicle.ManufacturerAddress = "Address";
@@ -70,9 +73,39 @@ namespace Vecto3GUI2020Test.ViewModelTests
 
 		}
 
+		[TestCase(true, TestName="With Airdrag Component")]
+		[TestCase(false, TestName="Without Airdrag Component")]
+		public void CreateCompletedFinalVIFWidthAirdrag(bool loadAirdrag)
+		{
+			var multistagevm = loadFile(_finalVifReport4);
 
+			var VehicleViewModel = multistagevm.MultiStageJobViewModel.ManufacturingStageViewModel.VehicleViewModel as InterimStageBusVehicleViewModel_v2_8;
 
-		[Test]
+			VehicleViewModel.Manufacturer = "Manufacturer";
+            VehicleViewModel.ManufacturerAddress = "Manufacturer Address";
+			VehicleViewModel.VIN = "1234567";
+			VehicleViewModel.Model = "asdf";
+			VehicleViewModel.AirdragModifiedEnum = AIRDRAGMODIFIED.FALSE;
+			VehicleViewModel.VehicleDeclarationType = VehicleDeclarationType.final;
+
+
+			if (loadAirdrag) {
+				Assert.IsTrue(VehicleViewModel.MultistageAirdragViewModel.LoadAirdragFile(GetFullPath(airdragLoadTestFile)));
+			}
+		
+			var resultFile = multistagevm.MultiStageJobViewModel.SaveVif(GetFullPath(
+				"completed_final" + ".xml"));
+
+			
+			var jobListVm = _kernel.Get<IJobListViewModel>();
+			Assert.That(() => jobListVm.Jobs.Count, Is.EqualTo(2));
+
+			Assert.IsTrue(jobListVm.Jobs[1].CanBeSimulated);
+		}
+
+
+
+        [Test]
 		public void CreateVifWrongDecimal()
 		{
 			var multistagevm = loadFile(primary_vehicle_only).MultiStageJobViewModel as MultiStageJobViewModel_v0_1;
-- 
GitLab