diff --git a/ServiceStation/ServiceStation.sln b/ServiceStation/ServiceStation.sln index 432cce4..386dc79 100644 --- a/ServiceStation/ServiceStation.sln +++ b/ServiceStation/ServiceStation.sln @@ -7,7 +7,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStation", "ServiceSt EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationDataModels", "ServiceStationDataModels\ServiceStationDataModels.csproj", "{B9302F55-74F5-4A39-8384-C99BDB7E5159}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStationContracts", "ServiceStationContracts\ServiceStationContracts.csproj", "{7813B987-065A-48FA-A3D0-70F02DFF21A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationContracts", "ServiceStationContracts\ServiceStationContracts.csproj", "{7813B987-065A-48FA-A3D0-70F02DFF21A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStationDatabaseImplement", "ServiceStationDatabaseImplement\ServiceStationDatabaseImplement.csproj", "{EE5A19E3-8363-48C3-A672-0CD32F26AA31}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,6 +29,10 @@ Global {7813B987-065A-48FA-A3D0-70F02DFF21A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {7813B987-065A-48FA-A3D0-70F02DFF21A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {7813B987-065A-48FA-A3D0-70F02DFF21A4}.Release|Any CPU.Build.0 = Release|Any CPU + {EE5A19E3-8363-48C3-A672-0CD32F26AA31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE5A19E3-8363-48C3-A672-0CD32F26AA31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE5A19E3-8363-48C3-A672-0CD32F26AA31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE5A19E3-8363-48C3-A672-0CD32F26AA31}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ServiceStation/ServiceStationContracts/BindingModels/DefectBindingModel.cs b/ServiceStation/ServiceStationContracts/BindingModels/DefectBindingModel.cs index c3ce5a2..5be5e4b 100644 --- a/ServiceStation/ServiceStationContracts/BindingModels/DefectBindingModel.cs +++ b/ServiceStation/ServiceStationContracts/BindingModels/DefectBindingModel.cs @@ -17,5 +17,7 @@ namespace ServiceStationContracts.BindingModels public double DefectPrice { get; set; } public int ExecutorId { get; set; } + + public Dictionary DefectCars { get; set; } = new(); } } diff --git a/ServiceStation/ServiceStationContracts/BindingModels/TechnicalWorkBindingModel.cs b/ServiceStation/ServiceStationContracts/BindingModels/TechnicalWorkBindingModel.cs index c2e459e..9a21f50 100644 --- a/ServiceStation/ServiceStationContracts/BindingModels/TechnicalWorkBindingModel.cs +++ b/ServiceStation/ServiceStationContracts/BindingModels/TechnicalWorkBindingModel.cs @@ -13,11 +13,12 @@ namespace ServiceStationContracts.BindingModels public string WorkType { get; set; } = string.Empty; - public DateTime DateLastWork { get; set; } = DateTime.Now; + public DateTime? DateStartWork { get; set; } = DateTime.Now; public double WorkPrice { get; set; } public int ExecutorId { get; set; } + public Dictionary TechnicalWorkCars { get; set; } = new(); } } diff --git a/ServiceStation/ServiceStationContracts/SearchModels/CarSearchModel.cs b/ServiceStation/ServiceStationContracts/SearchModels/CarSearchModel.cs index c9d28eb..50a8bc2 100644 --- a/ServiceStation/ServiceStationContracts/SearchModels/CarSearchModel.cs +++ b/ServiceStation/ServiceStationContracts/SearchModels/CarSearchModel.cs @@ -10,5 +10,6 @@ namespace ServiceStationContracts.SearchModels { public int? Id { get; set; } public string? CarNumber { get; set; } + public int? ExecutorId { get; set; } } } diff --git a/ServiceStation/ServiceStationContracts/SearchModels/DefectSearchModel.cs b/ServiceStation/ServiceStationContracts/SearchModels/DefectSearchModel.cs index e1edfdf..7d740a7 100644 --- a/ServiceStation/ServiceStationContracts/SearchModels/DefectSearchModel.cs +++ b/ServiceStation/ServiceStationContracts/SearchModels/DefectSearchModel.cs @@ -10,5 +10,6 @@ namespace ServiceStationContracts.SearchModels { public int? Id { get; set; } public string? DefectType { get; set; } + public int? ExecutorId { get; set; } } } diff --git a/ServiceStation/ServiceStationContracts/SearchModels/TechnicalWorkSearchModel.cs b/ServiceStation/ServiceStationContracts/SearchModels/TechnicalWorkSearchModel.cs index 732de0a..63b051b 100644 --- a/ServiceStation/ServiceStationContracts/SearchModels/TechnicalWorkSearchModel.cs +++ b/ServiceStation/ServiceStationContracts/SearchModels/TechnicalWorkSearchModel.cs @@ -10,5 +10,8 @@ namespace ServiceStationContracts.SearchModels { public int? Id { get; set; } public string? WorkType { get; set; } + public DateTime? DateFrom { get; set; } + public DateTime? DateTo { get; set; } + public int? ExecutorId { get; set; } } } diff --git a/ServiceStation/ServiceStationContracts/ViewModels/DefectViewModel.cs b/ServiceStation/ServiceStationContracts/ViewModels/DefectViewModel.cs index 4bb85be..ad4313a 100644 --- a/ServiceStation/ServiceStationContracts/ViewModels/DefectViewModel.cs +++ b/ServiceStation/ServiceStationContracts/ViewModels/DefectViewModel.cs @@ -20,5 +20,7 @@ namespace ServiceStationContracts.ViewModels public double DefectPrice { get; set; } public int ExecutorId { get; set; } + + public Dictionary DefectCars { get; set; } = new(); } } diff --git a/ServiceStation/ServiceStationContracts/ViewModels/ExecutorViewModel.cs b/ServiceStation/ServiceStationContracts/ViewModels/ExecutorViewModel.cs index a765d3a..3ede831 100644 --- a/ServiceStation/ServiceStationContracts/ViewModels/ExecutorViewModel.cs +++ b/ServiceStation/ServiceStationContracts/ViewModels/ExecutorViewModel.cs @@ -14,7 +14,7 @@ namespace ServiceStationContracts.ViewModels [DisplayName("ФИО исполнителя")] public string ExecutorFIO { get; set; } = string.Empty; [DisplayName("Почти исполнителя(логин)")] - public string ExecutorEmail { get; set; } = string.Empty; + public string? ExecutorEmail { get; set; } [DisplayName("Пароль исполнителя")] public string ExecutorPassword { get; set; } = string.Empty; [DisplayName("Номер телефона исполнителя")] diff --git a/ServiceStation/ServiceStationContracts/ViewModels/TechnicalWorkViewModel.cs b/ServiceStation/ServiceStationContracts/ViewModels/TechnicalWorkViewModel.cs index 48ee738..7d01462 100644 --- a/ServiceStation/ServiceStationContracts/ViewModels/TechnicalWorkViewModel.cs +++ b/ServiceStation/ServiceStationContracts/ViewModels/TechnicalWorkViewModel.cs @@ -14,10 +14,12 @@ namespace ServiceStationContracts.ViewModels [DisplayName("Тип ТО")] public string WorkType { get; set; } = string.Empty; [DisplayName("Дата последнего ТО")] - public DateTime DateLastWork { get; set; } = DateTime.Now; + public DateTime? DateStartWork { get; set; } = DateTime.Now; [DisplayName("Цена ТО")] public double WorkPrice { get; set; } public int ExecutorId { get; set; } + + public Dictionary TechnicalWorkCars { get; set; } = new(); } } diff --git a/ServiceStation/ServiceStationDataModels/Models/ICarModel.cs b/ServiceStation/ServiceStationDataModels/Models/ICarModel.cs index 933e37e..e45d729 100644 --- a/ServiceStation/ServiceStationDataModels/Models/ICarModel.cs +++ b/ServiceStation/ServiceStationDataModels/Models/ICarModel.cs @@ -11,7 +11,5 @@ namespace ServiceStationDataModels.Models string CarNumber { get; } string CarBrand { get; } int ExecutorId { get; } - public Dictionary CarDefects { get; } - public Dictionary CarTechnicalWorks { get; } } } diff --git a/ServiceStation/ServiceStationDataModels/Models/IDefectModel.cs b/ServiceStation/ServiceStationDataModels/Models/IDefectModel.cs index 84679c8..60ee589 100644 --- a/ServiceStation/ServiceStationDataModels/Models/IDefectModel.cs +++ b/ServiceStation/ServiceStationDataModels/Models/IDefectModel.cs @@ -12,5 +12,6 @@ namespace ServiceStationDataModels.Models string DefectType { get; } double DefectPrice { get; } int ExecutorId { get; } + public Dictionary DefectCars { get; } } } diff --git a/ServiceStation/ServiceStationDataModels/Models/IExecutorModel.cs b/ServiceStation/ServiceStationDataModels/Models/IExecutorModel.cs index 7327863..1491821 100644 --- a/ServiceStation/ServiceStationDataModels/Models/IExecutorModel.cs +++ b/ServiceStation/ServiceStationDataModels/Models/IExecutorModel.cs @@ -9,7 +9,7 @@ namespace ServiceStationDataModels.Models public interface IExecutorModel : IId { string ExecutorFIO { get; } - string ExecutorEmail { get; } + string? ExecutorEmail { get; } string ExecutorPassword { get; } string ExecutorNumber { get; } } diff --git a/ServiceStation/ServiceStationDataModels/Models/ITechnicalWorkModel.cs b/ServiceStation/ServiceStationDataModels/Models/ITechnicalWorkModel.cs index 0e18d8b..27bb6ec 100644 --- a/ServiceStation/ServiceStationDataModels/Models/ITechnicalWorkModel.cs +++ b/ServiceStation/ServiceStationDataModels/Models/ITechnicalWorkModel.cs @@ -9,8 +9,9 @@ namespace ServiceStationDataModels.Models public interface ITechnicalWorkModel : IId { string WorkType { get; } - DateTime DateLastWork { get; } + DateTime? DateStartWork { get; } double WorkPrice { get; } int ExecutorId { get; } + public Dictionary TechnicalWorkCars { get; } } } diff --git a/ServiceStation/ServiceStationDatabaseImplement/Implements/CarStorage.cs b/ServiceStation/ServiceStationDatabaseImplement/Implements/CarStorage.cs new file mode 100644 index 0000000..8e43752 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Implements/CarStorage.cs @@ -0,0 +1,118 @@ +using Microsoft.EntityFrameworkCore; +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.SearchModels; +using ServiceStationContracts.StoragesContracts; +using ServiceStationContracts.ViewModels; +using ServiceStationDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Implements +{ + public class CarStorage : ICarStorage + { + public List GetFullList() + { + using var context = new ServiceStationDatabase(); + return context.Cars + .Include(x => x.CarDefects) + .ThenInclude(x => x.Defect) + .Include(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + .Include(x => x.Executor) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(CarSearchModel model) + { + if (string.IsNullOrEmpty(model.CarNumber) && !model.ExecutorId.HasValue) return new(); + using var context = new ServiceStationDatabase(); + + if (model.ExecutorId.HasValue) + { + return context.Cars + .Include(x => x.CarDefects) + .ThenInclude(x => x.Defect) + .Include(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + .Include(x => x.Executor) + .Where(x => x.ExecutorId == model.ExecutorId) + .Select(x => x.GetViewModel) + .ToList(); + } + + return context.Cars + .Include(x => x.CarDefects) + .ThenInclude(x => x.Defect) + .Include(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + .Include(x => x.Executor) + .Where(x => x.CarNumber.Contains(model.CarNumber)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public CarViewModel? GetElement(CarSearchModel model) + { + if(string.IsNullOrEmpty(model.CarNumber) && !model.Id.HasValue) return null; + using var context = new ServiceStationDatabase(); + + return context.Cars + .Include(x => x.CarDefects) + .ThenInclude(x => x.Defect) + .Include(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + .Include(x => x.Executor) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.CarNumber) && model.CarNumber == x.CarNumber) || (model.Id.HasValue && x.Id == model.Id))? + .GetViewModel; + } + + public CarViewModel? Insert(CarBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var newCar = Car.Create(model); + if(newCar == null) return null; + + context.Cars.Add(newCar); + context.SaveChanges(); + + return newCar.GetViewModel; + } + + public CarViewModel? Update(CarBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var car = context.Cars.FirstOrDefault(x => x.Id == model.Id); + + if(car == null) return null; + + car.Update(model); + context.SaveChanges(); + + return car.GetViewModel; + } + + public CarViewModel? Delete(CarBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var element = context.Cars.FirstOrDefault(x => x.Id == model.Id); + + if(element != null) + { + context.Cars.Remove(element); + context.SaveChanges(); + + return element.GetViewModel; + } + + return null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Implements/DefectStorage.cs b/ServiceStation/ServiceStationDatabaseImplement/Implements/DefectStorage.cs new file mode 100644 index 0000000..de42362 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Implements/DefectStorage.cs @@ -0,0 +1,129 @@ +using Microsoft.EntityFrameworkCore; +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.SearchModels; +using ServiceStationContracts.StoragesContracts; +using ServiceStationContracts.ViewModels; +using ServiceStationDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Transactions; + +namespace ServiceStationDatabaseImplement.Implements +{ + public class DefectStorage : IDefectStorage + { + public List GetFullList() + { + using var context = new ServiceStationDatabase(); + return context.Defects + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(DefectSearchModel model) + { + if (string.IsNullOrEmpty(model.DefectType) && !model.ExecutorId.HasValue) return new(); + using var context = new ServiceStationDatabase(); + + if (model.ExecutorId.HasValue) + { + return context.Defects + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Where(x => x.ExecutorId == model.ExecutorId) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + return context.Defects + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Where(x => x.DefectType == model.DefectType) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public DefectViewModel? GetElement(DefectSearchModel model) + { + if (string.IsNullOrEmpty(model.DefectType) && !model.Id.HasValue) return null; + + using var context = new ServiceStationDatabase(); + + return context.Defects + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarTechnicalWorks) + .ThenInclude(x => x.TechnicalWork) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.DefectType) && x.DefectType == model.DefectType) || (model.Id.HasValue && x.Id == model.Id))? + .GetViewModel; + } + + public DefectViewModel? Insert(DefectBindingModel model) + { + using var context = new ServiceStationDatabase(); + var newDefect = Defect.Create(context, model); + if(newDefect == null) return null; + context.Add(newDefect); + context.SaveChanges(); + return newDefect.GetViewModel; + } + + public DefectViewModel? Update(DefectBindingModel model) + { + using var context = new ServiceStationDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var elem = context.Defects.FirstOrDefault(rec => rec.Id == model.Id); + if (elem == null) return null; + elem.Update(model); + context.SaveChanges(); + if (model.DefectCars != null) elem.UpdateCars(context, model); + transaction.Commit(); + return elem.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + public DefectViewModel? Delete(DefectBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var element = context.Defects + .Include(x => x.Cars) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Defects.Remove(element); + context.SaveChanges(); + + return element.GetViewModel; + } + return null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Implements/ExecutorStorage.cs b/ServiceStation/ServiceStationDatabaseImplement/Implements/ExecutorStorage.cs new file mode 100644 index 0000000..5a3db9a --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Implements/ExecutorStorage.cs @@ -0,0 +1,103 @@ +using Microsoft.EntityFrameworkCore; +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.SearchModels; +using ServiceStationContracts.StoragesContracts; +using ServiceStationContracts.ViewModels; +using ServiceStationDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Implements +{ + public class ExecutorStorage : IExecutorStorage + { + public List GetFullList() + { + using var context = new ServiceStationDatabase(); + + return context.Executors + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ExecutorSearchModel model) + { + if (string.IsNullOrEmpty(model.ExecutorFIO)) return new(); + using var context = new ServiceStationDatabase(); + + return context.Executors + .Include(x => x.Cars) + .Include(x => x.Defects) + .Include(x => x.TechnicalWorks) + .Where(x => x.ExecutorFIO.Contains(model.ExecutorFIO)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ExecutorViewModel? GetElement(ExecutorSearchModel model) + { + using var context = new ServiceStationDatabase(); + if (!model.Id.HasValue && !string.IsNullOrEmpty(model.ExecutorFIO)) return null; + + if (!string.IsNullOrEmpty(model.ExecutorFIO)) + { + return context.Executors + .Include(x => x.Cars) + .Include(x => x.Defects) + .Include(x => x.TechnicalWorks) + .FirstOrDefault(x => x.ExecutorFIO.Contains(model.ExecutorFIO))? + .GetViewModel; + } + return context.Executors + .Include(x => x.Cars) + .Include(x => x.Defects) + .Include(x => x.TechnicalWorks) + .FirstOrDefault(x => x.Id == model.Id)? + .GetViewModel; + } + + public ExecutorViewModel? Insert(ExecutorBindingModel model) + { + var newExecutor = Executor.Create(model); + if(newExecutor == null) return null; + + using var context = new ServiceStationDatabase(); + context.Executors.Add(newExecutor); + context.SaveChanges(); + + return newExecutor.GetViewModel; + } + + public ExecutorViewModel? Update(ExecutorBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var executor = context.Executors.FirstOrDefault(x => x.Id == model.Id); + + if(executor == null) return null; + + executor.Update(model); + context.SaveChanges(); + + return executor.GetViewModel; + } + + public ExecutorViewModel? Delete(ExecutorBindingModel model) + { + using var context = new ServiceStationDatabase(); + var element = context.Executors.FirstOrDefault(x => x.Id == model.Id); + + if(element != null) + { + context.Executors.Remove(element); + context.SaveChanges(); + + return element.GetViewModel; + } + return null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Implements/TechnicalWorkStorage.cs b/ServiceStation/ServiceStationDatabaseImplement/Implements/TechnicalWorkStorage.cs new file mode 100644 index 0000000..30315b0 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Implements/TechnicalWorkStorage.cs @@ -0,0 +1,149 @@ +using Microsoft.EntityFrameworkCore; +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.SearchModels; +using ServiceStationContracts.StoragesContracts; +using ServiceStationContracts.ViewModels; +using ServiceStationDatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Implements +{ + public class TechnicalWorkStorage : ITechnicalWorkStorage + { + public List GetFullList() + { + using var context = new ServiceStationDatabase(); + return context.TechnicalWorks + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarDefects) + .ThenInclude(x => x.Defect) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(TechnicalWorkSearchModel model) + { + if(!model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ExecutorId.HasValue) + { + return new(); + } + using var context = new ServiceStationDatabase(); + + if(model.DateTo.HasValue && model.DateTo.HasValue) + { + return context.TechnicalWorks + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarDefects) + .ThenInclude(x => x.Defect) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Where(x => x.DateStartWork >= model.DateFrom && x.DateStartWork <= model.DateTo && x.ExecutorId == model.ExecutorId) + .Select(x => x.GetViewModel) + .ToList(); + } + else if (model.ExecutorId.HasValue) + { + return context.TechnicalWorks + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarDefects) + .ThenInclude(x => x.Defect) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Where(x => x.ExecutorId == model.ExecutorId) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + return context.TechnicalWorks + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarDefects) + .ThenInclude(x => x.Defect) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .Where(x => x.WorkType.Contains(model.WorkType)) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public TechnicalWorkViewModel? GetElement(TechnicalWorkSearchModel model) + { + if (string.IsNullOrEmpty(model.WorkType) && !model.Id.HasValue) return null; + using var context = new ServiceStationDatabase(); + + return context.TechnicalWorks + .Include(x => x.Cars) + .ThenInclude(x => x.Car) + .ThenInclude(x => x.CarDefects) + .ThenInclude(x => x.Defect) + //.Include(x => x.Сущность Сани) + .Include(x => x.Executor) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.WorkType) && x.WorkType == model.WorkType) || (model.Id.HasValue && x.Id == model.Id))? + .GetViewModel; + } + + public TechnicalWorkViewModel? Insert(TechnicalWorkBindingModel model) + { + using var context = new ServiceStationDatabase(); + var newWork = TechnicalWork.Create(context, model); + if(newWork == null) return null; + + context.TechnicalWorks.Add(newWork); + context.SaveChanges(); + + return newWork.GetViewModel; + } + + public TechnicalWorkViewModel? Update(TechnicalWorkBindingModel model) + { + using var context = new ServiceStationDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var elem = context.TechnicalWorks.FirstOrDefault(rec => rec.Id == model.Id); + if (elem == null) return null; + + elem.Update(model); + context.SaveChanges(); + if (model.TechnicalWorkCars != null) elem.UpdateCars(context, model); + transaction.Commit(); + return elem.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + public TechnicalWorkViewModel? Delete(TechnicalWorkBindingModel model) + { + using var context = new ServiceStationDatabase(); + + var element = context.TechnicalWorks + .Include(x => x.Cars) + .FirstOrDefault(rec => rec.Id == model.Id); + + if(element != null) + { + context.TechnicalWorks.Remove(element); + context.SaveChanges(); + + return element.GetViewModel; + } + return null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/Car.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/Car.cs new file mode 100644 index 0000000..9468010 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/Car.cs @@ -0,0 +1,63 @@ +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.ViewModels; +using ServiceStationDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class Car : ICarModel + { + public int Id { get; set; } + + [Required] + public string CarNumber { get; set; } = string.Empty; + + [Required] + public string CarBrand { get; set; } = string.Empty; + + [Required] + public int ExecutorId { get; set; } + + public virtual Executor Executor { get; set; } + + [ForeignKey("CarId")] + public virtual List CarDefects { get; set; } = new(); + + [ForeignKey("CarId")] + public virtual List CarTechnicalWorks { get; set; } = new(); + + public static Car? Create(CarBindingModel model) + { + if (model == null) return null; + return new Car() + { + Id = model.Id, + CarNumber = model.CarNumber, + CarBrand = model.CarBrand, + ExecutorId = model.ExecutorId + }; + } + + public void Update(CarBindingModel model) + { + if (model == null) return; + CarNumber = model.CarNumber; + CarBrand = model.CarBrand; + ExecutorId = model.ExecutorId; + } + + public CarViewModel GetViewModel => new() + { + Id = Id, + CarNumber = CarNumber, + CarBrand = CarBrand, + ExecutorId = ExecutorId + }; + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/CarDefect.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/CarDefect.cs new file mode 100644 index 0000000..752e0f3 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/CarDefect.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class CarDefect + { + public int Id { get; set; } + + [Required] + public int CarId { get; set; } + + [Required] + public int DefectId { get; set; } + + public virtual Car Car { get; set; } = new(); + + public virtual Defect Defect { get; set; } = new(); + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/CarTechnicalWork.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/CarTechnicalWork.cs new file mode 100644 index 0000000..7543930 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/CarTechnicalWork.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class CarTechnicalWork + { + public int Id { get; set; } + + [Required] + public int CarId { get; set; } + + [Required] + public int TechnicalWorkId { get; set; } + + public virtual Car Car { get; set; } = new(); + public virtual TechnicalWork TechnicalWork { get; set; } = new(); + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/Defect.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/Defect.cs new file mode 100644 index 0000000..916cc0b --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/Defect.cs @@ -0,0 +1,105 @@ +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.ViewModels; +using ServiceStationDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class Defect : IDefectModel + { + public int Id { get; set; } + + [Required] + public string DefectType { get; set; } = string.Empty; + + [Required] + public double DefectPrice { get; set; } + + [Required] + public int ExecutorId { get; set; } + + public virtual Executor Executor { get; set; } + + private Dictionary? _defectCars = null; + [NotMapped] + public Dictionary DefectCars + { + get + { + if (_defectCars == null) + { + _defectCars = Cars.ToDictionary(rec => rec.CarId, rec => rec.Car as ICarModel); + } + return _defectCars; + } + } + [ForeignKey("DefectId")] + public virtual List Cars { get; set; } = new(); + + public static Defect? Create(ServiceStationDatabase context, DefectBindingModel model) + { + if (model == null) return null; + return new Defect() + { + Id = model.Id, + DefectType = model.DefectType, + DefectPrice = model.DefectPrice, + ExecutorId = model.ExecutorId, + Cars = model.DefectCars.Select(x => new CarDefect + { + Car = context.Cars.First(y => y.Id == x.Key) + }).ToList() + }; + } + + public void Update(DefectBindingModel model) + { + if(model == null) return; + DefectType = model.DefectType; + DefectPrice = model.DefectPrice; + } + + public DefectViewModel GetViewModel => new() + { + Id = Id, + DefectType = DefectType, + DefectPrice = DefectPrice, + ExecutorId = ExecutorId, + DefectCars = DefectCars + }; + + public void UpdateCars(ServiceStationDatabase context, DefectBindingModel model) + { + var carDefects = context.CarDefects.Where(rec => rec.DefectId == model.Id).ToList(); + if(carDefects != null && carDefects.Count > 0) + { + context.CarDefects.RemoveRange(carDefects.Where(rec => !model.DefectCars.ContainsKey(rec.CarId))); + context.SaveChanges(); + + foreach(var updateCar in carDefects) + { + model.DefectCars.Remove(updateCar.CarId); + } + context.SaveChanges(); + } + + var defect = context.Defects.First(x => x.Id == Id); + foreach(var cd in model.DefectCars) + { + context.CarDefects.Add(new CarDefect + { + Defect = defect, + Car = context.Cars.First(x => x.Id == cd.Key) + }); + context.SaveChanges(); + } + _defectCars = null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/Executor.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/Executor.cs new file mode 100644 index 0000000..602fc6c --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/Executor.cs @@ -0,0 +1,67 @@ +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.ViewModels; +using ServiceStationDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class Executor : IExecutorModel + { + public int Id { get; set; } + + [Required] + public string ExecutorFIO { get; set; } = string.Empty; + + public string? ExecutorEmail { get; set; } = string.Empty; + + [Required] + public string ExecutorPassword { get; set; } = string.Empty; + + [Required] + public string ExecutorNumber { get; set; } = string.Empty; + + [ForeignKey("ExecutorId")] + public virtual List Cars { get; set; } = new(); + [ForeignKey("ExecutorId")] + public virtual List Defects { get; set; } = new(); + [ForeignKey("ExecutorId")] + public virtual List TechnicalWorks { get; set; } = new(); + + public static Executor? Create(ExecutorBindingModel model) + { + if (model == null) return null; + return new Executor() + { + Id = model.Id, + ExecutorFIO = model.ExecutorFIO, + ExecutorEmail = model.ExecutorEmail, + ExecutorPassword = model.ExecutorPassword, + ExecutorNumber = model.ExecutorNumber + }; + } + + public void Update(ExecutorBindingModel model) + { + if(model == null) return; + ExecutorFIO = model.ExecutorFIO; + ExecutorEmail = model.ExecutorEmail; + ExecutorPassword = model.ExecutorPassword; + ExecutorNumber = model.ExecutorNumber; + } + + public ExecutorViewModel GetViewModel => new() + { + Id = Id, + ExecutorFIO = ExecutorFIO, + ExecutorEmail = ExecutorEmail, + ExecutorPassword = ExecutorPassword, + ExecutorNumber = ExecutorNumber + }; + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/Models/TechnicalWork.cs b/ServiceStation/ServiceStationDatabaseImplement/Models/TechnicalWork.cs new file mode 100644 index 0000000..5b95787 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/Models/TechnicalWork.cs @@ -0,0 +1,106 @@ +using ServiceStationContracts.BindingModels; +using ServiceStationContracts.ViewModels; +using ServiceStationDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStationDatabaseImplement.Models +{ + public class TechnicalWork : ITechnicalWorkModel + { + public int Id { get; set; } + + [Required] + public string WorkType { get; set; } = string.Empty; + + public DateTime? DateStartWork { get; set; } = DateTime.Now; + + [Required] + public double WorkPrice { get; set; } + + [Required] + public int ExecutorId { get; set; } + public virtual Executor Executor { get; set; } + + private Dictionary? _technicalWorkCars = null; + public Dictionary TechnicalWorkCars + { + get + { + if (_technicalWorkCars == null) + { + _technicalWorkCars = Cars.ToDictionary(rec => rec.CarId, rec => rec.Car as ICarModel); + } + return _technicalWorkCars; + } + } + [ForeignKey("TechnicalWorkId")] + public virtual List Cars { get; set; } = new(); + + public static TechnicalWork? Create(ServiceStationDatabase context, TechnicalWorkBindingModel model) + { + if (model == null) return null; + return new TechnicalWork() + { + Id = model.Id, + WorkType = model.WorkType, + DateStartWork = model.DateStartWork, + WorkPrice = model.WorkPrice, + ExecutorId = model.ExecutorId, + Cars = model.TechnicalWorkCars.Select(x => new CarTechnicalWork + { + Car = context.Cars.First(y => y.Id == x.Key) + }).ToList() + }; + } + + public void Update(TechnicalWorkBindingModel model) + { + WorkType = model.WorkType; + WorkPrice = model.WorkPrice; + DateStartWork = model.DateStartWork; + ExecutorId = model.ExecutorId; + } + public TechnicalWorkViewModel GetViewModel => new() + { + Id = Id, + WorkType = WorkType, + DateStartWork = DateStartWork, + WorkPrice = WorkPrice, + ExecutorId = ExecutorId + }; + + public void UpdateCars(ServiceStationDatabase context, TechnicalWorkBindingModel model) + { + var carTechnicalWorks = context.CarTechnicalWorks.Where(rec => rec.TechnicalWorkId == model.Id).ToList(); + if (carTechnicalWorks != null && carTechnicalWorks.Count > 0) + { + context.CarTechnicalWorks.RemoveRange(carTechnicalWorks.Where(rec => !model.TechnicalWorkCars.ContainsKey(rec.CarId))); + context.SaveChanges(); + + foreach (var updateCar in carTechnicalWorks) + { + model.TechnicalWorkCars.Remove(updateCar.CarId); + } + context.SaveChanges(); + } + + var technicalWork = context.TechnicalWorks.First(x => x.Id == Id); + foreach (var cd in model.TechnicalWorkCars) + { + context.CarTechnicalWorks.Add(new CarTechnicalWork + { + TechnicalWork = technicalWork, + Car = context.Cars.First(x => x.Id == cd.Key) + }); + context.SaveChanges(); + } + _technicalWorkCars = null; + } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabase.cs b/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabase.cs new file mode 100644 index 0000000..8799d7e --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabase.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using ServiceStationDatabaseImplement.Models; + +namespace ServiceStationDatabaseImplement +{ + public class ServiceStationDatabase : DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if(optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseSqlServer(@"Data Source=.\SQLEXPRESS;Initial Catalog=ServiceStationDatabase;Integrated Security=True;MultipleActiveResultSets=True;TrustServerCertificate=True"); + } + base.OnConfiguring(optionsBuilder); + } + + public virtual DbSet Cars { get; set; } + public virtual DbSet Defects { get; set; } + public virtual DbSet CarDefects { get; set; } + public virtual DbSet Executors { get; set; } + public virtual DbSet TechnicalWorks { get; set; } + public virtual DbSet CarTechnicalWorks { get; set; } + } +} diff --git a/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabaseImplement.csproj b/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabaseImplement.csproj new file mode 100644 index 0000000..b4ff117 --- /dev/null +++ b/ServiceStation/ServiceStationDatabaseImplement/ServiceStationDatabaseImplement.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + +