Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 00a8846f33 | |||
| c692f50d0d | |||
| e7dcfd6f30 | |||
| a3e1230e5c | |||
| 8f5c38d239 | |||
| dbc3fb8394 | |||
| 524bfca4d0 | |||
| 6b7212a13d | |||
| 4113d2ab9e | |||
| d295b50e32 | |||
| f9966ae73d | |||
| d84b3850d6 | |||
| 6449c0df73 | |||
| 7beb84b967 | |||
| 082111e301 | |||
| 14b48e3a30 | |||
| f649754da7 | |||
| cec7b9240e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,7 +10,7 @@
|
|||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
*.idea
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><configuration>
|
|
||||||
<runtime>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
</runtime>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("CandyHouseTests")]
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<EnableDefaultItems>false</EnableDefaultItems>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="AssemblyInfo.cs" />
|
|
||||||
<Compile Include="DataModels\IngredientDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\OrderDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\PekarDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\PekarHistoryDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\PositionDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\ProductDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\RecipeDataModel.cs" />
|
|
||||||
<Compile Include="DataModels\SalaryDataModel.cs" />
|
|
||||||
<Compile Include="Enums\PositionType.cs" />
|
|
||||||
<Compile Include="Enums\StatusType.cs" />
|
|
||||||
<Compile Include="Exceptions\DateTimeExtensions.cs" />
|
|
||||||
<Compile Include="Exceptions\ElementDeletedException.cs" />
|
|
||||||
<Compile Include="Exceptions\ElementExistsException.cs" />
|
|
||||||
<Compile Include="Exceptions\ElementNotFoundException.cs" />
|
|
||||||
<Compile Include="Exceptions\IncorrectDatesException.cs" />
|
|
||||||
<Compile Include="Exceptions\NullListException.cs" />
|
|
||||||
<Compile Include="Exceptions\StorageException.cs" />
|
|
||||||
<Compile Include="Exceptions\StringExtensions.cs" />
|
|
||||||
<Compile Include="Exceptions\ValidationException.cs" />
|
|
||||||
<Compile Include="Implementations\IngredientBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Implementations\OrderBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Implementations\PekarBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Implementations\PositionBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Implementations\ProductBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Implementations\SalaryBusinessLogicContract.cs" />
|
|
||||||
<Compile Include="Infrastructure\Infrastructure.cs" />
|
|
||||||
<Compile Include="Infrastructure\IValidation.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\IIngredientBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\IOrderBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\IPekarBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\IPositionBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\IProductBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\BusinessLogicsContracts\ISalaryBusinessLogicContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\IIngredientStorageContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\IOrderStorageContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\IPekarStorageContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\IPositionStorageContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\IProductStorageContact.cs" />
|
|
||||||
<Compile Include="Interfaces\StoragesContracts\ISalaryStorageContact.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<InternalsVisibleTo Include="CatHasPawsTests" />
|
|
||||||
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="App.config" />
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
|
||||||
<_Parameter1>CandyHouseTests</_Parameter1>
|
|
||||||
</AssemblyAttribute>
|
|
||||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
|
||||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
|
||||||
</AssemblyAttribute>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-preview.1.25080.5" />
|
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class IngredientDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
|
||||||
public string Name { get; private set; }
|
|
||||||
public string Unit { get; private set; }
|
|
||||||
public decimal Cost { get; private set; }
|
|
||||||
|
|
||||||
public IngredientDataModel(string id, string name, string unit, decimal cost)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Name = name;
|
|
||||||
Unit = unit;
|
|
||||||
Cost = cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (Name.IsEmpty()) throw new ValidationException("Field Name is empty");
|
|
||||||
if (Unit.IsEmpty()) throw new ValidationException("Field Unit is empty");
|
|
||||||
if (Cost < 0) throw new ValidationException("Cost must be non-negative");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
using System;
|
|
||||||
using CandyHouseBase.Enums;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class OrderDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
|
||||||
public string CustomerName { get; private set; } // Может быть null, если клиент разовый
|
|
||||||
public DateTime OrderDate { get; private set; }
|
|
||||||
public decimal TotalAmount { get; private set; }
|
|
||||||
public decimal DiscountAmount { get; private set; }
|
|
||||||
public string ProductId { get; private set; }
|
|
||||||
public string PekarId { get; private set; }
|
|
||||||
public StatusType StatusType { get; private set; }
|
|
||||||
|
|
||||||
public OrderDataModel(string id, string customerName, DateTime orderDate, decimal totalAmount,
|
|
||||||
decimal discountAmount, string productId, string pekarId, StatusType statusType)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
CustomerName = customerName;
|
|
||||||
OrderDate = orderDate;
|
|
||||||
TotalAmount = totalAmount;
|
|
||||||
DiscountAmount = discountAmount;
|
|
||||||
ProductId = productId;
|
|
||||||
PekarId = pekarId;
|
|
||||||
StatusType = statusType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (CustomerName.IsEmpty())
|
|
||||||
throw new ValidationException("CustomerName is empty");
|
|
||||||
if (TotalAmount < 0) throw new ValidationException("TotalAmount cannot be negative");
|
|
||||||
if (DiscountAmount < 0) throw new ValidationException("DiscountAmount cannot be negative");
|
|
||||||
if (ProductId.IsEmpty()) throw new ValidationException("Field productId is empty");
|
|
||||||
if (!ProductId.IsGuid()) throw new ValidationException("productId must be a GUID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class PekarDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
|
||||||
public string FIO { get; private set; }
|
|
||||||
public string Position { get; private set; }
|
|
||||||
public decimal BonusCoefficient { get; private set; }
|
|
||||||
public bool IsDeleted { get; private set; }
|
|
||||||
public List<ProductDataModel> ProductsItems { get; private set; }
|
|
||||||
|
|
||||||
public PekarDataModel()
|
|
||||||
{
|
|
||||||
ProductsItems = new List<ProductDataModel>();
|
|
||||||
}
|
|
||||||
public PekarDataModel(string id, string fio, string position, decimal bonusCoefficient,
|
|
||||||
List<ProductDataModel> productsItems)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
FIO = fio;
|
|
||||||
Position = position;
|
|
||||||
BonusCoefficient = bonusCoefficient;
|
|
||||||
ProductsItems = productsItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (FIO.IsEmpty()) throw new ValidationException("Field FIO is empty");
|
|
||||||
var fioPattern = @"^[A-Za-zА-Яа-яЁё\s\-]+$";
|
|
||||||
if (!Regex.IsMatch(FIO, fioPattern))
|
|
||||||
throw new ValidationException("FIO contains invalid characters");
|
|
||||||
|
|
||||||
if (Position.IsEmpty()) throw new ValidationException("Field Position is empty");
|
|
||||||
if (!Position.IsGuid()) throw new ValidationException("Field must be a GUID");
|
|
||||||
if (BonusCoefficient <= 0) throw new ValidationException("BonusCoefficient must be positive");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class PekarHistoryDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string PekarId { get; private set; }
|
|
||||||
public string FIO { get; private set; }
|
|
||||||
public string PositionId { get; private set; }
|
|
||||||
public DateTime Date { get; private set; }
|
|
||||||
public decimal BonusCoefficient { get; private set; }
|
|
||||||
|
|
||||||
public PekarHistoryDataModel(string peKarId, string fio, string positionId, decimal bonusCoefficient, DateTime dateTime)
|
|
||||||
{
|
|
||||||
PekarId = peKarId;
|
|
||||||
FIO = fio;
|
|
||||||
PositionId = positionId;
|
|
||||||
BonusCoefficient = bonusCoefficient;
|
|
||||||
Date = dateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (PekarId.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!PekarId.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (FIO.IsEmpty()) throw new ValidationException("Field FIO is empty");
|
|
||||||
if (PositionId.IsEmpty()) throw new ValidationException("Field Position is empty");
|
|
||||||
if (!PositionId.IsGuid()) throw new ValidationException("Field must be a GUID");
|
|
||||||
if (BonusCoefficient <= 0) throw new ValidationException("BonusCoefficient must be positive");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using CandyHouseBase.Enums;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class PositionDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public PositionType Type { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
public PositionDataModel(string id, PositionType type, string title)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Type = type;
|
|
||||||
Title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
var titlePattern = @"^[A-Za-zА-Яа-яЁё\s\-]+$";
|
|
||||||
if (!Regex.IsMatch(Title, titlePattern))
|
|
||||||
throw new ValidationException("FIO contains invalid characters");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Title)) throw new ValidationException("Field Title is empty");
|
|
||||||
if (!Enum.IsDefined(typeof(PositionType), Type)) throw new ValidationException("Invalid PositionType");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class ProductDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get => name;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (!name.IsEmpty()) OldName = name;
|
|
||||||
name = value.Trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Description
|
|
||||||
{
|
|
||||||
get => description;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (!description.IsEmpty()) OldDescription = description;
|
|
||||||
description = value.Trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string? OldName { get; private set; }
|
|
||||||
|
|
||||||
public string? OldDescription { get; private set; }
|
|
||||||
|
|
||||||
private string name;
|
|
||||||
private string description;
|
|
||||||
|
|
||||||
public List<IngredientDataModel> IngredientsItems { get; private set; }
|
|
||||||
|
|
||||||
public ProductDataModel()
|
|
||||||
{
|
|
||||||
IngredientsItems = new List<IngredientDataModel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductDataModel(string id, string name, string description, List<IngredientDataModel> ingredients)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Name = name;
|
|
||||||
Description = description;
|
|
||||||
IngredientsItems = ingredients;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductDataModel(string id, string name, string description, string oldName, string oldDescription,
|
|
||||||
List<IngredientDataModel> ingredients)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Name = name;
|
|
||||||
Description = description;
|
|
||||||
IngredientsItems = ingredients;
|
|
||||||
OldName = oldName;
|
|
||||||
OldDescription = oldDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (Name.IsEmpty()) throw new ValidationException("Field Name is empty");
|
|
||||||
if (Description.IsEmpty()) throw new ValidationException("Field Description is empty");
|
|
||||||
if (IngredientsItems.Count == 0) throw new ValidationException("Field IngredientsItems is empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class RecipeDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string ProductId { get; private set; }
|
|
||||||
public string IngredientId { get; private set; }
|
|
||||||
public int Quantity { get; private set; }
|
|
||||||
|
|
||||||
public RecipeDataModel(string productId, string ingredientId, int quantity)
|
|
||||||
{
|
|
||||||
ProductId = productId;
|
|
||||||
IngredientId = ingredientId;
|
|
||||||
Quantity = quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (!ProductId.IsGuid()) throw new ValidationException("ProductId must be a GUID");
|
|
||||||
if (!IngredientId.IsGuid()) throw new ValidationException("IngredientId must be a GUID");
|
|
||||||
if (Quantity <= 0) throw new ValidationException("Quantity must be positive");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.DataModels
|
|
||||||
{
|
|
||||||
public class SalaryDataModel : IValidation
|
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
|
||||||
public string PekarId { get; private set; }
|
|
||||||
public DateTime Period { get; private set; }
|
|
||||||
public decimal BaseRate { get; private set; }
|
|
||||||
public decimal BonusRate { get; private set; }
|
|
||||||
public decimal TotalSalary { get; private set; }
|
|
||||||
|
|
||||||
public SalaryDataModel(string id, string pekarId, DateTime period, decimal baseRate, decimal bonusRate, decimal totalSalary)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
PekarId = pekarId;
|
|
||||||
Period = period;
|
|
||||||
BaseRate = baseRate;
|
|
||||||
BonusRate = bonusRate;
|
|
||||||
TotalSalary = totalSalary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Validate()
|
|
||||||
{
|
|
||||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
|
||||||
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
|
|
||||||
if (PekarId.IsEmpty()) throw new ValidationException("Field PekarId is empty");
|
|
||||||
if (!PekarId.IsGuid()) throw new ValidationException("PekarId must be a GUID");
|
|
||||||
if (BaseRate < 0) throw new ValidationException("BaseRate cannot be negative");
|
|
||||||
if (BonusRate < 0) throw new ValidationException("BonusRate cannot be negative");
|
|
||||||
if (TotalSalary < 0) throw new ValidationException("TotalSalary cannot be negative");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace CandyHouseBase.Enums
|
|
||||||
{
|
|
||||||
public enum PositionType
|
|
||||||
{
|
|
||||||
None = 1,
|
|
||||||
Small = 2,
|
|
||||||
Medium = 3,
|
|
||||||
Cool = 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace CandyHouseBase.Enums
|
|
||||||
{
|
|
||||||
public enum StatusType
|
|
||||||
{
|
|
||||||
Pending,
|
|
||||||
Completed,
|
|
||||||
Cancelled,
|
|
||||||
InProgress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace CandyHouseBase.Exceptions;
|
|
||||||
|
|
||||||
public class ElementDeletedException(string id) : Exception($"Cannot modify a deleted item (id: {id})");
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
|
||||||
|
|
||||||
public class IncorrectDatesException : Exception
|
|
||||||
{
|
|
||||||
public IncorrectDatesException(DateTime start, DateTime end) : base(
|
|
||||||
$"The end date must be later than the start date.. StartDate: {start:dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
|
||||||
|
|
||||||
public class NullListException : Exception
|
|
||||||
{
|
|
||||||
public NullListException() : base("The returned list is null")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
|
||||||
|
|
||||||
public class StorageException(Exception ex) : Exception($"Error while working in storage: {ex.Message}", ex);
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Extensions
|
|
||||||
{
|
|
||||||
public static class StringExtensions
|
|
||||||
{
|
|
||||||
public static bool IsEmpty(this string str) => string.IsNullOrWhiteSpace(str);
|
|
||||||
public static bool IsGuid(this string str) => Guid.TryParse(str, out _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions
|
|
||||||
{
|
|
||||||
public class ValidationException : Exception
|
|
||||||
{
|
|
||||||
public ValidationException(string message) : base(message) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class IngredientBusinessLogicContract(
|
|
||||||
IIngredientStorageContact ingredientStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: IIngredientBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly IIngredientStorageContact _ingredientStorageContact = ingredientStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<IngredientDataModel> GetAllIngredients()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllIngredients");
|
|
||||||
var ingredients = _ingredientStorageContact.GetList() ?? throw new NullListException();
|
|
||||||
return ingredients;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IngredientDataModel GetIngredientByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetIngredientByData for data: {data}", data);
|
|
||||||
if (data == null)
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (string.IsNullOrEmpty(data))
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (data.IsGuid())
|
|
||||||
{
|
|
||||||
var ingredient = _ingredientStorageContact.GetElementById(data);
|
|
||||||
if (ingredient == null)
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
return ingredient;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var ingredient = _ingredientStorageContact.GetElementByName(data);
|
|
||||||
if (ingredient == null)
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
return ingredient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertIngredient(IngredientDataModel ingredient)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertIngredient: {json}", JsonSerializer.Serialize(ingredient));
|
|
||||||
if (ingredient == null)
|
|
||||||
throw new ArgumentNullException(nameof(ingredient));
|
|
||||||
ingredient.Validate();
|
|
||||||
_ingredientStorageContact.AddElement(ingredient);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateIngredient(IngredientDataModel ingredient)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdateIngredient: {json}", JsonSerializer.Serialize(ingredient));
|
|
||||||
if (ingredient == null)
|
|
||||||
throw new ArgumentNullException(nameof(ingredient));
|
|
||||||
ingredient.Validate();
|
|
||||||
_ingredientStorageContact.UpdateElement(ingredient);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteIngredient(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeleteIngredient for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var ingredient = _ingredientStorageContact.GetElementById(id);
|
|
||||||
if (ingredient == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
_ingredientStorageContact.DeleteElement(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Enums;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class OrderBusinessLogicContract(
|
|
||||||
IOrderStorageContact orderStorageContact,
|
|
||||||
IPekarStorageContact pekarStorageContact,
|
|
||||||
IProductStorageContact productStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: IOrderBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly IOrderStorageContact _orderStorageContact = orderStorageContact;
|
|
||||||
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
|
|
||||||
private readonly IProductStorageContact _productStorageContact = productStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<OrderDataModel> GetAllOrders()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllOrders");
|
|
||||||
var orders = _orderStorageContact.GetOrders() ?? throw new NullListException();
|
|
||||||
return orders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OrderDataModel GetOrderByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetOrderByData for data: {data}", data);
|
|
||||||
if (data == null)
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (string.IsNullOrEmpty(data))
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (!data.IsGuid())
|
|
||||||
throw new ValidationException("data must be a GUID");
|
|
||||||
|
|
||||||
var order = _orderStorageContact.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertOrder(OrderDataModel order)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertOrder: {json}", JsonSerializer.Serialize(order));
|
|
||||||
if (order == null)
|
|
||||||
throw new ArgumentNullException(nameof(order));
|
|
||||||
order.Validate();
|
|
||||||
|
|
||||||
// Check if Pekar exists
|
|
||||||
if (_pekarStorageContact.GetElementById(order.PekarId) == null)
|
|
||||||
throw new ElementNotFoundException(order.PekarId);
|
|
||||||
|
|
||||||
// Check if Product exists
|
|
||||||
if (_productStorageContact.GetElementById(order.ProductId) == null)
|
|
||||||
throw new ElementNotFoundException(order.ProductId);
|
|
||||||
|
|
||||||
// Check if order with this ID already exists
|
|
||||||
var existingOrder = _orderStorageContact.GetElementById(order.Id);
|
|
||||||
if (existingOrder != null)
|
|
||||||
throw new ElementExistsException("ID", order.Id);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_orderStorageContact.AddElement(order);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new StorageException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateOrder(OrderDataModel order)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdateOrder: {json}", JsonSerializer.Serialize(order));
|
|
||||||
if (order == null)
|
|
||||||
throw new ArgumentNullException(nameof(order));
|
|
||||||
order.Validate();
|
|
||||||
|
|
||||||
// Check if Pekar exists
|
|
||||||
if (_pekarStorageContact.GetElementById(order.PekarId) == null)
|
|
||||||
throw new ElementNotFoundException(order.PekarId);
|
|
||||||
|
|
||||||
// Check if Product exists
|
|
||||||
if (_productStorageContact.GetElementById(order.ProductId) == null)
|
|
||||||
throw new ElementNotFoundException(order.ProductId);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_orderStorageContact.UpdateElement(order);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new StorageException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteOrder(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeleteOrder for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var order = _orderStorageContact.GetElementById(id);
|
|
||||||
if (order == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_orderStorageContact.DeleteElement(order);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new StorageException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Enums;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class PekarBusinessLogicContract(
|
|
||||||
IPekarStorageContact pekarStorageContact,
|
|
||||||
IProductStorageContact productStorageContact,
|
|
||||||
IPositionStorageContact positionStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: IPekarBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
|
|
||||||
private readonly IProductStorageContact _productStorageContact = productStorageContact;
|
|
||||||
private readonly IPositionStorageContact _positionStorageContact = positionStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<PekarDataModel> GetAllPekars()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllPekars");
|
|
||||||
var pekars = _pekarStorageContact.GetList() ?? throw new NullListException();
|
|
||||||
return pekars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PekarDataModel> GetAllDataOfPekar(string pekarId)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllDataOfPekar for pekarId: {pekarId}", pekarId);
|
|
||||||
if (pekarId.IsEmpty())
|
|
||||||
throw new ArgumentNullException(nameof(pekarId));
|
|
||||||
if (!pekarId.IsGuid())
|
|
||||||
throw new ValidationException("pekarId must be a GUID");
|
|
||||||
|
|
||||||
var pekarsWithHistory = _pekarStorageContact.GetPekarWithHistory(pekarId);
|
|
||||||
if (pekarsWithHistory == null || !pekarsWithHistory.Any())
|
|
||||||
throw new ElementNotFoundException(pekarId);
|
|
||||||
|
|
||||||
var historyRecords = new List<PekarDataModel>();
|
|
||||||
foreach (var pekar in pekarsWithHistory)
|
|
||||||
{
|
|
||||||
Guid positionGuid;
|
|
||||||
if (!Guid.TryParse(pekar.Position, out positionGuid))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Invalid Position GUID: {Position}", pekar.Position);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var position = _positionStorageContact.GetElementById(positionGuid.ToString());
|
|
||||||
if (position == null)
|
|
||||||
throw new ElementNotFoundException(pekar.Position);
|
|
||||||
historyRecords.Add(new PekarDataModel(pekar.Id, pekar.FIO, position.Id, pekar.BonusCoefficient,
|
|
||||||
new List<ProductDataModel>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!historyRecords.Any())
|
|
||||||
{
|
|
||||||
var firstPekar = pekarsWithHistory.First();
|
|
||||||
Guid positionGuid;
|
|
||||||
if (Guid.TryParse(firstPekar.Position, out positionGuid))
|
|
||||||
{
|
|
||||||
var position = _positionStorageContact.GetElementById(positionGuid.ToString());
|
|
||||||
if (position != null)
|
|
||||||
historyRecords.Add(new PekarDataModel(firstPekar.Id, firstPekar.FIO, position.Id,
|
|
||||||
firstPekar.BonusCoefficient,
|
|
||||||
new List<ProductDataModel>()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return historyRecords;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PekarDataModel GetPekarByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetPekarByData for data: {data}", data);
|
|
||||||
if (data.IsEmpty())
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (!data.IsGuid() && !Regex.IsMatch(data, @"^[A-Za-zА-Яа-яЁё\s\-]+$"))
|
|
||||||
throw new ValidationException("data must be a GUID or FIO");
|
|
||||||
|
|
||||||
var pekar = _pekarStorageContact.GetElementById(data) ?? _pekarStorageContact.GetElementByFio(data) ??
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
return pekar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertPekar(PekarDataModel pekar)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertPekar: {json}", JsonSerializer.Serialize(pekar));
|
|
||||||
if (pekar == null)
|
|
||||||
throw new ArgumentNullException(nameof(pekar));
|
|
||||||
|
|
||||||
pekar.Validate();
|
|
||||||
|
|
||||||
var existingPekar = _pekarStorageContact.GetElementById(pekar.Id);
|
|
||||||
if (existingPekar != null)
|
|
||||||
{
|
|
||||||
var history = new PekarHistoryDataModel(
|
|
||||||
existingPekar.Id,
|
|
||||||
existingPekar.FIO,
|
|
||||||
existingPekar.Position,
|
|
||||||
existingPekar.BonusCoefficient,
|
|
||||||
DateTime.Now
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var product in pekar.ProductsItems)
|
|
||||||
{
|
|
||||||
if (_productStorageContact.GetElementById(product.Id) == null)
|
|
||||||
throw new ElementNotFoundException(product.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pekarStorageContact.AddElement(pekar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdatePekar(PekarDataModel pekar)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdatePekar: {json}", JsonSerializer.Serialize(pekar));
|
|
||||||
if (pekar == null)
|
|
||||||
throw new ArgumentNullException(nameof(pekar));
|
|
||||||
|
|
||||||
pekar.Validate();
|
|
||||||
|
|
||||||
foreach (var product in pekar.ProductsItems)
|
|
||||||
{
|
|
||||||
if (_productStorageContact.GetElementById(product.Id) == null)
|
|
||||||
throw new ElementNotFoundException(product.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pekarStorageContact.UpdateElement(pekar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeletePekar(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeletePekar for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var pekar = _pekarStorageContact.GetElementById(id);
|
|
||||||
if (pekar == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
_pekarStorageContact.DeleteElement(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RestorePekar(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("RestorePekar for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var pekar = _pekarStorageContact.GetElementById(id);
|
|
||||||
if (pekar == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
_pekarStorageContact.RestoreElement(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Enums;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class PositionBusinessLogicContract(
|
|
||||||
IPositionStorageContact positionStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: IPositionBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly IPositionStorageContact _positionStorageContact = positionStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<PositionDataModel> GetAllPositions()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllPositions");
|
|
||||||
var positions = _positionStorageContact.GetList() ?? throw new NullListException();
|
|
||||||
return positions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PositionDataModel GetPositionByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetPositionByData for data: {data}", data);
|
|
||||||
if (data.IsEmpty())
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
|
|
||||||
var position = _positionStorageContact.GetElementById(data);
|
|
||||||
if (position == null)
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
if (!data.IsGuid())
|
|
||||||
throw new ValidationException("data must be a GUID");
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertPosition(PositionDataModel position)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertPosition: {json}", JsonSerializer.Serialize(position));
|
|
||||||
if (position == null)
|
|
||||||
throw new ArgumentNullException(nameof(position));
|
|
||||||
|
|
||||||
position.Validate();
|
|
||||||
_positionStorageContact.AddElement(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdatePosition(PositionDataModel position)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdatePosition: {json}", JsonSerializer.Serialize(position));
|
|
||||||
if (position == null)
|
|
||||||
throw new ArgumentNullException(nameof(position));
|
|
||||||
|
|
||||||
position.Validate();
|
|
||||||
_positionStorageContact.UpdateElement(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeletePosition(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeletePosition for id: {id}", id);
|
|
||||||
if (id.IsEmpty())
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var position = _positionStorageContact.GetElementById(id);
|
|
||||||
if (position == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_positionStorageContact.DeleteElement(id);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new StorageException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class ProductBusinessLogicContract(
|
|
||||||
IProductStorageContact productStorageContact,
|
|
||||||
IIngredientStorageContact ingredientStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: IProductBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly IProductStorageContact _productStorageContact = productStorageContact;
|
|
||||||
private readonly IIngredientStorageContact _ingredientStorageContact = ingredientStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<ProductDataModel> GetAllProducts()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllProducts");
|
|
||||||
var products = _productStorageContact.GetList() ?? throw new NullListException();
|
|
||||||
return products;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductDataModel GetProductByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetProductByData for data: {data}", data);
|
|
||||||
if (data == null)
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (string.IsNullOrEmpty(data))
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
|
|
||||||
if (data.IsGuid())
|
|
||||||
{
|
|
||||||
var product = _productStorageContact.GetElementById(data);
|
|
||||||
if (product == null)
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
if (!data.IsGuid()) // Validate after existence check (redundant but kept for consistency)
|
|
||||||
throw new ValidationException("data must be a GUID");
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var products = _productStorageContact.GetList();
|
|
||||||
var productByName = products.FirstOrDefault(p => p.Name == data || (p.OldName != null && p.OldName == data));
|
|
||||||
if (productByName == null)
|
|
||||||
throw new ElementNotFoundException(data);
|
|
||||||
return productByName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertProduct(ProductDataModel product)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertProduct: {json}", JsonSerializer.Serialize(product));
|
|
||||||
if (product == null)
|
|
||||||
throw new ArgumentNullException(nameof(product));
|
|
||||||
product.Validate();
|
|
||||||
|
|
||||||
foreach (var ingredient in product.IngredientsItems)
|
|
||||||
{
|
|
||||||
if (_ingredientStorageContact.GetElementById(ingredient.Id) == null)
|
|
||||||
throw new ElementNotFoundException(ingredient.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_productStorageContact.AddElement(product);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateProduct(ProductDataModel product)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdateProduct: {json}", JsonSerializer.Serialize(product));
|
|
||||||
if (product == null)
|
|
||||||
throw new ArgumentNullException(nameof(product));
|
|
||||||
product.Validate();
|
|
||||||
|
|
||||||
foreach (var ingredient in product.IngredientsItems)
|
|
||||||
{
|
|
||||||
if (_ingredientStorageContact.GetElementById(ingredient.Id) == null)
|
|
||||||
throw new ElementNotFoundException(ingredient.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_productStorageContact.UpdateElement(product);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteProduct(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeleteProduct for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var product = _productStorageContact.GetElementById(id);
|
|
||||||
if (product == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_productStorageContact.DeleteElement(id);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new StorageException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
using CandyHouseBase.Exceptions;
|
|
||||||
using CandyHouseBase.Extensions;
|
|
||||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
|
||||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Implementations
|
|
||||||
{
|
|
||||||
internal class SalaryBusinessLogicContract(
|
|
||||||
ISalaryStorageContact salaryStorageContact,
|
|
||||||
IPekarStorageContact pekarStorageContact,
|
|
||||||
ILogger logger)
|
|
||||||
: ISalaryBusinessLogicContact
|
|
||||||
{
|
|
||||||
private readonly ISalaryStorageContact _salaryStorageContact = salaryStorageContact;
|
|
||||||
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
|
|
||||||
private readonly ILogger _logger = logger;
|
|
||||||
|
|
||||||
public List<SalaryDataModel> GetAllSalaries()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetAllSalaries");
|
|
||||||
var salaries = _salaryStorageContact.GetList() ?? throw new NullListException();
|
|
||||||
return salaries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SalaryDataModel GetSalaryByData(string data)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("GetSalaryByData for data: {data}", data);
|
|
||||||
if (data == null)
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (string.IsNullOrEmpty(data))
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
if (!data.IsGuid())
|
|
||||||
throw new ValidationException("data must be a GUID");
|
|
||||||
|
|
||||||
var salary = _salaryStorageContact.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
|
||||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
|
||||||
throw new ElementNotFoundException(salary.PekarId);
|
|
||||||
return salary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InsertSalary(SalaryDataModel salary)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("InsertSalary: {json}", JsonSerializer.Serialize(salary));
|
|
||||||
if (salary == null)
|
|
||||||
throw new ArgumentNullException(nameof(salary));
|
|
||||||
salary.Validate();
|
|
||||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
|
||||||
throw new ElementNotFoundException(salary.PekarId);
|
|
||||||
_salaryStorageContact.AddElement(salary);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateSalary(SalaryDataModel salary)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("UpdateSalary: {json}", JsonSerializer.Serialize(salary));
|
|
||||||
if (salary == null)
|
|
||||||
throw new ArgumentNullException(nameof(salary));
|
|
||||||
salary.Validate();
|
|
||||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
|
||||||
throw new ElementNotFoundException(salary.PekarId);
|
|
||||||
_salaryStorageContact.UpdateElement(salary);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteSalary(string id)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("DeleteSalary for id: {id}", id);
|
|
||||||
if (id == null)
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (string.IsNullOrEmpty(id))
|
|
||||||
throw new ArgumentNullException(nameof(id));
|
|
||||||
if (!id.IsGuid())
|
|
||||||
throw new ValidationException("id must be a GUID");
|
|
||||||
|
|
||||||
var salary = _salaryStorageContact.GetElementById(id);
|
|
||||||
if (salary == null)
|
|
||||||
throw new ElementNotFoundException(id);
|
|
||||||
|
|
||||||
_salaryStorageContact.DeleteElement(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace CandyHouseBase.Infrastructure
|
|
||||||
{
|
|
||||||
public interface IValidation
|
|
||||||
{
|
|
||||||
void Validate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace CandyHouseBase.Infrastructure;
|
|
||||||
|
|
||||||
public interface IConfigurationDatabase
|
|
||||||
{
|
|
||||||
public string ConnectionString =>
|
|
||||||
"Host=127.0.0.1;Port=5432;Database=CandyHouseTest;Username=postgres;Password=postgres;";
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface IIngredientBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<IngredientDataModel> GetAllIngredients();
|
|
||||||
IngredientDataModel GetIngredientByData(string data);
|
|
||||||
void InsertIngredient(IngredientDataModel ingredient);
|
|
||||||
void UpdateIngredient(IngredientDataModel ingredient);
|
|
||||||
void DeleteIngredient(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface IOrderBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<OrderDataModel> GetAllOrders();
|
|
||||||
OrderDataModel GetOrderByData(string data);
|
|
||||||
void InsertOrder(OrderDataModel order);
|
|
||||||
void UpdateOrder(OrderDataModel order);
|
|
||||||
void DeleteOrder(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface IPekarBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<PekarDataModel> GetAllPekars();
|
|
||||||
List<PekarDataModel> GetAllDataOfPekar(string pekarId);
|
|
||||||
PekarDataModel GetPekarByData(string data);
|
|
||||||
void InsertPekar(PekarDataModel order);
|
|
||||||
void UpdatePekar(PekarDataModel order);
|
|
||||||
void DeletePekar(string id);
|
|
||||||
void RestorePekar(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface IPositionBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<PositionDataModel> GetAllPositions();
|
|
||||||
PositionDataModel GetPositionByData(string data);
|
|
||||||
void InsertPosition(PositionDataModel position);
|
|
||||||
void UpdatePosition(PositionDataModel position);
|
|
||||||
void DeletePosition(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface IProductBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<ProductDataModel> GetAllProducts();
|
|
||||||
ProductDataModel GetProductByData(string data);
|
|
||||||
void InsertProduct(ProductDataModel product);
|
|
||||||
void UpdateProduct(ProductDataModel product);
|
|
||||||
void DeleteProduct(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
|
||||||
{
|
|
||||||
public interface ISalaryBusinessLogicContact
|
|
||||||
{
|
|
||||||
List<SalaryDataModel> GetAllSalaries();
|
|
||||||
SalaryDataModel GetSalaryByData(string data);
|
|
||||||
void InsertSalary(SalaryDataModel salary);
|
|
||||||
void UpdateSalary(SalaryDataModel salary);
|
|
||||||
void DeleteSalary(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface IIngredientStorageContact
|
|
||||||
{
|
|
||||||
List<IngredientDataModel> GetList();
|
|
||||||
IngredientDataModel GetElementById(string id);
|
|
||||||
IngredientDataModel GetElementByName(string name);
|
|
||||||
void AddElement(IngredientDataModel ingredient);
|
|
||||||
void UpdateElement(IngredientDataModel ingredient);
|
|
||||||
void DeleteElement(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface IOrderStorageContact
|
|
||||||
{
|
|
||||||
List<OrderDataModel> GetOrders();
|
|
||||||
void AddElement(OrderDataModel order);
|
|
||||||
void UpdateElement(OrderDataModel order);
|
|
||||||
void DeleteElement(OrderDataModel order);
|
|
||||||
OrderDataModel GetElementById(string orderId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface IPekarStorageContact
|
|
||||||
{
|
|
||||||
List<PekarDataModel> GetList();
|
|
||||||
List<PekarDataModel> GetPekarWithHistory(string id);
|
|
||||||
PekarDataModel GetElementById(string id);
|
|
||||||
PekarDataModel GetElementByFio(string fio);
|
|
||||||
void AddElement(PekarDataModel item);
|
|
||||||
void UpdateElement(PekarDataModel item);
|
|
||||||
void DeleteElement(string id);
|
|
||||||
void RestoreElement(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface IProductStorageContact
|
|
||||||
{
|
|
||||||
List<ProductDataModel> GetList();
|
|
||||||
ProductDataModel GetElementById(string id);
|
|
||||||
ProductDataModel GetElementByName(string name);
|
|
||||||
ProductDataModel GetElementByOldName(string name);
|
|
||||||
void AddElement(ProductDataModel element);
|
|
||||||
void UpdateElement(ProductDataModel element);
|
|
||||||
void DeleteElement(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface IPositionStorageContact
|
|
||||||
{
|
|
||||||
List<PositionDataModel> GetList();
|
|
||||||
PositionDataModel GetElementById(string id);
|
|
||||||
void AddElement(PositionDataModel element);
|
|
||||||
void UpdateElement(PositionDataModel element);
|
|
||||||
void DeleteElement(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using CandyHouseBase.DataModels;
|
|
||||||
|
|
||||||
namespace CandyHouseBase.Interfaces.StoragesContracts
|
|
||||||
{
|
|
||||||
public interface ISalaryStorageContact
|
|
||||||
{
|
|
||||||
List<SalaryDataModel> GetList();
|
|
||||||
SalaryDataModel GetElementById(string id);
|
|
||||||
void AddElement(SalaryDataModel element);
|
|
||||||
void UpdateElement(SalaryDataModel element);
|
|
||||||
void DeleteElement(string id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<InternalsVisibleTo Include="CandyHouseTests" />
|
||||||
|
<InternalsVisibleTo Include="CandyHouseWebApi" />
|
||||||
|
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\CandyHouseContracts\CandyHouseContracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
|
||||||
|
public class ClientBusinessLogicContract(IClientStorageContract clientStorageContract, ILogger logger) : IClientBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly IClientStorageContract _clientStorageContract = clientStorageContract;
|
||||||
|
|
||||||
|
public List<ClientDataModel> GetAllClients()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllClients");
|
||||||
|
return _clientStorageContract.GetList() ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientDataModel GetClientByData(string data)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Get element by data: {data}", data);
|
||||||
|
if (data.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(data));
|
||||||
|
}
|
||||||
|
if (data.IsGuid())
|
||||||
|
{
|
||||||
|
return _clientStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
if (Regex.IsMatch(data, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$"))
|
||||||
|
{
|
||||||
|
return _clientStorageContract.GetElementByPhoneNumber(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
return _clientStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertClient(ClientDataModel clientDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(clientDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(clientDataModel);
|
||||||
|
clientDataModel.Validate();
|
||||||
|
_clientStorageContract.AddElement(clientDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateClient(ClientDataModel clientDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(clientDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(clientDataModel);
|
||||||
|
clientDataModel.Validate();
|
||||||
|
_clientStorageContract.UpdElement(clientDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteClient(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Delete by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_clientStorageContract.DelElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
|
||||||
|
public class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeStorageContract, ILogger logger) : IEmployeeBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly IEmployeeStorageContract _employeeStorageContract = employeeStorageContract;
|
||||||
|
|
||||||
|
public List<EmployeeDataModel> GetAllEmployees(bool onlyActive = true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllEmployees params: {onlyActive}", onlyActive);
|
||||||
|
return _employeeStorageContract.GetList(onlyActive) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmployeeDataModel> GetAllEmployeesByPost(string postId, bool onlyActive = true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllEmployees params: {postId}, {onlyActive},", postId, onlyActive);
|
||||||
|
if (postId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(postId));
|
||||||
|
}
|
||||||
|
if (!postId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field postId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _employeeStorageContract.GetList(onlyActive, postId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmployeeDataModel> GetAllEmployeesByBirthDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllEmployees params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
return _employeeStorageContract.GetList(onlyActive, fromBirthDate: fromDate, toBirthDate: toDate) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmployeeDataModel> GetAllEmployeesByEmploymentDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllEmployees params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
return _employeeStorageContract.GetList(onlyActive, fromEmploymentDate: fromDate, toEmploymentDate: toDate) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmployeeDataModel GetEmployeeByData(string data)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Get element by data: {data}", data);
|
||||||
|
if (data.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(data));
|
||||||
|
}
|
||||||
|
if (data.IsGuid())
|
||||||
|
{
|
||||||
|
return _employeeStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
if (Regex.IsMatch(data, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
|
||||||
|
{
|
||||||
|
return _employeeStorageContract.GetElementByEmail(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
return _employeeStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertEmployee(EmployeeDataModel employeeDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(employeeDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(employeeDataModel);
|
||||||
|
employeeDataModel.Validate();
|
||||||
|
_employeeStorageContract.AddElement(employeeDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateEmployee(EmployeeDataModel employeeDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(employeeDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(employeeDataModel);
|
||||||
|
employeeDataModel.Validate();
|
||||||
|
_employeeStorageContract.UpdElement(employeeDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteEmployee(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Delete by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_employeeStorageContract.DelElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
|
||||||
|
public class PostBusinessLogicContract(IPostStorageContract postStorageContract, ILogger logger) : IPostBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly IPostStorageContract _postStorageContract = postStorageContract;
|
||||||
|
public List<PostDataModel> GetAllPosts()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllPosts");
|
||||||
|
return _postStorageContract.GetList() ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PostDataModel> GetAllDataOfPost(string postId)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllDataOfPost for {postId}", postId);
|
||||||
|
if (postId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(postId));
|
||||||
|
}
|
||||||
|
if (!postId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field postId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _postStorageContract.GetPostWithHistory(postId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostDataModel GetPostByData(string data)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Get element by data: {data}", data);
|
||||||
|
if (data.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(data));
|
||||||
|
}
|
||||||
|
if (data.IsGuid())
|
||||||
|
{
|
||||||
|
return _postStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
return _postStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertPost(PostDataModel postDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(postDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(postDataModel);
|
||||||
|
postDataModel.Validate();
|
||||||
|
_postStorageContract.AddElement(postDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdatePost(PostDataModel postDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(postDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(postDataModel);
|
||||||
|
postDataModel.Validate();
|
||||||
|
_postStorageContract.UpdElement(postDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeletePost(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Delete by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_postStorageContract.DelElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestorePost(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Restore by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_postStorageContract.ResElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
|
||||||
|
public class ProductBusinessLogicContract(IProductStorageContract productStorageContract, ILogger logger) : IProductBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly IProductStorageContract _productStorageContract = productStorageContract;
|
||||||
|
public List<ProductDataModel> GetAllProducts()
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllProducts");
|
||||||
|
return _productStorageContract.GetList() ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductHistoryDataModel> GetProductHistoryByProduct(string productId)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetProductHistoryByProduct for {productId}", productId);
|
||||||
|
if (productId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(productId));
|
||||||
|
}
|
||||||
|
if (!productId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field productId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _productStorageContract.GetHistoryByProductId(productId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductDataModel GetProductByData(string data)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Get element by data: {data}", data);
|
||||||
|
if (data.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(data));
|
||||||
|
}
|
||||||
|
if (data.IsGuid())
|
||||||
|
{
|
||||||
|
return _productStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
return _productStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertProduct(ProductDataModel productDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(productDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(productDataModel);
|
||||||
|
productDataModel.Validate();
|
||||||
|
_productStorageContract.AddElement(productDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateProduct(ProductDataModel productDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(productDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(productDataModel);
|
||||||
|
productDataModel.Validate();
|
||||||
|
_productStorageContract.UpdElement(productDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteProduct(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Delete by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_productStorageContract.DelElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.Infrastructure.PostConfigurations;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
public class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract,ISaleStorageContract saleStorageContract,
|
||||||
|
IPostStorageContract postStorageContract, IEmployeeStorageContract employeeStorageContract, ILogger logger, IConfigurationSalary сonfiguration) : ISalaryBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly ISalaryStorageContract _salaryStorageContract = salaryStorageContract;
|
||||||
|
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
|
||||||
|
private readonly IPostStorageContract _postStorageContract = postStorageContract;
|
||||||
|
private readonly IEmployeeStorageContract _employeeStorageContract = employeeStorageContract;
|
||||||
|
private readonly IConfigurationSalary _salaryConfiguration = сonfiguration;
|
||||||
|
private readonly Lock _lockObject = new();
|
||||||
|
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}", fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
return _salaryStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SalaryDataModel> GetAllSalariesByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId)
|
||||||
|
{
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
if (employeeId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(employeeId));
|
||||||
|
}
|
||||||
|
if (!employeeId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field employeeId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}, {employeeId}", fromDate, toDate, employeeId);
|
||||||
|
return _salaryStorageContract.GetList(fromDate, toDate, employeeId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CalculateSalaryByMounth(DateTime date)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("CalculateSalaryByMounth: {date}", date);
|
||||||
|
var startDate = new DateTime(date.Year, date.Month, 1);
|
||||||
|
var finishDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
|
||||||
|
var employees = _employeeStorageContract.GetList() ?? throw new NullListException();
|
||||||
|
foreach (var employee in employees)
|
||||||
|
{
|
||||||
|
var sales = _saleStorageContract.GetList(startDate, finishDate, employeeId: employee.Id) ?? throw new NullListException();
|
||||||
|
var post = _postStorageContract.GetElementById(employee.PostId) ?? throw new NullListException();
|
||||||
|
var salary = post.ConfigurationModel switch
|
||||||
|
{
|
||||||
|
null => 0,
|
||||||
|
ManagerPostConfiguration cpc => CalculateSalaryForSuperManager(sales, startDate, finishDate, cpc),
|
||||||
|
BakerPostConfiguration spc => CalculateSalaryForChief(startDate, finishDate, spc),
|
||||||
|
PostConfiguration pc => pc.Rate,
|
||||||
|
};
|
||||||
|
_logger.LogDebug("The employee {employeeId} was paid a salary of {salary}", employee.Id, salary);
|
||||||
|
_salaryStorageContract.AddElement(new SalaryDataModel(employee.Id, finishDate, salary));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private double CalculateSalaryForSuperManager(List<SaleDataModel> sales, DateTime startDate, DateTime finishDate, ManagerPostConfiguration config)
|
||||||
|
{
|
||||||
|
var calcPercent = 0.0;
|
||||||
|
var dates = new List<DateTime>();
|
||||||
|
for (var date = startDate; date < finishDate; date = date.AddDays(1))
|
||||||
|
{
|
||||||
|
dates.Add(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
var parallelOptions = new ParallelOptions
|
||||||
|
{
|
||||||
|
MaxDegreeOfParallelism = _salaryConfiguration.MaxConcurrentThreads
|
||||||
|
};
|
||||||
|
|
||||||
|
Parallel.ForEach(dates, parallelOptions, date =>
|
||||||
|
{
|
||||||
|
var salesInDay = sales.Where(x => x.SaleDate.Date == date.Date).ToArray();
|
||||||
|
if (salesInDay.Length > 0)
|
||||||
|
{
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
calcPercent += (salesInDay.Sum(x => x.Sum) / salesInDay.Length) * config.SalePercent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
double calcBonusTask = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
calcBonusTask = sales.Where(x => x.Sum > _salaryConfiguration.ExtraSaleSum).Sum(x => x.Sum) * config.BonusForExtraSales;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error in bonus calculation");
|
||||||
|
}
|
||||||
|
return config.Rate + calcPercent + calcBonusTask;
|
||||||
|
}
|
||||||
|
private double CalculateSalaryForChief(DateTime startDate, DateTime finishDate, BakerPostConfiguration config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return config.Rate + config.PersonalCountTrendPremium * _employeeStorageContract.GetEmployeeTrend(startDate, finishDate);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error in the chief payroll process");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
using CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseBusinessLogic.Implementations;
|
||||||
|
|
||||||
|
public class SaleBusinessLogicContract(ISaleStorageContract saleStorageContract, ILogger logger) : ISaleBusinessLogicContract
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
|
||||||
|
|
||||||
|
public List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllSales params: {fromDate}, {toDate}", fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
return _saleStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SaleDataModel> GetAllSalesByEmployeeByPeriod(string employeeId, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllSales params: {employeeId}, {fromDate}, {toDate}", employeeId, fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
if (employeeId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(employeeId));
|
||||||
|
}
|
||||||
|
if (!employeeId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field employeeId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _saleStorageContract.GetList(fromDate, toDate, employeeId: employeeId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SaleDataModel> GetAllSalesByClientByPeriod(string clientId, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllSales params: {buyerId}, {fromDate}, {toDate}", clientId, fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
if (clientId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(clientId));
|
||||||
|
}
|
||||||
|
if (!clientId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field clientId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _saleStorageContract.GetList(fromDate, toDate, clientId: clientId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SaleDataModel> GetAllSalesByProductByPeriod(string productId, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("GetAllSales params: {productId}, {fromDate}, {toDate}", productId, fromDate, toDate);
|
||||||
|
if (fromDate.IsDateNotOlder(toDate))
|
||||||
|
{
|
||||||
|
throw new IncorrectDatesException(fromDate, toDate);
|
||||||
|
}
|
||||||
|
if (productId.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(productId));
|
||||||
|
}
|
||||||
|
if (!productId.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("The value in the field productId is not a unique identifier.");
|
||||||
|
}
|
||||||
|
return _saleStorageContract.GetList(fromDate, toDate, productId: productId) ?? throw new NullListException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaleDataModel GetSaleByData(string data)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Get element by data: {data}", data);
|
||||||
|
if (data.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(data));
|
||||||
|
}
|
||||||
|
if (!data.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
return _saleStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertSale(SaleDataModel saleDataModel)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(saleDataModel));
|
||||||
|
ArgumentNullException.ThrowIfNull(saleDataModel);
|
||||||
|
saleDataModel.Validate();
|
||||||
|
_saleStorageContract.AddElement(saleDataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CancelSale(string id)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Cancel by id: {id}", id);
|
||||||
|
if (id.IsEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(id));
|
||||||
|
}
|
||||||
|
if (!id.IsGuid())
|
||||||
|
{
|
||||||
|
throw new ValidationException("Id is not a unique identifier");
|
||||||
|
}
|
||||||
|
_saleStorageContract.DelElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using CandyHouseContracts.BindingModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface IClientAdapter
|
||||||
|
{
|
||||||
|
ClientOperationResponse GetList();
|
||||||
|
|
||||||
|
ClientOperationResponse GetElement(string data);
|
||||||
|
|
||||||
|
ClientOperationResponse RegisterClient(ClientBindingModel clientModel);
|
||||||
|
|
||||||
|
ClientOperationResponse ChangeClientInfo(ClientBindingModel clientModel);
|
||||||
|
|
||||||
|
ClientOperationResponse RemoveClient(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using CandyHouseContracts.BindingModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface IEmployeeAdapter
|
||||||
|
{
|
||||||
|
EmployeeOperationResponse GetList(bool includeDeleted);
|
||||||
|
|
||||||
|
EmployeeOperationResponse GetPostList(string id, bool includeDeleted);
|
||||||
|
|
||||||
|
EmployeeOperationResponse GetListByBirthDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
|
||||||
|
|
||||||
|
EmployeeOperationResponse GetListByEmploymentDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
|
||||||
|
|
||||||
|
EmployeeOperationResponse GetElement(string data);
|
||||||
|
|
||||||
|
EmployeeOperationResponse RegisterEmployee(EmployeeBindingModel employeeModel);
|
||||||
|
|
||||||
|
EmployeeOperationResponse ChangeEmployeeInfo(EmployeeBindingModel employeeModel);
|
||||||
|
|
||||||
|
EmployeeOperationResponse RemoveEmployee(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using CandyHouseContracts.BindingModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface IPostAdapter
|
||||||
|
{
|
||||||
|
PostOperationResponse GetList();
|
||||||
|
|
||||||
|
PostOperationResponse GetHistory(string id);
|
||||||
|
|
||||||
|
PostOperationResponse GetElement(string data);
|
||||||
|
|
||||||
|
PostOperationResponse RegisterPost(PostBindingModel postModel);
|
||||||
|
|
||||||
|
PostOperationResponse ChangePostInfo(PostBindingModel postModel);
|
||||||
|
|
||||||
|
PostOperationResponse RemovePost(string id);
|
||||||
|
|
||||||
|
PostOperationResponse RestorePost(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using CandyHouseContracts.BindingModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface IProductAdapter
|
||||||
|
{
|
||||||
|
ProductOperationResponse GetList(bool includeDeleted);
|
||||||
|
|
||||||
|
ProductOperationResponse GetHistory(string id);
|
||||||
|
|
||||||
|
ProductOperationResponse GetElement(string data);
|
||||||
|
|
||||||
|
ProductOperationResponse RegisterProduct(ProductBindingModel productModel);
|
||||||
|
|
||||||
|
ProductOperationResponse ChangeProductInfo(ProductBindingModel productModel);
|
||||||
|
|
||||||
|
ProductOperationResponse RemoveProduct(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface ISalaryAdapter
|
||||||
|
{
|
||||||
|
SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate);
|
||||||
|
SalaryOperationResponse GetListByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId);
|
||||||
|
SalaryOperationResponse CalculateSalary(DateTime date);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
using CandyHouseContracts.BindingModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts;
|
||||||
|
|
||||||
|
public interface ISaleAdapter
|
||||||
|
{
|
||||||
|
SaleOperationResponse GetList(DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
SaleOperationResponse GetEmployeeList(string id, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
SaleOperationResponse GetClientList(string id, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
SaleOperationResponse GetProductList(string id, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
SaleOperationResponse GetElement(string id);
|
||||||
|
|
||||||
|
SaleOperationResponse MakeSale(SaleBindingModel saleModel);
|
||||||
|
|
||||||
|
SaleOperationResponse CancelSale(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class ClientOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static ClientOperationResponse OK(List<ClientViewModel> data) => OK<ClientOperationResponse, List<ClientViewModel>>(data);
|
||||||
|
|
||||||
|
public static ClientOperationResponse OK(ClientViewModel data) => OK<ClientOperationResponse, ClientViewModel>(data);
|
||||||
|
|
||||||
|
public static ClientOperationResponse NoContent() => NoContent<ClientOperationResponse>();
|
||||||
|
|
||||||
|
public static ClientOperationResponse BadRequest(string message) => BadRequest<ClientOperationResponse>(message);
|
||||||
|
|
||||||
|
public static ClientOperationResponse NotFound(string message) => NotFound<ClientOperationResponse>(message);
|
||||||
|
|
||||||
|
public static ClientOperationResponse InternalServerError(string message) => InternalServerError<ClientOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class EmployeeOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static EmployeeOperationResponse OK(List<EmployeeViewModel> data) => OK<EmployeeOperationResponse, List<EmployeeViewModel>>(data);
|
||||||
|
|
||||||
|
public static EmployeeOperationResponse OK(EmployeeViewModel data) => OK<EmployeeOperationResponse, EmployeeViewModel>(data);
|
||||||
|
|
||||||
|
public static EmployeeOperationResponse NoContent() => NoContent<EmployeeOperationResponse>();
|
||||||
|
|
||||||
|
public static EmployeeOperationResponse NotFound(string message) => NotFound<EmployeeOperationResponse>(message);
|
||||||
|
|
||||||
|
public static EmployeeOperationResponse BadRequest(string message) => BadRequest<EmployeeOperationResponse>(message);
|
||||||
|
|
||||||
|
public static EmployeeOperationResponse InternalServerError(string message) => InternalServerError<EmployeeOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class PostOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static PostOperationResponse OK(List<PostViewModel> data) => OK<PostOperationResponse, List<PostViewModel>>(data);
|
||||||
|
|
||||||
|
public static PostOperationResponse OK(PostViewModel data) => OK<PostOperationResponse, PostViewModel>(data);
|
||||||
|
|
||||||
|
public static PostOperationResponse NoContent() => NoContent<PostOperationResponse>();
|
||||||
|
|
||||||
|
public static PostOperationResponse NotFound(string message) => NotFound<PostOperationResponse>(message);
|
||||||
|
|
||||||
|
public static PostOperationResponse BadRequest(string message) => BadRequest<PostOperationResponse>(message);
|
||||||
|
|
||||||
|
public static PostOperationResponse InternalServerError(string message) => InternalServerError<PostOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class ProductOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static ProductOperationResponse OK(List<ProductViewModel> data) => OK<ProductOperationResponse, List<ProductViewModel>>(data);
|
||||||
|
|
||||||
|
public static ProductOperationResponse OK(List<ProductHistoryViewModel> data) => OK<ProductOperationResponse, List<ProductHistoryViewModel>>(data);
|
||||||
|
|
||||||
|
public static ProductOperationResponse OK(ProductViewModel data) => OK<ProductOperationResponse, ProductViewModel>(data);
|
||||||
|
|
||||||
|
public static ProductOperationResponse NoContent() => NoContent<ProductOperationResponse>();
|
||||||
|
|
||||||
|
public static ProductOperationResponse NotFound(string message) => NotFound<ProductOperationResponse>(message);
|
||||||
|
|
||||||
|
public static ProductOperationResponse BadRequest(string message) => BadRequest<ProductOperationResponse>(message);
|
||||||
|
|
||||||
|
public static ProductOperationResponse InternalServerError(string message) => InternalServerError<ProductOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class SalaryOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static SalaryOperationResponse OK(List<SalaryViewModel> data) => OK<SalaryOperationResponse, List<SalaryViewModel>>(data);
|
||||||
|
public static SalaryOperationResponse NoContent() => NoContent<SalaryOperationResponse>();
|
||||||
|
public static SalaryOperationResponse NotFound(string message) => NotFound<SalaryOperationResponse>(message);
|
||||||
|
public static SalaryOperationResponse BadRequest(string message) => BadRequest<SalaryOperationResponse>(message);
|
||||||
|
public static SalaryOperationResponse InternalServerError(string message) => InternalServerError<SalaryOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.AdapterContracts.OperationResponses;
|
||||||
|
|
||||||
|
public class SaleOperationResponse : OperationResponse
|
||||||
|
{
|
||||||
|
public static SaleOperationResponse OK(List<SaleViewModel> data) => OK<SaleOperationResponse, List<SaleViewModel>>(data);
|
||||||
|
|
||||||
|
public static SaleOperationResponse OK(SaleViewModel data) => OK<SaleOperationResponse, SaleViewModel>(data);
|
||||||
|
|
||||||
|
public static SaleOperationResponse NoContent() => NoContent<SaleOperationResponse>();
|
||||||
|
|
||||||
|
public static SaleOperationResponse NotFound(string message) => NotFound<SaleOperationResponse>(message);
|
||||||
|
|
||||||
|
public static SaleOperationResponse BadRequest(string message) => BadRequest<SaleOperationResponse>(message);
|
||||||
|
|
||||||
|
public static SaleOperationResponse InternalServerError(string message) => InternalServerError<SaleOperationResponse>(message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class ClientBindingModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
public string? FIO { get; set; }
|
||||||
|
|
||||||
|
public string? PhoneNumber { get; set; }
|
||||||
|
|
||||||
|
public double DiscountSize { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class EmployeeBindingModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
public string? FIO { get; set; }
|
||||||
|
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
public string? PostId { get; set; }
|
||||||
|
|
||||||
|
public DateTime BirthDate { get; set; }
|
||||||
|
|
||||||
|
public DateTime EmploymentDate { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class PostBindingModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
public string? PostId => Id;
|
||||||
|
|
||||||
|
public string? PostName { get; set; }
|
||||||
|
|
||||||
|
public string? PostType { get; set; }
|
||||||
|
public string? ConfigurationJson { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class ProductBindingModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? ProductName { get; set; }
|
||||||
|
public string? ProductDescription { get; set; }
|
||||||
|
public double Price { get; set; }
|
||||||
|
public string? ProductType { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class SaleBindingModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
public string? EmployeeId { get; set; }
|
||||||
|
|
||||||
|
public string? ClientId { get; set; }
|
||||||
|
|
||||||
|
public int DiscountType { get; set; }
|
||||||
|
|
||||||
|
public List<SaleProductBindingModel>? Products { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BindingModels;
|
||||||
|
|
||||||
|
public class SaleProductBindingModel
|
||||||
|
{
|
||||||
|
public string? SaleId { get; set; }
|
||||||
|
|
||||||
|
public string? ProductId { get; set; }
|
||||||
|
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
|
public double Price { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface IClientBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<ClientDataModel> GetAllClients();
|
||||||
|
|
||||||
|
ClientDataModel GetClientByData(string data);
|
||||||
|
|
||||||
|
void InsertClient(ClientDataModel clientDataModel);
|
||||||
|
|
||||||
|
void UpdateClient(ClientDataModel clientDataModel);
|
||||||
|
|
||||||
|
void DeleteClient(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface IEmployeeBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<EmployeeDataModel> GetAllEmployees(bool onlyActive = true);
|
||||||
|
|
||||||
|
List<EmployeeDataModel> GetAllEmployeesByPost(string employeeId, bool onlyActive = true);
|
||||||
|
|
||||||
|
List<EmployeeDataModel> GetAllEmployeesByBirthDate(DateTime fromDate, DateTime toDate, bool onlyActive = true);
|
||||||
|
|
||||||
|
List<EmployeeDataModel> GetAllEmployeesByEmploymentDate(DateTime fromDate, DateTime toDate, bool onlyActive = true);
|
||||||
|
|
||||||
|
EmployeeDataModel GetEmployeeByData(string data);
|
||||||
|
|
||||||
|
void InsertEmployee(EmployeeDataModel employeeDataModel);
|
||||||
|
|
||||||
|
void UpdateEmployee(EmployeeDataModel employeeDataModel);
|
||||||
|
|
||||||
|
void DeleteEmployee(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface IPostBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<PostDataModel> GetAllPosts();
|
||||||
|
|
||||||
|
List<PostDataModel> GetAllDataOfPost(string postId);
|
||||||
|
|
||||||
|
PostDataModel GetPostByData(string data);
|
||||||
|
|
||||||
|
void InsertPost(PostDataModel postDataModel);
|
||||||
|
|
||||||
|
void UpdatePost(PostDataModel postDataModel);
|
||||||
|
|
||||||
|
void DeletePost(string id);
|
||||||
|
|
||||||
|
void RestorePost(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface IProductBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<ProductDataModel> GetAllProducts();
|
||||||
|
|
||||||
|
List<ProductHistoryDataModel> GetProductHistoryByProduct(string productId);
|
||||||
|
|
||||||
|
ProductDataModel GetProductByData(string data);
|
||||||
|
|
||||||
|
void InsertProduct(ProductDataModel productDataModel);
|
||||||
|
|
||||||
|
void UpdateProduct(ProductDataModel productDataModel);
|
||||||
|
|
||||||
|
void DeleteProduct(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface ISalaryBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
List<SalaryDataModel> GetAllSalariesByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId);
|
||||||
|
|
||||||
|
void CalculateSalaryByMounth(DateTime date);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.BuisnessLogicContracts;
|
||||||
|
|
||||||
|
public interface ISaleBusinessLogicContract
|
||||||
|
{
|
||||||
|
List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
List<SaleDataModel> GetAllSalesByEmployeeByPeriod(string employeeId, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
List<SaleDataModel> GetAllSalesByClientByPeriod(string clientId, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
List<SaleDataModel> GetAllSalesByProductByPeriod(string productId, DateTime fromDate, DateTime toDate);
|
||||||
|
|
||||||
|
SaleDataModel GetSaleByData(string data);
|
||||||
|
|
||||||
|
void InsertSale(SaleDataModel saleDataModel);
|
||||||
|
|
||||||
|
void CancelSale(string id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ValidationException = CandyHouseContracts.Exceptions.ValidationException;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class ClientDataModel(string id, string fIO, string phoneNumber, double discountSize) : IValidation
|
||||||
|
{
|
||||||
|
public string Id { get; private set; } = id;
|
||||||
|
|
||||||
|
public string FIO { get; private set; } = fIO;
|
||||||
|
|
||||||
|
public string PhoneNumber { get; private set; } = phoneNumber;
|
||||||
|
|
||||||
|
public double DiscountSize { get; private set; } = discountSize;
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (Id.IsEmpty())
|
||||||
|
throw new ValidationException("Field Id is empty");
|
||||||
|
|
||||||
|
if (!Id.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
|
|
||||||
|
if (FIO.IsEmpty())
|
||||||
|
throw new ValidationException("Field FIO is empty");
|
||||||
|
|
||||||
|
if (PhoneNumber.IsEmpty())
|
||||||
|
throw new ValidationException("Field PhoneNumber is empty");
|
||||||
|
|
||||||
|
if (!Regex.IsMatch(PhoneNumber, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$"))
|
||||||
|
throw new ValidationException("Field PhoneNumber is not a phone number");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation
|
||||||
|
{
|
||||||
|
private readonly PostDataModel? _post;
|
||||||
|
|
||||||
|
public string Id { get; private set; } = id;
|
||||||
|
|
||||||
|
public string FIO { get; private set; } = fio;
|
||||||
|
|
||||||
|
public string Email { get; private set; } = email;
|
||||||
|
|
||||||
|
public string PostId { get; private set; } = postId;
|
||||||
|
|
||||||
|
public DateTime BirthDate { get; private set; } = birthDate;
|
||||||
|
|
||||||
|
public DateTime EmploymentDate { get; private set; } = employmentDate;
|
||||||
|
|
||||||
|
public bool IsDeleted { get; private set; } = isDeleted;
|
||||||
|
|
||||||
|
public string PostName => _post?.PostName ?? string.Empty;
|
||||||
|
|
||||||
|
public EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate,
|
||||||
|
bool isDeleted, PostDataModel post) : this(id, fio, email, postId, birthDate, employmentDate, isDeleted)
|
||||||
|
{
|
||||||
|
_post = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate,
|
||||||
|
DateTime employmentDate) : this(id, fio, email, postId, birthDate, employmentDate, false) { }
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (Id.IsEmpty())
|
||||||
|
throw new ValidationException("Field Id is empty");
|
||||||
|
|
||||||
|
if (!Id.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
|
|
||||||
|
if (FIO.IsEmpty())
|
||||||
|
throw new ValidationException("Field FIO is empty");
|
||||||
|
|
||||||
|
if (Email.IsEmpty())
|
||||||
|
throw new ValidationException("Field Email is empty");
|
||||||
|
|
||||||
|
if (!Regex.IsMatch(Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
|
||||||
|
throw new ValidationException("Field Email is not a valid email address");
|
||||||
|
|
||||||
|
if (PostId.IsEmpty())
|
||||||
|
throw new ValidationException("Field PostId is empty");
|
||||||
|
|
||||||
|
if (!PostId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field PostId is not a unique identifier");
|
||||||
|
|
||||||
|
if (BirthDate.Date > DateTime.Now.AddYears(-18).Date)
|
||||||
|
throw new ValidationException($"Only adults can be hired (BirthDate = {BirthDate.ToShortDateString()})");
|
||||||
|
|
||||||
|
if (EmploymentDate.Date < BirthDate.Date)
|
||||||
|
throw new ValidationException("The date of employment cannot be less than the date of birth");
|
||||||
|
|
||||||
|
if ((EmploymentDate - BirthDate).TotalDays / 365 < 18)
|
||||||
|
throw new ValidationException($"Only adults can be hired (EmploymentDate - {EmploymentDate.ToShortDateString()}, BirthDate - {BirthDate.ToShortDateString()})");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using CandyHouseContracts.Enums;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using CandyHouseContracts.Infrastructure.PostConfigurations;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class PostDataModel(string postId, string postName, PostType postType, PostConfiguration configuration) : IValidation
|
||||||
|
{
|
||||||
|
public string Id { get; private set; } = postId;
|
||||||
|
public string PostName { get; private set; } = postName;
|
||||||
|
public PostType PostType { get; private set; } = postType;
|
||||||
|
public PostConfiguration ConfigurationModel { get; private set; } = configuration;
|
||||||
|
|
||||||
|
public PostDataModel(string postId, string postName, PostType postType, string configurationJson) : this(postId, postName, postType, (PostConfiguration)null)
|
||||||
|
{
|
||||||
|
var obj = JToken.Parse(configurationJson);
|
||||||
|
if (obj is not null)
|
||||||
|
{
|
||||||
|
ConfigurationModel = obj.Value<string>("Type") switch
|
||||||
|
{
|
||||||
|
nameof(ManagerPostConfiguration) => JsonConvert.DeserializeObject<ManagerPostConfiguration>(configurationJson)!,
|
||||||
|
nameof(BakerPostConfiguration) => JsonConvert.DeserializeObject<BakerPostConfiguration>(configurationJson)!,
|
||||||
|
_ => JsonConvert.DeserializeObject<PostConfiguration>(configurationJson)!,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (Id.IsEmpty())
|
||||||
|
throw new ValidationException("Field Id is empty");
|
||||||
|
if (!Id.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
|
if (PostName.IsEmpty())
|
||||||
|
throw new ValidationException("Field PostName is empty");
|
||||||
|
if (PostType == PostType.None)
|
||||||
|
throw new ValidationException("Field PostType is empty");
|
||||||
|
if (ConfigurationModel is null)
|
||||||
|
throw new ValidationException("Field ConfigurationModel is not initialized");
|
||||||
|
if (ConfigurationModel!.Rate <= 0)
|
||||||
|
throw new ValidationException("Field Rate is less or equal zero");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using CandyHouseContracts.Enums;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class ProductDataModel(string id, string productName, string productDescription, double price, ProductType productType) : IValidation
|
||||||
|
{
|
||||||
|
public string Id { get; private set; } = id;
|
||||||
|
public string ProductName { get; private set; } = productName;
|
||||||
|
public string ProductDescription { get; private set; } = productDescription;
|
||||||
|
public double Price { get; private set; } = price;
|
||||||
|
public ProductType ProductType { get; private set; } = productType;
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (Id.IsEmpty())
|
||||||
|
throw new ValidationException("Field Id is empty");
|
||||||
|
if (!Id.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
|
if (ProductName.IsEmpty())
|
||||||
|
throw new ValidationException("Field ProductName is empty");
|
||||||
|
if (ProductDescription.IsEmpty())
|
||||||
|
throw new ValidationException("Field ProductDescription is empty");
|
||||||
|
if (Price <= 0)
|
||||||
|
throw new ValidationException("Field Price is less than or equal to 0");
|
||||||
|
if (ProductType == ProductType.None)
|
||||||
|
throw new ValidationException("Field Type is empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class ProductHistoryDataModel(string productId, double oldPrice) : IValidation
|
||||||
|
{
|
||||||
|
private readonly ProductDataModel? _product;
|
||||||
|
|
||||||
|
public string ProductId { get; private set; } = productId;
|
||||||
|
|
||||||
|
public double OldPrice { get; private set; } = oldPrice;
|
||||||
|
|
||||||
|
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
public string ProductName => _product?.ProductName ?? string.Empty;
|
||||||
|
|
||||||
|
public ProductHistoryDataModel(string productId, double oldPrice, DateTime changeDate, ProductDataModel product) : this(productId, oldPrice)
|
||||||
|
{
|
||||||
|
ChangeDate = changeDate;
|
||||||
|
_product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (ProductId.IsEmpty())
|
||||||
|
throw new ValidationException("Field ProductId is empty");
|
||||||
|
|
||||||
|
if (!ProductId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field ProductId is not a unique identifier");
|
||||||
|
|
||||||
|
if (OldPrice <= 0)
|
||||||
|
throw new ValidationException("Field OldPrice is less than or equal to 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary) : IValidation
|
||||||
|
{
|
||||||
|
private readonly EmployeeDataModel? _employee;
|
||||||
|
public string EmployeeId { get; private set; } = employeeId;
|
||||||
|
|
||||||
|
public DateTime SalaryDate { get; private set; } = salaryDate;
|
||||||
|
|
||||||
|
public double Salary { get; private set; } = employeeSalary;
|
||||||
|
|
||||||
|
public string EmployeeFIO => _employee?.FIO ?? string.Empty;
|
||||||
|
|
||||||
|
public SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary, EmployeeDataModel employee) : this(employeeId, salaryDate, employeeSalary)
|
||||||
|
{
|
||||||
|
_employee = employee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (EmployeeId.IsEmpty())
|
||||||
|
throw new ValidationException("Field EmployeeId is empty");
|
||||||
|
|
||||||
|
if (!EmployeeId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field EmployeeId is not a unique identifier");
|
||||||
|
|
||||||
|
if (Salary <= 0)
|
||||||
|
throw new ValidationException("Field Salary is less than or equal to 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
using CandyHouseContracts.Enums;
|
||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class SaleDataModel : IValidation
|
||||||
|
{
|
||||||
|
private readonly ClientDataModel? _client;
|
||||||
|
|
||||||
|
private readonly EmployeeDataModel? _employee;
|
||||||
|
|
||||||
|
public string Id { get; private set; }
|
||||||
|
|
||||||
|
public string EmployeeId { get; private set; }
|
||||||
|
|
||||||
|
public string? ClientId { get; private set; }
|
||||||
|
|
||||||
|
public DateTime SaleDate { get; private set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
public double Sum { get; private set; }
|
||||||
|
|
||||||
|
public DiscountType DiscountType { get; private set; }
|
||||||
|
|
||||||
|
public double Discount { get; private set; }
|
||||||
|
|
||||||
|
public bool IsCancel { get; private set; }
|
||||||
|
|
||||||
|
public List<SaleProductDataModel>? Products { get; private set; }
|
||||||
|
|
||||||
|
public string ClientFIO => _client?.FIO ?? string.Empty;
|
||||||
|
|
||||||
|
public string EmployeeFIO => _employee?.FIO ?? string.Empty;
|
||||||
|
|
||||||
|
public SaleDataModel(string id, string employeeId, string? clientId, DiscountType discountType, bool isCancel, List<SaleProductDataModel> saleProducts)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
EmployeeId = employeeId;
|
||||||
|
ClientId = clientId;
|
||||||
|
DiscountType = discountType;
|
||||||
|
IsCancel = isCancel;
|
||||||
|
Products = saleProducts;
|
||||||
|
var percent = 0.0;
|
||||||
|
foreach (DiscountType elem in Enum.GetValues<DiscountType>())
|
||||||
|
{
|
||||||
|
if ((elem & discountType) != 0)
|
||||||
|
{
|
||||||
|
switch (elem)
|
||||||
|
{
|
||||||
|
case DiscountType.None:
|
||||||
|
break;
|
||||||
|
case DiscountType.OnSale:
|
||||||
|
percent += 0.1;
|
||||||
|
break;
|
||||||
|
case DiscountType.RegularCustomer:
|
||||||
|
percent += 0.5;
|
||||||
|
break;
|
||||||
|
case DiscountType.Certificate:
|
||||||
|
percent += 0.3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sum = Products?.Sum(x => x.Price * x.Count) ?? 0;
|
||||||
|
Discount = Sum * percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaleDataModel(string id, string employeeId, string? clientId, double sum, DiscountType discountType, double discount, bool isCancel,
|
||||||
|
List<SaleProductDataModel> saleProducts, EmployeeDataModel employee, ClientDataModel? client) : this(id, employeeId, clientId, discountType, isCancel, saleProducts)
|
||||||
|
{
|
||||||
|
Sum = sum;
|
||||||
|
Discount = discount;
|
||||||
|
_employee = employee;
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaleDataModel(string id, string employeeId, string? clientId, int discountType,
|
||||||
|
List<SaleProductDataModel> products) : this(id, employeeId, clientId, (DiscountType)discountType, false, products) { }
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (Id.IsEmpty())
|
||||||
|
throw new ValidationException("Field Id is empty");
|
||||||
|
|
||||||
|
if (!Id.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
|
|
||||||
|
if (EmployeeId.IsEmpty())
|
||||||
|
throw new ValidationException("Field EmployeeId is empty");
|
||||||
|
|
||||||
|
if (!EmployeeId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field EmployeeId is not a unique identifier");
|
||||||
|
|
||||||
|
if (!ClientId?.IsGuid() ?? !ClientId?.IsEmpty() ?? false)
|
||||||
|
throw new ValidationException("The value in the field BuyerId is not a unique identifier");
|
||||||
|
|
||||||
|
if (Sum <= 0)
|
||||||
|
throw new ValidationException("Field Sum is less than or equal to 0");
|
||||||
|
|
||||||
|
if ((Products?.Count ?? 0) == 0)
|
||||||
|
throw new ValidationException("The sale must include products");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using CandyHouseContracts.Exceptions;
|
||||||
|
using CandyHouseContracts.Extensions;
|
||||||
|
using CandyHouseContracts.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.DataModels;
|
||||||
|
|
||||||
|
public class SaleProductDataModel(string saleId, string productId, int count, double price) : IValidation
|
||||||
|
{
|
||||||
|
private readonly ProductDataModel? _product;
|
||||||
|
|
||||||
|
public string SaleId { get; private set; } = saleId;
|
||||||
|
|
||||||
|
public string ProductId { get; private set; } = productId;
|
||||||
|
|
||||||
|
public int Count { get; private set; } = count;
|
||||||
|
|
||||||
|
public double Price { get; private set; } = price;
|
||||||
|
|
||||||
|
public string ProductName => _product?.ProductName ?? string.Empty;
|
||||||
|
|
||||||
|
public SaleProductDataModel(string saleId, string productId, int count, double price, ProductDataModel product) : this(saleId, productId, count, price)
|
||||||
|
{
|
||||||
|
_product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
if (SaleId.IsEmpty())
|
||||||
|
throw new ValidationException("Field SaleId is empty");
|
||||||
|
|
||||||
|
if (!SaleId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field SaleId is not a unique identifier");
|
||||||
|
|
||||||
|
if (ProductId.IsEmpty())
|
||||||
|
throw new ValidationException("Field ProductId is empty");
|
||||||
|
|
||||||
|
if (!ProductId.IsGuid())
|
||||||
|
throw new ValidationException("The value in the field ProductId is not a unique identifier");
|
||||||
|
|
||||||
|
if (Count <= 0)
|
||||||
|
throw new ValidationException("Field Count is less than or equal to 0");
|
||||||
|
|
||||||
|
if (Price <= 0)
|
||||||
|
throw new ValidationException("Field Price is less than or equal to 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
15
CandyHouseSolution/CandyHouseContracts/Enums/DiscountType.cs
Normal file
15
CandyHouseSolution/CandyHouseContracts/Enums/DiscountType.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Enums;
|
||||||
|
[Flags]
|
||||||
|
public enum DiscountType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
OnSale = 1,
|
||||||
|
RegularCustomer = 2,
|
||||||
|
Certificate = 4
|
||||||
|
}
|
||||||
15
CandyHouseSolution/CandyHouseContracts/Enums/PostType.cs
Normal file
15
CandyHouseSolution/CandyHouseContracts/Enums/PostType.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Enums;
|
||||||
|
|
||||||
|
public enum PostType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Manager = 1,
|
||||||
|
SuperManager = 2,
|
||||||
|
Baker = 3,
|
||||||
|
}
|
||||||
15
CandyHouseSolution/CandyHouseContracts/Enums/ProductType.cs
Normal file
15
CandyHouseSolution/CandyHouseContracts/Enums/ProductType.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Enums;
|
||||||
|
|
||||||
|
public enum ProductType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Candy = 1,
|
||||||
|
Cake = 2,
|
||||||
|
Chocolate = 3,
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
|
public class ElementDeletedException : Exception
|
||||||
|
{
|
||||||
|
public ElementDeletedException(string id) : base($"Cannot modify a deleted item (id: {id})") { }
|
||||||
|
}
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
public class ElementExistsException : Exception
|
public class ElementExistsException : Exception
|
||||||
{
|
{
|
||||||
public string ParamName { get; private set; }
|
public string ParamName { get; private set; }
|
||||||
|
|
||||||
public string ParamValue { get; private set; }
|
public string ParamValue { get; private set; }
|
||||||
|
|
||||||
public ElementExistsException(string paramName, string paramValue) :
|
public ElementExistsException(string paramName, string paramValue) : base($"There is already an element with value{paramValue} of parameter {paramName}")
|
||||||
base($"There is already an element with value {paramValue} of parameter {paramName}")
|
|
||||||
{
|
{
|
||||||
ParamName = paramName;
|
ParamName = paramName;
|
||||||
ParamValue = paramValue;
|
ParamValue = paramValue;
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
public class ElementNotFoundException : Exception
|
public class ElementNotFoundException : Exception
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
|
public class IncorrectDatesException : Exception
|
||||||
|
{
|
||||||
|
public IncorrectDatesException(DateTime start, DateTime end) : base($"The end date must be later than the start date.. StartDate: " +
|
||||||
|
$"{start:dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}") { }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
|
public class NullListException : Exception
|
||||||
|
{
|
||||||
|
public NullListException() : base("The returned list is null") { }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
|
public class StorageException : Exception
|
||||||
|
{
|
||||||
|
public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex) { }
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Exceptions;
|
||||||
|
|
||||||
|
public class ValidationException(string message) : Exception(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CandyHouseBase.Exceptions;
|
namespace CandyHouseContracts.Extensions;
|
||||||
|
|
||||||
public static class DateTimeExtensions
|
public static class DateTimeExtensions
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Extensions;
|
||||||
|
|
||||||
|
public static class StringExtensions
|
||||||
|
{
|
||||||
|
public static bool IsEmpty(this string str) => string.IsNullOrWhiteSpace(str);
|
||||||
|
public static bool IsGuid(this string str) => Guid.TryParse(str, out _);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Infrastructure;
|
||||||
|
|
||||||
|
public interface IConfigurationDatabase
|
||||||
|
{
|
||||||
|
string ConnectionString { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace CandyHouseContracts.Infrastructure;
|
||||||
|
|
||||||
|
public interface IConfigurationSalary
|
||||||
|
{
|
||||||
|
double ExtraSaleSum { get; }
|
||||||
|
|
||||||
|
int MaxConcurrentThreads { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Infrastructure;
|
||||||
|
|
||||||
|
public interface IValidation
|
||||||
|
{
|
||||||
|
void Validate();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.Infrastructure;
|
||||||
|
|
||||||
|
public class OperationResponse
|
||||||
|
{
|
||||||
|
protected HttpStatusCode StatusCode { get; set; }
|
||||||
|
|
||||||
|
protected object? Result { get; set; }
|
||||||
|
|
||||||
|
public IActionResult GetResponse(HttpRequest request, HttpResponse response)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(request);
|
||||||
|
ArgumentNullException.ThrowIfNull(response);
|
||||||
|
|
||||||
|
response.StatusCode = (int)StatusCode;
|
||||||
|
|
||||||
|
if (Result is null)
|
||||||
|
{
|
||||||
|
return new StatusCodeResult((int)StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ObjectResult(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static TResult OK<TResult, TData>(TData data) where TResult : OperationResponse,
|
||||||
|
new() => new() { StatusCode = HttpStatusCode.OK, Result = data };
|
||||||
|
|
||||||
|
protected static TResult NoContent<TResult>() where TResult : OperationResponse,
|
||||||
|
new() => new() { StatusCode = HttpStatusCode.NoContent };
|
||||||
|
|
||||||
|
protected static TResult BadRequest<TResult>(string? errorMessage = null) where TResult : OperationResponse,
|
||||||
|
new() => new() { StatusCode = HttpStatusCode.BadRequest, Result = errorMessage };
|
||||||
|
|
||||||
|
protected static TResult NotFound<TResult>(string? errorMessage = null) where TResult : OperationResponse,
|
||||||
|
new() => new() { StatusCode = HttpStatusCode.NotFound, Result = errorMessage };
|
||||||
|
|
||||||
|
protected static TResult InternalServerError<TResult>(string? errorMessage = null) where TResult : OperationResponse,
|
||||||
|
new() => new() { StatusCode = HttpStatusCode.InternalServerError, Result = errorMessage };
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace CandyHouseContracts.Infrastructure.PostConfigurations;
|
||||||
|
|
||||||
|
public class BakerPostConfiguration : PostConfiguration
|
||||||
|
{
|
||||||
|
public override string Type => nameof(BakerPostConfiguration);
|
||||||
|
public double PersonalCountTrendPremium { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace CandyHouseContracts.Infrastructure.PostConfigurations;
|
||||||
|
|
||||||
|
public class ManagerPostConfiguration : PostConfiguration
|
||||||
|
{
|
||||||
|
public override string Type => nameof(ManagerPostConfiguration);
|
||||||
|
public double SalePercent { get; set; }
|
||||||
|
public double BonusForExtraSales { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace CandyHouseContracts.Infrastructure.PostConfigurations;
|
||||||
|
|
||||||
|
public class PostConfiguration
|
||||||
|
{
|
||||||
|
public virtual string Type => nameof(PostConfiguration);
|
||||||
|
public double Rate { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using CandyHouseContracts.DataModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CandyHouseContracts.StoragesContracts;
|
||||||
|
|
||||||
|
public interface IClientStorageContract
|
||||||
|
{
|
||||||
|
List<ClientDataModel> GetList();
|
||||||
|
|
||||||
|
ClientDataModel? GetElementById(string id);
|
||||||
|
|
||||||
|
ClientDataModel? GetElementByPhoneNumber(string phoneNumber);
|
||||||
|
|
||||||
|
ClientDataModel? GetElementByFIO(string fio);
|
||||||
|
|
||||||
|
void AddElement(ClientDataModel clientDataModel);
|
||||||
|
|
||||||
|
void UpdElement(ClientDataModel clientDataModel);
|
||||||
|
|
||||||
|
void DelElement(string id);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user