This commit is contained in:
2025-04-14 22:07:51 +04:00
parent 6449c0df73
commit d84b3850d6
259 changed files with 11655 additions and 10019 deletions

2
.gitignore vendored
View File

@@ -10,7 +10,7 @@
*.user
*.userosscache
*.sln.docstates
*.idea
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

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,9 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class IngredientBindingModel
{
public string? Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Unit { get; set; } = string.Empty;
public decimal Cost { get; set; }
}

View File

@@ -1,15 +0,0 @@
using CandyHouseBase.Enums;
namespace CandyHouseBase.Contracts.BindingModels;
public class OrderBindingModel
{
public string? Id { get; set; }
public string? CustomerName { get; set; }
public DateTime OrderDate { get; set; } = DateTime.UtcNow;
public decimal TotalAmount { get; set; }
public decimal DiscountAmount { get; set; }
public string ProductId { get; set; } = string.Empty;
public string PekarId { get; set; } = string.Empty;
public StatusType Status { get; set; }
}

View File

@@ -1,10 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class PekarBindingModel
{
public string? Id { get; set; }
public string FIO { get; set; } = string.Empty;
public string PositionId { get; set; } = string.Empty;
public decimal BonusCoefficient { get; set; }
public bool IsDeleted { get; set; } = false;
}

View File

@@ -1,11 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class PekarHistoryBindingModel
{
public string? Id { get; set; }
public string PekarId { get; set; } = string.Empty;
public string FIO { get; set; } = string.Empty;
public string PositionId { get; set; } = string.Empty;
public DateTime Date { get; set; }
public decimal BonusCoefficient { get; set; }
}

View File

@@ -1,13 +0,0 @@
using CandyHouseBase.Enums;
namespace CandyHouseBase.Contracts.BindingModels;
public class PositionBindingModel
{
public string? Id { get; set; }
public string? PositionId { get; set; }
public string Title { get; set; } = string.Empty;
public PositionType Type { get; set; }
public bool IsActual { get; set; } = true;
public DateTime ChangeDate { get; set; } = DateTime.UtcNow;
}

View File

@@ -1,11 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class ProductBindingModel
{
public string? Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string? OldName { get; set; }
public string? OldDescription { get; set; }
public bool IsDeleted { get; set; } = false;
}

View File

@@ -1,8 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class RecipeBindingModel
{
public string ProductId { get; set; } = string.Empty;
public string IngredientId { get; set; } = string.Empty;
public int Quantity { get; set; }
}

View File

