From dff3d5f27a33851772c203ea77778e2ce94fcf9d Mon Sep 17 00:00:00 2001 From: Polina Date: Mon, 29 Apr 2024 18:17:16 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20UniversityDatabaseImplement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/ClassStorage.cs | 111 +++++++++++++ .../Implements/ClientStorage.cs | 41 +++++ .../Implements/CostStorage.cs | 96 +++++++++++ .../Implements/EmployeeStorage.cs | 41 +++++ .../Implements/PaymentStorage.cs | 76 +++++++++ .../Implements/PurchaseStorage.cs | 151 ++++++++++++++++++ .../Models/CarByPurchase.cs | 15 ++ .../BankDatabaseImplement/Models/Class.cs | 62 +++++++ .../BankDatabaseImplement/Models/Client.cs | 57 +++++++ .../BankDatabaseImplement/Models/Cost.cs | 81 ++++++++++ .../Models/CostByPurchase.cs | 13 ++ .../BankDatabaseImplement/Models/Employee.cs | 60 +++++++ .../BankDatabaseImplement/Models/Payment.cs | 51 ++++++ .../BankDatabaseImplement/Models/Purchase.cs | 95 +++++++++++ .../BankDatabaseImplement/UniversityDB.cs | 33 ++++ .../UniversityDatabaseImplement.csproj | 9 ++ University/University.sln | 6 + 17 files changed, 998 insertions(+) create mode 100644 University/BankDatabaseImplement/Implements/ClassStorage.cs create mode 100644 University/BankDatabaseImplement/Implements/ClientStorage.cs create mode 100644 University/BankDatabaseImplement/Implements/CostStorage.cs create mode 100644 University/BankDatabaseImplement/Implements/EmployeeStorage.cs create mode 100644 University/BankDatabaseImplement/Implements/PaymentStorage.cs create mode 100644 University/BankDatabaseImplement/Implements/PurchaseStorage.cs create mode 100644 University/BankDatabaseImplement/Models/CarByPurchase.cs create mode 100644 University/BankDatabaseImplement/Models/Class.cs create mode 100644 University/BankDatabaseImplement/Models/Client.cs create mode 100644 University/BankDatabaseImplement/Models/Cost.cs create mode 100644 University/BankDatabaseImplement/Models/CostByPurchase.cs create mode 100644 University/BankDatabaseImplement/Models/Employee.cs create mode 100644 University/BankDatabaseImplement/Models/Payment.cs create mode 100644 University/BankDatabaseImplement/Models/Purchase.cs create mode 100644 University/BankDatabaseImplement/UniversityDB.cs create mode 100644 University/BankDatabaseImplement/UniversityDatabaseImplement.csproj diff --git a/University/BankDatabaseImplement/Implements/ClassStorage.cs b/University/BankDatabaseImplement/Implements/ClassStorage.cs new file mode 100644 index 0000000..1b5b90a --- /dev/null +++ b/University/BankDatabaseImplement/Implements/ClassStorage.cs @@ -0,0 +1,111 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace UniversityDatabaseImplement.Implements +{ + public class ClassStorage : IClassStorage + { + private void CheckSearchModel(ClassSearchModel model) + { + if (model == null) + throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); + if (!model.Id.HasValue && !model.EmployeeId.HasValue && model.PurchasesIds == null) + throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); + } + + public ClassViewModel? Delete(ClassBindingModel model) + { + using var context = new UniversityDB(); + var element = context.Operations.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + context.Operations.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public ClassViewModel? GetElement(ClassSearchModel model) + { + CheckSearchModel(model); + if (!model.Id.HasValue) + { + return null; + } + using var context = new UniversityDB(); + return context.Operations + .Include(x => x.Employee) + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(ClassSearchModel model) + { + CheckSearchModel(model); + if (model.Id.HasValue) + { + var res = GetElement(model); + return res != null ? new() { res } : new(); + } + using var context = new UniversityDB(); + + var query = context.Operations.Include(x => x.Employee); + if (model.EmployeeId.HasValue) + { + + return query + .Where(x => model.EmployeeId == x.EmployeeId) + .Select(x => x.GetViewModel) + .ToList(); + } + + if (model.PurchasesIds != null) + return query + .Include(x => x.Purchases)! + .ThenInclude(x => x.Purchase) + .ThenInclude(x => x.Operations) + .Where(x => x.Purchases.Any(y => model.PurchasesIds.Contains(y.PurchaseId))) + .Select(x => x.GetViewModel) + .ToList(); + return new(); + } + + public List GetFullList() + { + using var context = new UniversityDB(); + return context.Operations.Include(x => x.Employee) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ClassViewModel? Insert(ClassBindingModel model) + { + var newOperation = Class.Create(model); + if (newOperation == null) + { + return null; + } + using var context = new UniversityDB(); + context.Operations.Add(newOperation); + context.SaveChanges(); + return newOperation.GetViewModel; + } + + public ClassViewModel? Update(ClassBindingModel model) + { + using var context = new UniversityDB(); + var car = context.Operations.FirstOrDefault(x => x.Id == model.Id); + if (car == null) + { + return null; + } + car.Update(model); + context.SaveChanges(); + return car.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Implements/ClientStorage.cs b/University/BankDatabaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..2e60cc9 --- /dev/null +++ b/University/BankDatabaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,41 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement; +using UniversityDatabaseImplement.Models; + +namespace UiversityDatabaseImplement.Implements +{ + public class ClientStorage : IClassStorage + { + private void CheckSearchModel(ClientSearchModel model) + { + if (model == null) + throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); + if (!model.Id.HasValue && string.IsNullOrEmpty(model.PhoneNumber) && string.IsNullOrEmpty(model.Password)) + throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); + if (!model.Id.HasValue && (string.IsNullOrEmpty(model.PhoneNumber) && !string.IsNullOrEmpty(model.Password))) + throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин"); + } + public ClassViewModel? GetElement(ClientSearchModel model) + { + CheckSearchModel(model); + using var context = new UniversityDB(); + + return context.Clients.FirstOrDefault(x => x.PhoneNumber.Equals(model.PhoneNumber) && (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel; + } + public ClassViewModel? Insert(ClientBindingModel model) + { + if (model == null) + { + return null; + } + var newClient = Client.Create(model); + using var context = new UniversityDB(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Implements/CostStorage.cs b/University/BankDatabaseImplement/Implements/CostStorage.cs new file mode 100644 index 0000000..5ce20a8 --- /dev/null +++ b/University/BankDatabaseImplement/Implements/CostStorage.cs @@ -0,0 +1,96 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace UniversityDatabaseImplement.Implements +{ + public class CostStorage : ICostStorage + { + private void CheckSearchModel(CostSearchModel model) + { + if (model == null) + throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); + if (!model.Id.HasValue && !model.EmployeeId.HasValue) + throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); + } + public CostViewModel? Delete(CostBindingModel model) + { + using var context = new BankDB(); + var element = context.Costs.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + context.Costs.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public CostViewModel? GetElement(CostSearchModel model) + { + CheckSearchModel(model); + using var context = new BankDB(); + if (!model.Id.HasValue) + { + return null; + } + return context.Costs + .Include(cost => cost.Employee) + .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase) + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(CostSearchModel model) + { + CheckSearchModel(model); + using var context = new UniversityDB(); + return context.Costs + .Include(cost => cost.Employee) + .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase) + .Where(x => x.EmployeeId == model.EmployeeId || x.Id == model.Id) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() + { + using var context = new UniversityDB(); + return context.Costs + .Include(cost => cost.Employee) + .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase) + .Select(x => x.GetViewModel) + .ToList(); + } + + public CostViewModel? Insert(CostBindingModel model) + { + var newCost = Cost.Create(model); + if (newCost == null) + { + return null; + } + using var context = new UniversityDB(); + + context.Costs.Add(newCost); + context.SaveChanges(); + return newCost.GetViewModel; + } + public CostViewModel? Update(CostBindingModel model) + { + using var context = new UniversityDB(); + var cost = context.Costs.FirstOrDefault(x => x.Id == model.Id); + if (cost == null) + { + return null; + } + cost.Update(model); + context.SaveChanges(); + cost.UpdatePurchases(context, model); + context.SaveChanges(); + return cost.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Implements/EmployeeStorage.cs b/University/BankDatabaseImplement/Implements/EmployeeStorage.cs new file mode 100644 index 0000000..cb44595 --- /dev/null +++ b/University/BankDatabaseImplement/Implements/EmployeeStorage.cs @@ -0,0 +1,41 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; + +namespace UniversityDatabaseImplement.Implements +{ + public class EmployeeStorage : IEmployeeStorage + { + private void CheckSearchModel(EmployeeSearchModel model) + { + if (model == null) + throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); + if (!model.Id.HasValue && string.IsNullOrEmpty(model.PhoneNumber) && string.IsNullOrEmpty(model.Password)) + throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); + if (!model.Id.HasValue && (string.IsNullOrEmpty(model.PhoneNumber) && !string.IsNullOrEmpty(model.Password))) + throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин"); + } + public EmployeeViewModel? GetElement(EmployeeSearchModel model) + { + CheckSearchModel(model); + using var context = new UniversityDB(); + + return context.Employees + .FirstOrDefault(x => x.PhoneNumber.Equals(model.PhoneNumber) && (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel; + } + public EmployeeViewModel? Insert(EmployeeBindingModel model) + { + if (model == null) + { + return null; + } + var newEmployee = Employee.Create(model); + using var context = new UniversityDB(); + context.Employees.Add(newEmployee); + context.SaveChanges(); + return newEmployee.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Implements/PaymentStorage.cs b/University/BankDatabaseImplement/Implements/PaymentStorage.cs new file mode 100644 index 0000000..6ae1f31 --- /dev/null +++ b/University/BankDatabaseImplement/Implements/PaymentStorage.cs @@ -0,0 +1,76 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; + +namespace UniversityDatabaseImplement.Implements +{ + public class PaymentStorage : IPaymentStorage + { + private static IIncludableQueryable Payments(UniversityDB context) + => context.Payments.Include(x => x.OperationByPurchase).ThenInclude(x => x.Operation); + + public List GetFullList() + { + using var context = new UniversityDB(); + return Payments(context) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(PaymentSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model), "Получена пустая поисковая модель"); + } + if (model.DateFrom.HasValue && !model.DateTo.HasValue || model.DateTo.HasValue && !model.DateFrom.HasValue) + { + throw new ArgumentException("Получена поисковая модель только с началом или концом периода"); + } + if (!model.DateFrom.HasValue && !model.OperationId.HasValue) + { + throw new ArgumentNullException(nameof(model.OperationId), "Получена поисковая модель без OperationId"); + + } + if (!model.DateFrom.HasValue && !model.PurchaseId.HasValue) + { + throw new ArgumentNullException(nameof(model.PurchaseId), "Получена поисковая модель без PurchaseId"); + } + using var context = new UniversityDB(); + if (model.DateFrom.HasValue) + return Payments(context) + .Where(x => model.DateFrom.Value <= x.Date && x.Date <= model.DateTo.Value) + .Select(x => x.GetViewModel) + .ToList(); + + return Payments(context) + .Where(x => x.OperationByPurchase != null && + x.OperationByPurchase.OperationId == model.OperationId && + x.OperationByPurchase.PurchaseId == model.PurchaseId) + .Select(x => x.GetViewModel) + .ToList(); + } + public PaymentViewModel? GetElement(PaymentSearchModel model) + { + using var context = new UniversityDB(); + return Payments(context) + .FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + public PaymentViewModel? Insert(PaymentBindingModel model) + { + if (model == null) + { + return null; + } + var newPayment = Payment.Create(model); + using var context = new UniversityDB(); + context.Payments.Add(newPayment); + context.SaveChanges(); + return newPayment.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Implements/PurchaseStorage.cs b/University/BankDatabaseImplement/Implements/PurchaseStorage.cs new file mode 100644 index 0000000..5923475 --- /dev/null +++ b/University/BankDatabaseImplement/Implements/PurchaseStorage.cs @@ -0,0 +1,151 @@ +using System.Security.Cryptography.X509Certificates; +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.StoragesContracts; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace UniversityDatabaseImplement.Implements +{ + public class PurchaseStorage : IPurchaseStorage + { + private void CheckSearchModel(PurchaseSearchModel model) + { + if (model == null) + throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); + if (!model.Id.HasValue && !model.ClientId.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && model.OperationsIds == null) + throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); + if (model.DateFrom.HasValue != model.DateTo.HasValue) + throw new ArgumentException($"Не указано начало {model.DateFrom} или конец {model.DateTo} периода для поиска по дате."); + } + public PurchaseViewModel? Delete(PurchaseBindingModel model) + { + using var context = new UniversityDB(); + var element = context.Purchases.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + context.Purchases.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + + public List GetPaymentsFromPurchaseAndOperation(PurchaseSearchModel modelPurchase, ClassSearchModel modelOperation) + { + if (!modelPurchase.Id.HasValue) + { + throw new ArgumentNullException(nameof(modelPurchase), "Получена поисковая модель без Id"); + } + if (!modelOperation.Id.HasValue) + { + throw new ArgumentNullException(nameof(modelOperation), "Получена поисковая модель без Id"); + } + using var context = new UniversityDB(); + var carByPurchase = context.OperationByPurchases + .Include(x => x.Payments) + .FirstOrDefault(x => x.OperationId == modelOperation.Id && x.PurchaseId == modelPurchase.Id); + if (carByPurchase?.Payments == null) + { + throw new InvalidOperationException( + $"Не существует связи между данной операции(Id={modelOperation.Id}) и покупкой(Id={modelPurchase.Id})"); + } + return carByPurchase.Payments.Select(payment => payment.GetViewModel).ToList(); + } + + public PurchaseViewModel? GetElement(PurchaseSearchModel model) + { + using var context = new UniversityDB(); + if (!model.Id.HasValue) + { + return null; + } + return context.Purchases + .Include(x => x.Client) + .Include(x => x.Operations) + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(PurchaseSearchModel model) + { + CheckSearchModel(model); + if (model.Id.HasValue) + { + var res = GetElement(model); + return res != null ? new() { res } : new(); + } + + using var context = new UniversityDB(); + + var query = context.Purchases.Include(x => x.Client); + IQueryable? resultQuery = null; + if (model.ClientId.HasValue) + { + + return query + .Where(x => model.ClientId == x.ClientId) + .Select(x => x.GetViewModel) + .ToList(); + } + + if (model.DateTo.HasValue) + resultQuery = query + .Include(x => x.Operations) + .ThenInclude(x => x.Operation) + .Include(x => x.Costs)! + .ThenInclude(x => x.Cost) + .Where(x => model.DateFrom <= x.DatePurchase && x.DatePurchase <= model.DateTo); + + else if (model.OperationsIds != null) + resultQuery = query + .Where(x => x.Operations.Any(x => model.OperationsIds.Contains(x.OperationId))) + .Include(x => x.Operations) + .ThenInclude(x => x.Operation); + + return resultQuery? + .Select(x => x.GetViewModel) + .ToList() ?? new(); + } + + public List GetFullList() + { + using var context = new UniversityDB(); + return context.Purchases + .Include(x => x.Client) + .Include(x => x.Operations) + .Select(x => x.GetViewModel) + .ToList(); + } + + public PurchaseViewModel? Insert(PurchaseBindingModel model) + { + var newPurchase = Purchase.Create(model); + if (newPurchase == null) + { + return null; + } + using var context = new UniversityDB(); + context.Purchases.Add(newPurchase); + context.SaveChanges(); + newPurchase.UpdateOperations(context, model); + context.SaveChanges(); + return newPurchase.GetViewModel; + } + + public PurchaseViewModel? Update(PurchaseBindingModel model) + { + using var context = new UniversityDB(); + var purchase = context.Purchases.FirstOrDefault(x => x.Id == model.Id); + if (purchase == null) + { + return null; + } + purchase.Update(model); + purchase.UpdateOperations(context, model); + context.SaveChanges(); + return purchase.GetViewModel; + } + } +} diff --git a/University/BankDatabaseImplement/Models/CarByPurchase.cs b/University/BankDatabaseImplement/Models/CarByPurchase.cs new file mode 100644 index 0000000..ffec289 --- /dev/null +++ b/University/BankDatabaseImplement/Models/CarByPurchase.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; +using UniversityDataModels.ProxyModels; + +namespace UniversityDatabaseImplement.Models +{ + public class ClassByPurchase : ClassByPurchaseModel + { + [Required] + public Class? Class { get; private set; } + [Required] + public Purchase? Purchase { get; private set; } + [Required] + public List? Payments { get; private set; } + } +} \ No newline at end of file diff --git a/University/BankDatabaseImplement/Models/Class.cs b/University/BankDatabaseImplement/Models/Class.cs new file mode 100644 index 0000000..286ab1f --- /dev/null +++ b/University/BankDatabaseImplement/Models/Class.cs @@ -0,0 +1,62 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.SearchModels; +using UniversityContracts.ViewModels; +using UniversityDatabaseImplement.Implements; +using UniversityDataModels; +using UniversityDataModels.ProxyModels; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace UniversityDatabaseImplement.Models +{ + public class Class : IClassModel + { + [Required] + public int EmployeeId { get; private set; } + [Required] + public string Model { get; private set; } = string.Empty; + [Required] + public double Price { get; private set; } + [Required] + public string Mark { get; private set; } = string.Empty; + + public int Id { get; private set; } + [Required] + public Employee? Employee { get; private set; } + + [Required] + public List Purchases { get; private set; } = new(); + + public static Class Create(ClassBindingModel model) + { + if (model == null) + { + return null; + } + return new Class() + { + EmployeeId = model.EmployeeId, + Model = model.Model, + Price = model.Price, + Mark = model.Mark, + Id = model.Id, + }; + } + + public ClassViewModel GetViewModel => new() + { + EmployeePhoneNumber = Employee?.PhoneNumber??string.Empty, + EmployeeId = EmployeeId, + Model = Model, + Price = Price, + Mark = Mark, + Id = Id, + Purchases = Purchases.Select(x=>x.Purchase?.GetViewModel2).ToList(), + }; + + public void Update(ClassBindingModel model) + { + Price = model.Price; + } + } +} diff --git a/University/BankDatabaseImplement/Models/Client.cs b/University/BankDatabaseImplement/Models/Client.cs new file mode 100644 index 0000000..c1bb3df --- /dev/null +++ b/University/BankDatabaseImplement/Models/Client.cs @@ -0,0 +1,57 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; +using UniversityDataModels; +using System.ComponentModel.DataAnnotations; + +namespace UniversityDatabaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; set; } + [Required] + public string FirstName { get; private set; } = string.Empty; + [Required] + public string LastName { get; private set; } = string.Empty; + + public string? MiddleName { get; private set; } + [Required] + public string Address { get; private set; } = string.Empty; + [Required] + public string PhoneNumber { get; private set; } = string.Empty; + [Required] + public string Email { get; set; } = string.Empty; + [Required] + public string Password { get; private set; } = string.Empty; + [Required] + public List? Purchases { get; private set; } + + public static Client Create(ClientBindingModel model) + { + if (model == null) + { + return null; + } + return new Client() + { + FirstName = model.FirstName, + LastName = model.LastName, + MiddleName = model.MiddleName, + PhoneNumber = model.PhoneNumber, + Password = model.Password, + Id = model.Id, + Email = model.Email, + }; + } + + public ClientViewModel GetViewModel => new() + { + FirstName = FirstName, + LastName = LastName, + MiddleName = MiddleName, + PhoneNumber =PhoneNumber, + Password = Password, + Id = Id, + Email = Email, + }; + } +} diff --git a/University/BankDatabaseImplement/Models/Cost.cs b/University/BankDatabaseImplement/Models/Cost.cs new file mode 100644 index 0000000..e9a20e9 --- /dev/null +++ b/University/BankDatabaseImplement/Models/Cost.cs @@ -0,0 +1,81 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; +using UniversityDataModels; +using System.ComponentModel.DataAnnotations; +using UniversityDataModels.ProxyModels; + +namespace UniversityDatabaseImplement.Models +{ + public class Cost : ICostModel + { + [Required] + public int EmployeeId { get; private set; } + [Required] + public string NameOfCost { get; private set; } = string.Empty; + public int Id { get; private set; } + [Required] + public double Price { get; private set; } + private Dictionary? _cachedPurchases; + public Dictionary PurchasesModels => _cachedPurchases ??= Purchases.Select(x => (CostByPurchaseModel)x).ToDictionary(x => x.PurchaseId, x => x); + [Required] + public Employee? Employee { get; private set; } + [Required] + public List Purchases { get; private set; } = new(); + + public static Cost Create(CostBindingModel model) + { + if (model == null) + { + return null; + } + return new Cost() + { + EmployeeId = model.EmployeeId, + NameOfCost = model.NameOfCost, + Price = model.Price, + //PurchasesModels = model.PurchasesModels, + Id = model.Id + }; + } + + public CostViewModel GetViewModel => new() + { + PhoneNumber = Employee?.PhoneNumber??string.Empty, + PurchaseModels = PurchasesModels, + EmployeeId = EmployeeId, + NameOfCost = NameOfCost, + Price = Price, + Id = Id + }; + + public void Update(CostBindingModel model) + { + NameOfCost = model.NameOfCost; + Price = model.Price; + } + + /// + /// Привязка статей затрат к покупкам + /// + public void UpdatePurchases(UniversityDB context, CostBindingModel model) + { + var oldPurchases = context.CostByPurchases.Where(x => x.CostId == model.Id).ToDictionary(x => x.PurchaseId, x => x); + var newPurchases = model.PurchasesModels.ToDictionary( + x => x.Key, + x => new CostByPurchase() + { + CostId = model.Id, + PurchaseId = x.Key, + Count = x.Value.Count, + } + ); + context.RemoveRange(oldPurchases.Where(x => !newPurchases.ContainsKey(x.Key)).Select(x => x.Value)); + context.AddRange (newPurchases.Where(x => !oldPurchases.ContainsKey(x.Key)).Select(x => x.Value)); + oldPurchases.Where(x => newPurchases.ContainsKey(x.Key)) + .Select(x => x.Value).ToList() + .ForEach(x => x.Count = newPurchases[x.PurchaseId].Count); + context.SaveChanges(); + _cachedPurchases = null; + } + } +} diff --git a/University/BankDatabaseImplement/Models/CostByPurchase.cs b/University/BankDatabaseImplement/Models/CostByPurchase.cs new file mode 100644 index 0000000..60aa4e5 --- /dev/null +++ b/University/BankDatabaseImplement/Models/CostByPurchase.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; +using UniversityDataModels.ProxyModels; + +namespace UniversityDatabaseImplement.Models +{ + public class CostByPurchase : CostByPurchaseModel + { + [Required] + public Cost? Cost { get; private set; } + [Required] + public Purchase? Purchase { get; private set; } + } +} diff --git a/University/BankDatabaseImplement/Models/Employee.cs b/University/BankDatabaseImplement/Models/Employee.cs new file mode 100644 index 0000000..33e0184 --- /dev/null +++ b/University/BankDatabaseImplement/Models/Employee.cs @@ -0,0 +1,60 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; +using UniversityDataModels; +using System.ComponentModel.DataAnnotations; + +namespace UniversityDatabaseImplement.Models +{ + public class Employee : IEmployeeModel + { + public int Id { get; private set; } + [Required] + public string FirstName { get; private set; } = string.Empty; + [Required] + public string LastName { get; private set; } = string.Empty; + public string? MiddleName { get; private set; } + [Required] + public string Post { get; private set; } = string.Empty; + [Required] + public string PhoneNumber { get; private set; } = string.Empty; + [Required] + public string Password { get; private set; } = string.Empty; + [Required] + public string Email { get; set; } = string.Empty; + [Required] + public List? Class { get; private set; } + [Required] + public List? Costs { get; private set; } + + public static Employee Create(EmployeeBindingModel model) + { + if (model == null) + { + return null; + } + return new Employee() + { + FirstName = model.FirstName, + LastName = model.LastName, + MiddleName = model.MiddleName, + PhoneNumber = model.PhoneNumber, + Password = model.Password, + Id = model.Id, + Post = model.Post, + Email = model.Email, + }; + } + + public EmployeeViewModel GetViewModel => new() + { + FirstName = FirstName, + LastName = LastName, + MiddleName = MiddleName, + PhoneNumber = PhoneNumber, + Password = Password, + Id = Id, + Post = Post, + Email = Email, + }; + } +} \ No newline at end of file diff --git a/University/BankDatabaseImplement/Models/Payment.cs b/University/BankDatabaseImplement/Models/Payment.cs new file mode 100644 index 0000000..eda99b5 --- /dev/null +++ b/University/BankDatabaseImplement/Models/Payment.cs @@ -0,0 +1,51 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; +using UniversityDataModels; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; + +namespace UniversityDatabaseImplement.Models +{ + public class Payment : IPaymentModel + { + [Required] + public int OperationByPurchaseId { get; private set; } + + [Required] + public DateOnly Date { get; private set; } + + [Required] + public double PaidPrice { get; private set; } + + public int Id { get; private set; } + + [Required] + public ClassByPurchase? ClassByPurchase { get; private set; } + + public static Payment Create(PaymentBindingModel model) + { + if (model == null) + { + return null; + } + return new Payment() + { + + Date = model.Date, + PaidPrice = model.PaidPrice, + Id = model.Id, + OperationByPurchaseId = model.OperationByPurchaseId, + }; + } + public PaymentViewModel GetViewModel => new() + { + Operation = OperationByPurchase?.Operation?.GetViewModel, + OperationByPurchase = OperationByPurchase, + FullPrice = OperationByPurchase?.Operation?.Price ?? -1, + Date = Date, + PaidPrice = PaidPrice, + Id = Id, + OperationByPurchaseId = OperationByPurchaseId, + }; + } +} diff --git a/University/BankDatabaseImplement/Models/Purchase.cs b/University/BankDatabaseImplement/Models/Purchase.cs new file mode 100644 index 0000000..9777d88 --- /dev/null +++ b/University/BankDatabaseImplement/Models/Purchase.cs @@ -0,0 +1,95 @@ +using UniversityContracts.BindingModels; +using UniversityContracts.ViewModels; +using UniversityDataModels; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; +using UniversityDataModels.ProxyModels; + +namespace UniversityDatabaseImplement.Models +{ + public class Purchase : IPurchaseModel + { + public int ClientId { get; private set; } + public DateOnly DatePurchase { get; private set; } + private Dictionary? _cachedOperations; + [NotMapped] + public Dictionary ClassModel => _cachedOperations ??= Class.Select(x => (ClassByPurchaseModel)x).ToDictionary(x => x.ClassId, x => x); + [NotMapped] + public List? CostsModel => null; + public int Id { get; private set; } + [Required] + public Client? Client { get; private set; } + [Required] + public List Operations { get; private set; } = new(); + [Required] + public List Costs { get; private set; } = new(); + + public static Purchase Create(PurchaseBindingModel model) + { + return new Purchase() + { + ClientId = model.ClientId, + Id = model.Id, + DatePurchase = model.DatePurchase, + + }; + } + public void Update(PurchaseBindingModel model) + { + DatePurchase = model.DatePurchase; + } + + public PurchaseViewModel GetViewModel => new() + { + OperationsModel = OperationsModel, + Id = Id, + DatePurchase = DatePurchase, + ClientId = ClientId, + ClientPhoneNumber = Client?.PhoneNumber ?? string.Empty, + + CostViewModels = Costs? + .Select(x => x.Cost.GetViewModel) + .ToList() ?? new(), + OperationViewModels = Operations? + .Select(x => x.Operation?.GetViewModel) + .ToList() ?? new() + }; + + public PurchaseViewModel GetViewModel2 => new() + { + OperationsModel = OperationsModel, + Id = Id, + DatePurchase = DatePurchase, + ClientId = ClientId, + ClientPhoneNumber = Client?.PhoneNumber ?? string.Empty, + + CostViewModels = Costs? + .Select(x => x.Cost.GetViewModel) + .ToList() ?? new() + }; + + public void UpdateOperations(UniversityDB context, PurchaseBindingModel model) + { + var oldOperations = context.OperationByPurchases.Where(x => x.PurchaseId == model.Id).ToDictionary(x => x.OperationId, x => x); + var newOperations = model.OperationsModel.ToDictionary( + x => x.Key, + x => new ClassnByPurchase() + { + OperationId = x.Key, + PurchaseId = Id, + CountOperations = x.Value.CountOperations + } + ); + + context.RemoveRange(oldOperations.Where(x => !newOperations.ContainsKey(x.Key)).Select(x => x.Value)); + context.AddRange (newOperations.Where(x => !oldOperations.ContainsKey(x.Key)).Select(x => x.Value)); + oldOperations + .Where(x => newOperations.ContainsKey(x.Key)) + .Select(x => x.Value).ToList() + .ForEach(x => x.CountOperations = newOperations[x.OperationId].CountOperations); + context.SaveChanges(); + _cachedOperations = null; + } + } +} diff --git a/University/BankDatabaseImplement/UniversityDB.cs b/University/BankDatabaseImplement/UniversityDB.cs new file mode 100644 index 0000000..64dd356 --- /dev/null +++ b/University/BankDatabaseImplement/UniversityDB.cs @@ -0,0 +1,33 @@ +using UniversityDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; + +namespace UniversityDatabaseImplement + +{ + public class UniversityDB: DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseNpgsql(@" + Host=localhost; + Port=5432; + Database=BankFullNew; + Username=postgres; + Password=55256636a;"); + } + base.OnConfiguring(optionsBuilder); + } + + public virtual DbSet Clients { set; get; } + public virtual DbSet Costs { set; get; } + public virtual DbSet CostByPurchases { set; get; } + public virtual DbSet Employees { set; get; } + public virtual DbSet Operations { set; get; } + public virtual DbSet OperationByPurchases { set; get; } + public virtual DbSet Payments { set; get; } + public virtual DbSet Purchases { set; get; } + } +} \ No newline at end of file diff --git a/University/BankDatabaseImplement/UniversityDatabaseImplement.csproj b/University/BankDatabaseImplement/UniversityDatabaseImplement.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/University/BankDatabaseImplement/UniversityDatabaseImplement.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/University/University.sln b/University/University.sln index 4303571..b6e5db2 100644 --- a/University/University.sln +++ b/University/University.sln @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityClientApp", "Univ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityEmpoyeeApp", "UniversityEmpoyeeApp\UniversityEmpoyeeApp.csproj", "{8B5945B5-28E5-4417-965A-A3771F639436}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityDatabaseImplement", "BankDatabaseImplement\UniversityDatabaseImplement.csproj", "{BE727695-0051-424E-B175-A488D5C5D2D7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {8B5945B5-28E5-4417-965A-A3771F639436}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B5945B5-28E5-4417-965A-A3771F639436}.Release|Any CPU.ActiveCfg = Release|Any CPU {8B5945B5-28E5-4417-965A-A3771F639436}.Release|Any CPU.Build.0 = Release|Any CPU + {BE727695-0051-424E-B175-A488D5C5D2D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE727695-0051-424E-B175-A488D5C5D2D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE727695-0051-424E-B175-A488D5C5D2D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE727695-0051-424E-B175-A488D5C5D2D7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE