23 Commits

Author SHA1 Message Date
a03bb5e7aa pretty JSON formatting 2024-06-21 20:54:47 +04:00
c207c9142d add UnityDependencyContainer implementation of IDependencyContainer 2024-06-21 01:47:51 +04:00
662f9f18d3 replace ServiceProvider with DependencyManager in Forms 2024-06-21 01:42:06 +04:00
20cf8869fa change ServiceProvider to DependencyManager in Program.cs 2024-06-21 01:31:35 +04:00
1adb6bb874 implement CreateBackup in MainForm 2024-06-21 01:06:04 +04:00
69e0aa3313 ListImplement 2024-04-20 23:21:53 +04:00
71e0aec32b FileImplement extension 2024-04-20 23:06:11 +04:00
54f300251d Dynamic dependency loading 2024-04-20 22:45:14 +04:00
d509fd016f fixed ViewModels 2024-04-20 22:08:14 +04:00
e827e57c6b Grid configuring in forms 2024-04-20 21:31:20 +04:00
44548da8de Set ViewModel attributes 2024-04-20 21:08:46 +04:00
cfd78033b2 Search client by login 2024-04-20 19:08:51 +04:00
7ff81c6bbd MailWorker Singleton fix 2024-04-20 19:02:55 +04:00
ae8a20a5bb ListImplement and FileImplement 2024-04-20 00:09:57 +04:00
5b1e3e6d58 Update migration 2024-04-19 23:55:01 +04:00
2ed258e3b8 Edit Program.cs 2024-04-19 23:46:09 +04:00
2a2d3d1845 Forms 2024-04-19 23:21:23 +04:00
14aeac885b Messages BusinessLogic 2024-04-19 23:13:19 +04:00
505a708ddf Messages DatabaseImplement 2024-04-19 22:47:28 +04:00
a5df68d9df ClientApp Mails view 2024-04-19 21:41:12 +04:00
0b7edbd7a0 RestApi ClientController 2024-04-19 21:34:16 +04:00
6581e26f7f MailWorker 2024-04-19 21:10:18 +04:00
f07e32804d MessageInfo DataModels, Contracts 2024-04-19 20:32:50 +04:00
223 changed files with 2564 additions and 80494 deletions

4
.gitignore vendored
View File

