доработки

This commit is contained in:
анна 2024-05-26 19:47:37 +04:00
parent 7abc48f86c
commit 6e622c82ce
39 changed files with 289 additions and 73 deletions

View File

@ -29,7 +29,7 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
if (model == null) if (model == null)
{ {
throw new ArgumentNullException(nameof(model), "Произошла ошибка на уровне проверки OperationBindingModel"); throw new ArgumentNullException(nameof(model), "Произошла ошибка на уровне проверки ClassBindingModel");
} }
} }
@ -38,7 +38,7 @@ namespace UniversityBusinessLogics.BusinessLogic
CheckOnlyModel(model); CheckOnlyModel(model);
if (model.Price <= 0) if (model.Price <= 0)
{ {
throw new ArgumentException($"Произошла ошибка на уровне проверки OperationBindingModel. Стоимость операции (Price={model.Price}) должна быть больше 0"); throw new ArgumentException($"Произошла ошибка на уровне проверки ClassBindingModel. Стоимость операции (Price={model.Price}) должна быть больше 0");
} }
} }
@ -48,7 +48,7 @@ namespace UniversityBusinessLogics.BusinessLogic
CheckUpdateModel(model); CheckUpdateModel(model);
if (string.IsNullOrEmpty(model.Name) && string.IsNullOrEmpty(model.Time)) if (string.IsNullOrEmpty(model.Name) && string.IsNullOrEmpty(model.Time))
{ {
throw new ArgumentNullException($"Произошла ошибка на уровне проверки OperationBindingModel.Вид и тип операции не должна быть нулевыми или пустыми."); throw new ArgumentNullException($"Произошла ошибка на уровне проверки ClassBindingModel.Вид и тип операции не должна быть нулевыми или пустыми.");
} }
} }
@ -57,13 +57,13 @@ namespace UniversityBusinessLogics.BusinessLogic
try try
{ {
var results = model != null ? _carStorage.GetFilteredList(model) : _carStorage.GetFullList(); var results = model != null ? _carStorage.GetFilteredList(model) : _carStorage.GetFullList();
_logger.LogDebug("Список операций: {@operations}", results); _logger.LogDebug("Список операций: {@classes}", results);
_logger.LogInformation("Извлечение списка операций по {@OperationSearchModel} модели", model); _logger.LogInformation("Извлечение списка операций по {@ClassSearchModel} модели", model);
return results; return results;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, "Произошла ошибка при попытки получить список по {@OperationSearchModel} модели", model); _logger.LogError(e, "Произошла ошибка при попытки получить список по {@ClassSearchModel} модели", model);
throw; throw;
} }
} }
@ -77,12 +77,12 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
throw new ArgumentNullException($"Не получилось получить эдемент с id {model.Id}"); throw new ArgumentNullException($"Не получилось получить эдемент с id {model.Id}");
} }
_logger.LogInformation("Извлечение элемента {@OperationViewModel} c обследований по {@OperationSearchModel} модели", result, model); _logger.LogInformation("Извлечение элемента {@ClassViewModel} c обследований по {@ClassSearchModel} модели", result, model);
return result; return result;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, "Произошла ошибка при попытки получить элемент по {@OperationSearchModel} модели:", model); _logger.LogError(e, "Произошла ошибка при попытки получить элемент по {@ClassSearchModel} модели:", model);
throw; throw;
} }
} }
@ -97,12 +97,12 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
throw new ArgumentNullException($"Не получилось создать операцию"); throw new ArgumentNullException($"Не получилось создать операцию");
} }
_logger.LogInformation("Создана сущность {@OperationViewModel}", result); _logger.LogInformation("Создана сущность {@ClassViewModel}", result);
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, "Произошла ошибка при попытки создать элемент по {@OperationBindingModel} модели", model); _logger.LogError(e, "Произошла ошибка при попытки создать элемент по {@ClassBindingModel} модели", model);
throw; throw;
} }
} }
@ -117,12 +117,12 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
throw new ArgumentNullException($"Результат обновления обследований оказался нулевым"); throw new ArgumentNullException($"Результат обновления обследований оказался нулевым");
} }
_logger.LogInformation("Была обновлена сущность на: {@OperationViewModel}", result); _logger.LogInformation("Была обновлена сущность на: {@ClassViewModel}", result);
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, "Произошла ошибка при попытки обновить элемент по модели: {@OperationBindingModel}", model); _logger.LogError(e, "Произошла ошибка при попытки обновить элемент по модели: {@ClassBindingModel}", model);
throw; throw;
} }
} }
@ -137,12 +137,12 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
throw new ArgumentNullException($"Не получилось удалить операциб"); throw new ArgumentNullException($"Не получилось удалить операциб");
} }
_logger.LogInformation("Удалена сущность {@OperationViewModel}", result); _logger.LogInformation("Удалена сущность {@ClassViewModel}", result);
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, "Произошла ошибка при попытки удалить элемент по {@OperationBindingModel} модели", model); _logger.LogError(e, "Произошла ошибка при попытки удалить элемент по {@ClassBindingModel} модели", model);
throw; throw;
} }
} }

