чудесно))

This commit is contained in:
antoc0der 2024-04-06 18:45:56 +04:00
parent 8a64257355
commit 0870c015f5
38 changed files with 1121 additions and 18 deletions

View File

@ -0,0 +1,121 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.BusinessLogicsContracts;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.StoragesContracts;
using FlowerShopContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopBusinessLogic.BusinessLogic
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage componentStorage)
{
_logger = logger;
_clientStorage = componentStorage;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. ClientFIO:{ClientFIO}. Id:{ Id}", model?.ClientFIO, model?.Id);
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ClientFIO:{ClientFIO}.Id:{ Id}", model.ClientFIO, model.Id);
var element = _clientStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_clientStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel model, bool withParams =
true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет ФИО клиента",
nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет Email клиента",
nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля клиента",
nameof(model.ClientFIO));
}
_logger.LogInformation("Client. ClientFIO:{ClientFIO}." +
"Email:{ Email}. Password:{ Password}. Id: { Id} ", model.ClientFIO, model.Email, model.Password, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email,
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким лоигном уже есть");
}
}
}
}

View File

@ -0,0 +1,17 @@
using FlowerShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopContracts.BindingModels
{
public class ClientBindingModel : IClientModel
{
public int Id { get; set; }
public string ClientFIO { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

View File

@ -17,5 +17,7 @@ namespace FlowerShopContracts.BindingModels
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime? DateImplement { get; set; }
public int ClientId { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.ViewModels;
using FlowerShopContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopContracts.BusinessLogicsContracts
{
public interface IClientLogic
{
List<ClientViewModel>? ReadList(ClientSearchModel? model);
ClientViewModel? ReadElement(ClientSearchModel model);
bool Create(ClientBindingModel model);
bool Update(ClientBindingModel model);
bool Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopContracts.SearchModels
{
public class ClientSearchModel
{
public int? Id { get; set; }
public string? ClientFIO { get; set; }
public string? Email { get; set; }
}
}

View File

@ -11,5 +11,7 @@ namespace FlowerShopContracts.SearchModels
public int? Id { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public int? ClientId { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopContracts.StoragesContracts
{
public interface IClientStorage
{
List<ClientViewModel> GetFullList();
List<ClientViewModel> GetFilteredList(ClientSearchModel model);
ClientViewModel? GetElement(ClientSearchModel model);
ClientViewModel? Insert(ClientBindingModel model);
ClientViewModel? Update(ClientBindingModel model);
ClientViewModel? Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using FlowerShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
public int Id { get; set; }
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Логин (эл. почта)")]
public string Email { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
}
}

View File

@ -26,5 +26,8 @@ namespace FlowerShopContracts.ViewModels
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
public int ClientId { get; set; }
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopDataModels.Models
{
public interface IClientModel : IId
{
string ClientFIO { get; }
string Email { get; }
string Password { get; }
}
}

View File

@ -15,6 +15,8 @@ namespace FlowerShopDataModels
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
int ClientId { get; }
}
}

View File

@ -0,0 +1,69 @@
using FlowerShopDataModels.Models;
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace FlowerShopDatabaseImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
[Required]
public string ClientFIO { get; private set; } = string.Empty;
[Required]
public string Email { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public static Client Create(ClientViewModel model)
{
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
}
}

View File

@ -0,0 +1,86 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.StoragesContracts;
using FlowerShopContracts.ViewModels;
using FlowerShopDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopDatabaseImplement.Implements
{
public class ClientStorage : IClientStorage
{
public List<ClientViewModel> GetFullList()
{
using var context = new FlowerShopDataBase();
return context.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email))
{
return new();
}
using var context = new FlowerShopDataBase();
return context.Clients
.Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) &&
(string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email))))
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) &&
!model.Id.HasValue)
{
return null;
}
using var context = new FlowerShopDataBase();
return context.Clients
.FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO == model.ClientFIO) &&
(!model.Id.HasValue || x.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || x.Email == model.Email))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
using var context = new FlowerShopDataBase();
context.Clients.Add(newClient);
context.SaveChanges();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
using var context = new FlowerShopDataBase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return client.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
using var context = new FlowerShopDataBase();
var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Clients.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -22,5 +22,7 @@ namespace FlowerShopDatabaseImplement
public virtual DbSet<Flower> Flowers { set; get; }
public virtual DbSet<FlowerComponent> FlowerComponents { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
}
}

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace FlowerShopDatabaseImplement.Migrations
{
[DbContext(typeof(FlowerShopDataBase))]
[Migration("20240312171524_InitialCreate")]
[Migration("20240406141822_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -24,6 +24,31 @@ namespace FlowerShopDatabaseImplement.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
@ -90,7 +115,7 @@ namespace FlowerShopDatabaseImplement.Migrations
b.ToTable("FlowerComponents");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b =>
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@ -98,6 +123,9 @@ namespace FlowerShopDatabaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
@ -118,6 +146,8 @@ namespace FlowerShopDatabaseImplement.Migrations
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FlowerId");
b.ToTable("Orders");
@ -142,13 +172,28 @@ namespace FlowerShopDatabaseImplement.Migrations
b.Navigation("Flower");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b =>
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b =>
{
b.HasOne("FlowerShopDatabaseImplement.Models.Flower", null)
b.HasOne("FlowerShopDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower")
.WithMany("Orders")
.HasForeignKey("FlowerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Flower");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b =>

View File

@ -9,6 +9,21 @@ namespace FlowerShopDatabaseImplement.Migrations
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClientFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Components",
columns: table => new
@ -75,11 +90,18 @@ namespace FlowerShopDatabaseImplement.Migrations
Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true),
FlowerId = table.Column<int>(type: "int", nullable: false)
FlowerId = table.Column<int>(type: "int", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Orders_Flowers_FlowerId",
column: x => x.FlowerId,
@ -98,6 +120,11 @@ namespace FlowerShopDatabaseImplement.Migrations
table: "FlowerComponents",
column: "FlowerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_FlowerId",
table: "Orders",
@ -115,6 +142,9 @@ namespace FlowerShopDatabaseImplement.Migrations
migrationBuilder.DropTable(
name: "Components");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Flowers");
}

View File

@ -22,6 +22,31 @@ namespace FlowerShopDatabaseImplement.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
@ -88,7 +113,7 @@ namespace FlowerShopDatabaseImplement.Migrations
b.ToTable("FlowerComponents");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b =>
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@ -96,6 +121,9 @@ namespace FlowerShopDatabaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
@ -116,6 +144,8 @@ namespace FlowerShopDatabaseImplement.Migrations
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FlowerId");
b.ToTable("Orders");
@ -140,13 +170,28 @@ namespace FlowerShopDatabaseImplement.Migrations
b.Navigation("Flower");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Order", b =>
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Order", b =>
{
b.HasOne("FlowerShopDatabaseImplement.Models.Flower", null)
b.HasOne("FlowerShopDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower")
.WithMany("Orders")
.HasForeignKey("FlowerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Flower");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b =>

View File

@ -27,6 +27,9 @@ namespace FlowerShopDatabaseImplement.Models
public DateTime? DateImplement { get; private set; }
[Required]
public int FlowerId { get; private set; }
[Required]
public int ClientId { get; private set; }
public virtual Client? Client { get; private set; }
public virtual Flower? Flower { get; set; }
public static Order? Create(OrderBindingModel model)
{
@ -43,6 +46,7 @@ namespace FlowerShopDatabaseImplement.Models
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
FlowerId = model.FlowerId,
ClientId = model.ClientId,
};
}
@ -62,10 +66,12 @@ namespace FlowerShopDatabaseImplement.Models
Count = Count,
Sum = Sum,
Status = Status,
ClientId = ClientId,
DateCreate = DateCreate,
DateImplement = DateImplement,
FlowerName = Flower?.FlowerName ?? String.Empty,
Id = Id,
ClientFIO = Client.ClientFIO
};
}

View File

@ -41,7 +41,7 @@ namespace FlowerShopDatabaseImplement.Implements
return null;
}
using var context = new FlowerShopDataBase();
return context.Orders.Include(x => x.Flower).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
return context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
@ -58,7 +58,7 @@ namespace FlowerShopDatabaseImplement.Implements
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new FlowerShopDataBase();
var order = context.Orders.Include(x => x.Flower).FirstOrDefault(x => x.Id ==
var order = context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(x => x.Id ==
model.Id);
if (order == null)
{
@ -71,8 +71,7 @@ namespace FlowerShopDatabaseImplement.Implements
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new FlowerShopDataBase();
var element = context.Orders.Include(x => x.Flower).FirstOrDefault(rec => rec.Id ==
model.Id);
var element = context.Orders.Include(x => x.Flower).Include(x => x.Client).FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Orders.Remove(element);

View File

@ -0,0 +1,73 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.ViewModels;
using FlowerShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FlowerShopFileImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public static Client? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Client()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ClientFIO = element.Element("ClientFIO")!.Value,
Email = element.Element("Email")!.Value,
Password = element.Element("Password")!.Value
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
public XElement GetXElement => new("Client",
new XAttribute("Id", Id),
new XElement("ClientFIO", ClientFIO),
new XElement("Email", Email.ToString()),
new XElement("Password", Password.ToString())
);
}
}

