diff --git a/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs b/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs index 2c0900405ea84929d92543e4583721efc438112c..ed9c9b9f6c8b71d3638a03850ca26a2910cf2976 100644 --- a/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs +++ b/VECTO3GUI2020/ViewModel/Implementation/JobListViewModel.cs @@ -734,7 +734,7 @@ namespace VECTO3GUI2020.ViewModel.Implementation get { return _openSourceFileCommand ?? (_openSourceFileCommand = - new RelayCommand(() => { ProcessHelper.OpenFile(_selectedJob?.DataSource.SourceFile); }, + new RelayCommand(() => { ProcessHelper.OpenFile(_selectedJob?.DataSource?.SourceFile); }, () => _selectedJob != null)); } } @@ -744,7 +744,7 @@ namespace VECTO3GUI2020.ViewModel.Implementation get { return _showSourceFileInExplorerCommand ?? (_showSourceFileInExplorerCommand = - new RelayCommand(() => { ProcessHelper.OpenFolder(_selectedJob?.DataSource.SourceFile); }, + new RelayCommand(() => { ProcessHelper.OpenFolder(_selectedJob?.DataSource?.SourceFile); }, () => _selectedJob != null)); } } diff --git a/VECTO3GUI2020/ViewModel/MultiStage/Implementation/CreateVifViewModel.cs b/VECTO3GUI2020/ViewModel/MultiStage/Implementation/CreateVifViewModel.cs index 8f36c515544fe5990e7c2a672e3479b704b14b3d..be39484ad8eceb640301fab7a4d66718965e1c84 100644 --- a/VECTO3GUI2020/ViewModel/MultiStage/Implementation/CreateVifViewModel.cs +++ b/VECTO3GUI2020/ViewModel/MultiStage/Implementation/CreateVifViewModel.cs @@ -1,9 +1,14 @@ using System; using System.Windows; using System.Windows.Input; +using InteractiveDataDisplay.WPF; using Microsoft.Toolkit.Mvvm.Input; +using Microsoft.WindowsAPICodePack.Shell.Interop; using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCore.InputData.FileIO.XML; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider; using TUGraz.VectoCore.Utils; using VECTO3GUI2020.Helper; using VECTO3GUI2020.ViewModel.Implementation.Common; @@ -14,17 +19,37 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation { public interface ICreateVifViewModel: IDocumentViewModel, IEditViewModel { - + bool LoadStageInput(string fileName); + bool LoadPrimaryInput(string fileName); + bool? ExemptedPrimary { get; set; } + bool? StageInputExempted { get; set; } + string PrimaryInputPath { get; set; } + string StageInputPath { get; set; } } public class CreateVifViewModel : ViewModelBase, ICreateVifViewModel { - private string _primaryInputFile; - private string _completedInputFile; + private string _primaryInputPath; + private string _stageInputPath; private readonly IDialogHelper _dialogHelper; private readonly IXMLInputDataReader _inputDataReader; - private static uint _newVifCounter = 0; + private bool? _exemptedPrimary; + + public bool? ExemptedPrimary + { + get => _exemptedPrimary; + set => SetProperty(ref _exemptedPrimary, value); + } + + private bool? _stageInputExempted; + + public bool? StageInputExempted + { + get => _stageInputExempted; + set => SetProperty(ref _stageInputExempted, value); + } + public CreateVifViewModel(IDialogHelper dialogHelper, IXMLInputDataReader inputDataReader) { _dialogHelper = dialogHelper; @@ -35,42 +60,131 @@ namespace VECTO3GUI2020.ViewModel.MultiStage.Implementation } - public string PrimaryInputFile + public string PrimaryInputPath { - get => _primaryInputFile; - set => SetProperty(ref _primaryInputFile, value); + get => _primaryInputPath; + set => SetProperty(ref _primaryInputPath, value); } - public string CompletedInputFile + public string StageInputPath { - get => _completedInputFile; - set => SetProperty(ref _completedInputFile, value); + get => _stageInputPath; + set => SetProperty(ref _stageInputPath, value); } public ICommand SelectCompletedInputFileCommand { get => _selectCompletedInputFileCommand ?? (_selectCompletedInputFileCommand = new RelayCommand(() => { var selectedFile = _dialogHelper.OpenXMLFileDialog(); - + LoadStageInput(selectedFile); + + })); } + public bool LoadStageInput(string fileName) + { + if (fileName == null) { + return false; + } + + var valid = true; + IVehicleDeclarationInputData vehicleInputData = null; + try { + var inputData = _inputDataReader.Create(fileName) as IDeclarationInputDataProvider; + vehicleInputData = inputData.JobInputData.Vehicle; + var type = vehicleInputData.GetType(); + valid = (inputData != null) && (vehicleInputData is XMLDeclarationInterimStageBusDataProviderV28) || (vehicleInputData is XMLDeclarationExemptedInterimStageBusDataProviderV28); + } catch (Exception e) { + valid = false; + } + + valid = valid && SetStageInputExempted(vehicleInputData.ExemptedVehicle); + + if (valid) { + StageInputPath = fileName; + } else { + _dialogHelper.ShowMessageBox("Invalid File", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + + + + + return valid; + } + public ICommand SelectPrimaryInputFileCommand { get => _selectPrimaryInputFileCommand ?? (_selectPrimaryInputFileCommand = new RelayCommand(() => { - PrimaryInputFile = _dialogHelper.OpenXMLFileDialog(); + var selectedFilePath = _dialogHelper.OpenXMLFileDialog(); + LoadPrimaryInput(selectedFilePath); })); } + public bool LoadPrimaryInput(string fileName) + { + if (fileName == null) { + return false; + } + + var valid = true; + IDeclarationInputDataProvider inputData = null; + try { + inputData = _inputDataReader.Create(fileName) as IDeclarationInputDataProvider; + valid = inputData != null && inputData.JobInputData.Vehicle.VehicleCategory.IsBus(); + } catch (Exception ex) { + valid = false; + } + + valid = valid && SetPrimaryInputExempted(inputData.JobInputData.Vehicle.ExemptedVehicle); - public bool CheckDocumentType(string fileName, XmlDocumentType expectedDocumentType) + + + if (valid) { + PrimaryInputPath = fileName; + } else { + _dialogHelper.ShowMessageBox("Invalid File", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + + + return valid; + } + + private bool SetPrimaryInputExempted(bool primaryExempted) { - var xElement = new System.Xml.XmlDocument(); - xElement.Load(fileName); + var valid = StageInputExempted == null || StageInputExempted == primaryExempted; + + if (valid) { + ExemptedPrimary = primaryExempted; + } else { + _dialogHelper.ShowMessageBox( + caption: "Error", + button: MessageBoxButton.OK, + icon: MessageBoxImage.Error, + messageBoxText: (primaryExempted + ? "Exempted primary vehicle not allowed for non-exempted interim/completed input" + : "Only exempted input allowed for selected interim/completed input")); + } + return valid; + } - var documentType = XMLHelper.GetDocumentType(xElement?.DocumentElement?.LocalName); - return documentType.HasValue && documentType.Value == expectedDocumentType; + private bool SetStageInputExempted(bool stageInputExempted) + { + var valid = ExemptedPrimary == null || ExemptedPrimary == stageInputExempted; + + if (valid) { + StageInputExempted = stageInputExempted; + } else { + _dialogHelper.ShowMessageBox( + caption: "Error", + button: MessageBoxButton.OK, + icon: MessageBoxImage.Error, + messageBoxText: (stageInputExempted + ? "Exempted interim/complete input is invalid for non-exempted primary vehicle" + : "Only exempted input allowed for selected primary vehicle")); + } + return valid; } diff --git a/VECTO3GUI2020/Views/Multistage/CreateVifView.xaml b/VECTO3GUI2020/Views/Multistage/CreateVifView.xaml index 7c5ba2d78d94c685004885c229009ccf2007e5e6..ffde33ef14cab9e53fc9485db807ad37af863d63 100644 --- a/VECTO3GUI2020/Views/Multistage/CreateVifView.xaml +++ b/VECTO3GUI2020/Views/Multistage/CreateVifView.xaml @@ -10,27 +10,41 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance implementation1:CreateVifViewModel}"> <Grid> - <DockPanel LastChildFill="False"> + <DockPanel Width="600" LastChildFill="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <StackPanel DockPanel.Dock="Top"> <Label Style="{DynamicResource LabelStyle1}">Select Primary Input</Label> - <customControls:FilePicker - Text="{Binding PrimaryInputFile}" - Command="{Binding SelectPrimaryInputFileCommand}"></customControls:FilePicker> - <Label Style="{DynamicResource LabelStyle1}">Select Stage Input</Label> - <customControls:FilePicker - Text="{Binding CompletedInputFile}" - Command="{Binding SelectCompletedInputFileCommand}"></customControls:FilePicker> + + <DockPanel HorizontalAlignment="Stretch"> + <Button DockPanel.Dock="Right" ContentTemplate="{StaticResource TrashIcon}" Width="30" Padding="4" Margin="2 4"> + + </Button> + <customControls:FilePicker DockPanel.Dock="Left" HorizontalAlignment="Stretch" + Text="{Binding PrimaryInputPath}" + Command="{Binding SelectPrimaryInputFileCommand}"/> + + </DockPanel> + <Label Style="{DynamicResource LabelStyle1}">Select Interim/Completed Input</Label> + <DockPanel HorizontalAlignment="Stretch"> + <Button DockPanel.Dock="Right" ContentTemplate="{StaticResource TrashIcon}" Width="30" Padding="4" Margin="2 4"> + + </Button> + <customControls:FilePicker DockPanel.Dock="Left" + Text="{Binding StageInputPath}" + Command="{Binding SelectCompletedInputFileCommand}"></customControls:FilePicker> + </DockPanel> + + </StackPanel> <DockPanel DockPanel.Dock="Bottom" LastChildFill="False"> - <UniformGrid DockPanel.Dock="Right" Rows="1" Width="300" HorizontalAlignment="Right"> - <Button Style="{StaticResource MultiStageButtonStyle1}">Create New VIF</Button> + <UniformGrid DockPanel.Dock="Right" Rows="1" Width="500" HorizontalAlignment="Right"> + <Button Style="{StaticResource MultiStageButtonStyle1}">Create new VIF</Button> + <Button Style="{StaticResource MultiStageButtonStyle1}">Save Job as ...</Button> + <Button Style="{StaticResource MultiStageButtonStyle1}">Save Job</Button> <Button Style="{StaticResource MultiStageButtonStyle1}" Command="{Binding CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">Close</Button> </UniformGrid> - </DockPanel> </DockPanel> - </Grid> </UserControl> diff --git a/Vecto3GUI2020Test/ViewModelTests/CreateVifViewModelTests.cs b/Vecto3GUI2020Test/ViewModelTests/CreateVifViewModelTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..abfd4f4ca9fcdf092bd449e442b33e08612ca204 --- /dev/null +++ b/Vecto3GUI2020Test/ViewModelTests/CreateVifViewModelTests.cs @@ -0,0 +1,137 @@ +using System.Diagnostics; +using Ninject; +using NUnit.Framework; +using VECTO3GUI2020.ViewModel.MultiStage.Implementation; + +namespace Vecto3GUI2020Test.ViewModelTests +{ + [TestFixture] + public class CreateVifViewModelTests : ViewModelTestBase + { + private ICreateVifViewModel _createVifViewModel; + + private const string testdata_2_6 = "XML\\XMLReaderDeclaration\\SchemaVersion2.6_Buses\\"; + private const string testdata_2_8 = "XML\\XMLReaderDeclaration\\SchemaVersion2.8\\"; + + private const string vecto_vehicle_primary_heavyBusSample = + testdata_2_6 + "vecto_vehicle-primary_heavyBus-sample.xml"; + + private const string vecto_vehicle_exempted_input_only_certain_entries = + "vecto_vehicle-exempted_input_only_certain_entries01-sample.xml"; + + private const string vecto_vehicle_primary_heavyBusExempted = testdata_2_6 + "exempted_primary_heavyBus.xml"; + + [SetUp] + public void SetUpCreateVif() + { + _createVifViewModel = _kernel.Get<ICreateVifViewModel>(); + } + + [TestCase(stageInputFullSample, TestName="InvalidPrimaryFile_StageInput")] + [TestCase(airdragLoadTestFile, TestName="InvalidPrimaryFile_Airdrag")] + [TestCase(consolidated_multiple_stages_airdrag, TestName = "InvalidPrimaryFile_VIF")] + [TestCase(vecto_vehicle_exempted_input_only_certain_entries, TestName="InvalidPrimaryFile_ExemptedStageInput")] + public void LoadInvalidPrimaryFile(string fileName) + { + var filePath = GetTestDataPath(fileName); + Assert.IsFalse(_createVifViewModel.LoadPrimaryInput(filePath)); + Assert.IsNull(_createVifViewModel.PrimaryInputPath); + Assert.IsNull(_createVifViewModel.ExemptedPrimary); + } + + + [TestCase(stageInputFullSample, TestName = "InvalidPrimaryFile_StageInput")] + [TestCase(airdragLoadTestFile, TestName = "InvalidPrimaryFile_Airdrag")] + [TestCase(consolidated_multiple_stages_airdrag, TestName = "InvalidPrimaryFile_VIF")] + public void LoadInvalidCompletedFile(string fileName) + { + var filePath = GetTestDataPath(fileName); + Assert.IsFalse(_createVifViewModel.LoadStageInput(filePath)); + Assert.IsNull(_createVifViewModel.StageInputExempted); + Assert.IsNull(_createVifViewModel.StageInputPath); + } + + [Ignore("incomplete")] + [Test] + public void LoadExemptedCompletedAndNonExemptedPrimary() + { + + } + + [Test] + public void LoadNonExemptedCompletedAndExemptedPrimary() + { + var exemptedPrimaryPath = GetTestDataPath(vecto_vehicle_primary_heavyBusExempted); + var stageInputPath = GetTestDataPath(stageInputFullSample); + + Assert.IsTrue(_createVifViewModel.LoadPrimaryInput(exemptedPrimaryPath)); + Assert.IsFalse(_createVifViewModel.LoadStageInput(stageInputPath)); + + + } + + + + [Test] + public void LoadValidPrimaryFile() + { + var filePath = GetTestDataPath(vecto_vehicle_primary_heavyBusSample); + Assert.IsTrue(_createVifViewModel.LoadPrimaryInput(filePath)); + Assert.AreEqual(filePath, _createVifViewModel.PrimaryInputPath); + + } + + [TestCase(stageInputFullSample, TestName = "ValidStageInput_fullStageInput")] + [TestCase(vecto_vehicle_exempted_input_only_certain_entries, TestName = "ValidStageInput_exemptedStageInput")] + public void LoadValidStageInputFile(string fileName) + { + var filePath = GetTestDataPath(fileName); + Assert.IsTrue(_createVifViewModel.LoadStageInput(filePath)); + Assert.AreEqual(filePath, _createVifViewModel.StageInputPath); + } + + [Test] + public void LoadValidNonExemptedFiles() + { + var primaryPath = GetTestDataPath(vecto_vehicle_primary_heavyBusSample); + var stageInputPath = GetTestDataPath(stageInputFullSample); + + Assert.IsTrue(_createVifViewModel.LoadPrimaryInput(primaryPath)); + Assert.IsTrue(_createVifViewModel.LoadStageInput(stageInputPath)); + + + } + + [Test] + public void LoadValidExemptedFiles() + { + + + } + + + //[TestCase(null, true, true, TestName="StageInputExempted_PrimaryNotSet1")] + //[TestCase(null, false, true, TestName = "StageInputExempted_PrimaryNotSet2")] + //[TestCase(true, true, true, TestName = "StageInputExempted_PrimaryExempted")] + //[TestCase(false, false, true, TestName = "StageInputExempted_PrimaryExempted2")] + //[TestCase(true, false, false, TestName = "StageInputExempted_PrimaryNonExempted")] + //[TestCase(false, true, false, TestName = "StageInputExempted_PrimaryNonExempted1")] + //public void SetStageInputExempted(bool? primaryExpected, bool stageInputExempted, bool expectedResult) + //{ + + //} + + //[TestCase(null, true, TestName = "PrimaryNotSet")] + //[TestCase(null, true, TestName = "PrimaryNotSet")] + //[TestCase(null, true, TestName = "PrimaryNotSet")] + //public void SetPrimaryInputExempted(bool? primaryExpected, bool stageInputExempted, bool expectedResult) + //{ + + //} + + + + + + } +} \ No newline at end of file