diff --git a/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj b/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj
new file mode 100644
index 0000000..a470328
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj
@@ -0,0 +1,70 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5DF70B46-31F7-4D15-8C60-52C0A0A364F0}
+ Exe
+ Properties
+ CandyHouseBase
+ CandyHouseBase
+ v4.7.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/CustomerDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/CustomerDataModel.cs
new file mode 100644
index 0000000..bd167e7
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/CustomerDataModel.cs
@@ -0,0 +1,36 @@
+using System.Text.RegularExpressions;
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class CustomerDataModel : IValidation
+ {
+ public string Id { get; private set; }
+ public string FIO { get; private set; }
+ public string Phone { get; private set; }
+ public string Email { get; private set; }
+
+ public CustomerDataModel(string id, string fio, string phone, string email)
+ {
+ Id = id;
+ FIO = fio;
+ Phone = phone;
+ Email = email;
+ }
+
+ 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");
+ if (Phone.IsEmpty()) throw new ValidationException("Field Phone is empty");
+
+ var phoneRegex = new Regex(@"^\+7\d{10}$");
+ if (!phoneRegex.IsMatch(Phone)) throw new ValidationException("Invalid phone format");
+
+ if (Email.IsEmpty() || !Email.Contains("@")) throw new ValidationException("Invalid email format");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/IngredientDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/IngredientDataModel.cs
new file mode 100644
index 0000000..60265c3
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/IngredientDataModel.cs
@@ -0,0 +1,31 @@
+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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/IngredientStockDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/IngredientStockDataModel.cs
new file mode 100644
index 0000000..b869940
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/IngredientStockDataModel.cs
@@ -0,0 +1,37 @@
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class IngredientStockDataModel : IValidation
+ {
+ public string IngredientId { get; private set; }
+ public int Quantity { get; private set; }
+
+ public IngredientStockDataModel(string ingredientId, int quantity)
+ {
+ IngredientId = ingredientId;
+ Quantity = quantity;
+ }
+
+ public void Validate()
+ {
+ if (!IngredientId.IsGuid()) throw new ValidationException("IngredientId must be a GUID");
+ if (Quantity < 0) throw new ValidationException("Quantity cannot be negative");
+ }
+
+ public void AddStock(int amount)
+ {
+ if (amount <= 0) throw new ValidationException("Added quantity must be positive");
+ Quantity += amount;
+ }
+
+ public void RemoveStock(int amount)
+ {
+ if (amount <= 0) throw new ValidationException("Removed quantity must be positive");
+ if (amount > Quantity) throw new ValidationException("Not enough stock available");
+ Quantity -= amount;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs
new file mode 100644
index 0000000..86f2a9f
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class OrderDataModel : IValidation
+ {
+ public string Id { get; private set; }
+ public string CustomerId { get; private set; } // Может быть null, если клиент разовый
+ public DateTime OrderDate { get; private set; }
+ public decimal TotalAmount { get; private set; }
+ public decimal DiscountAmount { get; private set; }
+ public List OrderItems { get; private set; }
+ public bool IsCompleted { get; private set; }
+
+ public OrderDataModel(string id, string customerId, DateTime orderDate, decimal totalAmount,
+ decimal discountAmount, List orderItems, bool isCompleted)
+ {
+ Id = id;
+ CustomerId = customerId;
+ OrderDate = orderDate;
+ TotalAmount = totalAmount;
+ DiscountAmount = discountAmount;
+ OrderItems = orderItems;
+ IsCompleted = isCompleted;
+ }
+
+ 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 (!CustomerId.IsEmpty() && !CustomerId.IsGuid())
+ throw new ValidationException("CustomerId must be a GUID or empty");
+ if (OrderItems == null || OrderItems.Count == 0)
+ throw new ValidationException("Order must contain at least one product");
+ if (TotalAmount < 0) throw new ValidationException("TotalAmount cannot be negative");
+ if (DiscountAmount < 0) throw new ValidationException("DiscountAmount cannot be negative");
+ }
+
+ public void MarkAsCompleted()
+ {
+ IsCompleted = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/OrderItemDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/OrderItemDataModel.cs
new file mode 100644
index 0000000..d55d7be
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/OrderItemDataModel.cs
@@ -0,0 +1,30 @@
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class OrderItemDataModel : IValidation
+ {
+ public string OrderId { get; private set; }
+ public string ProductId { get; private set; }
+ public int Quantity { get; private set; }
+ public decimal Price { get; private set; } // Цена на момент заказа
+
+ public OrderItemDataModel(string orderId, string productId, int quantity, decimal price)
+ {
+ OrderId = orderId;
+ ProductId = productId;
+ Quantity = quantity;
+ Price = price;
+ }
+
+ public void Validate()
+ {
+ if (!OrderId.IsGuid()) throw new ValidationException("OrderId must be a GUID");
+ if (!ProductId.IsGuid()) throw new ValidationException("ProductId must be a GUID");
+ if (Quantity <= 0) throw new ValidationException("Quantity must be positive");
+ if (Price < 0) throw new ValidationException("Price cannot be negative");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/PekarDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/PekarDataModel.cs
new file mode 100644
index 0000000..b0c120a
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/PekarDataModel.cs
@@ -0,0 +1,31 @@
+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 PekarDataModel(string id, string fio, string position, decimal bonusCoefficient)
+ {
+ Id = id;
+ FIO = fio;
+ Position = position;
+ BonusCoefficient = bonusCoefficient;
+ }
+
+ 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");
+ if (Position.IsEmpty()) throw new ValidationException("Field Position is empty");
+ if (BonusCoefficient <= 0) throw new ValidationException("BonusCoefficient must be positive");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs
new file mode 100644
index 0000000..f5b801b
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs
@@ -0,0 +1,27 @@
+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; private set; }
+ public string Description { get; private set; }
+
+ public ProductDataModel(string id, string name, string description)
+ {
+ Id = id;
+ Name = name;
+ Description = description;
+ }
+
+ 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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/ProductStockDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/ProductStockDataModel.cs
new file mode 100644
index 0000000..2727483
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/ProductStockDataModel.cs
@@ -0,0 +1,37 @@
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class ProductStockDataModel : IValidation
+ {
+ public string ProductId { get; private set; }
+ public int Quantity { get; private set; }
+
+ public ProductStockDataModel(string productId, int quantity)
+ {
+ ProductId = productId;
+ Quantity = quantity;
+ }
+
+ public void Validate()
+ {
+ if (!ProductId.IsGuid()) throw new ValidationException("ProductId must be a GUID");
+ if (Quantity < 0) throw new ValidationException("Quantity cannot be negative");
+ }
+
+ public void AddStock(int amount)
+ {
+ if (amount <= 0) throw new ValidationException("Added quantity must be positive");
+ Quantity += amount;
+ }
+
+ public void RemoveStock(int amount)
+ {
+ if (amount <= 0) throw new ValidationException("Removed quantity must be positive");
+ if (amount > Quantity) throw new ValidationException("Not enough stock available");
+ Quantity -= amount;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/ProductionDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/ProductionDataModel.cs
new file mode 100644
index 0000000..733c68c
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/ProductionDataModel.cs
@@ -0,0 +1,33 @@
+using System;
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class ProductionDataModel : IValidation
+ {
+ public string Id { get; private set; }
+ public string PekarId { get; private set; }
+ public string ProductId { get; private set; }
+ public DateTime ProductionDate { get; private set; }
+ public int Quantity { get; private set; }
+
+ public ProductionDataModel(string id, string pekarId, string productId, DateTime productionDate, int quantity)
+ {
+ Id = id;
+ PekarId = pekarId;
+ ProductId = productId;
+ ProductionDate = productionDate;
+ Quantity = quantity;
+ }
+
+ public void Validate()
+ {
+ if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
+ if (!PekarId.IsGuid()) throw new ValidationException("PekarId must be a GUID");
+ if (!ProductId.IsGuid()) throw new ValidationException("ProductId must be a GUID");
+ if (Quantity <= 0) throw new ValidationException("Quantity must be positive");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/RecipeDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/RecipeDataModel.cs
new file mode 100644
index 0000000..fbe97d2
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/RecipeDataModel.cs
@@ -0,0 +1,27 @@
+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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/SupplyDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/SupplyDataModel.cs
new file mode 100644
index 0000000..32d6e55
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/SupplyDataModel.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class SupplyDataModel : IValidation
+ {
+ public string Id { get; private set; }
+ public DateTime SupplyDate { get; private set; }
+ public List SupplyItems { get; private set; }
+
+ public SupplyDataModel(string id, DateTime supplyDate, List supplyItems)
+ {
+ Id = id;
+ SupplyDate = supplyDate;
+ SupplyItems = supplyItems;
+ }
+
+ public void Validate()
+ {
+ if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
+ if (SupplyItems == null || SupplyItems.Count == 0) throw new ValidationException("Supply must contain at least one item");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/SupplyItemDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/SupplyItemDataModel.cs
new file mode 100644
index 0000000..947e478
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/DataModels/SupplyItemDataModel.cs
@@ -0,0 +1,30 @@
+using CandyHouseBase.Enums;
+using CandyHouseBase.Exceptions;
+using CandyHouseBase.Extensions;
+using CandyHouseBase.Infrastructure;
+
+namespace CandyHouseBase.DataModels
+{
+ public class SupplyItemDataModel : IValidation
+ {
+ public string SupplyId { get; private set; }
+ public string ItemId { get; private set; }
+ public int Quantity { get; private set; }
+ public ItemType ItemType { get; private set; } // 'ingredient' или 'product'
+
+ public SupplyItemDataModel(string supplyId, string itemId, int quantity, ItemType itemType)
+ {
+ SupplyId = supplyId;
+ ItemId = itemId;
+ Quantity = quantity;
+ ItemType = itemType;
+ }
+
+ public void Validate()
+ {
+ if (!SupplyId.IsGuid()) throw new ValidationException("SupplyId must be a GUID");
+ if (!ItemId.IsGuid()) throw new ValidationException("ItemId must be a GUID");
+ if (Quantity <= 0) throw new ValidationException("Quantity must be positive");
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/Enums/ItemType.cs b/CandyHouseSolution/CandyHouseBase/Enums/ItemType.cs
new file mode 100644
index 0000000..6f7eb5e
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/Enums/ItemType.cs
@@ -0,0 +1,8 @@
+namespace CandyHouseBase.Enums
+{
+ public enum ItemType
+ {
+ Ingredient = 1,
+ Product = 2
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/ValidationException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/ValidationException.cs
new file mode 100644
index 0000000..97af727
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/Exceptions/ValidationException.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace CandyHouseBase.Exceptions
+{
+ public class ValidationException : Exception
+ {
+ public ValidationException(string message) : base(message) { }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/Extensions/StringExtensions.cs b/CandyHouseSolution/CandyHouseBase/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..17e6077
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/Extensions/StringExtensions.cs
@@ -0,0 +1,10 @@
+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 _);
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/Infrastructure/IValidation.cs b/CandyHouseSolution/CandyHouseBase/Infrastructure/IValidation.cs
new file mode 100644
index 0000000..07c21c6
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/Infrastructure/IValidation.cs
@@ -0,0 +1,7 @@
+namespace CandyHouseBase.Infrastructure
+{
+ public interface IValidation
+ {
+ void Validate();
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseBase/Program.cs b/CandyHouseSolution/CandyHouseBase/Program.cs
new file mode 100644
index 0000000..9fda858
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseBase/Program.cs
@@ -0,0 +1,9 @@
+namespace CandyHouseBase
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseSolution.sln b/CandyHouseSolution/CandyHouseSolution.sln
new file mode 100644
index 0000000..1cc98dd
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseSolution.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseBase", "CandyHouseBase\CandyHouseBase.csproj", "{5DF70B46-31F7-4D15-8C60-52C0A0A364F0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseTests", "CandyHouseTests\CandyHouseTests.csproj", "{396EA8C4-6102-479E-83A2-C83E6B74A14E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5DF70B46-31F7-4D15-8C60-52C0A0A364F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5DF70B46-31F7-4D15-8C60-52C0A0A364F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5DF70B46-31F7-4D15-8C60-52C0A0A364F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5DF70B46-31F7-4D15-8C60-52C0A0A364F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {396EA8C4-6102-479E-83A2-C83E6B74A14E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {396EA8C4-6102-479E-83A2-C83E6B74A14E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {396EA8C4-6102-479E-83A2-C83E6B74A14E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {396EA8C4-6102-479E-83A2-C83E6B74A14E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/CandyHouseSolution/CandyHouseTests/App.config b/CandyHouseSolution/CandyHouseTests/App.config
new file mode 100644
index 0000000..74b8a4e
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/App.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj b/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj
new file mode 100644
index 0000000..c47af43
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+ Debug
+ AnyCPU
+ {396EA8C4-6102-479E-83A2-C83E6B74A14E}
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ Properties
+ CandyHouseTests
+ CandyHouseTests
+ v4.7.1
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll
+
+
+
+ ..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll
+
+
+ ..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll
+
+
+ ..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
+
+
+ ..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll
+
+
+ ..\packages\Microsoft.Testing.Platform.1.5.3\lib\netstandard2.0\Microsoft.Testing.Platform.dll
+
+
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
+
+
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
+
+
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
+
+
+
+
+ ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+ ..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll
+
+
+
+
+
+ ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll
+
+
+ ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
+
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll
+
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+
+ ..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {5df70b46-31f7-4d15-8c60-52c0a0a364f0}
+ CandyHouseBase
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CandyHouseSolution/CandyHouseTests/DataModelsTests/CustomerDataModelTests.cs b/CandyHouseSolution/CandyHouseTests/DataModelsTests/CustomerDataModelTests.cs
new file mode 100644
index 0000000..2ade668
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/DataModelsTests/CustomerDataModelTests.cs
@@ -0,0 +1,55 @@
+using System;
+using CandyHouseBase.DataModels;
+using CandyHouseBase.Exceptions;
+using NUnit.Framework;
+
+namespace CandyHouseTests.DataModelsTests
+{
+ [TestFixture]
+ public class CustomerDataModelTests
+ {
+ [Test]
+ public void Customer_ShouldThrowException_WhenIdIsInvalid()
+ {
+ var customerDataModel1 = new CustomerDataModel("", "John Doe", "+79998887766", "john@example.com");
+ var customerDataModel2 =
+ new CustomerDataModel("invalid-guid", "John Doe", "+79998887766", "john@example.com");
+ Assert.Throws(customerDataModel1.Validate);
+ Assert.Throws(customerDataModel2.Validate);
+ }
+
+ [Test]
+ public void Customer_ShouldThrowException_WhenFIO_IsEmpty()
+ {
+ var customerDataModel1 =
+ new CustomerDataModel(Guid.NewGuid().ToString(), "", "+79998887766", "john@example.com");
+ Assert.Throws(customerDataModel1.Validate);
+ }
+
+ [Test]
+ public void Customer_ShouldThrowException_WhenPhone_IsInvalid()
+ {
+ var customerDataModel1 =
+ new CustomerDataModel(Guid.NewGuid().ToString(), "John Doe", "123456", "john@example.com");
+ Assert.Throws(customerDataModel1.Validate);
+ }
+
+ [Test]
+ public void Customer_ShouldThrowException_WhenEmail_IsInvalid()
+ {
+ var customerDataModel1 =
+ new CustomerDataModel(Guid.NewGuid().ToString(), "John Doe", "+79998887766", "invalid-email");
+ Assert.Throws(customerDataModel1.Validate);
+ }
+
+ [Test]
+ public void Customer_ShouldCreateSuccessfully_WithValidData()
+ {
+ var customer = new CustomerDataModel(Guid.NewGuid().ToString(), "John Doe", "+79998887766",
+ "john@example.com");
+ Assert.That(customer.FIO, Is.EqualTo("John Doe"));
+ Assert.That(customer.Phone, Is.EqualTo("+79998887766"));
+ Assert.That(customer.Email, Is.EqualTo("john@example.com"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs b/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs
new file mode 100644
index 0000000..d9d36f0
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+using CandyHouseBase.DataModels;
+using CandyHouseBase.Exceptions;
+
+namespace CandyHouseTests.DataModelsTests
+{
+ [TestFixture]
+ public class OrderDataModelTests
+ {
+ [Test]
+ public void Order_ShouldThrowException_WhenIdIsInvalid()
+ {
+ var orderDataModel = new OrderDataModel("", Guid.NewGuid().ToString(), DateTime.UtcNow,
+ 100, 5, new List(), false);
+ Assert.Throws(orderDataModel.Validate);
+ }
+
+ [Test]
+ public void Order_ShouldThrowException_WhenNoItemsInOrder()
+ {
+ var orderDataModel = new OrderDataModel(Guid.NewGuid().ToString(),
+ Guid.NewGuid().ToString(), DateTime.UtcNow, 100, 5, new List(), false);
+ Assert.Throws(orderDataModel.Validate);
+ }
+
+ [Test]
+ public void Order_ShouldCreateSuccessfully_WithValidData()
+ {
+ var order = new OrderDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), DateTime.UtcNow, 200,
+ 10, new List
+ {
+ new OrderItemDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 2, 50)
+ }, false);
+
+ Assert.That(order.TotalAmount, Is.EqualTo(200));
+ Assert.That(order.DiscountAmount, Is.EqualTo(10));
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseTests/DataModelsTests/ProductStockDataModelTests.cs b/CandyHouseSolution/CandyHouseTests/DataModelsTests/ProductStockDataModelTests.cs
new file mode 100644
index 0000000..6de0581
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/DataModelsTests/ProductStockDataModelTests.cs
@@ -0,0 +1,40 @@
+using System;
+using NUnit.Framework;
+using CandyHouseBase.DataModels;
+using CandyHouseBase.Exceptions;
+
+namespace CandyHouseTests.DataModelsTests
+{
+ [TestFixture]
+ public class ProductStockDataModelTests
+ {
+ [Test]
+ public void ProductStock_ShouldThrowException_WhenIdIsInvalid()
+ {
+ var productStockDataModel = new ProductStockDataModel("", 10);
+ Assert.Throws(productStockDataModel.Validate);
+ }
+
+ [Test]
+ public void ProductStock_ShouldThrowException_WhenQuantityIsNegative()
+ {
+ var productStockDataModel = new ProductStockDataModel(Guid.NewGuid().ToString(), -5);
+ Assert.Throws(productStockDataModel.Validate);
+ }
+
+ [Test]
+ public void ProductStock_ShouldAddStockCorrectly()
+ {
+ var stock = new ProductStockDataModel(Guid.NewGuid().ToString(), 10);
+ stock.AddStock(5);
+ Assert.That(stock.Quantity, Is.EqualTo(15));
+ }
+
+ [Test]
+ public void ProductStock_ShouldThrowException_WhenRemovingTooMuchStock()
+ {
+ var stock = new ProductStockDataModel(Guid.NewGuid().ToString(), 10);
+ Assert.Throws(() => stock.RemoveStock(15));
+ }
+ }
+}
\ No newline at end of file
diff --git a/CandyHouseSolution/CandyHouseTests/packages.config b/CandyHouseSolution/CandyHouseTests/packages.config
new file mode 100644
index 0000000..f1136e5
--- /dev/null
+++ b/CandyHouseSolution/CandyHouseTests/packages.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file