View File

@ -0,0 +1,85 @@
using FlowerShopContracts.StoragesContracts;
using FlowerShopContracts.ViewModels;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.BindingModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FlowerShopFileImplement.Models;
namespace FlowerShopFileImplement.Implements
{
public class ClientStorage : IClientStorage
{
private readonly DataFileSingleton source;
public ClientStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ClientViewModel> GetFullList()
{
return source.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel
model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email))
{
return new();
}
return source.Clients
.Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) &&
(string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email))))
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
return source.Clients
.FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO == model.ClientFIO) &&
(!model.Id.HasValue || x.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || x.Email == model.Email))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
model.Id = source.Clients.Count > 0 ? source.Clients.Max(x =>
x.Id) + 1 : 1;
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
source.Clients.Add(newClient);
source.SaveClients();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
var client = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
source.SaveClients();
return client.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
var element = source.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
source.Clients.Remove(element);
source.SaveClients();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -9,9 +9,13 @@ internal class DataFileSingleton
private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string FlowerFileName = "Product.xml";
private readonly string ClientFileName = "Client.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Flower> Flowers { get; private set; }
public List<Client> Clients { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
@ -26,11 +30,14 @@ internal class DataFileSingleton
"Flowers", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName,
"Orders", x => x.GetXElement);
private DataFileSingleton()
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Flowers = LoadData(FlowerFileName, "Flower", x => Flower.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{
@ -41,8 +48,7 @@ private DataFileSingleton()
}
return new List<T>();
}
private static void SaveData<T>(List<T> data, string filename, string
xmlNodeName, Func<T, XElement> selectFunction)
private static void SaveData<T>(List<T> data, string filename, string xmlNodeName, Func<T, XElement> selectFunction)
{
if (data != null)
{

View File

@ -15,6 +15,8 @@ namespace FlowerShopFileImplement.Models
public OrderStatus Status { get; private set; }
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; }
public int ClientId { get; private set; }
public static Order? Create(OrderBindingModel model)
{
@ -31,6 +33,8 @@ namespace FlowerShopFileImplement.Models
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
ClientId = model.ClientId,
};
}
public static Order? Create(XElement element)
@ -47,6 +51,7 @@ namespace FlowerShopFileImplement.Models
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value.ToString()),
DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value),
ClientId = Convert.ToInt32(element.Element("ClientId")!.Value),
DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : Convert.ToDateTime(element.Element("DateImplement")!.Value)
};
}
@ -65,6 +70,7 @@ namespace FlowerShopFileImplement.Models
FlowerId = FlowerId,
Count = Count,
Sum = Sum,
ClientId = ClientId,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
@ -76,6 +82,7 @@ namespace FlowerShopFileImplement.Models
new XElement("Count", Count),
new XElement("Status", Status.ToString()),
new XElement("DateCreate", DateCreate.ToString()),
new XElement("ClientId", ClientId),
new XElement("DateImplement", DateImplement.ToString())
);