@@ -398,3 +398,7 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
# AutoWorkshop assemblies
ImplementationExtensions/*.dll

View File

@@ -15,13 +15,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopListImplement",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopFileImplement", "AutoWorkshopFileImplement\AutoWorkshopFileImplement.csproj", "{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopDatabaseImplement", "AutoWorkshopDatabaseImplement\AutoWorkshopDatabaseImplement.csproj", "{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshopDatabaseImplement", "AutoWorkshopDatabaseImplement\AutoWorkshopDatabaseImplement.csproj", "{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopRestApi", "AutoWorkshopRestApi\AutoWorkshopRestApi.csproj", "{15C54F32-1549-4887-BE08-DC6845B0D7ED}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshopRestApi", "AutoWorkshopRestApi\AutoWorkshopRestApi.csproj", "{15C54F32-1549-4887-BE08-DC6845B0D7ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopClientApp", "AutoWorkshopClientApp\AutoWorkshopClientApp.csproj", "{EAE83B19-8CE1-4589-907A-DB9C8313FA06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshopShopApp", "AutoWorkshopShopApp\AutoWorkshopShopApp.csproj", "{5934B924-59F1-42B6-9116-33F4947525CC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshopClientApp", "AutoWorkshopClientApp\AutoWorkshopClientApp.csproj", "{EAE83B19-8CE1-4589-907A-DB9C8313FA06}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -65,10 +63,6 @@ Global
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Release|Any CPU.Build.0 = Release|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>

View File

@@ -0,0 +1,102 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopDataModels.Models;
using Microsoft.Extensions.Logging;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.Serialization.Json;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class BackUpLogic : IBackUpLogic
{
private readonly ILogger _logger;
private readonly IBackUpInfo _backUpInfo;
public BackUpLogic(ILogger<BackUpLogic> Logger, IBackUpInfo BackUpInfo)
{
_logger = Logger;
_backUpInfo = BackUpInfo;
}
public void CreateBackUp(BackUpSaveBindingModel Model)
{
if (_backUpInfo == null)
return;
try
{
_logger.LogDebug("Clear folder");
var DirInfo = new DirectoryInfo(Model.FolderName);
if (DirInfo.Exists)
{
foreach (var File in DirInfo.GetFiles())
{
File.Delete();
}
}
_logger.LogDebug("Delete archive");
string FileName = $"{Model.FolderName}.zip";
if (File.Exists(FileName))
{
File.Delete(FileName);
}
_logger.LogDebug("Get assembly");
var TypeIId = typeof(IId);
var Assembly = TypeIId.Assembly;
if (Assembly == null)
{
throw new ArgumentNullException("Сборка не найдена", nameof(Assembly));
}
var Types = Assembly.GetTypes();
var Method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance);
_logger.LogDebug("Found {count} types", Types.Length);
foreach (var Type in Types)
{
if (Type.IsInterface && Type.GetInterface(TypeIId.Name) != null)
{
var ModelType = _backUpInfo.GetTypeByModelInterface(Type.Name);
if (ModelType == null)
{
throw new InvalidOperationException($"Не найден класс - модель для { Type.Name }");
}
_logger.LogDebug("Call SaveToFile method for {name} Type", Type.Name);
Method?.MakeGenericMethod(ModelType).Invoke(this, new object[] { Model.FolderName });
}
}
_logger.LogDebug("Create zip and remove folder");
ZipFile.CreateFromDirectory(Model.FolderName, FileName);
DirInfo.Delete(true);
}
catch (Exception)
{
throw;
}
}
private void SaveToFile<T>(string FolderName) where T : class, new()
{
var Records = _backUpInfo.GetList<T>();
if (Records == null)
{
_logger.LogWarning("{type} type get null list", typeof(T).Name);
return;
}
var JsonFormatter = new DataContractJsonSerializer(typeof(List<T>));
using var fs = new FileStream(string.Format("{0}/{1}.json", FolderName, typeof(T).Name), FileMode.OpenOrCreate);
using var writer = JsonReaderWriterFactory.CreateJsonWriter(fs, System.Text.Encoding.UTF8, false, true);
JsonFormatter.WriteObject(writer, Records);
}
}
}

View File

@@ -4,10 +4,11 @@ using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
@@ -100,11 +101,11 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
if (string.IsNullOrEmpty(Model.ClientFIO))
throw new ArgumentNullException("Нет ФИО клиента", nameof(Model.ClientFIO));
if (string.IsNullOrEmpty(Model.Email))
throw new ArgumentNullException("Нет Email клиента", nameof(Model.ClientFIO));
if (string.IsNullOrEmpty(Model.Email) || !Regex.IsMatch(Model.Email, @"^[a-z0-9._%+-]+\@([a-z0-9-]+\.)+[a-z]{2,4}$"))
throw new ArgumentException("Почта не соответствует требованиям", nameof(Model.Email));
if (string.IsNullOrEmpty(Model.Password))
throw new ArgumentNullException("Нет пароля клиента", nameof(Model.ClientFIO));
if (string.IsNullOrEmpty(Model.Password) || !Regex.IsMatch(Model.Password, @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9\n]).{10,50}$"))
throw new ArgumentException("Пароль не соответствует требованиям", nameof(Model.Password));
_logger.LogInformation("Client. ClientFIO: {ClientFIO}." +
"Email: {Email}. Password: {Password}. Id: {Id} ", Model.ClientFIO, Model.Email, Model.Password, Model.Id);

View File

@@ -0,0 +1,85 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
private readonly IClientStorage _clientStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> Logger, IMessageInfoStorage MessageInfoStorage, IClientStorage ClientStorage)
{
_logger = Logger;
_messageInfoStorage = MessageInfoStorage;
_clientStorage = ClientStorage;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? Model)
{
_logger.LogDebug("ReadList. MessageId: {MessageId}, ClientId: {ClientId}", Model?.MessageId, Model?.ClientId);
var Result = Model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(Model);
_logger.LogDebug("ReadList result. Count: {Count}", Result.Count);
return Result;
}
public bool Create(MessageInfoBindingModel Model)
{
CheckModel(Model);
if (_messageInfoStorage.Insert(Model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(MessageInfoBindingModel Model, bool WithParams = true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (string.IsNullOrEmpty(Model.MessageId))
throw new ArgumentNullException("Не указан id сообщения", nameof(Model.MessageId));
if (string.IsNullOrEmpty(Model.SenderName))
throw new ArgumentNullException("Не указао почта", nameof(Model.SenderName));
if (string.IsNullOrEmpty(Model.Subject))
throw new ArgumentNullException("Не указана тема", nameof(Model.Subject));
if (string.IsNullOrEmpty(Model.Body))
throw new ArgumentNullException("Не указан текст сообщения", nameof(Model.Subject));
_logger.LogInformation("MessageInfo. MessageId: {MessageId}. SenderName: {SenderName}. Subject: {Subject}. Body: {Body}",
Model.MessageId, Model.SenderName, Model.Subject, Model.Body);
var Element = _clientStorage.GetElement(new ClientSearchModel
{
Email = Model.SenderName
});
if (Element == null)
{
_logger.LogWarning("Не удалось найти клиента, отправившего письмо с адреса {Email}", Model.SenderName);
}
else
{
Model.ClientId = Element.Id;
}
}
}
}

View File

@@ -1,29 +1,29 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopBusinessLogic.MailWorker;
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using DocumentFormat.OpenXml.EMMA;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private static readonly object _locker = new object();
private readonly AbstractMailWorker _mailLogic;
public OrderLogic(ILogger<RepairLogic> Logger, IOrderStorage OrderStorage, IShopStorage ShopStorage)
static readonly object _locker = new object();
public OrderLogic(ILogger<RepairLogic> Logger, IOrderStorage OrderStorage, AbstractMailWorker MailLogic)
{
_logger = Logger;
_orderStorage = OrderStorage;
_shopStorage = ShopStorage;
_mailLogic = MailLogic;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? Model)
@@ -40,6 +40,7 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count: {Count}", List.Count);
return List;
}
public bool CreateOrder(OrderBindingModel Model)
{
CheckModel(Model);
@@ -52,32 +53,69 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
Model.Status = OrderStatus.Accepted;
if (_orderStorage.Insert(Model) is null)
var CreatedOrder = _orderStorage.Insert(Model);
if (CreatedOrder == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private bool ChangeOrderStatus(OrderBindingModel Model, OrderStatus NewStatus)
{
Model = FillOrderBindingModel(Model);
if (Model.Status + 1 != NewStatus)
Task.Run(() => _mailLogic.SendMailAsync(new MailSendInfoBindingModel
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {NewStatus}. Current status: {currStatus}",
NewStatus, Model.Status);
MailAddress = CreatedOrder.ClientEmail,
Subject = $"Изменение статуса заказа номер {CreatedOrder.Id}",
Text = $"Ваш заказ номер {CreatedOrder.Id} на ремонт {CreatedOrder.RepairName} от {CreatedOrder.DateCreate} на сумму {CreatedOrder.Sum} принят."
}));
return true;
}
private bool ChangeOrderStatus(OrderBindingModel Model, OrderStatus NewStatus)
{
CheckModel(Model, false);
var Order = _orderStorage.GetElement(new OrderSearchModel { Id = Model.Id });
if (Order == null)
{
_logger.LogWarning("Change status operation failed. Order not found");
return false;
}
if (Order.Status + 1 != NewStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {NewStatus}. Current status: {currStatus}",
NewStatus, Order.Status);
return false;
}
Model.RepairId = Order.RepairId;
Model.ClientId = Order.ClientId;
if (!Model.ImplementerId.HasValue) Model.ImplementerId = Order.ImplementerId;
Model.Count = Order.Count;
Model.Sum = Order.Sum;
Model.DateCreate = Order.DateCreate;
Model.Status = NewStatus;
if (Model.Status == OrderStatus.Ready)
Model.DateImplement = DateTime.Now;
else
Model.DateImplement = Order.DateImplement;
if (_orderStorage.Update(Model) == null)
{
_logger.LogWarning("Change status operation failed");
return false;
}
return UpdateOrder(Model);
string DateInfo = Model.DateImplement.HasValue ? $"Дата выполнения: {Model.DateImplement}" : "";
Task.Run(() => _mailLogic.SendMailAsync(new MailSendInfoBindingModel
{
MailAddress = Order.ClientEmail,
Subject = $"Изменение статуса заказа номер {Order.Id}",
Text = $"Ваш заказ номер {Order.Id} на ремонт {Order.RepairName} от {Order.DateCreate} на сумму {Order.Sum}. Статус изменен на {NewStatus}. {DateInfo}"
}));
return true;
}
public bool TakeOrderInWork(OrderBindingModel Model)
@@ -95,29 +133,7 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public bool DeliveryOrder(OrderBindingModel Model)
{
lock ( _locker)
{
Model = FillOrderBindingModel(Model);
if (Model.Status != OrderStatus.Ready && Model.Status != OrderStatus.Waiting)
{
_logger.LogWarning("Changing status operation failed");
throw new InvalidOperationException($"Невозможно присвоить статус Delivered заказу с текущим статусом {Model.Status}");
}
if (!_shopStorage.RestockingShops(new SupplyBindingModel
{
RepairId = Model.RepairId,
Count = Model.Count
}))
{
Model.Status = OrderStatus.Waiting;
return UpdateOrder(Model);
}
Model.Status = OrderStatus.Delivered;
return UpdateOrder(Model);
}
return ChangeOrderStatus(Model, OrderStatus.Delivered);
}
private void CheckModel(OrderBindingModel Model, bool WithParams = true)
@@ -161,42 +177,5 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
_logger.LogInformation("ReadElement find. Id: {Id}", Order.Id);
return Order;
}
private OrderBindingModel FillOrderBindingModel(OrderBindingModel Model)
{
CheckModel(Model, false);
var OrderViewModel = _orderStorage.GetElement(new OrderSearchModel()
{
Id = Model.Id
});
if (OrderViewModel == null)
{
throw new InvalidOperationException(nameof(OrderViewModel));
}
Model.Id = OrderViewModel.Id;
Model.DateCreate = OrderViewModel.DateCreate;
Model.RepairId = OrderViewModel.RepairId;
Model.DateImplement = OrderViewModel.DateImplement;
Model.ClientId = OrderViewModel.ClientId;
Model.Status = OrderViewModel.Status;
Model.Count = OrderViewModel.Count;
Model.Sum = OrderViewModel.Sum;
if (!Model.ImplementerId.HasValue)
{
Model.ImplementerId = OrderViewModel.ImplementerId;
}
return Model;
}
private bool UpdateOrder(OrderBindingModel Model)
{
if (_orderStorage.Update(Model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
_logger.LogWarning("Update operation sucsess");
return true;
}
}
}
}

View File

@@ -13,18 +13,16 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
private readonly IComponentStorage _componentStorage;
private readonly IRepairStorage _RepairStorage;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IRepairStorage RepairStorage, IComponentStorage ComponentStorage, IOrderStorage OrderStorage, IShopStorage ShopStorage,
public ReportLogic(IRepairStorage RepairStorage, IComponentStorage ComponentStorage, IOrderStorage OrderStorage,
AbstractSaveToExcel SaveToExcel, AbstractSaveToWord SaveToWord, AbstractSaveToPdf SaveToPdf)
{
_RepairStorage = RepairStorage;
_componentStorage = ComponentStorage;
_orderStorage = OrderStorage;
_shopStorage = ShopStorage;
_saveToExcel = SaveToExcel;
_saveToWord = SaveToWord;
@@ -43,26 +41,6 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
.ToList();
}
public List<ReportShopsViewModel> GetShops()
{
return _shopStorage.GetFullList().Select(x => new ReportShopsViewModel
{
ShopName = x.ShopName,
Repairs = x.ShopRepairs.Select(x => (x.Value.Item1.RepairName, x.Value.Item2)).ToList(),
TotalCount = x.ShopRepairs.Select(x => x.Value.Item2).Sum()
}).ToList();
}
public List<ReportGroupedOrdersViewModel> GetGroupedOrders()
{
return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportGroupedOrdersViewModel
{
Date = x.Key,
OrdersCount = x.Count(),
OrdersSum = x.Select(y => y.Sum).Sum()
}).ToList();
}
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel Model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel { DateFrom = Model.DateFrom, DateTo = Model.DateTo })
@@ -79,7 +57,7 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public void SaveRepairsToWordFile(ReportBindingModel Model)
{
_saveToWord.CreateRepairsDoc(new WordRepairsInfo
_saveToWord.CreateDoc(new WordInfo
{
FileName = Model.FileName,
Title = "Список ремонтов",
@@ -89,7 +67,7 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public void SaveRepairComponentToExcelFile(ReportBindingModel Model)
{
_saveToExcel.CreateReport(new ExcelRepairsInfo
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = Model.FileName,
Title = "Список ремонтов",
@@ -99,7 +77,7 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public void SaveOrdersToPdfFile(ReportBindingModel Model)
{
_saveToPdf.CreateDoc(new PdfOrdersInfo
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = Model.FileName,
Title = "Список заказов",
@@ -108,35 +86,5 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
Orders = GetOrders(Model)
});
}
public void SaveShopsToWordFile(ReportBindingModel model)
{
_saveToWord.CreateShopsDoc(new WordShopsInfo
{
FileName = model.FileName,
Title = "Список магазинов",
Shops = _shopStorage.GetFullList()
});
}
public void SaveShopsToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateShopRepairsReport(new ExcelShopsInfo
{
FileName = model.FileName,
Title = "Загруженность магазинов",
ShopRepairs = GetShops()
});
}
public void SaveGroupedOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateGroupedOrdersDoc(new PdfGroupedOrdersInfo
{
FileName = model.FileName,
Title = "Список заказов, объединенных по датам",
GroupedOrders = GetGroupedOrders()
});
}
}
}

View File

@@ -1,194 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
private readonly IRepairStorage _repairStorage;
public ShopLogic(ILogger<ShopLogic> Logger, IShopStorage ShopStorage, IRepairStorage RepairStorage)
{
_logger = Logger;
_shopStorage = ShopStorage;
_repairStorage = RepairStorage;
}
public List<ShopViewModel>? ReadList(ShopSearchModel? Model)
{
_logger.LogInformation("ReadList. ShopName:{ShopName}.Id:{ Id}", Model?.ShopName, Model?.Id);
var List = Model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(Model);
if (List == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", List.Count);
return List;
}
public ShopViewModel? ReadElement(ShopSearchModel Model)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
_logger.LogInformation("ReadElement. ShopName:{ShopName}.Id:{ Id}", Model.ShopName, Model.Id);
var Element = _shopStorage.GetElement(Model);
if (Element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", Element.Id);
return Element;
}
public bool Create(ShopBindingModel Model)
{
CheckModel(Model);
if (_shopStorage.Insert(Model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ShopBindingModel Model)
{
CheckModel(Model);
if (_shopStorage.Update(Model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ShopBindingModel Model)
{
CheckModel(Model, false);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_shopStorage.Delete(Model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public bool MakeSupply(SupplyBindingModel Model)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (Model.Count <= 0)
throw new ArgumentException("Количество ремонтов должно быть больше 0");
ShopViewModel? Shop = _shopStorage.GetElement(new ShopSearchModel
{
Id = Model.ShopId
});
if (Shop == null)
throw new ArgumentException("Магазина не существует");
int CurrentRepairsNum = Shop.ShopRepairs.Select(x => x.Value.Item2).Sum();
if (Model.Count > Shop.RepairsMaxCount - CurrentRepairsNum)
{
_logger.LogWarning("Попытка добавить в магазин число элементов, большее RepairsMaxCount");
return false;
}
if (Shop.ShopRepairs.ContainsKey(Model.RepairId))
{
var RepairsNum = Shop.ShopRepairs[Model.RepairId];
RepairsNum.Item2 += Model.Count;
Shop.ShopRepairs[Model.RepairId] = RepairsNum;
}
else
{
var Repair = _repairStorage.GetElement(new RepairSearchModel
{
Id = Model.RepairId
});
if (Repair == null)
throw new ArgumentException($"Поставка: Товар с id {Model.RepairId} не найден");
Shop.ShopRepairs.Add(Model.RepairId, (Repair, Model.Count));
}
_shopStorage.Update(new ShopBindingModel()
{
Id = Shop.Id,
ShopName = Shop.ShopName,
Address = Shop.Address,
OpeningDate = Shop.OpeningDate,
ShopRepairs = Shop.ShopRepairs,
RepairsMaxCount = Shop.RepairsMaxCount,
});
return true;
}
private void CheckModel(ShopBindingModel Model, bool WithParams=true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (string.IsNullOrEmpty(Model.Address))
throw new ArgumentException("Адрес магазина длжен быть заполнен", nameof(Model.Address));
if (string.IsNullOrEmpty(Model.ShopName))
throw new ArgumentException("Название магазина должно быть заполнено", nameof(Model.ShopName));
_logger.LogInformation("Shop. ShopName: {ShopName}. Address: {Address}. OpeningDate: {OpeningDate}. Id:{Id}",
Model.ShopName, Model.Address, Model.OpeningDate, Model.Id);
var Element = _shopStorage.GetElement(new ShopSearchModel
{
ShopName = Model.ShopName
});
if (Element != null && Element.Id != Model.Id)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
public bool MakeSell(SupplySearchModel Model)
{
if (!Model.RepairId.HasValue || !Model.Count.HasValue)
return false;
_logger.LogInformation("Поиск ремонтов во всех магазинах");
if (_shopStorage.Sell(Model))
{
_logger.LogInformation("Продажа выполнена успешно");
return true;
}
_logger.LogInformation("Продажа не выполнена");
return false;
}
}
}

View File

@@ -36,18 +36,13 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
var Orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Accepted });
var BeingProcessedOrders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.BeingProcessed });
var WaitingOrders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Waiting });
// in case there are BeingProcessed orders but no Accepted orders
if (Orders == null || BeingProcessedOrders == null || WaitingOrders == null)
if (Orders == null || BeingProcessedOrders == null || (Orders.Count == 0 && BeingProcessedOrders.Count == 0))
{
_logger.LogWarning("DoWork. Orders are null");
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
if (Orders.Count == 0 && BeingProcessedOrders.Count == 0 && WaitingOrders.Count == 0)
{
_logger.LogWarning("DoWork. No orders to process");
return;
}
_logger.LogDebug("DoWork for {Count} orders", Orders.Count);
@@ -63,9 +58,8 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
{
return;
}
await RunWaitingOrders(Implementer);
await RunOrderInWork(Implementer);
await RunOrderInWork(Implementer);
await Task.Run(() =>
{
@@ -92,8 +86,10 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 1000) * Order.Count);
_logger.LogDebug("WorkerWorkAsync. Worker {Id} finish order {Order}", Implementer.Id, Order.Id);
_orderLogic.FinishOrder(new OrderBindingModel { Id = Order.Id });
_orderLogic.DeliveryOrder(new OrderBindingModel { Id = Order.Id });
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = Order.Id
});
}
catch (InvalidOperationException ex)
@@ -134,8 +130,10 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 300) * RunOrder.Count);
_logger.LogDebug("RunOrderInWork. Worker {Id} finish order {Order}", Implementer.Id, RunOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel { Id = RunOrder.Id });
_orderLogic.DeliveryOrder(new OrderBindingModel { Id = RunOrder.Id });
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = RunOrder.Id
});
Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100));
}
@@ -151,43 +149,5 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
throw;
}
}
private async Task RunWaitingOrders(ImplementerViewModel Implementer)
{
if (_orderLogic == null || Implementer == null)
return;
var WaitingOrders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel
{
ImplementerId = Implementer.Id,
Status = OrderStatus.Waiting
}));
if (WaitingOrders == null || WaitingOrders.Count == 0)
{
return;
}
_logger.LogDebug("RunWaitingOrders for {Count} orders. Implementer: {id}.", WaitingOrders.Count, Implementer.Id);
foreach (var WaitingOrder in WaitingOrders)
{
try
{
_logger.LogInformation("RunWaitingOrders. Order {Order} delivery", WaitingOrder.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = WaitingOrder.Id
});
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, $"Error try deliver waiting order {WaitingOrder.Id}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error while delivering waiting order {WaitingOrder.Id}");
throw;
}
}
}
}
}
}

View File

@@ -0,0 +1,84 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.MailWorker
{
public abstract class AbstractMailWorker
{
protected string _mailLogin = string.Empty;
protected string _mailPassword = string.Empty;
protected string _smtpClientHost = string.Empty;
protected int _smtpClientPort;
protected string _popHost = string.Empty;
protected int _popPort;
private readonly IMessageInfoLogic _messageInfoLogic;
private readonly ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> Logger, IMessageInfoLogic MessageInfoLogic)
{
_logger = Logger;
_messageInfoLogic = MessageInfoLogic;
}
public void MailConfig(MailConfigBindingModel Config)
{
_mailLogin = Config.MailLogin;
_mailPassword = Config.MailPassword;
_smtpClientHost = Config.SmtpClientHost;
_smtpClientPort = Config.SmtpClientPort;
_popHost = Config.PopHost;
_popPort = Config.PopPort;
_logger.LogDebug("MailConfig: {Login}, {Password}, {ClientHost}, {ClientPort}, {PopHost}, {PopPort}",
_mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
}
public async void SendMailAsync(MailSendInfoBindingModel Info)
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
return;
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0)
return;
if (string.IsNullOrEmpty(Info.MailAddress) || string.IsNullOrEmpty(Info.Subject) || string.IsNullOrEmpty(Info.Text))
return;
_logger.LogDebug("MailSendAsync: {To}, {Subject}", Info.MailAddress, Info.Subject);
await SendMailImpl(Info);
}
public async void CheckMailAsync()
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
return;
if (string.IsNullOrEmpty(_popHost) || _popPort == 0)
return;
if (_messageInfoLogic == null)
return;
var List = await ReceiveMailImpl();
_logger.LogDebug("CheckMailAsync: New mails: {Count}", List.Count);
foreach (var Mail in List)
{
_messageInfoLogic.Create(Mail);
}
}
protected abstract Task SendMailImpl(MailSendInfoBindingModel Info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailImpl();
}
}

View File

@@ -0,0 +1,85 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace AutoWorkshopBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> Logger, IMessageInfoLogic MessageInfoLogic)
: base(Logger, MessageInfoLogic) { }
protected override async Task SendMailImpl(MailSendInfoBindingModel Info)
{
using var MailMessage = new MailMessage();
using var SmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
MailMessage.From = new MailAddress(_mailLogin);
MailMessage.To.Add(new MailAddress(Info.MailAddress));
MailMessage.Subject = Info.Subject;
MailMessage.Body = Info.Text;
MailMessage.SubjectEncoding = Encoding.UTF8;
MailMessage.BodyEncoding = Encoding.UTF8;
SmtpClient.UseDefaultCredentials = false;
SmtpClient.EnableSsl = true;
SmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
SmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => SmtpClient.Send(MailMessage));
}
catch (Exception)
{
throw;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailImpl()
{
var Result = new List<MessageInfoBindingModel>();
using var Client = new Pop3Client();
await Task.Run(() =>
{
try
{
Client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect);
Client.Authenticate(_mailLogin, _mailPassword);
for (int i = 0; i < Client.Count; i++)
{
var Message = Client.GetMessage(i);
foreach (var Mail in Message.From.Mailboxes)
{
Result.Add(new MessageInfoBindingModel
{
DateDelivery = Message.Date.DateTime,
MessageId = Message.MessageId,
SenderName = Mail.Address,
Subject = Message.Subject,
Body = Message.TextBody
});
}
}
}
catch (AuthenticationException)
{ }
finally
{
Client.Disconnect(true);
}
});
return Result;
}
}
}

View File

@@ -5,7 +5,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
public void CreateReport(ExcelRepairsInfo Info)
public void CreateReport(ExcelInfo Info)
{
CreateExcel(Info);
@@ -78,88 +78,13 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
SaveExcel(Info);
}
public void CreateShopRepairsReport(ExcelShopsInfo Info)
{
CreateExcel(Info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = Info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint RowIndex = 2;
foreach (var ShopRep in Info.ShopRepairs)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = ShopRep.ShopName,
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
foreach (var (Repair, Count) in ShopRep.Repairs)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = RowIndex,
Text = Repair,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = Count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
RowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = ShopRep.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
}
SaveExcel(Info);
}
protected abstract void CreateExcel(IDocumentInfo Info);
protected abstract void CreateExcel(ExcelInfo Info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters ExcelParams);
protected abstract void MergeCells(ExcelMergeParameters ExcelParams);
protected abstract void SaveExcel(IDocumentInfo Info);
protected abstract void SaveExcel(ExcelInfo Info);
}
}

View File

@@ -5,7 +5,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfOrdersInfo Info)
public void CreateDoc(PdfInfo Info)
{
CreatePdf(Info);
CreateParagraph(new PdfParagraph { Text = Info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
@@ -33,35 +33,8 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
SavePdf(Info);
}
public void CreateGroupedOrdersDoc(PdfGroupedOrdersInfo Info)
{
CreatePdf(Info);
CreateParagraph(new PdfParagraph { Text = Info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
CreateTable(new List<string> { "4cm", "3cm", "2cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Дата заказа", "Кол-во", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var groupedOrder in Info.GroupedOrders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { groupedOrder.Date.ToShortDateString(), groupedOrder.OrdersCount.ToString(), groupedOrder.OrdersSum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph { Text = $"Итого: {Info.GroupedOrders.Sum(x => x.OrdersSum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center });
SavePdf(Info);
}
protected abstract void CreatePdf(IDocumentInfo Info);
protected abstract void CreatePdf(PdfInfo Info);
protected abstract void CreateParagraph(PdfParagraph Paragraph);
@@ -69,6 +42,6 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
protected abstract void CreateRow(PdfRowParameters RowParameters);
protected abstract void SavePdf(IDocumentInfo Info);
protected abstract void SavePdf(PdfInfo Info);
}
}

View File

@@ -5,7 +5,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateRepairsDoc(WordRepairsInfo Info)
public void CreateDoc(WordInfo Info)
{
CreateWord(Info);
@@ -37,57 +37,11 @@ namespace AutoWorkshopBusinessLogic.OfficePackage
SaveWord(Info);
}
public void CreateShopsDoc(WordShopsInfo Info)
{
CreateWord(Info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (Info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
CreateTable(new List<string> { "3000", "3000", "3000" });
CreateRow(new WordRowParameters
{
Texts = new List<string> { "Название", "Адрес", "Дата открытия" },
TextProperties = new WordTextProperties
{
Size = "24",
Bold = true,
JustificationType = WordJustificationType.Center
}
});
foreach (var Shop in Info.Shops)
{
CreateRow(new WordRowParameters
{
Texts = new List<string> { Shop.ShopName, Shop.Address, Shop.OpeningDate.ToString() },
TextProperties = new WordTextProperties
{
Size = "22",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(Info);
}
protected abstract void CreateWord(IDocumentInfo Info);
protected abstract void CreateWord(WordInfo Info);
protected abstract void CreateParagraph(WordParagraph Paragraph);
protected abstract void SaveWord(IDocumentInfo Info);
protected abstract void CreateTable(List<string> Colums);
protected abstract void CreateRow(WordRowParameters RowParameters);
protected abstract void SaveWord(WordInfo Info);
}
}

View File

@@ -2,7 +2,7 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class ExcelRepairsInfo : IDocumentInfo
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;

View File

@@ -1,13 +0,0 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class ExcelShopsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportShopsViewModel> ShopRepairs { get; set; } = new();
}
}

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public interface IDocumentInfo
{
public string FileName { get; set; }
public string Title { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class PdfGroupedOrdersInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportGroupedOrdersViewModel> GroupedOrders { get; set; } = new();
}
}

View File

@@ -2,7 +2,7 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class PdfOrdersInfo : IDocumentInfo
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;

View File

@@ -2,7 +2,7 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordRepairsInfo : IDocumentInfo
public class WordInfo
{
public string FileName { get; set; } = string.Empty;

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordRowParameters
{
public List<string> Texts { get; set; } = new();
public WordTextProperties TextProperties { get; set; } = new();
}
}

View File

@@ -1,13 +0,0 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordShopsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ShopViewModel> Shops { get; set; } = new();
}
}

View File

@@ -139,7 +139,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
};
}
protected override void CreateExcel(IDocumentInfo Info)
protected override void CreateExcel(ExcelInfo Info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(Info.FileName, SpreadsheetDocumentType.Workbook);
@@ -269,7 +269,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
MergeCells.Append(MergeCell);
}
protected override void SaveExcel(IDocumentInfo Info)
protected override void SaveExcel(ExcelInfo Info)
{
if (_spreadsheetDocument == null)
return;

View File

@@ -33,7 +33,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
Style.Font.Bold = true;
}
protected override void CreatePdf(IDocumentInfo Info)
protected override void CreatePdf(PdfInfo Info)
{
_document = new Document();
DefineStyles(_document);
@@ -94,7 +94,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
}
}
protected override void SavePdf(IDocumentInfo Info)
protected override void SavePdf(PdfInfo Info)
{
var Renderer = new PdfDocumentRenderer(true)
{

View File

@@ -64,7 +64,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
return Properties;
}
protected override void CreateWord(IDocumentInfo Info)
protected override void CreateWord(WordInfo Info)
{
_wordDocument = WordprocessingDocument.Create(Info.FileName, WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
@@ -103,7 +103,7 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
_docBody.AppendChild(DocParagraph);
}
protected override void SaveWord(IDocumentInfo Info)
protected override void SaveWord(WordInfo Info)
{
if (_docBody == null || _wordDocument == null)
{
@@ -114,79 +114,5 @@ namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Close();
}
private Table? _lastTable;
protected override void CreateTable(List<string> Columns)
{
if (_docBody == null)
return;
_lastTable = new Table();
var TableProp = new TableProperties();
TableProp.AppendChild(new TableLayout { Type = TableLayoutValues.Fixed });
TableProp.AppendChild(new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 }
));
TableProp.AppendChild(new TableWidth { Type = TableWidthUnitValues.Auto });
_lastTable.AppendChild(TableProp);
TableGrid TableGrid = new TableGrid();
foreach (var Column in Columns)
{
TableGrid.AppendChild(new GridColumn() { Width = Column });
}
_lastTable.AppendChild(TableGrid);
_docBody.AppendChild(_lastTable);
}
protected override void CreateRow(WordRowParameters RowParameters)
{
if (_docBody == null || _lastTable == null)
return;
TableRow DocRow = new TableRow();
foreach (var Column in RowParameters.Texts)
{
var DocParagraph = new Paragraph();
WordParagraph Paragraph = new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (Column, RowParameters.TextProperties) },
TextProperties = RowParameters.TextProperties
};
DocParagraph.AppendChild(CreateParagraphProperties(Paragraph.TextProperties));
foreach (var Run in Paragraph.Texts)
{
var DocRun = new Run();
var Properties = new RunProperties();
Properties.AppendChild(new FontSize { Val = Run.Item2.Size });
if (Run.Item2.Bold)
{
Properties.AppendChild(new Bold());
}
DocRun.AppendChild(Properties);
DocRun.AppendChild(new Text { Text = Run.Item1, Space = SpaceProcessingModeValues.Preserve });
DocParagraph.AppendChild(DocRun);
}
TableCell docCell = new TableCell();
docCell.AppendChild(DocParagraph);
DocRow.AppendChild(docCell);
}
_lastTable.AppendChild(DocRow);
}
}
}

View File

@@ -156,5 +156,16 @@ namespace AutoWorkshopClientApp.Controllers
RepairViewModel? Repair = ApiClient.GetRequest<RepairViewModel>($"api/main/getrepair?repairId={repair}");
return count * (Repair?.Price ?? 1);
}
[HttpGet]
public IActionResult Mails()
{
if (ApiClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(ApiClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={ApiClient.Client.Id}"));
}
}
}

View File

@@ -0,0 +1,51 @@
@using AutoWorkshopContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</th>
</tr>
</thead>
<tbody>
@foreach (var Item in Model)
{
<tr>
<td>
@Html.DisplayFor(ModelItem => Item.DateDelivery)
</td>
<td>
@Html.DisplayFor(ModelItem => Item.Subject)
</td>
<td>
@Html.DisplayFor(ModelItem => Item.Body)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@@ -26,6 +26,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li>
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@@ -0,0 +1,26 @@
namespace AutoWorkshopContracts.Attrubites
{
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public ColumnAttribute(string Title = "", bool Visible = true, int Width = 0,
GridViewAutoSize GridViewAutoSize = GridViewAutoSize.None, bool IsUseAutoSize = false)
{
this.Title = Title;
this.Visible = Visible;
this.Width = Width;
this.GridViewAutoSize = GridViewAutoSize;
this.IsUseAutoSize = IsUseAutoSize;
}
public string Title { get; private set; }
public bool Visible { get; private set; }
public int Width { get; private set; }
public GridViewAutoSize GridViewAutoSize { get; private set; }
public bool IsUseAutoSize { get; private set; }
}
}

View File

@@ -0,0 +1,14 @@
namespace AutoWorkshopContracts.Attrubites
{
public enum GridViewAutoSize
{
NotSet = 0,
None = 1,
ColumnHeader = 2,
AllCellsExceptHeader = 4,
AllCells = 6,
DisplayedCellsExceptHeader = 8,
DisplayedCells = 10,
Fill = 16
}
}

View File

@@ -6,6 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoWorkshopDataModels\AutoWorkshopDataModels.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,7 @@
namespace AutoWorkshopContracts.BindingModels
{
public class BackUpSaveBindingModel
{
public string FolderName { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,17 @@
namespace AutoWorkshopContracts.BindingModels
{
public class MailConfigBindingModel
{
public string MailLogin { get; set; } = string.Empty;
public string MailPassword { get; set; } = string.Empty;
public string SmtpClientHost { get; set; } = string.Empty;
public int SmtpClientPort { get; set; }
public string PopHost { get; set; } = string.Empty;
public int PopPort { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace AutoWorkshopContracts.BindingModels
{
public class MailSendInfoBindingModel
{
public string MailAddress { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,21 @@
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.BindingModels
{
public class MessageInfoBindingModel : IMessageInfoModel
{
public int Id { get; set; }
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
}
}

View File

@@ -1,19 +0,0 @@
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.BindingModels
{
public class ShopBindingModel : IShopModel
{
public int Id { get; set; }
public string ShopName { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public DateTime OpeningDate { get; set; } = DateTime.Now;
public Dictionary<int, (IRepairModel, int)> ShopRepairs { get; set; } = new();
public int RepairsMaxCount { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.BindingModels
{
public class SupplyBindingModel : ISupplyModel
{
public int ShopId { get; set; }
public int RepairId { get; set; }
public int Count { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
using AutoWorkshopContracts.BindingModels;
namespace AutoWorkshopContracts.BusinessLogicContracts
{
public interface IBackUpLogic
{
void CreateBackUp(BackUpSaveBindingModel Model);
}
}

View File

@@ -0,0 +1,13 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.BusinessLogicContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? Model);
bool Create(MessageInfoBindingModel Model);
}
}

View File

@@ -8,21 +8,11 @@ namespace AutoWorkshopContracts.BusinessLogicContracts
List<ReportRepairComponentViewModel> GetRepairComponents();
List<ReportOrdersViewModel> GetOrders(ReportBindingModel Model);
List<ReportShopsViewModel> GetShops();
List<ReportGroupedOrdersViewModel> GetGroupedOrders();
void SaveRepairsToWordFile(ReportBindingModel Model);
void SaveRepairComponentToExcelFile(ReportBindingModel Model);
void SaveOrdersToPdfFile(ReportBindingModel Model);
void SaveShopsToWordFile(ReportBindingModel Model);
void SaveShopsToExcelFile(ReportBindingModel Model);
void SaveGroupedOrdersToPdfFile(ReportBindingModel Model);
}
}

View File

@@ -1,23 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.BusinessLogicsContracts
{
public interface IShopLogic
{
List<ShopViewModel>? ReadList(ShopSearchModel? Model);
ShopViewModel? ReadElement(ShopSearchModel Model);
bool Create(ShopBindingModel Model);
bool Update(ShopBindingModel Model);
bool Delete(ShopBindingModel Model);
bool MakeSupply(SupplyBindingModel Model);
bool MakeSell(SupplySearchModel Model);
}
}

View File

@@ -0,0 +1,48 @@
using Microsoft.Extensions.Logging;
namespace AutoWorkshopContracts.DI
{
public class DependencyManager
{
private readonly IDependencyContainer _dependencyContainer;
private static DependencyManager? _manager;
private static readonly object _lock = new();
private DependencyManager()
{
_dependencyContainer = new ServiceDependencyContainer();
}
public static DependencyManager Instance
{
get
{
if (_manager == null)
{
lock (_lock) { _manager = new DependencyManager(); }
}
return _manager;
}
}
public static void InitDependency()
{
var Ext = ServiceProviderLoader.GetImplementationExtension();
if (Ext == null)
{
throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям");
}
Ext.RegisterServices();
}
public void AddLogging(Action<ILoggingBuilder> Configure) => _dependencyContainer.AddLogging(Configure);
public void RegisterType<T, U>(bool IsSingleton = false) where U : class, T where T : class => _dependencyContainer.RegisterType<T, U>(IsSingleton);
public void RegisterType<T>(bool IsSingleton = false) where T : class => _dependencyContainer.RegisterType<T>(IsSingleton);
public T Resolve<T>() => _dependencyContainer.Resolve<T>();
}
}

View File

@@ -0,0 +1,15 @@
using Microsoft.Extensions.Logging;
namespace AutoWorkshopContracts.DI
{
public interface IDependencyContainer
{
void AddLogging(Action<ILoggingBuilder> Configure);
void RegisterType<T, U>(bool IsSingleton) where U : class, T where T : class;
void RegisterType<T>(bool IsSingleton) where T : class;
T Resolve<T>();
}
}

View File

@@ -0,0 +1,9 @@
namespace AutoWorkshopContracts.DI
{
public interface IImplementationExtension
{
public int Priority { get; }
public void RegisterServices();
}
}

View File

@@ -0,0 +1,59 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopContracts.DI
{
public class ServiceDependencyContainer : IDependencyContainer
{
private ServiceProvider? _serviceProvider;
private readonly ServiceCollection _serviceCollection;
public ServiceDependencyContainer()
{
_serviceCollection = new ServiceCollection();
}
public void AddLogging(Action<ILoggingBuilder> Configure)
{
_serviceCollection.AddLogging(Configure);
}
public void RegisterType<T, U>(bool IsSingleton) where U : class, T where T : class
{
if (IsSingleton)
{
_serviceCollection.AddSingleton<T, U>();
}
else
{
_serviceCollection.AddTransient<T, U>();
}
_serviceProvider = null;
}
public void RegisterType<T>(bool IsSingleton) where T : class
{
if (IsSingleton)
{
_serviceCollection.AddSingleton<T>();
}
else
{
_serviceCollection.AddTransient<T>();
}
_serviceProvider = null;
}
public T Resolve<T>()
{
if (_serviceProvider == null)
{
_serviceProvider = _serviceCollection.BuildServiceProvider();
}
return _serviceProvider.GetService<T>()!;
}
}
}

View File

@@ -0,0 +1,50 @@
using System.Reflection;
namespace AutoWorkshopContracts.DI
{
public static class ServiceProviderLoader
{
public static IImplementationExtension? GetImplementationExtension()
{
IImplementationExtension? Source = null;
var Files = Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", SearchOption.AllDirectories);
foreach (var File in Files.Distinct())
{
Assembly Asm = Assembly.LoadFrom(File);
foreach (var Type in Asm.GetExportedTypes())
{
if (Type.IsClass && typeof(IImplementationExtension).IsAssignableFrom(Type))
{
if (Source == null)
{
Source = (IImplementationExtension)Activator.CreateInstance(Type)!;
}
else
{
var NewSource = (IImplementationExtension)Activator.CreateInstance(Type)!;
if (NewSource.Priority > Source.Priority)
{
Source = NewSource;
}
}
}
}
}
return Source;
}
private static string TryGetImplementationExtensionsFolder()
{
var WorkingDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (WorkingDirectory != null && !WorkingDirectory.GetDirectories("ImplementationExtensions", SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions"))
{
WorkingDirectory = WorkingDirectory.Parent;
}
return $"{WorkingDirectory?.FullName}\\ImplementationExtensions";
}
}
}

View File

@@ -0,0 +1,38 @@
using Microsoft.Extensions.Logging;
using Unity;
using Unity.Microsoft.Logging;
namespace AutoWorkshopContracts.DI
{
public class UnityDependencyContainer : IDependencyContainer
{
private readonly IUnityContainer _container;
public UnityDependencyContainer()
{
_container = new UnityContainer();
}
public void AddLogging(Action<ILoggingBuilder> Configure)
{
var Factory = LoggerFactory.Create(Configure);
_container.AddExtension(new LoggingExtension(Factory));
}
public void RegisterType<T>(bool IsSingleton) where T : class
{
_container.RegisterType<T>(IsSingleton ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
void IDependencyContainer.RegisterType<T, U>(bool IsSingleton)
{
_container.RegisterType<T, U>(IsSingleton ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
}
}

View File

@@ -0,0 +1,9 @@
namespace AutoWorkshopContracts.SearchModels
{
public class MessageInfoSearchModel
{
public string? MessageId { get; set; }
public int? ClientId { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopContracts.SearchModels
{
public class ShopSearchModel
{
public int? Id { get; set; }
public string? ShopName { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopContracts.SearchModels
{
public class SupplySearchModel
{
public int? RepairId { get; set; }
public int? Count { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace AutoWorkshopContracts.StoragesContracts
{
public interface IBackUpInfo
{
List<T>? GetList<T>() where T : class, new();
Type? GetTypeByModelInterface(string ModelInterfaceName);
}
}

View File

@@ -0,0 +1,17 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.StoragesContracts
{
public interface IMessageInfoStorage
{
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel Model);
MessageInfoViewModel? Insert(MessageInfoBindingModel Model);
}
}

View File

@@ -1,25 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.StoragesContracts
{
public interface IShopStorage
{
List<ShopViewModel> GetFullList();
List<ShopViewModel> GetFilteredList(ShopSearchModel Model);
ShopViewModel? GetElement(ShopSearchModel Model);
ShopViewModel? Insert(ShopBindingModel Model);
ShopViewModel? Update(ShopBindingModel Model);
ShopViewModel? Delete(ShopBindingModel Model);
bool Sell(SupplySearchModel Model);
bool RestockingShops(SupplyBindingModel Model);
}
}

View File

@@ -1,19 +1,20 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.ViewModels
{
public class ClientViewModel : IClientModel
public class ClientViewModel : IClientModel
{
public int Id { get; set; }
[Column(Visible: false)]
public int Id { get; set; }
[Column(Title: "ФИО клиента", Width: 150)]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Логин (эл. почта)")]
public string Email { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[Column(Title: "Логин (эл. почта)", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string Email { get; set; } = string.Empty;
[Column(Title: "Пароль", Width: 150)]
public string Password { get; set; } = string.Empty;
}
}

View File

@@ -1,16 +1,17 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.ViewModels
{
public class ComponentViewModel : IComponentModel
public class ComponentViewModel : IComponentModel
{
public int Id { get; set; }
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("Название компонента")]
public string ComponentName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Cost { get; set; }
[Column(Title: "Название компонента", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string ComponentName { get; set; } = string.Empty;
[Column(Title: "Цена", Width: 150)]
public double Cost { get; set; }
}
}

View File

@@ -1,22 +1,23 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
public class ImplementerViewModel : IImplementerModel
{
public int Id { get; set; }
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
[Column(Title: "ФИО исполнителя", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[Column(Title: "Пароль", Width: 100)]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж работы")]
public int WorkExperience { get; set; }
[Column(Title: "Стаж работы", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
public int Qualification { get; set; }
[Column(Title: "Квалификация", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public int Qualification { get; set; }
}
}

View File

@@ -0,0 +1,29 @@
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.ViewModels
{
public class MessageInfoViewModel : IMessageInfoModel
{
[Column(Visible: false)]
public int Id { get; set; }
[Column(Visible: false)]
public string MessageId { get; set; } = string.Empty;
[Column(Visible: false)]
public int? ClientId { get; set; }
[Column(Title: "Отправитель", Width: 150)]
public string SenderName { get; set; } = string.Empty;
[Column(Title: "Дата доставки", Width: 120)]
public DateTime DateDelivery { get; set; }
[Column(Title: "Тема", Width: 120)]
public string Subject { get; set; } = string.Empty;
[Column(Title: "Содержание", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string Body { get; set; } = string.Empty;
}
}

View File

@@ -1,42 +1,48 @@
using AutoWorkshopDataModels.Enums;
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Enums;
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
namespace AutoWorkshopContracts.ViewModels
{
public class OrderViewModel : IOrderModel
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int RepairId { get; set; }
[Column(Title: "Номер", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public int Id { get; set; }
[DisplayName("Ремонт")]
public string RepairName { get; set; } = string.Empty;
[Column(Visible: false)]
public int RepairId { get; set; }
public int ClientId { get; set; }
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
[Column(Title: "Ремонт", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public string RepairName { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; }
[Column(Visible: false)]
public int ClientId { get; set; }
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Undefined;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
[Column(Title: "Клиент", Width: 120)]
public string ClientFIO { get; set; } = string.Empty;
[Column(Title: "Почта клиента", Width: 190)]
public string ClientEmail { get; set; } = string.Empty;
[Column(Visible: false)]
public int? ImplementerId { get; set; }
[Column(Title: "Исполнитель", Width: 120)]
public string? ImplementerFIO { get; set; }
[Column(Title: "Количество", Width: 100)]
public int Count { get; set; }
[Column(Title: "Сумма", Width: 75)]
public double Sum { get; set; }
[Column(Title: "Статус", Width: 70)]
public OrderStatus Status { get; set; } = OrderStatus.Undefined;
[Column(Title: "Дата создания", Width: 120)]
public DateTime DateCreate { get; set; } = DateTime.Now;
[Column(Title: "Дата выполнения", Width: 120)]
public DateTime? DateImplement { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopContracts.ViewModels
{
public class RepairCount
{
public RepairViewModel Repair { get; set; } = new();
public int Count { get; set; } = new();
}
}

View File

@@ -1,22 +1,20 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
using AutoWorkshopContracts.Attrubites;
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.ViewModels
{
public class RepairViewModel : IRepairModel
public class RepairViewModel : IRepairModel
{
public int Id { get; set; }
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("Название ремонта")]
public string RepairName { get; set; } = string.Empty;
[Column(Title: "Название ремонта", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string RepairName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> RepairComponents
{
get;
set;
} = new();
[Column(Title: "Цена", Width: 70)]
public double Price { get; set; }
[Column(Visible: false)]
public Dictionary<int, (IComponentModel, int)> RepairComponents { get; set; } = new();
}
}

View File

@@ -1,11 +0,0 @@
namespace AutoWorkshopContracts.ViewModels
{
public class ReportGroupedOrdersViewModel
{
public DateTime Date { get; set; } = DateTime.Now;
public int OrdersCount { get; set; }
public double OrdersSum { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
namespace AutoWorkshopContracts.ViewModels
{
public class ReportShopsViewModel
{
public string ShopName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<(string Repair, int Count)> Repairs { get; set; } = new();
}
}

View File

@@ -1,9 +0,0 @@
namespace AutoWorkshopContracts.ViewModels
{
public class ShopRepairsViewModel
{
public ShopViewModel Shop { get; set; } = new();
public Dictionary<int, RepairCount> ShopRepairs { get; set; } = new();
}
}

View File

@@ -1,24 +0,0 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
namespace AutoWorkshopContracts.ViewModels
{
public class ShopViewModel : IShopModel
{
public int Id { get; set; }
[DisplayName("Название")]
public string ShopName { get; set; } = string.Empty;
[DisplayName("Адрес")]
public string Address { get; set; } = string.Empty;
[DisplayName("Дата открытия")]
public DateTime OpeningDate { get; set; }
public Dictionary<int, (IRepairModel, int)> ShopRepairs { get; set; } = new();
[DisplayName("Вместимость")]
public int RepairsMaxCount { get; set; }
}
}

View File

@@ -7,6 +7,5 @@
BeingProcessed,
Ready,
Delivered,
Waiting,
}
}

View File

@@ -0,0 +1,17 @@
namespace AutoWorkshopDataModels.Models
{
public interface IMessageInfoModel : IId
{
string MessageId { get; }
int? ClientId { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@@ -1,15 +0,0 @@
namespace AutoWorkshopDataModels.Models
{
public interface IShopModel : IId
{
string ShopName { get; }
string Address { get; }
DateTime OpeningDate { get; }
Dictionary<int, (IRepairModel, int)> ShopRepairs { get; }
int RepairsMaxCount { get; }
}
}

View File

@@ -1,11 +0,0 @@
namespace AutoWorkshopDataModels.Models
{
public interface ISupplyModel
{
int ShopId { get; }
int RepairId { get; }
int Count { get; }
}
}

View File

@@ -9,7 +9,7 @@ namespace AutoWorkshopDatabaseImplement
{
if (OptionsBuilder.IsConfigured == false)
{
OptionsBuilder.UseNpgsql(@"Host=localhost;Port=5000;Database=AutoWorkshop_Hard;Username=postgres;Password=admin");
OptionsBuilder.UseNpgsql(@"Host=localhost;Database=AutoWorkshop;Port=5000;Username=postgres;Password=admin");
}
base.OnConfiguring(OptionsBuilder);
@@ -26,12 +26,10 @@ namespace AutoWorkshopDatabaseImplement
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Shop> Shops { get; set; }
public virtual DbSet<ShopRepair> ShopRepairs { get; set; }
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
public virtual DbSet<MessageInfo> Messages { set; get; }
}
}

View File

@@ -21,4 +21,8 @@
<ProjectReference Include="..\AutoWorkshopDataModels\AutoWorkshopDataModels.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@@ -0,0 +1,22 @@
using AutoWorkshopContracts.DI;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopDatabaseImplement.Implements;
namespace AutoWorkshopDatabaseImplement
{
public class ImplementationExtension : IImplementationExtension
{
public int Priority => 2;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<IRepairStorage, RepairStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,29 @@
using AutoWorkshopContracts.StoragesContracts;
namespace AutoWorkshopDatabaseImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
using var Context = new AutoWorkshopDatabase();
return Context.Set<T>().ToList();
}
public Type? GetTypeByModelInterface(string ModelInterfaceName)
{
var Assembly = typeof(BackUpInfo).Assembly;
var Types = Assembly.GetTypes();
foreach (var Type in Types)
{
if (Type.IsClass && Type.GetInterface(ModelInterfaceName) != null)
{
return Type;
}
}
return null;
}
}
}

View File

@@ -19,7 +19,7 @@ namespace AutoWorkshopDatabaseImplement.Implements
public List<ClientViewModel> GetFilteredList(ClientSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ClientFIO) && string.IsNullOrEmpty(Model.Email))
if (string.IsNullOrEmpty(Model.Email) && string.IsNullOrEmpty(Model.ClientFIO))
return new();
using var Context = new AutoWorkshopDatabase();
@@ -44,7 +44,7 @@ namespace AutoWorkshopDatabaseImplement.Implements
return Context.Clients
.FirstOrDefault(x => (string.IsNullOrEmpty(Model.ClientFIO) || x.ClientFIO == Model.ClientFIO) &&
(!Model.Id.HasValue || x.Id == Model.Id) && (string.IsNullOrEmpty(Model.Email) || x.Email == Model.Email) &&
(string.IsNullOrEmpty(Model.Email) || x.Email == Model.Email) && (!Model.Id.HasValue || x.Id == Model.Id) &&
(string.IsNullOrEmpty(Model.Password) || x.Password == Model.Password))?
.GetViewModel;
}

View File

@@ -0,0 +1,56 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDatabaseImplement.Models;
namespace AutoWorkshopDatabaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public List<MessageInfoViewModel> GetFullList()
{
using var Context = new AutoWorkshopDatabase();
return Context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model)
{
using var Context = new AutoWorkshopDatabase();
return Context.Messages
.Where(x => x.ClientId.HasValue && x.ClientId == Model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel Model)
{
if (string.IsNullOrEmpty(Model.MessageId))
return null;
using var Context = new AutoWorkshopDatabase();
return Context.Messages
.FirstOrDefault(x => x.MessageId == Model.MessageId)?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel Model)
{
var NewMessageInfo = MessageInfo.Create(Model);
if (NewMessageInfo == null)
return null;
using var Context = new AutoWorkshopDatabase();
Context.Messages.Add(NewMessageInfo);
Context.SaveChanges();
return NewMessageInfo.GetViewModel;
}
}
}

View File

@@ -1,221 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace AutoWorkshopDatabaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public List<ShopViewModel> GetFullList()
{
using var Context = new AutoWorkshopDatabase();
return Context.Shops
.Include(x => x.Repairs)
.ThenInclude(x => x.Repair)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ShopName))
return new();
using var Context = new AutoWorkshopDatabase();
return Context.Shops
.Include(x => x.Repairs)
.ThenInclude(x => x.Repair)
.Where(x => x.ShopName.Contains(Model.ShopName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? GetElement(ShopSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ShopName) && !Model.Id.HasValue)
return new();
using var Context = new AutoWorkshopDatabase();
return Context.Shops
.Include(x => x.Repairs)
.ThenInclude(x => x.Repair)
.FirstOrDefault(x => (!string.IsNullOrEmpty(Model.ShopName) && x.ShopName == Model.ShopName) ||
(Model.Id.HasValue && x.Id == Model.Id))?
.GetViewModel;
}
public ShopViewModel? Insert(ShopBindingModel Model)
{
using var Context = new AutoWorkshopDatabase();
var NewShop = Shop.Create(Context, Model);
if (NewShop == null)
return null;
Context.Shops.Add(NewShop);
Context.SaveChanges();
return NewShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel Model)
{
using var Context = new AutoWorkshopDatabase();
using var Transaction = Context.Database.BeginTransaction();
try
{
var Shop = Context.Shops.FirstOrDefault(x => x.Id == Model.Id);
if (Shop == null)
return null;
Shop.Update(Model);
Context.SaveChanges();
Shop.UpdateRepairs(Context, Model);
Transaction.Commit();
return Shop.GetViewModel;
}
catch
{
Transaction.Rollback();
throw;
}
}
public ShopViewModel? Delete(ShopBindingModel Model)
{
using var Context = new AutoWorkshopDatabase();
var Shop = Context.Shops
.Include(x => x.Repairs)
.FirstOrDefault(x => x.Id == Model.Id);
if (Shop == null)
return null;
Context.Shops.Remove(Shop);
Context.SaveChanges();
return Shop.GetViewModel;
}
public bool Sell(SupplySearchModel Model)
{
using var Context = new AutoWorkshopDatabase();
var Transaction = Context.Database.BeginTransaction();
try
{
var ShopsWithDesiredRepair = Context.Shops
.Include(x => x.Repairs)
.ThenInclude(x => x.Repair)
.ToList()
.Where(x => x.ShopRepairs.ContainsKey(Model.RepairId.Value))
.OrderByDescending(x => x.ShopRepairs[Model.RepairId.Value].Item2)
.ToList();
foreach (var Shop in ShopsWithDesiredRepair)
{
int Slack = Model.Count.Value - Shop.ShopRepairs[Model.RepairId.Value].Item2;
if (Slack > 0)
{
Shop.ShopRepairs.Remove(Model.RepairId.Value);
Shop.RepairsDictionatyUpdate(Context);
Context.SaveChanges();
Model.Count = Slack;
}
else
{
if (Slack == 0)
{
Shop.ShopRepairs.Remove(Model.RepairId.Value);
}
else
{
var RepairAndCount = Shop.ShopRepairs[Model.RepairId.Value];
RepairAndCount.Item2 = -Slack;
Shop.ShopRepairs[Model.RepairId.Value] = RepairAndCount;
}
Shop.RepairsDictionatyUpdate(Context);
Transaction.Commit();
return true;
}
}
Transaction.Rollback();
return false;
}
catch
{
Transaction.Rollback();
throw;
}
}
public bool RestockingShops(SupplyBindingModel Model)
{
using var Context = new AutoWorkshopDatabase();
var Transaction = Context.Database.BeginTransaction();
var Shops = Context.Shops
.Include(x => x.Repairs)
.ThenInclude(x => x.Repair)
.ToList()
.Where(x => x.RepairsMaxCount > x.ShopRepairs
.Select(x => x.Value.Item2).Sum())
.ToList();
try
{
foreach (Shop Shop in Shops)
{
int FreeSpaceNum = Shop.RepairsMaxCount - Shop.ShopRepairs.Select(x => x.Value.Item2).Sum();
int Refill = Math.Min(FreeSpaceNum, Model.Count);
Model.Count -= Refill;
if (Shop.ShopRepairs.ContainsKey(Model.RepairId))
{
var RepairAndCount = Shop.ShopRepairs[Model.RepairId];
RepairAndCount.Item2 += Refill;
Shop.ShopRepairs[Model.RepairId] = RepairAndCount;
}
else
{
var Repair = Context.Repairs.First(x => x.Id == Model.RepairId);
Shop.ShopRepairs.Add(Model.RepairId, (Repair, Refill));
}
Shop.RepairsDictionatyUpdate(Context);
if (Model.Count == 0)
{
Transaction.Commit();
return true;
}
}
Transaction.Rollback();
return false;
}
catch
{
Transaction.Rollback();
throw;
}
}
}
}

View File

@@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace AutoWorkshopDatabaseImplement.Migrations
{
[DbContext(typeof(AutoWorkshopDatabase))]
[Migration("20240621132359_Lab6_Hard")]
partial class Lab6_Hard
[Migration("20240419194703_Mails")]
partial class Mails
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -97,6 +97,36 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp without time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@@ -186,63 +216,17 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.ToTable("RepairComponents");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Shop", b =>
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("OpeningDate")
.HasColumnType("timestamp without time zone");
b.Property<int>("RepairsMaxCount")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.ShopRepair", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("RepairId")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("RepairId");
b.HasIndex("ShopId");
b.ToTable("ShopRepairs");
b.HasOne("AutoWorkshopDatabaseImplement.Models.Client", null)
.WithMany("ClientMessages")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Order", b =>
{
b.HasOne("AutoWorkshopDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.WithMany("ClientOrders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -283,28 +267,11 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.Navigation("Repair");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.ShopRepair", b =>
{
b.HasOne("AutoWorkshopDatabaseImplement.Models.Repair", "Repair")
.WithMany("Shops")
.HasForeignKey("RepairId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutoWorkshopDatabaseImplement.Models.Shop", "Shop")
.WithMany("Repairs")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Repair");
b.Navigation("Shop");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Component", b =>
@@ -322,13 +289,6 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.Navigation("Components");
b.Navigation("Orders");
b.Navigation("Shops");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Repairs");
});
#pragma warning restore 612, 618
}

View File

@@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace AutoWorkshopDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class Lab6_Hard : Migration
public partial class Mails : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@@ -72,19 +72,24 @@ namespace AutoWorkshopDatabaseImplement.Migrations
});
migrationBuilder.CreateTable(
name: "Shops",
name: "Messages",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ShopName = table.Column<string>(type: "text", nullable: false),
Address = table.Column<string>(type: "text", nullable: false),
OpeningDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
RepairsMaxCount = table.Column<int>(type: "integer", nullable: false)
MessageId = table.Column<string>(type: "text", nullable: false),
ClientId = table.Column<int>(type: "integer", nullable: true),
SenderName = table.Column<string>(type: "text", nullable: false),
DateDelivery = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
Subject = table.Column<string>(type: "text", nullable: false),
Body = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
table.PrimaryKey("PK_Messages", x => x.MessageId);
table.ForeignKey(
name: "FK_Messages_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
@@ -151,32 +156,10 @@ namespace AutoWorkshopDatabaseImplement.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ShopRepairs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RepairId = table.Column<int>(type: "integer", nullable: false),
ShopId = table.Column<int>(type: "integer", nullable: false),
Count = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopRepairs", x => x.Id);
table.ForeignKey(
name: "FK_ShopRepairs_Repairs_RepairId",
column: x => x.RepairId,
principalTable: "Repairs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopRepairs_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
@@ -202,30 +185,20 @@ namespace AutoWorkshopDatabaseImplement.Migrations
name: "IX_RepairComponents_RepairId",
table: "RepairComponents",
column: "RepairId");
migrationBuilder.CreateIndex(
name: "IX_ShopRepairs_RepairId",
table: "ShopRepairs",
column: "RepairId");
migrationBuilder.CreateIndex(
name: "IX_ShopRepairs_ShopId",
table: "ShopRepairs",
column: "ShopId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "RepairComponents");
migrationBuilder.DropTable(
name: "ShopRepairs");
migrationBuilder.DropTable(
name: "Clients");
@@ -237,9 +210,6 @@ namespace AutoWorkshopDatabaseImplement.Migrations
migrationBuilder.DropTable(
name: "Repairs");
migrationBuilder.DropTable(
name: "Shops");
}
}
}

View File

@@ -94,6 +94,36 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp without time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@@ -183,63 +213,17 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.ToTable("RepairComponents");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Shop", b =>
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("OpeningDate")
.HasColumnType("timestamp without time zone");
b.Property<int>("RepairsMaxCount")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.ShopRepair", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("RepairId")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("RepairId");
b.HasIndex("ShopId");
b.ToTable("ShopRepairs");
b.HasOne("AutoWorkshopDatabaseImplement.Models.Client", null)
.WithMany("ClientMessages")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Order", b =>
{
b.HasOne("AutoWorkshopDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.WithMany("ClientOrders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -280,28 +264,11 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.Navigation("Repair");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.ShopRepair", b =>
{
b.HasOne("AutoWorkshopDatabaseImplement.Models.Repair", "Repair")
.WithMany("Shops")
.HasForeignKey("RepairId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutoWorkshopDatabaseImplement.Models.Shop", "Shop")
.WithMany("Repairs")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Repair");
b.Navigation("Shop");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Component", b =>
@@ -319,13 +286,6 @@ namespace AutoWorkshopDatabaseImplement.Migrations
b.Navigation("Components");
b.Navigation("Orders");
b.Navigation("Shops");
});
modelBuilder.Entity("AutoWorkshopDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Repairs");
});
#pragma warning restore 612, 618
}

View File

@@ -3,24 +3,33 @@ using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class Client : IClientModel
{
[DataMember]
public int Id { get; private set; }
[Required]
[DataMember]
[Required]
public string ClientFIO { get; private set; } = string.Empty;
[Required]
[DataMember]
[Required]
public string Email { get; set; } = string.Empty;
[Required]
[DataMember]
[Required]
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
public virtual List<Order> ClientOrders { get; set; } = new();
[ForeignKey("ClientId")]
public virtual List<MessageInfo> ClientMessages { get; set; } = new();
public static Client? Create(ClientBindingModel Model)
{

View File

@@ -3,17 +3,22 @@ using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class Component : IComponentModel
{
[DataMember]
public int Id { get; private set; }
[Required]
[DataMember]
[Required]
public string ComponentName { get; private set; } = string.Empty;
[Required]
[DataMember]
[Required]
public double Cost { get; set; }
[ForeignKey("ComponentId")]

View File

@@ -3,23 +3,30 @@ using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class Implementer : IImplementerModel
{
[DataMember]
public int Id { get; set; }
[Required]
[DataMember]
[Required]
public string ImplementerFIO { get; set; } = string.Empty;
[Required]
[DataMember]
[Required]
public string Password { get; set; } = string.Empty;
[Required]
[DataMember]
[Required]
public int WorkExperience { get; set; }
[Required]
[DataMember]
[Required]
public int Qualification { get; set; }
[ForeignKey("ImplementerId")]

View File

@@ -0,0 +1,61 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class MessageInfo : IMessageInfoModel
{
[NotMapped]
public int Id { get; set; }
[DataMember]
[Key]
public string MessageId { get; set; } = string.Empty;
[DataMember]
public int? ClientId { get; set; }
[DataMember]
public string SenderName { get; set; } = string.Empty;
[DataMember]
public DateTime DateDelivery { get; set; }
[DataMember]
public string Subject { get; set; } = string.Empty;
[DataMember]
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? Model)
{
if (Model == null)
return null;
return new()
{
MessageId = Model.MessageId,
ClientId = Model.ClientId,
SenderName = Model.SenderName,
DateDelivery = Model.DateDelivery,
Subject = Model.Subject,
Body = Model.Body
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

@@ -3,40 +3,51 @@ using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class Order : IOrderModel
{
[DataMember]
public int Id { get; private set; }
[Required]
[DataMember]
[Required]
public int RepairId { get; private set; }
public virtual Repair Repair { get; set; }
[Required]
[DataMember]
[Required]
public int ClientId { get; private set; }
public virtual Client Client { get; set; }
public int? ImplementerId { get; private set; }
[DataMember]
public int? ImplementerId { get; private set; }
public virtual Implementer? Implementer { get; set; }
[Required]
[DataMember]
[Required]
public int Count { get; private set; }
[Required]
[DataMember]
[Required]
public double Sum { get; private set; }
[Required]
[DataMember]
[Required]
public OrderStatus Status { get; private set; } = OrderStatus.Undefined;
[Required]
[DataMember]
[Required]
public DateTime DateCreate { get; private set; } = DateTime.Now;
public DateTime? DateImplement { get; private set; }
[DataMember]
public DateTime? DateImplement { get; private set; }
public static Order? Create(OrderBindingModel Model)
{
@@ -75,6 +86,7 @@ namespace AutoWorkshopDatabaseImplement.Models
ImplementerId = ImplementerId,
RepairName = Repair.RepairName,
ClientFIO = Client.ClientFIO,
ClientEmail = Client.Email,
ImplementerFIO = Implementer?.ImplementerFIO,
Count = Count,
Sum = Sum,

View File

@@ -3,22 +3,28 @@ using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace AutoWorkshopDatabaseImplement.Models
{
[DataContract]
public class Repair : IRepairModel
{
[DataMember]
public int Id { get; set; }
[Required]
[DataMember]
[Required]
public string RepairName { get; set; } = string.Empty;
[Required]
[DataMember]
[Required]
public double Price { get; set; }
private Dictionary<int, (IComponentModel, int)>? _repairComponents = null;
[NotMapped]
[DataMember]
[NotMapped]
public Dictionary<int, (IComponentModel, int)> RepairComponents
{
get
@@ -38,10 +44,7 @@ namespace AutoWorkshopDatabaseImplement.Models
[ForeignKey("RepairId")]
public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("RepairId")]
public virtual List<ShopRepair> Shops { get; set; } = new();
public static Repair Create(AutoWorkshopDatabase Context, RepairBindingModel Model)
{
return new Repair()

View File

@@ -1,131 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace AutoWorkshopDatabaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; set; }
[Required]
public string ShopName { get; set; } = string.Empty;
[Required]
public string Address { get; set; } = string.Empty;
[Required]
public DateTime OpeningDate { get; set; }
[Required]
public int RepairsMaxCount { get; set; }
[ForeignKey("ShopId")]
public List<ShopRepair> Repairs { get; set; } = new();
private Dictionary<int, (IRepairModel, int)>? _shopRepairs = null;
[NotMapped]
public Dictionary<int, (IRepairModel, int)> ShopRepairs
{
get
{
if (_shopRepairs == null)
{
if (_shopRepairs == null)
{
_shopRepairs = Repairs.ToDictionary(ShopRep => ShopRep.RepairId, ShopRep => (ShopRep.Repair as IRepairModel, ShopRep.Count));
}
return _shopRepairs;
}
return _shopRepairs;
}
}
public static Shop Create(AutoWorkshopDatabase Context, ShopBindingModel Model)
{
return new Shop()
{
Id = Model.Id,
ShopName = Model.ShopName,
Address = Model.Address,
OpeningDate = Model.OpeningDate,
Repairs = Model.ShopRepairs.Select(x => new ShopRepair
{
Repair = Context.Repairs.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList(),
RepairsMaxCount = Model.RepairsMaxCount
};
}
public void Update(ShopBindingModel Model)
{
ShopName = Model.ShopName;
Address = Model.Address;
OpeningDate = Model.OpeningDate;
RepairsMaxCount = Model.RepairsMaxCount;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
OpeningDate = OpeningDate,
ShopRepairs = ShopRepairs,
RepairsMaxCount = RepairsMaxCount
};
public void UpdateRepairs(AutoWorkshopDatabase Context, ShopBindingModel Model)
{
var ShopRepairs = Context.ShopRepairs
.Where(rec => rec.ShopId == Model.Id)
.ToList();
if (ShopRepairs != null && ShopRepairs.Count > 0)
{
Context.ShopRepairs.RemoveRange(ShopRepairs.Where(rec => !Model.ShopRepairs.ContainsKey(rec.RepairId)));
Context.SaveChanges();
ShopRepairs = Context.ShopRepairs.Where(rec => rec.ShopId == Model.Id).ToList();
foreach (var RepairToUpdate in ShopRepairs)
{
RepairToUpdate.Count = Model.ShopRepairs[RepairToUpdate.RepairId].Item2;
Model.ShopRepairs.Remove(RepairToUpdate.RepairId);
}
Context.SaveChanges();
}
var Shop = Context.Shops.First(x => x.Id == Id);
foreach (var ShopRepair in Model.ShopRepairs)
{
Context.ShopRepairs.Add(new ShopRepair
{
Shop = Shop,
Repair = Context.Repairs.First(x => x.Id == ShopRepair.Key),
Count = ShopRepair.Value.Item2
});
Context.SaveChanges();
}
_shopRepairs = null;
}
public void RepairsDictionatyUpdate(AutoWorkshopDatabase Context)
{
UpdateRepairs(Context, new ShopBindingModel
{
Id = Id,
ShopRepairs = ShopRepairs
});
}
}
}

View File

@@ -1,22 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace AutoWorkshopDatabaseImplement.Models
{
public class ShopRepair
{
public int Id { get; set; }
[Required]
public int RepairId { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int Count { get; set; }
public virtual Shop Shop { get; set; } = new();
public virtual Repair Repair { get; set; } = new();
}
}

View File

@@ -11,4 +11,8 @@
<ProjectReference Include="..\AutoWorkshopDataModels\AutoWorkshopDataModels.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@@ -10,31 +10,31 @@ namespace AutoWorkshopFileImplement
private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string RepairFileName = "Repair.xml";
private readonly string ShopFileName = "Shop.xml";
private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageInfoFileName = "MessageInfo.xml";
public List<Component> Components { get; private set; }
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Repair> Repairs { get; private set; }
public List<Shop> Shops { get; private set; }
public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
private DataFileSingleton()
public List<MessageInfo> Messages { get; private set; }
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Repairs = LoadData(RepairFileName, "Repair", x => Repair.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
}
Messages = LoadData(MessageInfoFileName, "MessageInfo", x => MessageInfo.Create(x)!)!;
}
public static DataFileSingleton GetInstance()
{
@@ -49,11 +49,11 @@ namespace AutoWorkshopFileImplement
public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
public void SaveMessages() => SaveData(Orders, ImplementerFileName, "Messages", x => x.GetXElement);
private static List<T>? LoadData<T>(string FileName, string XmlNodeName, Func<XElement, T> SelectFunction)
private static List<T>? LoadData<T>(string FileName, string XmlNodeName, Func<XElement, T> SelectFunction)
{
if (File.Exists(FileName))
{

View File

@@ -0,0 +1,22 @@
using AutoWorkshopContracts.DI;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopFileImplement.Implements;
namespace AutoWorkshopFileImplement
{
public class ImplementationExtension : IImplementationExtension
{
public int Priority => 1;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<IRepairStorage, RepairStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,42 @@
using AutoWorkshopContracts.StoragesContracts;
using System.Reflection;
namespace AutoWorkshopFileImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
private readonly DataFileSingleton _source;
private readonly PropertyInfo[] _sourceProperties;
public BackUpInfo()
{
_source = DataFileSingleton.GetInstance();
_sourceProperties = _source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
}
public List<T>? GetList<T>() where T : class, new()
{
var RequiredType = typeof(T);
return (List<T>?)_sourceProperties
.FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == RequiredType)
?.GetValue(_source);
}
public Type? GetTypeByModelInterface(string ModelInterfaceName)
{
var Assembly = typeof(BackUpInfo).Assembly;
var Types = Assembly.GetTypes();
foreach (var Type in Types)
{
if (Type.IsClass && Type.GetInterface(ModelInterfaceName) != null)
{
return Type;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,56 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopFileImplement.Models;
namespace AutoWorkshopFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton _source;
public MessageInfoStorage()
{
_source = DataFileSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
return _source.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model)
{
return _source.Messages
.Where(x => x.ClientId.HasValue && x.ClientId == Model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel Model)
{
if (string.IsNullOrEmpty(Model.MessageId))
return null;
return _source.Messages
.FirstOrDefault(x => x.MessageId == Model.MessageId)?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel Model)
{
var NewMessageInfo = MessageInfo.Create(Model);
if (NewMessageInfo == null)
return null;
_source.Messages.Add(NewMessageInfo);
_source.SaveMessages();
return NewMessageInfo.GetViewModel;
}
}
}

View File

@@ -1,168 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopFileImplement.Models;
namespace AutoWorkshopFileImplement.Implements
{
public class ShopStorage : IShopStorage
{
private readonly DataFileSingleton _source;
public ShopStorage()
{
_source = DataFileSingleton.GetInstance();
}
public List<ShopViewModel> GetFullList()
{
return _source.Shops.Select(x => x.GetViewModel).ToList();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ShopName))
return new();
return _source.Shops
.Where(x => x.ShopName
.Contains(Model.ShopName))
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? GetElement(ShopSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ShopName) && !Model.Id.HasValue)
return null;
return _source.Shops.FirstOrDefault(x =>
(!string.IsNullOrEmpty(Model.ShopName) && x.ShopName == Model.ShopName) ||
(Model.Id.HasValue && x.Id == Model.Id))?
.GetViewModel;
}
public ShopViewModel? Insert(ShopBindingModel Model)
{
Model.Id = _source.Shops.Count > 0 ? _source.Shops.Max(x => x.Id) + 1 : 1;
var NewShop = Shop.Create(Model);
if (NewShop == null)
return null;
_source.Shops.Add(NewShop);
_source.SaveShops();
return NewShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel Model)
{
var Shop = _source.Shops.FirstOrDefault(x => x.Id == Model.Id);
if (Shop == null)
return null;
Shop.Update(Model);
_source.SaveShops();
return Shop.GetViewModel;
}
public ShopViewModel? Delete(ShopBindingModel Model)
{
var Shop = _source.Shops.FirstOrDefault(x => x.Id == Model.Id);
if (Shop == null)
return null;
_source.Shops.Remove(Shop);
_source.SaveShops();
return Shop.GetViewModel;
}
public bool Sell(SupplySearchModel Model)
{
if (Model == null || !Model.RepairId.HasValue || !Model.Count.HasValue)
return false;
int TotalRepairsNum = _source.Shops
.Select(x => x.Repairs.ContainsKey(Model.RepairId.Value) ? x.Repairs[Model.RepairId.Value] : 0)
.Sum();
if (TotalRepairsNum < Model.Count)
return false;
var ShopsWithDesiredRepair = _source.Shops
.Where(x => x.Repairs.ContainsKey(Model.RepairId.Value))
.OrderByDescending(x => x.Repairs[Model.RepairId.Value])
.ToList();
foreach (var Shop in ShopsWithDesiredRepair)
{
int Slack = Model.Count.Value - Shop.Repairs[Model.RepairId.Value];
if (Slack > 0)
{
Shop.Repairs.Remove(Model.RepairId.Value);
Shop.RepairsUpdate();
Model.Count = Slack;
}
else
{
if (Slack == 0)
Shop.Repairs.Remove(Model.RepairId.Value);
else
Shop.Repairs[Model.RepairId.Value] = -Slack;
Shop.RepairsUpdate();
_source.SaveShops();
return true;
}
}
_source.SaveShops();
return false;
}
public bool RestockingShops(SupplyBindingModel Model)
{
int TotalFreeSpaceNum = _source.Shops
.Select(x => x.RepairsMaxCount - x.ShopRepairs
.Select(y => y.Value.Item2)
.Sum())
.Sum();
if (TotalFreeSpaceNum < Model.Count)
return false;
foreach (Shop Shop in _source.Shops)
{
int FreeSpaceNum = Shop.RepairsMaxCount - Shop.ShopRepairs.Select(x => x.Value.Item2).Sum();
if (FreeSpaceNum <= 0)
continue;
FreeSpaceNum = Math.Min(FreeSpaceNum, Model.Count);
Model.Count -= FreeSpaceNum;
if (Shop.Repairs.ContainsKey(Model.RepairId))
Shop.Repairs[Model.RepairId] += FreeSpaceNum;
else
Shop.Repairs.Add(Model.RepairId, FreeSpaceNum);
Shop.RepairsUpdate();
if (Model.Count == 0)
{
_source.SaveShops();
return true;
}
}
return false;
}
}
}

View File

@@ -1,19 +1,25 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Client : IClientModel
[DataContract]
public class Client : IClientModel
{
[DataMember]
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
[DataMember]
public string ClientFIO { get; private set; } = string.Empty;
[DataMember]
public string Email { get; set; } = string.Empty;
[DataMember]
public string Password { get; set; } = string.Empty;
public static Client? Create(ClientBindingModel Model)
{

View File

@@ -1,17 +1,22 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Component : IComponentModel
[DataContract]
public class Component : IComponentModel
{
[DataMember]
public int Id { get; private set; }
public string ComponentName { get; private set; } = string.Empty;
public double Cost { get; set; }
[DataMember]
public string ComponentName { get; private set; } = string.Empty;
[DataMember]
public double Cost { get; set; }
public static Component? Create(ComponentBindingModel Model)
{

View File

@@ -1,21 +1,28 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Implementer : IImplementerModel
[DataContract]
public class Implementer : IImplementerModel
{
[DataMember]
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
[DataMember]
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
[DataMember]
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
[DataMember]
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
[DataMember]
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel Model)
{

View File

@@ -0,0 +1,85 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
[DataContract]
public class MessageInfo : IMessageInfoModel
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string MessageId { get; set; } = string.Empty;
[DataMember]
public int? ClientId { get; set; }
[DataMember]
public string SenderName { get; set; } = string.Empty;
[DataMember]
public DateTime DateDelivery { get; set; }
[DataMember]
public string Subject { get; set; } = string.Empty;
[DataMember]
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? Model)
{
if (Model == null)
return null;
return new()
{
MessageId = Model.MessageId,
ClientId = Model.ClientId,
SenderName = Model.SenderName,
DateDelivery = Model.DateDelivery,
Subject = Model.Subject,
Body = Model.Body
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
public static MessageInfo? Create(XElement Element)
{
if (Element == null)
return null;
return new()
{
MessageId = Element.Attribute("MessageId")!.Value,
ClientId = Convert.ToInt32(Element.Attribute("ClientId")!.Value),
SenderName = Element.Attribute("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(Element.Attribute("DateDelivery")!.Value),
Subject = Element.Attribute("Subject")!.Value,
Body = Element.Attribute("Body")!.Value,
};
}
public XElement GetXElement => new(
"MessageInfo",
new XAttribute("MessageId", MessageId),
new XAttribute("ClientId", ClientId),
new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery),
new XAttribute("Subject", Subject),
new XAttribute("Body", Body)
);
}
}

View File

@@ -2,29 +2,40 @@
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Order : IOrderModel
[DataContract]
public class Order : IOrderModel
{
[DataMember]
public int Id { get; private set; }
public int RepairId { get; private set; }
[DataMember]
public int RepairId { get; private set; }
public int ClientId { get; private set; }
[DataMember]
public int ClientId { get; private set; }
public int? ImplementerId { get; set; }
[DataMember]
public int? ImplementerId { get; set; }
public int Count { get; private set; }
[DataMember]
public int Count { get; private set; }
public double Sum { get; private set; }
[DataMember]
public double Sum { get; private set; }
public OrderStatus Status { get; private set; }
[DataMember]
public OrderStatus Status { get; private set; }
public DateTime DateCreate { get; private set; }
[DataMember]
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; }
[DataMember]
public DateTime? DateImplement { get; private set; }
public static Order? Create(OrderBindingModel? Model)
{

View File

@@ -1,23 +1,29 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Repair : IRepairModel
[DataContract]
public class Repair : IRepairModel
{
public int Id { get; private set; }
public string RepairName { get; private set; } = string.Empty;
public double Price { get; private set; }
[DataMember]
public int Id { get; private set; }
[DataMember]
public string RepairName { get; private set; } = string.Empty;
[DataMember]
public double Price { get; private set; }
public Dictionary<int, int> Components { get; private set; } = new();
private Dictionary<int, (IComponentModel, int)>? _RepairComponents = null;
public Dictionary<int, (IComponentModel, int)> RepairComponents
[DataMember]
public Dictionary<int, (IComponentModel, int)> RepairComponents
{
get
{

View File

@@ -1,110 +0,0 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Models;
using System.Xml.Linq;
namespace AutoWorkshopFileImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
public string ShopName { get; private set; } = string.Empty;
public string Address { get; private set; } = string.Empty;
public DateTime OpeningDate { get; private set; }
public Dictionary<int, int> Repairs { get; private set; } = new();
private Dictionary<int, (IRepairModel, int)>? _shopRepairs = null;
public Dictionary<int, (IRepairModel, int)> ShopRepairs
{
get
{
if (_shopRepairs == null)
{
var Source = DataFileSingleton.GetInstance();
_shopRepairs = Repairs.ToDictionary(x => x.Key, y => ((Source.Repairs.FirstOrDefault(z => z.Id == y.Key) as IRepairModel)!, y.Value));
}
return _shopRepairs;
}
}
public int RepairsMaxCount { get; private set; }
public static Shop? Create(ShopBindingModel? Model)
{
if (Model == null)
return null;
return new Shop()
{
Id = Model.Id,
ShopName = Model.ShopName,
Address = Model.Address,
OpeningDate = Model.OpeningDate,
Repairs = Model.ShopRepairs.ToDictionary(x => x.Key, x => x.Value.Item2),
RepairsMaxCount = Model.RepairsMaxCount
};
}
public static Shop? Create(XElement Element)
{
if (Element == null)
return null;
return new Shop()
{
Id = Convert.ToInt32(Element.Attribute("Id")!.Value),
ShopName = Element.Element("ShopName")!.Value,
Address = Element.Element("Address")!.Value,
OpeningDate = Convert.ToDateTime(Element.Element("OpeningDate")!.Value),
Repairs = Element.Element("ShopRepairs")!.Elements("ShopRepair")!.ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value),
x => Convert.ToInt32(x.Element("Value")?.Value)),
RepairsMaxCount = Convert.ToInt32(Element.Element("RepairsMaxCount")!.Value)
};
}
public void Update(ShopBindingModel? Model)
{
if (Model == null)
return;
ShopName = Model.ShopName;
Address = Model.Address;
OpeningDate = Model.OpeningDate;
RepairsMaxCount = Model.RepairsMaxCount;
Repairs = Model.ShopRepairs.ToDictionary(x => x.Key, x => x.Value.Item2);
_shopRepairs = null;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
OpeningDate = OpeningDate,
ShopRepairs = ShopRepairs,
RepairsMaxCount = RepairsMaxCount
};
public XElement GetXElement => new(
"Shop",
new XAttribute("Id", Id),
new XElement("ShopName", ShopName),
new XElement("Address", Address),
new XElement("OpeningDate", OpeningDate.ToString()),
new XElement("ShopRepairs", Repairs.Select(
x => new XElement("ShopRepair", new XElement("Key", x.Key), new XElement("Value", x.Value))).ToArray()),
new XElement("RepairsMaxCount", RepairsMaxCount.ToString())
);
public void RepairsUpdate()
{
_shopRepairs = null;
}
}
}

Some files were not shown because too many files have changed in this diff Show More