начало работы с бизнес логикой

This commit is contained in:
Альфия Тукаева 2023-04-06 23:30:18 +03:00
parent 2901d1bc61
commit eceb3f8f05
23 changed files with 608 additions and 87 deletions

View File

@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SchoolContracts", "SchoolCo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SchoolDataModels", "SchoolDataModels\SchoolDataModels.csproj", "{4C8DA0ED-B635-447F-AB51-99136A12854D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SchoolBusinessLogic", "SchoolBusinessLogic\SchoolBusinessLogic.csproj", "{1915B99C-5BB8-40E9-AA25-17D881E3E95B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -27,6 +29,10 @@ Global
{4C8DA0ED-B635-447F-AB51-99136A12854D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C8DA0ED-B635-447F-AB51-99136A12854D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C8DA0ED-B635-447F-AB51-99136A12854D}.Release|Any CPU.Build.0 = Release|Any CPU
{1915B99C-5BB8-40E9-AA25-17D881E3E95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1915B99C-5BB8-40E9-AA25-17D881E3E95B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1915B99C-5BB8-40E9-AA25-17D881E3E95B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1915B99C-5BB8-40E9-AA25-17D881E3E95B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,101 @@
using Microsoft.Extensions.Logging;
using SchoolContracts.BindingModel;
using SchoolContracts.BusinessLogicsContracts;
using SchoolContracts.SearchModel;
using SchoolContracts.StoragesContracts;
using SchoolContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SchoolBusinessLogic.BusinessLogics
{
public class CircleLogic : ICircleLogic
{
private readonly ILogger _logger;
private readonly ICircleStorage _circleStorage;
public CircleLogic(ILogger<CircleLogic> logger, ICircleStorage circleStorage)
{
_logger = logger;
_circleStorage = circleStorage;
}
public bool Create(CircleBindingModel model)
{
CheckModel(model);
if (_circleStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(CircleBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_circleStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public CircleViewModel? ReadElement(CircleSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}", model.Id);
var element = _circleStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id: {Id}", element.Id);
return element;
}
public List<CircleViewModel>? ReadList(CircleSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {Id}", model?.Id);
var list = model == null ? _circleStorage.GetFullList() : _circleStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Update(CircleBindingModel model)
{
CheckModel(model);
if (_circleStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(CircleBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentException(nameof(model));
}
if (!withParams)
{
return;
}
_logger.LogInformation("Circle. Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,154 @@
using Microsoft.Extensions.Logging;
using SchoolContracts.BindingModel;
using SchoolContracts.BusinessLogicsContracts;
using SchoolContracts.SearchModel;
using SchoolContracts.StoragesContracts;
using SchoolContracts.ViewModels;
using SchoolDatabaseImplement.Implements;
namespace SchoolBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_clientStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}", model.Id);
var element = _clientStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id: {Id}", element.Id);
return element;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {Id}", model?.Id);
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentException(nameof(model));
}
if (!withParams)
{
return;
}
//Введён ли email?
if (string.IsNullOrEmpty(model.ClientEmail))
{
_logger.LogWarning("Email is empty");
throw new ArgumentException("Не введён email");
}
//Логин должен быть больше 35 символов
if (model.ClientEmail.Length > 35)
{
_logger.LogWarning("Email {Email} length > 35", model.ClientEmail);
throw new ArgumentException("Длина email не должна превышать 35 символов");
}
//Проверяем email на уникальность
var existingClient = _clientStorage.GetElement(new()
{
ClientEmail = model.ClientEmail
});
if (existingClient != null)
{
_logger.LogWarning("Client with email {Email} already exists", model.ClientEmail);
throw new ArgumentException("Клиент с таким email уже существует");
}
//Введён ли пароль?
if (string.IsNullOrEmpty(model.ClientPassword))
{
_logger.LogWarning("Password is empty");
throw new ArgumentException("Не введён пароль");
}
//Пароль не должен быть менее 7 и более 30 символов
if (model.ClientPassword.Length < 7 || model.ClientPassword.Length > 30)
{
_logger.LogWarning("Password {Password} length > 30 or < 7", model.ClientPassword);
throw new ArgumentException("Длина пароля должна быть в промежутке между 7 и 30 символами");
}
//Введено ли имя?
if (string.IsNullOrEmpty(model.ClientName))
{
_logger.LogWarning("Name is empty");
throw new ArgumentException("Не введёно имя");
}
//Имя должно быть не более 30 символов
if (model.ClientName.Length > 30)
{
_logger.LogWarning("Name {Name} length > 30", model.ClientName);
throw new ArgumentException("Длина имени не должна превышать 30 символов");
}
//Введен ли телефон?
if (string.IsNullOrEmpty(model.ClientPhone))
{
_logger.LogWarning("Phone is empty");
throw new ArgumentException("Не введён телефон");
}
//Телефон должн быть 11 символов
if (model.ClientPhone.Length == 11)
{
_logger.LogWarning("Phone {Phone} length == 11", model.ClientPhone);
throw new ArgumentException("Длина телефона должна быть 11 символов");
}
_logger.LogInformation("Client. Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,100 @@
using Microsoft.Extensions.Logging;
using SchoolContracts.BindingModel;
using SchoolContracts.BusinessLogicsContracts;
using SchoolContracts.SearchModel;
using SchoolContracts.StoragesContracts;
using SchoolContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SchoolBusinessLogic.BusinessLogics
{
public class EmployeeLogic : IEmployeeLogic
{
private readonly ILogger _logger;
private readonly IEmployeeStorage _employeeStorage;
public EmployeeLogic(ILogger<EmployeeLogic> logger, IEmployeeStorage employeeStorage)
{
_logger = logger;
_employeeStorage = employeeStorage;
}
public bool Create(EmployeeBindingModel model)
{
CheckModel(model);
if (_employeeStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(EmployeeBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_employeeStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public EmployeeViewModel? ReadElement(EmployeeSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}", model.Id);
var element = _employeeStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id: {Id}", element.Id);
return element;
}
public List<EmployeeViewModel>? ReadList(EmployeeSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {Id}", model?.Id);
var list = model == null ? _employeeStorage.GetFullList() : _employeeStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Update(EmployeeBindingModel model)
{
CheckModel(model);
if (_employeeStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(EmployeeBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
_logger.LogInformation("Employee. Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,100 @@
using Microsoft.Extensions.Logging;
using SchoolContracts.BindingModel;
using SchoolContracts.BusinessLogicsContracts;
using SchoolContracts.SearchModel;
using SchoolContracts.StoragesContracts;
using SchoolContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SchoolBusinessLogic.BusinessLogics
{
public class LessonLogic : ILessonLogic
{
private readonly ILogger _logger;
private readonly ILessonStorage _lessonStorage;
public LessonLogic(ILogger<LessonLogic> logger, ILessonStorage lessonStorage)
{
_logger = logger;
_lessonStorage = lessonStorage;
}
public bool Create(LessonBindingModel model)
{
CheckModel(model);
if (_lessonStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(LessonBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_lessonStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public LessonViewModel? ReadElement(LessonSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}", model.Id);
var element = _lessonStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id: {Id}", element.Id);
return element;
}
public List<LessonViewModel>? ReadList(LessonSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {Id}", model?.Id);
var list = model == null ? _lessonStorage.GetFullList() : _lessonStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Update(LessonBindingModel model)
{
CheckModel(model);
if (_lessonStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(LessonBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
_logger.LogInformation("Lesson. Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -10,7 +10,6 @@ namespace SchoolContracts.BindingModels
public class ExpenseBindingModel : IExpenseModel
{
public int Id { get; set; }
public string ExpenseName { get; set; }
public double Sum { get; set;}
}
}

View File

@ -1,19 +0,0 @@
using SchoolContracts.BindingModel;
using SchoolContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SchoolContracts.BusinessLogicsContracts
{
public interface IEmploeeLogic
{
List<ExpenseViewModel> Read(EmployeeBindingModel model);
ExpenseViewModel Check(EmployeeBindingModel model);
void CreateOrUpdate(EmployeeBindingModel model);
void Delete(EmployeeBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using SchoolContracts.BindingModel;
using SchoolContracts.SearchModel;
using SchoolContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SchoolContracts.BusinessLogicsContracts
{
public interface IEmployeeLogic
{
List<EmployeeViewModel>? ReadList(EmployeeSearchModel? model);
EmployeeViewModel? ReadElement(EmployeeSearchModel model);
bool Create(EmployeeBindingModel model);
bool Update(EmployeeBindingModel model);
bool Delete(EmployeeBindingModel model);
}
}

View File

@ -11,12 +11,12 @@ namespace SchoolContracts.StoragesContracts
{
public interface IEmployeeStorage
{
List<ExpenseViewModel> GetFullList();
List<ExpenseViewModel> GetFilteredList(EmployeeSearchModel model);
ExpenseViewModel GetElement(EmployeeSearchModel model);
ExpenseViewModel? Insert(EmployeeBindingModel model);
ExpenseViewModel? Update(EmployeeBindingModel model);
ExpenseViewModel? Delete(EmployeeBindingModel model);
List<EmployeeViewModel> GetFullList();
List<EmployeeViewModel> GetFilteredList(EmployeeSearchModel model);
EmployeeViewModel GetElement(EmployeeSearchModel model);
EmployeeViewModel? Insert(EmployeeBindingModel model);
EmployeeViewModel? Update(EmployeeBindingModel model);
EmployeeViewModel? Delete(EmployeeBindingModel model);
}
}

View File

@ -10,7 +10,6 @@ namespace SchoolContracts.ViewModels
public class ExpenseViewModel : IExpenseModel
{
public int Id { get; set; }
public string ExpenseName { get; set; } = string.Empty;
public double Sum { get; set; }
}
}

View File

@ -6,9 +6,18 @@ using System.Threading.Tasks;
namespace SchoolDataModels.Models
{
/// <summary>
/// Кружок
/// </summary>
public interface ICircleModel : IId
{
/// <summary>
/// Дата начала
/// </summary>
public DateTime DateStart { get;}
/// <summary>
/// Id клиента
/// </summary>
public int ClientId { get;}
}
}

View File

@ -6,11 +6,26 @@ using System.Threading.Tasks;
namespace SchoolDataModels.Models
{
/// <summary>
/// Клиент
/// </summary>
public interface IClientModel : IId
{
/// <summary>
/// Имя
/// </summary>
public string ClientName { get; }
/// <summary>
/// Email
/// </summary>
public string ClientEmail { get; }
/// <summary>
/// Телефон
/// </summary>
public string ClientPhone { get; }
/// <summary>
/// Пароль
/// </summary>
public string ClientPassword { get; }
}
}

View File

@ -6,11 +6,26 @@ using System.Threading.Tasks;
namespace SchoolDataModels.Models
{
/// <summary>
/// Сотрудник
/// </summary>
public interface IEmployeeModel : IId
{
/// <summary>
/// Имя
/// </summary>
public string EmployeeName { get; set; }
/// <summary>
/// Пароль
/// </summary>
public string EmployeePassword { get; set; }
/// <summary>
/// Email
/// </summary>
public string EmployeeEmail { get; set; }
/// <summary>
/// Телефон
/// </summary>
public string EmployeePhone { get; set; }
}
}

View File

@ -6,9 +6,14 @@ using System.Threading.Tasks;
namespace SchoolDataModels.Models
{
/// <summary>
/// Затрата на кружок
/// </summary>
public interface IExpenseModel : IId
{
public string ExpenseName { get; set; }
public double Sum { get; set; }
/// <summary>
/// Сумма затраты
/// </summary>
public double Sum { get; }
}
}

View File

@ -1,9 +1,21 @@
namespace SchoolDataModels.Models
{
/// <summary>
/// Занятие
/// </summary>
public interface ILessonModel : IId
{
/// <summary>
/// Название
/// </summary>
public string LessonName { get; set; }
/// <summary>
/// Стоимость
/// </summary>
public double LessonPrice { get; set; }
/// <summary>
/// Id Сотрудника
/// </summary>
public int EmployeeId { get; set; }
}
}

View File

@ -6,11 +6,26 @@ using System.Threading.Tasks;
namespace SchoolDataModels.Models
{
/// <summary>
/// Оплата
/// </summary>
public interface IPaymentModel : IId
{
/// <summary>
/// Сумма
/// </summary>
public double Sum { get; set; }
/// <summary>
/// Остатки
/// </summary>
public double Remains { get; set; }
/// <summary>
/// Дата платежа
/// </summary>
public DateTime? DateOfPayment { get; set; }
/// <summary>
/// Id занятия
/// </summary>
public int LessonId { get; set; }
}
}

View File

@ -72,7 +72,7 @@ namespace SchoolDatabaseImplement.Implements
}
context.Clients.Add(newClient);
context.SaveChanges();
return newClient.GetViewModel();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{

View File

@ -19,6 +19,7 @@ namespace SchoolDatabaseImplement.Implements
{
using var context = new SchoolDatabase();
return context.Lessons
.Include (x => x.Employee)
.Select(x => x.GetViewModel)
.ToList();
}
@ -27,6 +28,7 @@ namespace SchoolDatabaseImplement.Implements
using var context = new SchoolDatabase();
return context.Lessons
.Where(x => x.Id == model.Id)
.Include(x => x.Employee)
.Select(x => x.GetViewModel)
.ToList();
}
@ -36,11 +38,13 @@ namespace SchoolDatabaseImplement.Implements
if (model.Id.HasValue)//сначала ищем по Id
{
return context.Lessons
.Include(x => x.Employee)
.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
if (!string.IsNullOrEmpty(model.LessonName))//затем по названию
{
return context.Lessons
.Include(x => x.Employee)
.FirstOrDefault(x => x.LessonName == model.LessonName)?.GetViewModel;
}
return null;

View File

@ -31,35 +31,31 @@ namespace SchoolDatabaseImplement.Implements
return null;
}
using var context = new SchoolDatabase();
var list = context.Payments.Where(rec => rec.LessonId == model.LessonId)
var list = context.Payments.Where(x => x.LessonId == model.LessonId)
.OrderBy(x => x.DateOfPayment)
.Include(rec => rec.Lesson);
.Include(x => x.Lesson);
return list
.Select(rec => new PaymentViewModel
.Select(x => new PaymentViewModel
{
DateOfPayment = rec.DateOfPayment,
Id = rec.Id,
Remains = rec.Remains,
Sum = rec.Sum,
LessonId = rec.LessonId
DateOfPayment = x.DateOfPayment,
Id = x.Id,
Remains = x.Remains,
Sum = x.Sum,
LessonId = x.LessonId
})
.ToList();
}
public PaymentViewModel GetElement(PaymentSearchModel model)
{
if (model == null)
{
return null;
}
var context = new SchoolDatabase();
using var context = new SchoolDatabase();
{
var payment = context.Payments.Include(rec => rec.Lesson)
.FirstOrDefault(rec => rec.LessonId == model.LessonId);
return payment != null ?
new PaymentViewModel
var payment = context.Payments.Include(x=> x.Lesson)
.FirstOrDefault(x => x.LessonId == model.LessonId);
return payment != null? new PaymentViewModel
{
DateOfPayment = payment.DateOfPayment,
Id = payment.Id,
@ -70,43 +66,25 @@ namespace SchoolDatabaseImplement.Implements
null;
}
}
public PaymentViewModel GetElementFirstLast(/*PaymentDateBindingModel model*/)
{
//TODO
//if (model == null)
//{
// return null;
//}
//var context = new SchoolDatabase();
//{
// return new PaymentViewModel()
// {
// Remains = context.Payments.Include(rec => rec.Lesson)
// .Where(x => x.DateOfPayment > model.DateFrom || x.DateOfPayment < model.DateTo).Sum(x => x.Sum)
// };
//}
return null;
}
public PaymentViewModel? Insert(PaymentBindingModel model)
{
//TODO
//var newPayment = Payment.Create(model);
//if(newPayment == null)
//{
// return null;
//}
//var context = new SchoolDatabase();
//context.Payments.Add(newPayment);
//context.SaveChanges();
//return newPayment.GetViewModel;
var context = new SchoolDatabase();
var newPayment = Payment.Create(context, model);
if (newPayment == null)
{
return null;
}
context.Payments.Add(newPayment);
context.SaveChanges();
return newPayment.GetViewModel;
}
public PaymentViewModel? Update(PaymentBindingModel model)
{
var context = new SchoolDatabase();
var element = context.Payments.FirstOrDefault(rec => rec.Id == model.Id);
var element = context.Payments.
Include(x => x.Lesson)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element == null)
{
throw new Exception("Оплата не найдена");
@ -115,13 +93,13 @@ namespace SchoolDatabaseImplement.Implements
context.SaveChanges();
return element.GetViewModel;
}
public PaymentViewModel? Delete(PaymentBindingModel model)
{
var context = new SchoolDatabase();
var element = context.Payments.FirstOrDefault(rec => rec.Id == model.Id);
var element = context.Payments
.Include(x => x.Lesson)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Payments.Remove(element);

View File

@ -51,7 +51,7 @@ namespace SchoolDatabaseImplement.Models
ClientPassword = model.ClientPassword;
ClientPhone = model.ClientPhone;
}
public ClientViewModel? GetViewModel() => new()
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientName = ClientName,

View File

@ -11,11 +11,9 @@ namespace SchoolDatabaseImplement.Models
{
public class Expense : IExpenseModel
{
public int Id { get; set; }
public int Id { get; private set; }
[Required]
public string ExpenseName { get; set; } = string.Empty;
[Required]
public double Sum { get; set; }
public double Sum { get; private set; }
[ForeignKey("ExpenseId")]
public virtual List<CircleExpense> CircleExpenses { get; set; } = new();
}