diff --git a/AutoService.sln b/AutoService.sln new file mode 100644 index 0000000..44ce420 --- /dev/null +++ b/AutoService.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36623.8 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoService", "AutoService\AutoService.csproj", "{5845584C-1904-4184-B773-BCE9FE08B4CA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5845584C-1904-4184-B773-BCE9FE08B4CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5845584C-1904-4184-B773-BCE9FE08B4CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5845584C-1904-4184-B773-BCE9FE08B4CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5845584C-1904-4184-B773-BCE9FE08B4CA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7DAD94C8-56AB-4CA7-B7DE-8C85BB9DA95F} + EndGlobalSection +EndGlobal diff --git a/AutoService/App.axaml b/AutoService/App.axaml new file mode 100644 index 0000000..85f1f93 --- /dev/null +++ b/AutoService/App.axaml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/AutoService/App.axaml.cs b/AutoService/App.axaml.cs new file mode 100644 index 0000000..e96aa66 --- /dev/null +++ b/AutoService/App.axaml.cs @@ -0,0 +1,55 @@ +using AutoService.ViewModels; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Data.Core.Plugins; +using Avalonia.Markup.Xaml; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Linq; + +namespace AutoService +{ + public partial class App : Application + { + private readonly IServiceProvider _provider; + + public App(IServiceProvider provider) + { + _provider = provider; + } + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + // Avoid duplicate validations from both Avalonia and the CommunityToolkit. + // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins + DisableAvaloniaDataAnnotationValidation(); + + var win = _provider.GetRequiredService(); + var vm = _provider.GetRequiredService(); + win.DataContext = vm; + desktop.MainWindow = win; + } + + base.OnFrameworkInitializationCompleted(); + } + + private void DisableAvaloniaDataAnnotationValidation() + { + // Get an array of plugins to remove + var dataValidationPluginsToRemove = + BindingPlugins.DataValidators.OfType().ToArray(); + + // remove each entry found + foreach (var plugin in dataValidationPluginsToRemove) + { + BindingPlugins.DataValidators.Remove(plugin); + } + } + } +} \ No newline at end of file diff --git a/AutoService/AutoService.csproj b/AutoService/AutoService.csproj new file mode 100644 index 0000000..6b8f581 --- /dev/null +++ b/AutoService/AutoService.csproj @@ -0,0 +1,35 @@ + + + WinExe + net8.0 + enable + app.manifest + true + + + + + + + + + + + None + All + + + + + + + + + + ReceiptWindow.axaml + + + WorksWindow.axaml + + + diff --git a/AutoService/Models/BaseRepository.cs b/AutoService/Models/BaseRepository.cs new file mode 100644 index 0000000..4ce9065 --- /dev/null +++ b/AutoService/Models/BaseRepository.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class BaseRepository + { + public readonly DatabaseSettings _databaseSetting; + + protected MySqlConnection connection; + + public BaseRepository(IOptions databaseSettings) + { + _databaseSetting = databaseSettings.Value; + connection = new MySqlConnection(_databaseSetting.ConnectionString); + + } + public bool OpenConnection() + { + try + { + connection.Open(); + return true; + }catch(Exception e) + { + Console.WriteLine(e); + return false; + } + } + + public bool CloseConnection() + { + try + { + connection.Close(); + return true; + } + catch(Exception e) + { + Console.WriteLine(e); + return false; + } + } + + } +} diff --git a/AutoService/Models/DatabaseSettings.cs b/AutoService/Models/DatabaseSettings.cs new file mode 100644 index 0000000..ccc5fd3 --- /dev/null +++ b/AutoService/Models/DatabaseSettings.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class DatabaseSettings + { + public string ConnectionString { get; set; } + } +} diff --git a/AutoService/Models/IServiceRepository.cs b/AutoService/Models/IServiceRepository.cs new file mode 100644 index 0000000..9b8afe4 --- /dev/null +++ b/AutoService/Models/IServiceRepository.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public interface IServiceRepository + { + IEnumerable GetAll(); + } +} diff --git a/AutoService/Models/IWorkRepository.cs b/AutoService/Models/IWorkRepository.cs new file mode 100644 index 0000000..f0f55e7 --- /dev/null +++ b/AutoService/Models/IWorkRepository.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public interface IWorkRepository + { + IEnumerable GetByServiceId(int serviceId); + + } +} diff --git a/AutoService/Models/LocalContainer.cs b/AutoService/Models/LocalContainer.cs new file mode 100644 index 0000000..95a3ebb --- /dev/null +++ b/AutoService/Models/LocalContainer.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class LocalContainer + { + public Dictionary StringValues { get; set; } = new(); + + public Service SelectedService { get; set; } + + public ObservableCollection Works { get; set; } + + } +} diff --git a/AutoService/Models/Service.cs b/AutoService/Models/Service.cs new file mode 100644 index 0000000..159efca --- /dev/null +++ b/AutoService/Models/Service.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class Service + { + public int Id { get; set; } + public string Title { get; set; } + public string Description { get; set; } + } +} diff --git a/AutoService/Models/ServiceRepository.cs b/AutoService/Models/ServiceRepository.cs new file mode 100644 index 0000000..d77bedb --- /dev/null +++ b/AutoService/Models/ServiceRepository.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.Options; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class ServiceRepository : BaseRepository, IServiceRepository + { + public ServiceRepository(IOptions databaseSettings) : base(databaseSettings) + { + } + + public IEnumerable GetAll() + { + string sql = "SELECT * FROM services"; + List result = new(); + + try + { + OpenConnection(); + using var mc = new MySqlCommand(sql, connection); + using var reader = mc.ExecuteReader(); + while (reader.Read()) + { + result.Add(new Service() + { + Id = reader.GetInt32("id"), + Title = reader.GetString("title"), + Description = reader.GetString("description") + }); + } + CloseConnection(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + return result; + + } + } +} diff --git a/AutoService/Models/Work.cs b/AutoService/Models/Work.cs new file mode 100644 index 0000000..2fdff5f --- /dev/null +++ b/AutoService/Models/Work.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class Work + { + public string Title { get; set; } + public int Price { get; set; } + + } +} diff --git a/AutoService/Models/WorkIsChecked.cs b/AutoService/Models/WorkIsChecked.cs new file mode 100644 index 0000000..7e33c3b --- /dev/null +++ b/AutoService/Models/WorkIsChecked.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class WorkIsChecked + { + public bool IsChecked { get; set; } + public Work Work { get; set; } + } +} diff --git a/AutoService/Models/WorkRepository.cs b/AutoService/Models/WorkRepository.cs new file mode 100644 index 0000000..41365a2 --- /dev/null +++ b/AutoService/Models/WorkRepository.cs @@ -0,0 +1,45 @@ +using Microsoft.Extensions.Options; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.Models +{ + public class WorkRepository : BaseRepository, IWorkRepository + { + public WorkRepository(IOptions databaseSettings) : base(databaseSettings) + { + } + + public IEnumerable GetByServiceId(int serviceId) + { + string sql = "SELECT work_name, price FROM works WHERE service_id=@SID"; + List result = new(); + try + { + OpenConnection(); + using var mc = new MySqlCommand(sql, connection); + mc.Parameters.AddWithValue("@SID", serviceId); + using var reader = mc.ExecuteReader(); + while (reader.Read()) + { + result.Add(new Work() + { + Title = reader.GetString("work_name"), + Price = reader.GetInt32("price") + + }); + } + CloseConnection(); + + }catch(Exception e) + { + Console.WriteLine(e); + } + return result; + } + } +} diff --git a/AutoService/Program.cs b/AutoService/Program.cs new file mode 100644 index 0000000..9f2e95a --- /dev/null +++ b/AutoService/Program.cs @@ -0,0 +1,50 @@ +using AutoService.Models; +using AutoService.ViewModels; +using Avalonia; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; + +namespace AutoService +{ + internal class Program + { + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) + { + + var host = Host.CreateDefaultBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppContext.BaseDirectory).AddJsonFile("appsettings.json").AddEnvironmentVariables(); + }) + .ConfigureServices((c,s) => + { + s.Configure(c.Configuration.GetSection("DatabaseSettings")); + s.AddTransient(); + s.AddTransient(); + s.AddTransient(); + s.AddTransient(); + s.AddTransient(); + s.AddTransient(); + s.AddSingleton(); + s.AddSingleton(); + s.AddSingleton(); + + + }).Build(); + BuildAvaloniaApp(host.Services) + .StartWithClassicDesktopLifetime(args); + } + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp(IServiceProvider provider) + => AppBuilder.Configure(() => new App(provider)) + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); + } +} diff --git a/AutoService/ViewModels/MainWindowVM.cs b/AutoService/ViewModels/MainWindowVM.cs new file mode 100644 index 0000000..e87b084 --- /dev/null +++ b/AutoService/ViewModels/MainWindowVM.cs @@ -0,0 +1,89 @@ +using AutoService.Models; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Microsoft.Extensions.DependencyInjection; +using MsBox.Avalonia; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.ViewModels +{ + public partial class MainWindowVM:ViewModelBase + { + private readonly IServiceProvider _serviceProvider; + private readonly IServiceRepository _serviceRepository; + private readonly LocalContainer _container; + + [ObservableProperty] + private ObservableCollection services; + + [ObservableProperty] + private string clientName; + + [ObservableProperty] + private string autoModel; + + [ObservableProperty] + private Service selectedService; + + + public MainWindowVM(IServiceProvider serviceProvider, IServiceRepository serviceRepository, LocalContainer localContainer) + { + _serviceProvider = serviceProvider; + _serviceRepository = serviceRepository; + _container = localContainer; + ClientName = ""; + AutoModel = ""; + try + { + services = new ObservableCollection(_serviceRepository.GetAll()); + SelectedService = Services.First(); + } + catch(Exception e) + { + Console.WriteLine(e); + services = new(); + } + + } + + [RelayCommand] + public async Task StartWorksWindowAsync() + { + if (ClientName.Length > 2 && AutoModel.Length > 2) + { + if (!_container.StringValues.ContainsKey("ClientName")) + { + _container.StringValues.Add("ClientName", ClientName); + } + else + { + _container.StringValues["ClientName"] = ClientName; + } + if (!_container.StringValues.ContainsKey("AutoModel")) + { + _container.StringValues.Add("AutoModel", AutoModel); + } + else + { + _container.StringValues["AutoModel"] = AutoModel; + } + + var vm = _serviceProvider.GetRequiredService(); + var win = _serviceProvider.GetRequiredService(); + win.DataContext = vm; + win.Show(); + } + else + { + var errWin = MessageBoxManager.GetMessageBoxStandard("Косяк!", "Поля \"Имя\" и \"Марка машины\" должны быть заполнены!", MsBox.Avalonia.Enums.ButtonEnum.Ok); + await errWin.ShowAsync(); + } + } + + } +} diff --git a/AutoService/ViewModels/ReceiptWindowVM.cs b/AutoService/ViewModels/ReceiptWindowVM.cs new file mode 100644 index 0000000..18c8c25 --- /dev/null +++ b/AutoService/ViewModels/ReceiptWindowVM.cs @@ -0,0 +1,47 @@ +using AutoService.Models; +using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.ViewModels +{ + public partial class ReceiptWindowVM: ViewModelBase + { + + private readonly IServiceProvider _serviceProvider; + + private readonly LocalContainer _localContainer; + + + [ObservableProperty] + private ObservableCollection works; + + [ObservableProperty] + private int sumPrice = 0; + + private double discount = 0; + + [ObservableProperty] + private string discountText; + + [ObservableProperty] + private double totalPrice; + public ReceiptWindowVM(IServiceProvider serviceProvider, ObservableCollection works, LocalContainer localContainer) + { + _serviceProvider = serviceProvider; + _localContainer = localContainer; + Works = works; + foreach (var item in Works) sumPrice += item.Price; + if (sumPrice >= 10_000) discount = 0.1; + else if (sumPrice >= 5_000) discount = 0.05; + DiscountText = (discount * 100).ToString() + "%"; + + TotalPrice = sumPrice * (1-discount); + + } + } +} diff --git a/AutoService/ViewModels/ViewModelBase.cs b/AutoService/ViewModels/ViewModelBase.cs new file mode 100644 index 0000000..bb53212 --- /dev/null +++ b/AutoService/ViewModels/ViewModelBase.cs @@ -0,0 +1,13 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.ViewModels +{ + public class ViewModelBase: ObservableObject + { + } +} diff --git a/AutoService/ViewModels/WorksWindowVM.cs b/AutoService/ViewModels/WorksWindowVM.cs new file mode 100644 index 0000000..04dabdf --- /dev/null +++ b/AutoService/ViewModels/WorksWindowVM.cs @@ -0,0 +1,57 @@ +using AutoService.Models; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoService.ViewModels +{ + public partial class WorksWindowVM:ViewModelBase + { + private readonly IServiceProvider _serviceProvider; + private readonly LocalContainer _localContainer; + + private Service _service; + + [ObservableProperty] + private ObservableCollection works; + + + public WorksWindowVM(IServiceProvider serviceProvider, IWorkRepository workRepository, LocalContainer container) + { + _serviceProvider = serviceProvider; + _service = container.SelectedService; + _localContainer = container; + Works = new ObservableCollection(); + foreach(Work work in workRepository.GetByServiceId(_service.Id)) + { + Works.Add(new WorkIsChecked + { + Work = work, + IsChecked = false + }); + } + + } + + [RelayCommand] + public void CalculateCount() + { + ObservableCollection selectedWorks = new(); + foreach(var work in Works) + { + if (work.IsChecked) selectedWorks.Add(work.Work); + } + var vm = ActivatorUtilities.CreateInstance(_serviceProvider, selectedWorks, _localContainer); + var win = _serviceProvider.GetRequiredService(); + win.DataContext = vm; + win.Show(); + } + + } +} diff --git a/AutoService/Views/MainWindow.axaml b/AutoService/Views/MainWindow.axaml new file mode 100644 index 0000000..03db5d8 --- /dev/null +++ b/AutoService/Views/MainWindow.axaml @@ -0,0 +1,23 @@ + + + + + + + + + + + +