View File

@ -36,7 +36,8 @@ namespace FlowerShopFileImplement.Implements
return source.Orders
.Where(x => ((!model.Id.HasValue || x.Id == model.Id) &&
(!model.DateFrom.HasValue || x.DateCreate >= model.DateFrom) &&
(!model.DateTo.HasValue || x.DateCreate <= model.DateTo)))
(!model.DateTo.HasValue || x.DateCreate <= model.DateTo) &&
(!model.ClientId.HasValue || x.ClientId == model.ClientId)))
.Select(x => AccessFlowerStorage(x.GetViewModel))
.ToList();
}
@ -102,5 +103,15 @@ namespace FlowerShopFileImplement.Implements
return model;
}
public OrderViewModel AccessClientStorage(OrderViewModel model)
{
if (model == null)
return null;
var client = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client != null)
model.ClientFIO = client.ClientFIO;
return model;
}
}
}

View File

@ -0,0 +1,50 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.ViewModels;
using FlowerShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlowerShopListImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
}
}

View File

@ -0,0 +1,104 @@
using FlowerShopContracts.StoragesContracts;
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FlowerShopListImplement.Models;
namespace FlowerShopListImplement.Implements
{
public class ClientStorage : IClientStorage
{
private readonly DataListSingleton _source;
public ClientStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ClientViewModel> GetFullList()
{
var result = new List<ClientViewModel>();
foreach (var client in _source.Clients)
{
result.Add(client.GetViewModel);
}
return result;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel
model)
{
var result = new List<ClientViewModel>();
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email))
{
return result;
}
foreach (var client in _source.Clients)
{
if (client.ClientFIO.Contains(model.ClientFIO))
{
result.Add(client.GetViewModel);
}
}
return result;
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
foreach (var client in _source.Clients)
{
if ((string.IsNullOrEmpty(model.ClientFIO) || client.ClientFIO == model.ClientFIO) &&
(!model.Id.HasValue || client.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || client.Email == model.Email))
{
return client.GetViewModel;
}
}
return null;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
model.Id = 1;
foreach (var client in _source.Clients)
{
if (model.Id <= client.Id)
{
model.Id = client.Id + 1;
}
}
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
_source.Clients.Add(newClient);
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
foreach (var client in _source.Clients)
{
if (client.Id == model.Id)
{
client.Update(model);
return client.GetViewModel;
}
}
return null;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
for (int i = 0; i < _source.Clients.Count; ++i)
{
if (_source.Clients[i].Id == model.Id)
{
var element = _source.Clients[i];
_source.Clients.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -13,11 +13,14 @@ namespace FlowerShopListImplement
public List<Component> Components { get; set; }
public List<Order> Orders { get; set; }
public List<Flower> Flowers { get; set; }
public List<Client> Clients { get; set; }
private DataListSingleton()
{
Components = new List<Component>();
Orders = new List<Order>();
Flowers = new List<Flower>();
Clients = new List<Client>();
}
public static DataListSingleton GetInstance()
{
@ -27,5 +30,6 @@ namespace FlowerShopListImplement
}
return _instance;
}
}
}