View File

@ -28,17 +28,17 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
return; return;
} }
if (string.IsNullOrEmpty(model.PhoneNumber)) if (string.IsNullOrEmpty(model.Login))
{ {
throw new ArgumentNullException(nameof(model.PhoneNumber), "Нет логина клиента"); throw new ArgumentNullException(nameof(model.Login), "Нет логина клиента");
} }
if (string.IsNullOrEmpty(model.Password)) if (string.IsNullOrEmpty(model.Password))
{ {
throw new ArgumentNullException(nameof(model.Password), "Нет пароля клиента"); throw new ArgumentNullException(nameof(model.Password), "Нет пароля клиента");
} }
if (model.PhoneNumber.Length is < 11) if (model.Login.Length is < 5)
{ {
throw new ArgumentException(nameof(model.PhoneNumber), "Длина номера телефона должна быть 11 цифр"); throw new ArgumentException(nameof(model.Login), "Длина логина должна быть 5 символов");
} }
if (model.Password.Length < 5) if (model.Password.Length < 5)
@ -54,11 +54,11 @@ namespace UniversityBusinessLogics.BusinessLogic
_logger.LogDebug("{level} Проверка логина пользователя на уникальность {@Client}", model); _logger.LogDebug("{level} Проверка логина пользователя на уникальность {@Client}", model);
var element = _clientStorage.GetElement(new ClientSearchModel var element = _clientStorage.GetElement(new ClientSearchModel
{ {
PhoneNumber = model.PhoneNumber, Login = model.Login,
}); });
if (element != null && element.Id != model.Id) if (element != null && element.Id != model.Id)
{ {
_logger.LogWarning("С номером {PhoneNumber}, уже есть пользователь: {@ExistClient}", model.PhoneNumber, element); _logger.LogWarning("С номером {Login}, уже есть пользователь: {@ExistClient}", model.Login, element);
throw new InvalidOperationException($"Клиент с таким номером телефона уже есть"); throw new InvalidOperationException($"Клиент с таким номером телефона уже есть");
} }
} }

View File

@ -41,6 +41,10 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
throw new ArgumentNullException(nameof(model.Password), "Нет пароля клиента"); throw new ArgumentNullException(nameof(model.Password), "Нет пароля клиента");
} }
if (model.Login.Length is < 5)
{
throw new ArgumentException(nameof(model.Login), "Длина номера телефона должна быть 11 цифр");
}
if (model.Password.Length < 5) if (model.Password.Length < 5)
{ {
@ -53,7 +57,15 @@ namespace UniversityBusinessLogics.BusinessLogic
"Пароль пользователя должен содержать хотя бы одну цифру"); "Пароль пользователя должен содержать хотя бы одну цифру");
} }
_logger.LogDebug("{level} Проверка логина пользователя на уникальность {@Employee}", model); _logger.LogDebug("{level} Проверка логина пользователя на уникальность {@Employee}", model);
var element = _employeeStorage.GetElement(new EmployeeSearchModel
{
Login = model.Login,
});
if (element != null && element.Id != model.Id)
{
_logger.LogWarning("С номером {Login}, уже есть пользователь: {@ExistEmployee}", model.Login, element);
throw new InvalidOperationException($"Сотрудник с таким логином уже есть");
}
} }
public bool Create(EmployeeBindingModel model) public bool Create(EmployeeBindingModel model)

