13 Commits
lab-2 ... lab-4

Author SHA1 Message Date
8c4829991d fix 2025-04-15 00:47:03 +04:00
524bfca4d0 ready 2025-04-14 22:46:08 +04:00
4113d2ab9e Merge remote-tracking branch 'origin/lab-4' into lab-4 2025-04-14 22:17:32 +04:00
d295b50e32 little update 2025-04-14 22:17:22 +04:00
f9966ae73d little update 2025-04-14 22:15:04 +04:00
d84b3850d6 lab4 2025-04-14 22:07:51 +04:00
6449c0df73 lab4 2025-04-11 10:16:19 +04:00
7beb84b967 lab4 ready 2025-04-11 01:55:51 +04:00
082111e301 lab4 ? 2025-04-11 01:36:54 +04:00
14b48e3a30 may be work 2025-04-09 11:17:10 +04:00
f649754da7 lab4-preready 2025-04-09 01:46:17 +04:00
cec7b9240e Ready full 2025-03-13 16:04:10 +04:00
d2f7afae63 lab-3 ready 2025-03-13 13:38:00 +04:00
198 changed files with 12375 additions and 5494 deletions

3
.gitignore vendored
View File

@@ -10,7 +10,7 @@
*.user
*.userosscache
*.sln.docstates
*.idea
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -414,3 +414,4 @@ FodyWeavers.xsd
# Built Visual Studio Code Extensions
*.vsix
/.idea/

View File

@@ -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>

View File

@@ -1,3 +0,0 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("CandyHouseTests")]

View File

@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="8.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"
Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5DF70B46-31F7-4D15-8C60-52C0A0A364F0}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CandyHouseBase</RootNamespace>
<AssemblyName>CandyHouseBase</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<LangVersion>12</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.20.72.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.20.72\lib\net462\Moq.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System"/>
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core"/>
<Reference Include="System.Data"/>
<Reference Include="System.Diagnostics.DiagnosticSource, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.1.25080.5\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.IO.Pipelines, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Pipelines.10.0.0-preview.1.25080.5\lib\net462\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.10.0.0-preview.1.25080.5\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.10.0.0-preview.1.25080.5\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml"/>
</ItemGroup>
<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\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\ValidationException.cs" />
<Compile Include="Extensions\StringExtensions.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\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" />
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="CatHasPawsTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="ILLink\ILLink.Descriptors.LibraryBuild.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(AssemblyName).Test.dll</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>

View File

@@ -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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -1,42 +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 List<ProductDataModel> ProductsItems { get; private set; }
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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -1,58 +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(string id, string name, string description, List<IngredientDataModel> ingredients)
{
Id = id;
Name = name;
Description = description;
IngredientsItems = ingredients;
}
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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -1,10 +0,0 @@
namespace CandyHouseBase.Enums
{
public enum PositionType
{
None = 1,
Small = 2,
Medium = 3,
Cool = 4,
}
}

View File

@@ -1,10 +0,0 @@
namespace CandyHouseBase.Enums
{
public enum StatusType
{
Pending,
Completed,
Cancelled,
InProgress
}
}

View File

@@ -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}")
{
}
}

View File

@@ -1,10 +0,0 @@
using System;
namespace CandyHouseBase.Exceptions;
public class NullListException : Exception
{
public NullListException() : base("The returned list is null")
{
}
}

View File

@@ -1,11 +0,0 @@
using System;
namespace CandyHouseBase.Exceptions;
public class StorageException : Exception
{
public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex)
{
}
}

View File

@@ -1,9 +0,0 @@
using System;
namespace CandyHouseBase.Exceptions
{
public class ValidationException : Exception
{
public ValidationException(string message) : base(message) { }
}
}

View File