View File

@ -16,6 +16,8 @@ namespace FlowerShopListImplement.Models
public int FlowerId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public int ClientId { get; private set; }
public OrderStatus Status { get; private set; }
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; }
@ -35,6 +37,8 @@ namespace FlowerShopListImplement.Models
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
ClientId = model.ClientId,
};
}
public void Update(OrderBindingModel? model)
@ -46,6 +50,7 @@ namespace FlowerShopListImplement.Models
Id = model.Id;
FlowerId = model.FlowerId;
Count = model.Count;
ClientId = model.ClientId;
Sum = model.Sum;
Status = model.Status;
DateCreate = model.DateCreate;
@ -55,6 +60,7 @@ namespace FlowerShopListImplement.Models
{
Id = Id,
FlowerId = FlowerId,
ClientId = ClientId,
Count = Count,
Sum = Sum,
Status = Status,

View File

@ -37,7 +37,10 @@ namespace FlowerShopListImplement.Implements
}
foreach (var order in _source.Orders)
{
if (order.Id == model.Id && model.DateFrom <= order.DateCreate && model.DateTo >= order.DateCreate)
if ((!model.Id.HasValue || order.Id == model.Id) &&
(!model.DateFrom.HasValue || order.DateCreate >= model.DateFrom) &&
(!model.DateTo.HasValue || order.DateCreate <= model.DateTo) &&
(!model.ClientId.HasValue || order.ClientId == model.ClientId))
{
result.Add(AccessFlowerStorage(order.GetViewModel));
}
@ -115,5 +118,12 @@ namespace FlowerShopListImplement.Implements
}
return model;
}
public OrderViewModel AccessClientStorage(OrderViewModel model)
{
var client = _source.Clients.FirstOrDefault(x => x.Id == model.ClientId);
if (client != null)
model.ClientFIO = client.ClientFIO;
return model;
}
}
}