View File

@ -3,6 +3,10 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.StoragesContracts; using UniversityContracts.StoragesContracts;
namespace UniversityBusinessLogics.BusinessLogic namespace UniversityBusinessLogics.BusinessLogic
@ -11,14 +15,14 @@ namespace UniversityBusinessLogics.BusinessLogic
{ {
private readonly AbstractSaveToWord _saveToWord; private readonly AbstractSaveToWord _saveToWord;
private readonly IPurchaseStorage _purchaseStorage; private readonly IPurchaseStorage _purchaseStorage;
private readonly IOperationStorage _carStorage; private readonly IClassStorage _carStorage;
private readonly AbstractSaveToExcel _saveToExcel; private readonly AbstractSaveToExcel _saveToExcel;
private readonly IPaymentStorage _paymentStorage; private readonly IPaymentStorage _paymentStorage;
private readonly AbstractMailWorker _mailWorker; private readonly AbstractMailWorker _mailWorker;
private readonly AbstractSaveToPdf _saveToPdf; private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(AbstractSaveToWord saveToWord, IPurchaseStorage purchaseStorage, AbstractSaveToExcel saveToExcel, public ReportLogic(AbstractSaveToWord saveToWord, IPurchaseStorage purchaseStorage, AbstractSaveToExcel saveToExcel,
AbstractMailWorker mailWorker, IPaymentStorage paymentStorage, AbstractSaveToPdf saveToPdf, IOperationStorage carStorage) AbstractMailWorker mailWorker, IPaymentStorage paymentStorage, AbstractSaveToPdf saveToPdf, IClassStorage carStorage)
{ {
_mailWorker = mailWorker; _mailWorker = mailWorker;
_paymentStorage = paymentStorage; _paymentStorage = paymentStorage;
@ -36,7 +40,7 @@ namespace UniversityBusinessLogics.BusinessLogic
FileName = option.FileName, FileName = option.FileName,
Stream = option.Stream, Stream = option.Stream,
Title = "Список сделок вместе с операциями", Title = "Список сделок вместе с операциями",
ReportObjects = _purchaseStorage.GetFilteredList(new() { OperationsIds = option.Ids.ToList() }) ReportObjects = _purchaseStorage.GetFilteredList(new() { ClassesIds = option.Ids.ToList() })
.Select(x => (object)x).ToList(), .Select(x => (object)x).ToList(),
}); });
} }
@ -48,7 +52,7 @@ namespace UniversityBusinessLogics.BusinessLogic
FileName = option.FileName, FileName = option.FileName,
Stream = option.Stream, Stream = option.Stream,
Title = "Список сделок вместе с операциями", Title = "Список сделок вместе с операциями",
ReportObjects = _purchaseStorage.GetFilteredList(new() { OperationsIds = option.Ids.ToList() }) ReportObjects = _purchaseStorage.GetFilteredList(new() { ClassesIds = option.Ids.ToList() })
.Select(x => (object)x).ToList(), .Select(x => (object)x).ToList(),
Headers = new() { "Сделка", "Дата сделки", } Headers = new() { "Сделка", "Дата сделки", }
}); });

View File