@@ -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 _);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -1,7 +0,0 @@
namespace CandyHouseBase.Infrastructure
{
public interface IValidation
{
void Validate();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -1,9 +0,0 @@
namespace CandyHouseBase
{
public class Program
{
public static void Main(string[] args)
{
}
}
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,67 @@
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.Threading.Tasks;
namespace CandyHouseBusinessLogic.Implementations;
public class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract,ISaleStorageContract saleStorageContract,
IPostStorageContract postStorageContract, IEmployeeStorageContract employeeStorageContract, ILogger logger) : 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;
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)?.Sum(x => x.Sum) ??
throw new NullListException();
var post = _postStorageContract.GetElementById(employee.PostId) ??
throw new NullListException();
var salary = post.Salary + sales * 0.1;
_logger.LogDebug("The employee {employeeId} was paid a salary of {salary}", employee.Id, salary);
_salaryStorageContract.AddElement(new SalaryDataModel(employee.Id, DateTime.SpecifyKind(finishDate, DateTimeKind.Utc), salary));
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -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 PostBindingModel
{
public string? Id { get; set; }
public string? PostId => Id;
public string? PostName { get; set; }
public string? PostType { get; set; }
public double Salary { get; set; }
}

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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");
}
}

View File

@@ -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()})");
}
}

View File

@@ -0,0 +1,33 @@
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 PostDataModel(string postId, string postName, PostType postType, double salary) : IValidation
{
public string Id { get; private set; } = postId;
public string PostName { get; private set; } = postName;
public PostType PostType { get; private set; } = postType;
public double Salary { get; private set; } = salary;
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 (Salary <= 0)
throw new ValidationException("Field Salary is empty");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View 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
}

View 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,
}

View 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,
}

View File

@@ -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})") { }
}

View File

@@ -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 string ParamName { get; private set; }
public string ParamValue { get; private set; }
public ElementExistsException(string paramName, string paramValue) :
base($"There is already an element with value {paramValue} of parameter {paramName}")
public ElementExistsException(string paramName, string paramValue) : base($"There is already an element with value{paramValue} of parameter {paramName}")
{
ParamName = paramName;
ParamValue = paramValue;

View File

@@ -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
{

View File

@@ -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}") { }
}

View File

@@ -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") { }
}

View File

@@ -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) { }
}

View File

@@ -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)
{
}

View File

@@ -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
{

View File

@@ -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 _);
}

View File

@@ -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; }
}

View File

@@ -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();
}

View File

@@ -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 };
}

View File

@@ -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);
}

View File

@@ -0,0 +1,26 @@
using CandyHouseContracts.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CandyHouseContracts.StoragesContracts;
public interface IEmployeeStorageContract
{
List<EmployeeDataModel> GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null,
DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null);
EmployeeDataModel? GetElementById(string id);
EmployeeDataModel? GetElementByFIO(string fio);
EmployeeDataModel? GetElementByEmail(string email);
void AddElement(EmployeeDataModel employeeDataModel);
void UpdElement(EmployeeDataModel employeeDataModel);
void DelElement(string id);
}

View File

@@ -0,0 +1,20 @@
using CandyHouseContracts.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CandyHouseContracts.StoragesContracts;
public interface IPostStorageContract
{
List<PostDataModel> GetList();
List<PostDataModel> GetPostWithHistory(string postId);
PostDataModel? GetElementById(string id);
PostDataModel? GetElementByName(string name);
void AddElement(PostDataModel postDataModel);
void UpdElement(PostDataModel postDataModel);
void DelElement(string id);
void ResElement(string id);
}

View File

@@ -0,0 +1,19 @@
using CandyHouseContracts.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CandyHouseContracts.StoragesContracts;
public interface IProductStorageContract
{
List<ProductDataModel> GetList();
List<ProductHistoryDataModel> GetHistoryByProductId(string productId);
ProductDataModel? GetElementById(string id);
ProductDataModel? GetElementByName(string name);
void AddElement(ProductDataModel productDataModel);
void UpdElement(ProductDataModel productDataModel);
void DelElement(string id);
}

View File

@@ -0,0 +1,15 @@
using CandyHouseContracts.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CandyHouseContracts.StoragesContracts;
public interface ISalaryStorageContract
{
List<SalaryDataModel> GetList(DateTime? startDate, DateTime? endDate, string? employeeId = null);
void AddElement(SalaryDataModel salaryDataModel);
}

View File

@@ -0,0 +1,20 @@
using CandyHouseContracts.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CandyHouseContracts.StoragesContracts;
public interface ISaleStorageContract
{
List<SaleDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? employeeId = null,
string? clientId = null, string? productId = null);
SaleDataModel? GetElementById(string id);
void AddElement(SaleDataModel saleDataModel);
void DelElement(string id);
}

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