@@ -1,11 +0,0 @@
namespace CandyHouseBase.Contracts.BindingModels;
public class SalaryBindingModel
{
public string? Id { get; set; }
public string PekarId { get; set; } = string.Empty;
public DateTime Period { get; set; }
public decimal BaseRate { get; set; }
public decimal BonusRate { get; set; }
public decimal TotalSalary { get; set; }
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class IngredientOperationResponse : OperationResponse
{
public static IngredientOperationResponse OK(List<IngredientViewModel> data) =>
OK<IngredientOperationResponse, List<IngredientViewModel>>(data);
public static IngredientOperationResponse OK(IngredientViewModel data) =>
OK<IngredientOperationResponse, IngredientViewModel>(data);
public static IngredientOperationResponse NoContent() =>
NoContent<IngredientOperationResponse>();
public static IngredientOperationResponse NotFound(string message) =>
NotFound<IngredientOperationResponse>(message);
public static IngredientOperationResponse BadRequest(string message) =>
BadRequest<IngredientOperationResponse>(message);
public static IngredientOperationResponse InternalServerError(string message) =>
InternalServerError<IngredientOperationResponse>(message);
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class OrderOperationResponse : OperationResponse
{
public static OrderOperationResponse OK(List<OrderViewModel> data) =>
OK<OrderOperationResponse, List<OrderViewModel>>(data);
public static OrderOperationResponse OK(OrderViewModel data) =>
OK<OrderOperationResponse, OrderViewModel>(data);
public static OrderOperationResponse NoContent() =>
NoContent<OrderOperationResponse>();
public static OrderOperationResponse NotFound(string message) =>
NotFound<OrderOperationResponse>(message);
public static OrderOperationResponse BadRequest(string message) =>
BadRequest<OrderOperationResponse>(message);
public static OrderOperationResponse InternalServerError(string message) =>
InternalServerError<OrderOperationResponse>(message);
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class PekarHistoryOperationResponse : OperationResponse
{
public static PekarHistoryOperationResponse OK(List<PekarHistoryViewModel> data) =>
OK<PekarHistoryOperationResponse, List<PekarHistoryViewModel>>(data);
public static PekarHistoryOperationResponse OK(PekarHistoryViewModel data) =>
OK<PekarHistoryOperationResponse, PekarHistoryViewModel>(data);
public static PekarHistoryOperationResponse NoContent() =>
NoContent<PekarHistoryOperationResponse>();
public static PekarHistoryOperationResponse NotFound(string message) =>
NotFound<PekarHistoryOperationResponse>(message);
public static PekarHistoryOperationResponse BadRequest(string message) =>
BadRequest<PekarHistoryOperationResponse>(message);
public static PekarHistoryOperationResponse InternalServerError(string message) =>
InternalServerError<PekarHistoryOperationResponse>(message);
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class PekarOperationResponse : OperationResponse
{
public static PekarOperationResponse OK(List<PekarViewModel> data) =>
OK<PekarOperationResponse, List<PekarViewModel>>(data);
public static PekarOperationResponse OK(PekarViewModel data) =>
OK<PekarOperationResponse, PekarViewModel>(data);
public static PekarOperationResponse NoContent() =>
NoContent<PekarOperationResponse>();
public static PekarOperationResponse NotFound(string message) =>
NotFound<PekarOperationResponse>(message);
public static PekarOperationResponse BadRequest(string message) =>
BadRequest<PekarOperationResponse>(message);
public static PekarOperationResponse InternalServerError(string message) =>
InternalServerError<PekarOperationResponse>(message);
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class PositionOperationResponse : OperationResponse
{
public static PositionOperationResponse OK(List<PositionViewModel> data) =>
OK<PositionOperationResponse, List<PositionViewModel>>(data);
public static PositionOperationResponse OK(PositionViewModel data) =>
OK<PositionOperationResponse, PositionViewModel>(data);
public static PositionOperationResponse NoContent() =>
NoContent<PositionOperationResponse>();
public static PositionOperationResponse NotFound(string message) =>
NotFound<PositionOperationResponse>(message);
public static PositionOperationResponse BadRequest(string message) =>
BadRequest<PositionOperationResponse>(message);
public static PositionOperationResponse InternalServerError(string message) =>
InternalServerError<PositionOperationResponse>(message);
}

View File

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class ProductOperationResponse : OperationResponse
{
public static ProductOperationResponse OK(List<ProductViewModel> data) =>
OK<ProductOperationResponse, List<ProductViewModel>>(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

@@ -1,25 +0,0 @@
using CandyHouseBase.Contracts.ViewModels;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.Contracts.OperationResponses;
public class SalaryOperationResponse : OperationResponse
{
public static SalaryOperationResponse OK(List<SalaryViewModel> data) =>
OK<SalaryOperationResponse, List<SalaryViewModel>>(data);
public static SalaryOperationResponse OK(SalaryViewModel data) =>
OK<SalaryOperationResponse, 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

@@ -1,9 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class IngredientViewModel
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Unit { get; set; }
public decimal Cost { get; set; }
}

View File

@@ -1,17 +0,0 @@
using CandyHouseBase.Enums;
namespace CandyHouseBase.Contracts.ViewModels;
public class OrderViewModel
{
public required string Id { get; set; }
public string? CustomerName { get; set; }
public DateTime OrderDate { get; set; }
public decimal TotalAmount { get; set; }
public decimal DiscountAmount { get; set; }
public required string ProductId { get; set; }
public string? ProductName { get; set; }
public required string PekarId { get; set; }
public string? PekarFIO { get; set; }
public StatusType Status { get; set; }
}

View File

@@ -1,12 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class PekarHistoryViewModel
{
public required string Id { get; set; }
public required string PekarId { get; set; }
public string FIO { get; set; } = string.Empty;
public required string PositionId { get; set; }
public string? PositionTitle { get; set; }
public DateTime Date { get; set; }
public decimal BonusCoefficient { get; set; }
}

View File

@@ -1,11 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class PekarViewModel
{
public required string Id { get; set; }
public string FIO { get; set; } = string.Empty;
public required string PositionId { get; set; }
public string? PositionTitle { get; set; }
public decimal BonusCoefficient { get; set; }
public bool IsDeleted { get; set; }
}

View File

@@ -1,13 +0,0 @@
using CandyHouseBase.Enums;
namespace CandyHouseBase.Contracts.ViewModels;
public class PositionViewModel
{
public required string Id { get; set; }
public string? PositionId { get; set; }
public string Title { get; set; } = string.Empty;
public PositionType Type { get; set; }
public bool IsActual { get; set; }
public DateTime ChangeDate { get; set; }
}

View File

@@ -1,12 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class ProductViewModel
{
public required string Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string? OldName { get; set; }
public string? OldDescription { get; set; }
public bool IsDeleted { get; set; }
public decimal? TotalCost { get; set; } // Calculated field for UI display
}

View File

@@ -1,13 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class RecipeViewModel
{
public string ProductId { get; set; } = string.Empty;
public string? ProductName { get; set; }
public string IngredientId { get; set; } = string.Empty;
public string? IngredientName { get; set; }
public string? Unit { get; set; }
public int Quantity { get; set; }
public decimal Cost { get; set; }
public decimal TotalCost { get; set; }
}

View File

@@ -1,13 +0,0 @@
namespace CandyHouseBase.Contracts.ViewModels;
public class SalaryViewModel
{
public required string Id { get; set; }
public required string PekarId { get; set; }
public string? PekarFIO { get; set; }
public string? PositionTitle { get; set; }
public DateTime Period { get; set; }
public decimal BaseRate { get; set; }
public decimal BonusRate { get; set; }
public decimal TotalSalary { get; set; }
}

View File

@@ -1,23 +0,0 @@
using CandyHouseBase.Exceptions;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.DataModels
{
public class IngredientDataModel(string id, string name, string unit, decimal cost)
: IValidation
{
public string Id { get; private set; } = id;
public string Name { get; private set; } = name;
public string Unit { get; private set; } = unit;
public decimal Cost { get; private set; } = 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,44 +0,0 @@
using System;
using CandyHouseBase.Enums;
using CandyHouseBase.Exceptions;
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,45 +0,0 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.DataModels
{
public class PekarDataModel : IValidation
{
public string Id { get; private set; }
public string FIO { get; private set; }
public string Position { get; private set; }
public decimal BonusCoefficient { get; private set; }
public bool IsDeleted { get; private set; }
public List<ProductDataModel> ProductsItems { get; private set; }
public PekarDataModel()
{
ProductsItems = new List<ProductDataModel>();
}
public PekarDataModel(string id, string fio, string position, decimal bonusCoefficient,
List<ProductDataModel> productsItems)
{
Id = id;
FIO = fio;
Position = position;
BonusCoefficient = bonusCoefficient;
ProductsItems = productsItems;
}
public void Validate()
{
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
if (FIO.IsEmpty()) throw new ValidationException("Field FIO is empty");
var fioPattern = @"^[A-Za-zА-Яа-яЁё\s\-]+$";
if (!Regex.IsMatch(FIO, fioPattern))
throw new ValidationException("FIO contains invalid characters");
if (Position.IsEmpty()) throw new ValidationException("Field Position is empty");
if (!Position.IsGuid()) throw new ValidationException("Field must be a GUID");
if (BonusCoefficient <= 0) throw new ValidationException("BonusCoefficient must be positive");
}
}
}

View File

@@ -1,34 +0,0 @@
using System;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Infrastructure;
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,36 +0,0 @@
using System;
using System.Text.RegularExpressions;
using CandyHouseBase.Enums;
using CandyHouseBase.Exceptions;
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 decimal Salary { get; set; }
public PositionDataModel(string id, PositionType type, string title, decimal salary)
{
Id = id;
Type = type;
Title = title;
Salary = salary;
}
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,73 +0,0 @@
using System.Collections.Generic;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.DataModels
{
public class ProductDataModel : IValidation
{
public string Id { get; private set; }
public string Name
{
get => name;
set
{
if (!name.IsEmpty()) OldName = name;
name = value.Trim();
}
}
public string Description
{
get => description;
set
{
if (!description.IsEmpty()) OldDescription = description;
description = value.Trim();
}
}
public string? OldName { get; private set; }
public string? OldDescription { get; private set; }
private string name;
private string description;
public List<IngredientDataModel> IngredientsItems { get; private set; }
public ProductDataModel()
{
IngredientsItems = new List<IngredientDataModel>();
}
public ProductDataModel(string id, string name, string description, List<IngredientDataModel> ingredients)
{
Id = id;
Name = name;
Description = description;
IngredientsItems = ingredients;
}
public ProductDataModel(string id, string name, string description, string oldName, string oldDescription,
List<IngredientDataModel> ingredients)
{
Id = id;
Name = name;
Description = description;
IngredientsItems = ingredients;
OldName = oldName;
OldDescription = oldDescription;
}
public void Validate()
{
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
if (Name.IsEmpty()) throw new ValidationException("Field Name is empty");
if (Description.IsEmpty()) throw new ValidationException("Field Description is empty");
if (IngredientsItems.Count == 0) throw new ValidationException("Field IngredientsItems is empty");
}
}
}

View File

@@ -1,26 +0,0 @@
using CandyHouseBase.Exceptions;
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,33 +0,0 @@
using System;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Infrastructure;
namespace CandyHouseBase.DataModels
{
public class SalaryDataModel : IValidation
{
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()
{
}
public SalaryDataModel(string pekarId, DateTime period, decimal salary)
{
PekarId = pekarId;
Period = period;
TotalSalary = salary;
}
public void Validate()
{
if (PekarId.IsEmpty()) throw new ValidationException("Field PekarId is empty");
if (!PekarId.IsGuid()) throw new ValidationException("PekarId must be a GUID");
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,3 +0,0 @@
namespace CandyHouseBase.Exceptions;
public class ElementDeletedException(string id) : Exception($"Cannot modify a deleted item (id: {id})");

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,5 +0,0 @@
using System;
namespace CandyHouseBase.Exceptions;
public class StorageException(Exception ex) : Exception($"Error while working in storage: {ex.Message}", ex);

View File

@@ -1,8 +0,0 @@
namespace CandyHouseBase.Exceptions
{
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,9 +0,0 @@
using System;
namespace CandyHouseBase.Exceptions
{
public class ValidationException : Exception
{
public ValidationException(string message) : base(message) { }
}
}

View File

@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using CandyHouseBase.DataModels;
using CandyHouseBase.Exceptions;
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,125 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using CandyHouseBase.DataModels;
using CandyHouseBase.Enums;
using CandyHouseBase.Exceptions;
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,173 +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.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,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using CandyHouseBase.DataModels;
using CandyHouseBase.Enums;
using CandyHouseBase.Exceptions;
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,113 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using CandyHouseBase.DataModels;
using CandyHouseBase.Exceptions;
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,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using CandyHouseBase.DataModels;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
using CandyHouseBase.Interfaces.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace CandyHouseBase.Implementations
{
internal class SalaryBusinessLogicContract(
ISalaryStorageContact salaryStorageContact,
IPekarStorageContact pekarStorageContact,
IPositionStorageContact positionStorageContact,
ILogger logger)
: ISalaryBusinessLogicContact
{
private readonly ISalaryStorageContact _salaryStorageContact = salaryStorageContact;
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
private readonly IPositionStorageContact _positionStorageContact = positionStorageContact;
private readonly ILogger _logger = logger;
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 _salaryStorageContact.GetList(fromDate, toDate) ?? throw new NullListException();
}
public List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime fromDate, DateTime toDate, string workerId)
{
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (workerId.IsEmpty())
{
throw new ArgumentNullException(nameof(workerId));
}
if (!workerId.IsGuid())
{
throw new ValidationException("The value in the field workerId is not a unique identifier.");
}
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}, {workerId}", fromDate, toDate, workerId);
return _salaryStorageContact.GetList(fromDate, toDate, workerId) ?? throw new NullListException();
}
public void CalculateSalaryByMonth(DateTime date)
{
_logger.LogInformation("CalculateSalaryByMouth: {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 workers = _pekarStorageContact.GetList() ?? throw new NullListException();
foreach (var worker in workers)
{
var post = _positionStorageContact.GetElementById(worker.Id) ??
throw new NullListException();
var salary = post.Salary;
_logger.LogDebug("The employee {workerId} was paid a salary of {salary}", worker.Id, salary);
_salaryStorageContact.AddElement(new SalaryDataModel(worker.Id, finishDate, salary));
}
}
}
}

View File

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

View File

@@ -1,7 +0,0 @@
namespace CandyHouseBase.Infrastructure;
public interface IConfigurationDatabase
{
public string ConnectionString =>
"Host=127.0.0.1;Port=5432;Database=CandyHouseTest;Username=postgres;Password=postgres;";
}

View File

@@ -1,37 +0,0 @@
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace CandyHouseBase.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

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IIngredientAdapter
{
IngredientOperationResponse GetList();
IngredientOperationResponse GetElement(string data);
IngredientOperationResponse Register(IngredientBindingModel model);
IngredientOperationResponse Update(IngredientBindingModel model);
IngredientOperationResponse Delete(string id);
}

View File

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IOrderAdapter
{
OrderOperationResponse GetList();
OrderOperationResponse GetElement(string data);
OrderOperationResponse Register(OrderBindingModel model);
OrderOperationResponse Update(OrderBindingModel model);
OrderOperationResponse Delete(string id);
}

View File

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IPekarAdapter
{
PekarOperationResponse GetList();
PekarOperationResponse GetElement(string data);
PekarOperationResponse Register(PekarBindingModel model);
PekarOperationResponse Update(PekarBindingModel model);
PekarOperationResponse Delete(string id);
}

View File

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IPekarHistoryAdapter
{
PekarHistoryOperationResponse GetList();
PekarHistoryOperationResponse GetElement(string data);
PekarHistoryOperationResponse Register(PekarHistoryBindingModel model);
PekarHistoryOperationResponse Update(PekarHistoryBindingModel model);
PekarHistoryOperationResponse Delete(string id);
}

View File

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IPositionAdapter
{
PositionOperationResponse GetList();
PositionOperationResponse GetElement(string data);
PositionOperationResponse Register(PositionBindingModel model);
PositionOperationResponse Update(PositionBindingModel model);
PositionOperationResponse Delete(string id);
}

View File

@@ -1,14 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface IProductAdapter
{
ProductOperationResponse GetList();
ProductOperationResponse GetElement(string data);
ProductOperationResponse Register(ProductBindingModel model);
ProductOperationResponse Update(ProductBindingModel model);
ProductOperationResponse Delete(string id);
}

View File

@@ -1,17 +0,0 @@
using CandyHouseBase.Contracts;
using CandyHouseBase.Contracts.BindingModels;
using CandyHouseBase.Contracts.OperationResponses;
namespace CandyHouseBase.Interfaces.Adapters;
public interface ISalaryAdapter
{
SalaryOperationResponse GetList(DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetPekarList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetManagerList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetSupervisorList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse CalculateSalary(SalaryBindingModel salaryModel);
}

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,13 +0,0 @@
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> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate);
List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime fromDate, DateTime toDate, string workerId);
void CalculateSalaryByMonth(DateTime date);
}
}

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,12 +0,0 @@
using System.Collections.Generic;
using CandyHouseBase.DataModels;
namespace CandyHouseBase.Interfaces.StoragesContracts
{
public interface ISalaryStorageContact
{
List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null);
void AddElement(SalaryDataModel salaryDataModel);
}
}

View File

@@ -5,16 +5,17 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="CandyHouseTests" />
<InternalsVisibleTo Include="CandyHouseWebApi" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" />
</ItemGroup>
</Project>
<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? ProductCountry { 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);
}

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