@ -1,7 +0,0 @@
namespace UniversityBusinessLogics
{
public class Class1
{
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UniversityContracts.BindingModels;
namespace UniversityBusinessLogics.MailWorker namespace UniversityBusinessLogics.MailWorker
{ {

View File

@ -7,6 +7,7 @@ using System.Net.Mime;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UniversityContracts.BindingModels;
namespace UniversityBusinessLogics.MailWorker namespace UniversityBusinessLogics.MailWorker
{ {

View File

@ -71,7 +71,7 @@ namespace UniversityBusinessLogics.OfficePackage
StyleInfo = ExcelStyleInfoType.Text StyleInfo = ExcelStyleInfoType.Text
}); });
int i = 0; int i = 0;
foreach (var car in purchase.OperationViewModels) foreach (var car in purchase.ClassViewModels)
{ {
if (info.Ids != null && !info.Ids.Contains(car.Id)) if (info.Ids != null && !info.Ids.Contains(car.Id))
{ {

View File

@ -6,30 +6,66 @@ using Serilog;
using UniversityDatabaseImplement.Implements; using UniversityDatabaseImplement.Implements;
using UiversityDatabaseImplement.Implements; using UiversityDatabaseImplement.Implements;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityBusinessLogics.OfficePackage;
using UniversityContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews(); builder.Services.AddControllersWithViews();
builder.Services.AddSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè builder.Services.AddSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IPurchaseLogic, PurchaseLogic>(); builder.Services.AddTransient<IPurchaseLogic, PurchaseLogic>();
builder.Services.AddTransient<IClassLogic, ClassLogic>(); builder.Services.AddTransient<IClassLogic, ClassLogic>();
builder.Services.AddTransient<IReportLogic, ReportLogic>();
builder.Services.AddTransient<IPaymentLogic, PaymentLogic>(); builder.Services.AddTransient<IPaymentLogic, PaymentLogic>();
builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>();
builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
builder.Services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IPurchaseStorage, PurchaseStorage>(); builder.Services.AddTransient<IPurchaseStorage, PurchaseStorage>();
builder.Services.AddTransient<IClassStorage, ClassStorage>(); builder.Services.AddTransient<IClassStorage, ClassStorage>();
builder.Services.AddTransient<IPaymentStorage, PaymentStorage>(); builder.Services.AddTransient<IPaymentStorage, PaymentStorage>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddLogging(option =>
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
option.AddSerilog(logger);
});
var app = builder.Build(); var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
{ {
app.UseExceptionHandler("/Error"); app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts(); app.UseHsts();
} }
@ -39,7 +75,10 @@ app.UseStaticFiles();
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();
app.UseSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè
app.MapRazorPages(); app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run(); app.Run();

View File

@ -0,0 +1,9 @@
namespace UniversityClientApp
{
public class SessionKeys
{
public const string ClientLogic = "AuthenticationClientLogic";
public const string ClientPassword = "AuthenticationClientPassword";
}
}

View File

@ -20,6 +20,8 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" /> <PackageReference Include="System.Text.Json" Version="6.0.0" />

View File

@ -11,7 +11,7 @@ namespace UniversityContracts.BindingModels
public string? MiddleName { get; set; } public string? MiddleName { get; set; }
public string PhoneNumber { get; set; } = string.Empty; public string Login { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;

View File

@ -12,7 +12,6 @@ namespace UniversityContracts.BindingModels
public int EmployeeId { get; set; } public int EmployeeId { get; set; }
public string NameOfCost { get; set; } = string.Empty; public string NameOfCost { get; set; } = string.Empty;
public string Discription { get; set; } = string.Empty;
public double Price { get; set; } public double Price { get; set; }
public Dictionary<int, CostByPurchaseModel> PurchasesModels { get; set; } = new(); public Dictionary<int, CostByPurchaseModel> PurchasesModels { get; set; } = new();

View File

@ -17,6 +17,8 @@ namespace UniversityContracts.BindingModels
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;
public int Id { get; set; } public int Id { get; set; }
public string Email { get; set; } = string.Empty;
} }

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityContracts.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,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityContracts.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;
/// <summary>
/// Список потоков и c именами файлов.
/// Потоки опциональны и нужны только если файла нет на диске.
/// </summary>
public List<Tuple<Stream?, string>> FilesStreams { get; set; } = new();
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityContracts.BindingModels
{
public class ReportBindingModel
{
public string? FileName { get; set; }
public Stream? Stream { get; set; }
/// <summary>
/// Массив айдишников по которым происходит выборка
/// </summary>
public int[] Ids { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityContracts.BindingModels
{
public class ReportDateRangeBindingModel
{
public string? FileName { get; set; }
public Stream? Stream { get; set; }
public DateOnly DateFrom { get; set; }
public DateOnly DateTo { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UniversityContracts.BindingModels;
namespace UniversityContracts.BusinessLogicContracts
{
public interface IReportLogic
{
void SavePurchasesToWord(ReportBindingModel option);
void SavePurchasesToExcel(ReportBindingModel option);
void SendPaymentsToEmail(ReportDateRangeBindingModel option, string email);
void SaveOperationsToWord(ReportBindingModel option);
void SaveOperationsToExcel(ReportBindingModel option);
void SendCostsToEmail(ReportDateRangeBindingModel option, string email);
}
}

View File

@ -3,7 +3,7 @@
public class ClientSearchModel public class ClientSearchModel
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? PhoneNumber { get; set; } public string? Login { get; set; }
public string? Password { get; set; } public string? Password { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@
public class EmployeeSearchModel public class EmployeeSearchModel
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? PhoneNumber { get; set; } public string? Login { get; set; }
public string? Password { get; set; } public string? Password { get; set; }
} }
} }

View File

@ -9,8 +9,8 @@ namespace UniversityContracts.ViewModels
{ {
public int Id { get; set; } public int Id { get; set; }
public int EmployeeId { get; set; } public int EmployeeId { get; set; }
[DisplayName("Номер телефона сотрудника")] [DisplayName("Логин сотрудника")]
public string EmployeePhoneNumber { get; set; } = string.Empty; public string EmployeeLogin { get; set; } = string.Empty;
[DisplayName("Стоимость")] [DisplayName("Стоимость")]
public double Price { get; set; } public double Price { get; set; }
[DisplayName("Вид операции")] [DisplayName("Вид операции")]

View File

@ -14,8 +14,8 @@ namespace UniversityContracts.ViewModels
public string FirstName { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty;
[DisplayName("Отчество")] [DisplayName("Отчество")]
public string? MiddleName { get; set; } = string.Empty; public string? MiddleName { get; set; } = string.Empty;
[DisplayName("Номер телефона")] [DisplayName("Логин")]
public string PhoneNumber { get; set; } = string.Empty; public string Login { get; set; } = string.Empty;
[DisplayName("Пароль")] [DisplayName("Пароль")]
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty; public string Email { get; set; } = string.Empty;

View File

@ -8,6 +8,9 @@ namespace UniversityContracts.ViewModels
{ {
public int Id { get; set; } public int Id { get; set; }
public int EmployeeId { get; set; } public int EmployeeId { get; set; }
[DisplayName("Логин сотрудника")]
public string Login { get; set; } = string.Empty;
[DisplayName("Наименование")] [DisplayName("Наименование")]
public string NameOfCost { get; set; } = string.Empty; public string NameOfCost { get; set; } = string.Empty;
[DisplayName("Стоимость")] [DisplayName("Стоимость")]

View File

@ -30,5 +30,7 @@ namespace UniversityContracts.ViewModels
[DisplayName("Должность")] [DisplayName("Должность")]
public string Post { get; set; } = string.Empty; public string Post { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
} }
} }

View File

@ -10,22 +10,22 @@ namespace UniversityContracts.ViewModels
public int Id { get; set; } public int Id { get; set; }
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("Логин клиента")] [DisplayName("Логин клиента")]
public string ClientPhoneNumber { get; set; } = string.Empty; public string ClientLogin { get; set; } = string.Empty;
[DisplayName("Дата Покупки")] [DisplayName("Дата Покупки")]
public DateOnly DatePurchase { get; set; } = DateOnly.FromDateTime(DateTime.Now); public DateOnly DatePurchase { get; set; } = DateOnly.FromDateTime(DateTime.Now);
public Dictionary<int, ClassByPurchaseModel> ClassModel { get; set; } = new(); public Dictionary<int, ClassByPurchaseModel> ClassModel { get; set; } = new();
public List<CostViewModel> CostViewModels { get; set; } = new(); public List<CostViewModel> CostViewModels { get; set; } = new();
public List<ClassViewModel> OperationViewModels { get; set; } = new(); public List<ClassViewModel> ClassViewModels { get; set; } = new();
public override string ToString() public override string ToString()
{ {
var result = new StringBuilder( var result = new StringBuilder(
$"Сделка, созданная {DatePurchase}, включает в себя операции:"); $"Сделка, созданная {DatePurchase}, включает в себя операции:");
for (int i = 0; i < OperationViewModels.Count; i++) for (int i = 0; i < ClassViewModels.Count; i++)
{ {
var car = OperationViewModels[i]; var car = ClassViewModels[i];
if (car == null) if (car == null)
{ {
break; break;

View File

@ -8,10 +8,11 @@ namespace UniversityDataModels
{ {
public interface IClientModel : IId public interface IClientModel : IId
{ {
string Email { get; }
string FirstName { get; } string FirstName { get; }
string LastName { get; } string LastName { get; }
string? MiddleName { get; } string? MiddleName { get; }
//string PhoneNumber { get; } string Login { get; }
string Password { get; } string Password { get; }
} }
} }

View File

@ -13,9 +13,9 @@ namespace UiversityDatabaseImplement.Implements
{ {
if (model == null) if (model == null)
throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model));
if (!model.Id.HasValue && string.IsNullOrEmpty(model.PhoneNumber) && string.IsNullOrEmpty(model.Password)) if (!model.Id.HasValue && string.IsNullOrEmpty(model.Login) && string.IsNullOrEmpty(model.Password))
throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null");
if (!model.Id.HasValue && (string.IsNullOrEmpty(model.PhoneNumber) && !string.IsNullOrEmpty(model.Password))) if (!model.Id.HasValue && (string.IsNullOrEmpty(model.Login) && !string.IsNullOrEmpty(model.Password)))
throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин"); throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин");
} }
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
@ -23,9 +23,7 @@ namespace UiversityDatabaseImplement.Implements
CheckSearchModel(model); CheckSearchModel(model);
using var context = new UniversityDB(); using var context = new UniversityDB();
return context.Clients.FirstOrDefault(x => x.PhoneNumber.Equals(model.PhoneNumber) && (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel; return context.Clients.FirstOrDefault(x => x.Login.Equals(model.Login) && (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel;
} }
public ClientViewModel? Insert(ClientBindingModel model) public ClientViewModel? Insert(ClientBindingModel model)
{ {

View File

@ -22,7 +22,7 @@ namespace UniversityDatabaseImplement.Implements
var element = context.Costs.FirstOrDefault(x => x.Id == model.Id); var element = context.Costs.FirstOrDefault(x => x.Id == model.Id);
if (element != null) if (element != null)
{ {
context.Costs.Remove(element); context.Costs.Remove(element);
context.SaveChanges(); context.SaveChanges();
return element.GetViewModel; return element.GetViewModel;
} }

View File

@ -12,9 +12,9 @@ namespace UniversityDatabaseImplement.Implements
{ {
if (model == null) if (model == null)
throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model)); throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model));
if (!model.Id.HasValue && string.IsNullOrEmpty(model.PhoneNumber) && string.IsNullOrEmpty(model.Password)) if (!model.Id.HasValue && string.IsNullOrEmpty(model.Login) && string.IsNullOrEmpty(model.Password))
throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null"); throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null");
if (!model.Id.HasValue && (string.IsNullOrEmpty(model.PhoneNumber) && !string.IsNullOrEmpty(model.Password))) if (!model.Id.HasValue && (string.IsNullOrEmpty(model.Login) && !string.IsNullOrEmpty(model.Password)))
throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин"); throw new ArgumentException("Для нахождения соответствующего пользователя вместе с паролем нужен логин");
} }
public EmployeeViewModel? GetElement(EmployeeSearchModel model) public EmployeeViewModel? GetElement(EmployeeSearchModel model)
@ -23,13 +23,13 @@ namespace UniversityDatabaseImplement.Implements
using var context = new UniversityDB(); using var context = new UniversityDB();
return context.Employees return context.Employees
.FirstOrDefault(x => (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel; .FirstOrDefault(x => x.Login.Equals(model.Login) && (string.IsNullOrEmpty(model.Password) || x.Password.Equals(model.Password)))?.GetViewModel;
} }
public EmployeeViewModel? Insert(EmployeeBindingModel model) public EmployeeViewModel? Insert(EmployeeBindingModel model)
{ {
if (model == null) if (model == null)
{ {
return null; return null;
} }
var newEmployee = Employee.Create(model); var newEmployee = Employee.Create(model);
using var context = new UniversityDB(); using var context = new UniversityDB();

View File

@ -11,7 +11,7 @@ namespace UniversityDatabaseImplement.Implements
{ {
public class PaymentStorage : IPaymentStorage public class PaymentStorage : IPaymentStorage
{ {
private static IIncludableQueryable<Payment, Class?> Payments(UniversityDB context) private static IIncludableQueryable<Payment, Class?> Payments(UniversityDB context)
=> context.Payments.Include(x => x.ClassByPurchase).ThenInclude(x => x.Class); => context.Payments.Include(x => x.ClassByPurchase).ThenInclude(x => x.Class);
public List<PaymentViewModel> GetFullList() public List<PaymentViewModel> GetFullList()

View File

@ -46,7 +46,7 @@ namespace UniversityDatabaseImplement.Implements
} }
using var context = new UniversityDB(); using var context = new UniversityDB();
var carByPurchase = context.ClassByPurchases var carByPurchase = context.ClassByPurchases
.Include(x => x.Payments) .Include(x => x.Payments)
.FirstOrDefault(x => x.ClassId == modelOperation.Id && x.PurchaseId == modelPurchase.Id); .FirstOrDefault(x => x.ClassId == modelOperation.Id && x.PurchaseId == modelPurchase.Id);
if (carByPurchase?.Payments == null) if (carByPurchase?.Payments == null)
{ {

View File

@ -44,7 +44,7 @@ namespace UniversityDatabaseImplement.Models
public ClassViewModel GetViewModel => new() public ClassViewModel GetViewModel => new()
{ {
EmployeePhoneNumber = Employee?.PhoneNumber??string.Empty, EmployeeLogin = Employee?.Login??string.Empty,
EmployeeId = EmployeeId, EmployeeId = EmployeeId,
Name = Name, Name = Name,
Price = Price, Price = Price,

View File

@ -17,7 +17,7 @@ namespace UniversityDatabaseImplement.Models
[Required] [Required]
public string Address { get; private set; } = string.Empty; public string Address { get; private set; } = string.Empty;
[Required] [Required]
public string PhoneNumber { get; private set; } = string.Empty; public string Login { get; private set; } = string.Empty;
[Required] [Required]
public string Email { get; set; } = string.Empty; public string Email { get; set; } = string.Empty;
[Required] [Required]
@ -36,7 +36,7 @@ namespace UniversityDatabaseImplement.Models
FirstName = model.FirstName, FirstName = model.FirstName,
LastName = model.LastName, LastName = model.LastName,
MiddleName = model.MiddleName, MiddleName = model.MiddleName,
PhoneNumber = model.PhoneNumber, Login = model.Login,
Password = model.Password, Password = model.Password,
Id = model.Id, Id = model.Id,
Email = model.Email, Email = model.Email,
@ -48,7 +48,7 @@ namespace UniversityDatabaseImplement.Models
FirstName = FirstName, FirstName = FirstName,
LastName = LastName, LastName = LastName,
MiddleName = MiddleName, MiddleName = MiddleName,
PhoneNumber =PhoneNumber, Login =Login,
Password = Password, Password = Password,
Id = Id, Id = Id,
Email = Email, Email = Email,

View File

@ -16,7 +16,7 @@ namespace UniversityDatabaseImplement.Models
[Required] [Required]
public string Post { get; private set; } = string.Empty; public string Post { get; private set; } = string.Empty;
[Required] [Required]
public string PhoneNumber { get; private set; } = string.Empty; public string Login { get; private set; } = string.Empty;
[Required] [Required]
public string Password { get; private set; } = string.Empty; public string Password { get; private set; } = string.Empty;
[Required] [Required]

View File

@ -47,12 +47,12 @@ namespace UniversityDatabaseImplement.Models
Id = Id, Id = Id,
DatePurchase = DatePurchase, DatePurchase = DatePurchase,
ClientId = ClientId, ClientId = ClientId,
ClientPhoneNumber = Client?.PhoneNumber ?? string.Empty, ClientLogin = Client?.Login ?? string.Empty,
CostViewModels = Costs? CostViewModels = Costs?
.Select(x => x.Cost.GetViewModel) .Select(x => x.Cost.GetViewModel)
.ToList() ?? new(), .ToList() ?? new(),
OperationViewModels = Operations? ClassViewModels = Operations?
.Select(x => x.Class?.GetViewModel) .Select(x => x.Class?.GetViewModel)
.ToList() ?? new() .ToList() ?? new()
}; };
@ -63,7 +63,7 @@ namespace UniversityDatabaseImplement.Models
Id = Id, Id = Id,
DatePurchase = DatePurchase, DatePurchase = DatePurchase,
ClientId = ClientId, ClientId = ClientId,
ClientPhoneNumber = Client?.PhoneNumber ?? string.Empty, ClientLogin = Client?.Login ?? string.Empty,
CostViewModels = Costs? CostViewModels = Costs?
.Select(x => x.Cost.GetViewModel) .Select(x => x.Cost.GetViewModel)

View File

@ -1,12 +1,16 @@
using Serilog; using Serilog;
using UniversityBusinessLogics.BusinessLogic; using UniversityBusinessLogics.BusinessLogic;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityBusinessLogics.OfficePackage;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.StoragesContracts; using UniversityContracts.StoragesContracts;
using UniversityDatabaseImplement.Implements; using UniversityDatabaseImplement.Implements;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews(); builder.Services.AddControllersWithViews();
builder.Services.AddSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè builder.Services.AddSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè
@ -15,7 +19,11 @@ builder.Services.AddTransient<IClassLogic, ClassLogic>();
builder.Services.AddTransient<ICostLogic, CostLogic>(); builder.Services.AddTransient<ICostLogic, CostLogic>();
builder.Services.AddTransient<IPurchaseLogic, PurchaseLogic>(); builder.Services.AddTransient<IPurchaseLogic, PurchaseLogic>();
builder.Services.AddTransient<IPaymentLogic, PaymentLogic>(); builder.Services.AddTransient<IPaymentLogic, PaymentLogic>();
builder.Services.AddTransient<IReportLogic, ReportLogic>();
builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>();
builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
builder.Services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
builder.Services.AddTransient<IEmployeeStorage, EmployeeStorage>(); builder.Services.AddTransient<IEmployeeStorage, EmployeeStorage>();
builder.Services.AddTransient<IClassStorage, ClassStorage>(); builder.Services.AddTransient<IClassStorage, ClassStorage>();
@ -23,25 +31,54 @@ builder.Services.AddTransient<ICostStorage, CostStorage>();
builder.Services.AddTransient<IPurchaseStorage, PurchaseStorage>(); builder.Services.AddTransient<IPurchaseStorage, PurchaseStorage>();
builder.Services.AddTransient<IPaymentStorage, PaymentStorage>(); builder.Services.AddTransient<IPaymentStorage, PaymentStorage>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddLogging(option =>
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
option.AddSerilog(logger);
});
var app = builder.Build(); var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
{ {
app.UseExceptionHandler("/Error"); app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts(); app.UseHsts();
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseRouting();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseSession(); // Äîáàâëÿåì ñåññèþ äëÿ àâòîðèçàöèè
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();
app.MapRazorPages(); app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run(); app.Run();

View File

@ -0,0 +1,9 @@
namespace UniversityEmpoyeeApp
{
public static class SessionKeys
{
public const string EmployeeLogin = "AuthenticationLogin";
public const string EmployeePassword = "AuthenticationPassword";
}
}

View File

@ -20,6 +20,8 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" /> <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" /> <PackageReference Include="System.Text.Json" Version="6.0.0" />