diff --git a/Enums/PeriodType.cs b/Enums/PeriodType.cs index 13b1a8b..668e3bd 100644 --- a/Enums/PeriodType.cs +++ b/Enums/PeriodType.cs @@ -1,4 +1,8 @@ -namespace GazpromApp.Enums; +using System; +using System.Globalization; +using Avalonia.Data.Converters; + +namespace GazpromApp.Enums; public enum PeriodType { @@ -35,4 +39,21 @@ public static class PeriodTypeExtensions _ => PeriodType.Unknown }; } +} + +public class PeriodConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is PeriodType periodType) + return periodType.ToDescription(); + return false; + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is string periodType) + return periodType.ToPeriodType(); + return false; + } } \ No newline at end of file diff --git a/Models/Inspection.cs b/Models/Inspection.cs index 8d3996c..6db5585 100644 --- a/Models/Inspection.cs +++ b/Models/Inspection.cs @@ -12,7 +12,7 @@ public class Inspection [Required] public string Name { get; set; } = string.Empty; [Required] - public DateTime InspectionDate { get; set; } + public DateTimeOffset InspectionDate { get; set; } [Required] public string PeriodType { get; set; } = string.Empty; [Required] diff --git a/Utils/DateCalculator.cs b/Utils/DateCalculator.cs new file mode 100644 index 0000000..e934585 --- /dev/null +++ b/Utils/DateCalculator.cs @@ -0,0 +1,47 @@ +using System; +using System.Linq; +using GazpromApp.Enums; +using GazpromApp.Models; +using GazpromApp.ViewModels; + +namespace GazpromApp.Utils; + +public static class DateCalculator +{ + public static DateTime[] GetNearestDates(this InspectionViewModel inspection) + { + var today = DateTime.Today; + + var firstFutureDate = AddPeriod(inspection.InspectionDate.DateTime, inspection.PeriodType, inspection.PeriodValue); + + if (firstFutureDate > today) + { + return [inspection.InspectionDate.DateTime, firstFutureDate]; + } + + DateTime futureDate = Enumerable.Range(1, int.MaxValue) + .Select(i => AddPeriod(inspection.InspectionDate.DateTime, inspection.PeriodType, inspection.PeriodValue * i)) + .First(d => d > today); + + DateTime pastDate = SubtractPeriod(futureDate, inspection.PeriodType, inspection.PeriodValue); + + return [pastDate, futureDate]; + } + + private static DateTime AddPeriod(DateTime date, PeriodType periodType, float value) + { + return periodType switch + { + PeriodType.Day => date.AddDays(value), + PeriodType.Week => date.AddDays(value * 7), + PeriodType.Month => date.AddDays(value * 30.436875), // Avg days/month + PeriodType.Year => date.AddDays(value * 365.2425), // Avg days/year (incl. leap years) + _ => throw new ArgumentException("Invalid period type") + }; + } + + private static DateTime SubtractPeriod(DateTime date, PeriodType periodType, float value) + { + return AddPeriod(date, periodType, -value); + } +} \ No newline at end of file diff --git a/ViewModels/Basic/EquipmentViewModel.cs b/ViewModels/Basic/EquipmentViewModel.cs index 36e8869..1882c1b 100644 --- a/ViewModels/Basic/EquipmentViewModel.cs +++ b/ViewModels/Basic/EquipmentViewModel.cs @@ -1,10 +1,10 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; -using System.IO; using System.Linq; -using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using GazpromApp.Models; +using GazpromApp.Utils; namespace GazpromApp.ViewModels; @@ -33,7 +33,7 @@ public partial class EquipmentViewModel : ViewModelBase Image = null; Properties = []; Inspections = []; - NearestInspection = DateTime.Now.ToLongDateString(); + NearestInspection = "Нету инспекций"; } public EquipmentViewModel(Equipment equipment) @@ -42,8 +42,22 @@ public partial class EquipmentViewModel : ViewModelBase Description = equipment.Description; Image = new ImageViewModel(equipment.Image ?? new Image()); Properties = new ObservableCollection(equipment.Properties.Select(e => new PropertyViewModel(e))); - Inspections = new ObservableCollection(equipment.Inspections.Select(e => new InspectionViewModel(e))); - NearestInspection = DateTime.Now.ToLongDateString(); + + List times = (equipment.Inspections.Select(e => new InspectionViewModel(e))) + .Select(e => e.GetNearestDates()) + .ToList(); + + Inspections = new ObservableCollection(equipment.Inspections + .Select((e, i) => new InspectionViewModel(e) { InspectionDate = times[i][0] })); + + NearestInspection = times + .Where(e => e[1] > DateTime.Now) + .Select(e => e[1]) + .OrderBy(e => e) + .FirstOrDefault() + .ToLongDateString(); + + if (Inspections.Count == 0) NearestInspection = "Нету инспекций"; } public Equipment GetEquipment() @@ -53,6 +67,7 @@ public partial class EquipmentViewModel : ViewModelBase Name = Name, Description = Description, Image = Image?.GetImage(), + Inspections = Inspections.Select(e => e.GetInspection()).ToList(), }; } } \ No newline at end of file diff --git a/ViewModels/Basic/InspectionViewModel.cs b/ViewModels/Basic/InspectionViewModel.cs index c2dfc32..46c186c 100644 --- a/ViewModels/Basic/InspectionViewModel.cs +++ b/ViewModels/Basic/InspectionViewModel.cs @@ -1,16 +1,50 @@ -using GazpromApp.Models; +using System; +using CommunityToolkit.Mvvm.ComponentModel; +using GazpromApp.Enums; +using GazpromApp.Models; namespace GazpromApp.ViewModels; public partial class InspectionViewModel : ViewModelBase { + [ObservableProperty] + private string _name; + [ObservableProperty] + private DateTimeOffset _inspectionDate; + [ObservableProperty] + private PeriodType _periodType; + [ObservableProperty] + private float _periodValue; + + // Visual properties + + [ObservableProperty] + private bool _isEditing = false; + public InspectionViewModel() { - + Name = string.Empty; + InspectionDate = DateTimeOffset.Now; + PeriodType = 0; + PeriodValue = 1; } public InspectionViewModel(Inspection inspection) { - + Name = inspection.Name; + InspectionDate = inspection.InspectionDate; + PeriodType = inspection.PeriodType.ToPeriodType(); + PeriodValue = inspection.PeriodValue; + } + + public Inspection GetInspection() + { + return new Inspection() + { + Name = Name, + InspectionDate = InspectionDate, + PeriodType = PeriodType.ToDescription(), + PeriodValue = PeriodValue + }; } } \ No newline at end of file diff --git a/ViewModels/EditEquipmentDialogViewModel.cs b/ViewModels/EditEquipmentDialogViewModel.cs index 85a7013..0429709 100644 --- a/ViewModels/EditEquipmentDialogViewModel.cs +++ b/ViewModels/EditEquipmentDialogViewModel.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using System.Threading.Tasks; using System.Web; using Avalonia.Controls; @@ -33,6 +35,8 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase [ObservableProperty] private ImageViewModel? _image; + public ObservableCollection Inspections { get; set; } + [RelayCommand] private void EditName() { @@ -90,6 +94,27 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase Image = null; IsImageSelected = false; } + + [RelayCommand] + private void AddInspection() + { + Inspections.Add(new InspectionViewModel { Name = "Название инспекции", InspectionDate = DateTimeOffset.Now, PeriodValue = 1, PeriodType = PeriodType.Day }); + } + + [RelayCommand] + private void EditInspection(InspectionViewModel inspection) + { + foreach (var item in Inspections) + if (item != inspection) + item.IsEditing = false; + inspection.IsEditing = !inspection.IsEditing; + } + + [RelayCommand] + private void DeleteInspection(InspectionViewModel inspection) + { + Inspections.Remove(inspection); + } private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name); @@ -102,6 +127,7 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase Name = Name, Description = Description, Image = Image?.GetImage(), + Inspections = Inspections.Select(e => e.GetInspection()).ToList(), Properties = [], }; WeakReferenceMessenger.Default.Send(new EditEquipmentDone(new EquipmentViewModel(equipment))); @@ -124,15 +150,20 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase private readonly EquipmentViewModel _equipment; + public PeriodType[] AllPeriods => Enum.GetValues() + .Where(p => p != PeriodType.Unknown) + .ToArray(); + public EditEquipmentDialogViewModel() { - Name = ""; - Description = ""; + Name = "Testing"; + Description = "Testing"; Image = null; + Inspections = []; IsImageSelected = false; - _equipment = new EquipmentViewModel(new Equipment()); + _equipment = new EquipmentViewModel(); } public EditEquipmentDialogViewModel(EquipmentViewModel equipment) @@ -140,6 +171,7 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase Name = equipment.Name; Description = equipment.Description; Image = equipment.Image; + Inspections = new ObservableCollection(equipment.Inspections.Select(e => e)); IsImageSelected = equipment.Image is { Bytes.Length: > 0 }; diff --git a/Views/EditEquipmentDialog.axaml b/Views/EditEquipmentDialog.axaml index 6a295a5..de4613f 100644 --- a/Views/EditEquipmentDialog.axaml +++ b/Views/EditEquipmentDialog.axaml @@ -3,6 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:GazpromApp.ViewModels" + xmlns:enums="using:GazpromApp.Enums" x:Name="Window" mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="600" Width="1000" Height="600" @@ -16,6 +17,21 @@ + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Views/EditEquipmentDialog.axaml.cs b/Views/EditEquipmentDialog.axaml.cs index c9550cf..95e04b3 100644 --- a/Views/EditEquipmentDialog.axaml.cs +++ b/Views/EditEquipmentDialog.axaml.cs @@ -53,7 +53,7 @@ public partial class EditEquipmentDialog : Window private void Window_OnClosing(object? sender, WindowClosingEventArgs e) { - if (DataContext is EditEquipmentDialogViewModel { IsClosed: false} vm) + if (DataContext is EditEquipmentDialogViewModel { IsClosed: false } vm) vm.CancelEditCommand.Execute(this); } diff --git a/obj/Debug/net8.0/Avalonia/Resources.Inputs.cache b/obj/Debug/net8.0/Avalonia/Resources.Inputs.cache index efe4197..540ccaa 100644 --- a/obj/Debug/net8.0/Avalonia/Resources.Inputs.cache +++ b/obj/Debug/net8.0/Avalonia/Resources.Inputs.cache @@ -1 +1 @@ -004891c51b7c26ff54260c1cbfcff302500ddbafa20549c101da76cc7da60e8a +3656b818a608cac55f3434fefe51f65e8b2346fa99aecf23bebe97e8e8aa269e diff --git a/obj/Debug/net8.0/Avalonia/resources b/obj/Debug/net8.0/Avalonia/resources index 6744473..e4464ab 100644 Binary files a/obj/Debug/net8.0/Avalonia/resources and b/obj/Debug/net8.0/Avalonia/resources differ diff --git a/obj/Debug/net8.0/GazpromApp.AssemblyInfo.cs b/obj/Debug/net8.0/GazpromApp.AssemblyInfo.cs index caa76f9..71b1ba4 100644 --- a/obj/Debug/net8.0/GazpromApp.AssemblyInfo.cs +++ b/obj/Debug/net8.0/GazpromApp.AssemblyInfo.cs @@ -13,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("GazpromApp")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5816f21e6cc989b7059d5a18a1f56939b27bf40d")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+725b6dc53998e3fe82d1e7e83d0312933ae96983")] [assembly: System.Reflection.AssemblyProductAttribute("GazpromApp")] [assembly: System.Reflection.AssemblyTitleAttribute("GazpromApp")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/obj/Debug/net8.0/GazpromApp.AssemblyInfoInputs.cache b/obj/Debug/net8.0/GazpromApp.AssemblyInfoInputs.cache index 8e37052..3ab3655 100644 --- a/obj/Debug/net8.0/GazpromApp.AssemblyInfoInputs.cache +++ b/obj/Debug/net8.0/GazpromApp.AssemblyInfoInputs.cache @@ -1 +1 @@ -22f6a7bf36b71d326c8840f0501afa961a7d4f13e9163340a4acf3e167738c72 +327dd27f22ee4d496be5fbf4fc27c7f9dfbad856b482d896a83e82e336f0e4fd diff --git a/obj/rider.project.model.nuget.info b/obj/rider.project.model.nuget.info index 55af6e8..eab3bf4 100644 --- a/obj/rider.project.model.nuget.info +++ b/obj/rider.project.model.nuget.info @@ -1 +1 @@ -17514599119483488 \ No newline at end of file +17518675823308854 \ No newline at end of file diff --git a/obj/rider.project.restore.info b/obj/rider.project.restore.info index 55af6e8..eab3bf4 100644 --- a/obj/rider.project.restore.info +++ b/obj/rider.project.restore.info @@ -1 +1 @@ -17514599119483488 \ No newline at end of file +17518675823308854 \ No newline at end of file