From 646f60e800da077d6f0e380695010dafc74187f1 Mon Sep 17 00:00:00 2001 From: retr0volkov <68907954+retr0volkov@users.noreply.github.com> Date: Sun, 6 Jul 2025 22:40:13 +0300 Subject: [PATCH] Inspections added --- Enums/PeriodType.cs | 23 +++++- Models/Inspection.cs | 2 +- Utils/DateCalculator.cs | 47 ++++++++++++ ViewModels/Basic/EquipmentViewModel.cs | 25 ++++-- ViewModels/Basic/InspectionViewModel.cs | 40 +++++++++- ViewModels/EditEquipmentDialogViewModel.cs | 38 ++++++++- Views/EditEquipmentDialog.axaml | 72 +++++++++++++++++- Views/EditEquipmentDialog.axaml.cs | 2 +- .../net8.0/Avalonia/Resources.Inputs.cache | 2 +- obj/Debug/net8.0/Avalonia/resources | Bin 330799 -> 335270 bytes obj/Debug/net8.0/GazpromApp.AssemblyInfo.cs | 2 +- .../GazpromApp.AssemblyInfoInputs.cache | 2 +- obj/rider.project.model.nuget.info | 2 +- obj/rider.project.restore.info | 2 +- 14 files changed, 239 insertions(+), 20 deletions(-) create mode 100644 Utils/DateCalculator.cs 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 67444734bfe6d9748abea5773ed5edb5bf9940dd..e4464ab62837db51340fa8b2faaf5cfa6896e71c 100644 GIT binary patch delta 2271 zcma)7U2GIp6t>G*x^3-`@@Ju?(`i8=OLy90Eu~v**#b=|61v(46Wd|u+D_P=S!Q-E z3n43#XySuH7CnMN`-Jg9Y)O9zv}{pBjU;3n$Z)S%D*BfZM@~!KanqN<;z@!){{4F@7=Uz(PN=!+1O1RTsc+l^D24+Q-VI-$p>{= z>22689`$Rgui5XfYNa?1{Q<3G6KA2=67G@}N$syXz;rdJd6?dmpUcr-V{#6CvD}q7BlYdlRbwNrc23B-LA-AYQ z)Ouxw(yFo784Js2pak27U>yqMkc;;}gEiT$k{lpru=yUWM`09lu;(Ii({&e~&8jiT zs&J@BxIN4;rjxIIk>}E2tGC+gx7zD?ZkMVAI_0B`K2~p#P-%d#%xTjz;0L0x4eb_d z2{!!z%Zrjog1z2eBiQlqFmNA_Kpwt43TyF|bMV|pVQWEwfsxjiZm<^Pz$g^Z)$K;P zc^ICh?ZHFXf&&A_w`WNj!Z2;8zJra+9ck>8%u)2=BotRR2Lq~|`~SWnp6?hbqlioJT^kv`4hQu~$6JZpKb+3QvNJN<^b+**+F zT$d~b`V6TFX+`u*LczM%L~k%X`?%xHsF8YE#ZJ|CP;DWRWspJsN?;1}m|vYIbsmj^ z-E=&*kCILkBFUwU;>dbZ%C@Qmfo%ciOCvCT(H-(LJJ+E~%<1k|yTnlH#l0?B_j|=q z2lE}IUxzsFX#iDrng;We%z3OcAO_MLzF?#sH><>L!|*h&{}ya3(kx`iiQFmR+%(M^ zeukWB+Oy|(QgQn^C?Wl?%1KT(e5~|^F&YWK+=BcC`bYIQng|z3^Z4gCP=K@(M+T=AAhXc8Ok{jlKI5d|CG&p#l## delta 134 zcmV;10D1qWyA-dO6tLO{0=f^A+y@^5E}xVA2OR>#!IK;a9R>2q1OQ%>J_s8EP|cHD z2qp=w-vj_x4FCWemoOa#8v+FFlcxwF1I_&egUbkq%LoC7%LoF8%LoIv%LoLzke4vs o1UR?rnFJXEx6r%<1O>OEqXa$$m%FzF7`KeK1XnM&{^kUzHjGy>XaE2J 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