View File

@ -0,0 +1,65 @@
using FlowerShopContracts.BindingModels;
using FlowerShopContracts.BusinessLogicsContracts;
using FlowerShopContracts.SearchModels;
using FlowerShopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace FlowerShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ClientController : Controller
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController>
logger)
{
_logger = logger;
_logic = logic;
}
[HttpGet]
public ClientViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ClientSearchModel
{
Email = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpPost]
public void Register(ClientBindingModel model)
{
try
{
_logic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
throw;
}
}
[HttpPost]
public void UpdateData(ClientBindingModel model)
{
try
{
_logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
}
}

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace FlowerShopRestApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FlowerShopBusinessLogic\FlowerShopBusinessLogic.csproj" />
<ProjectReference Include="..\FlowerShopContracts\FlowerShopContracts.csproj" />
<ProjectReference Include="..\FlowerShopDatabaseImplement\FlowerShopDatabaseImplement.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,41 @@
using FlowerShopBusinessLogic.BusinessLogic;
using FlowerShopContracts.BusinessLogicsContracts;
using FlowerShopContracts.StoragesContracts;
using FlowerShopDatabaseImplement.Implements;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config");
// Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IFlowerStorage, FlowerStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IFlowerLogic, FlowerLogic>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at
https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "FlowerShopRestApi",
Version
= "v1"
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
"FlowerShopRestApi v1"));
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:48724",
"sslPort": 44351
}
},
"profiles": {
"FlowerShopRestApi": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7213;http://localhost:5162",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,13 @@
namespace FlowerShopRestApi
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopListImplement", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopFileImplement", "FlowerShopFileImplement\FlowerShopFileImplement.csproj", "{0CFC7A18-2E56-4D0B-80AD-F52893222027}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlowerShopDatabaseImplement", "FlowerShopDatabaseImplement\FlowerShopDatabaseImplement.csproj", "{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlowerShopDatabaseImplement", "FlowerShopDatabaseImplement\FlowerShopDatabaseImplement.csproj", "{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlowerShopRestApi", "FlowerShopRestApi\FlowerShopRestApi.csproj", "{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -51,6 +53,10 @@ Global
{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD9FDCBB-1EE0-4726-85B7-4B9C6D40F761}.Release|Any CPU.Build.0 = Release|Any CPU
{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{729A747E-7DDA-4D6A-87C3-F83DCC6393F4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE