diff --git a/OrdersManagement/Components/Pages/Admin/Users.razor b/OrdersManagement/Components/Pages/Admin/Users.razor
new file mode 100644
index 0000000..f21f982
--- /dev/null
+++ b/OrdersManagement/Components/Pages/Admin/Users.razor
@@ -0,0 +1,151 @@
+@page "/admin/UsersManager"
+@using OrdersManagementDataModel.Dtos
+@using Syncfusion.Blazor.Grids
+@using Action = Syncfusion.Blazor.Grids.Action
+@* @inject UserService UserService *@
+@* @inject RoleService RoleService *@
+@* @inject FunctionService FunctionService *@
+
+
Zarządzanie Użytkownikami i Rolami
+
+
+
+Użytkownicy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Role
+
+
+
+
+
+
+
+
+
+
+
+Funkcje
+
+
+
+
+
+
+
+
+
+
+@code {
+ private List UserList { get; set; } = new();
+ private List Roles { get; set; } = new();
+ private List Functions { get; set; } = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ await LoadUsers();
+ await LoadRoles();
+ await LoadFunctions();
+ }
+
+ // Użytkownicy
+ private async Task UserActionBegin(ActionEventArgs args)
+ {
+ // if (args.RequestType.Equals(Action.Delete))
+ // {
+ // await UserService.DeleteUserAsync(args.Data.Id);
+ // }
+ // else if (args.RequestType.Equals(Action.Add))
+ // {
+ // args.Data.RowPointer = Guid.NewGuid();
+ // }
+ }
+
+ private async Task UserActionComplete(ActionEventArgs args)
+ {
+ switch (args.RequestType)
+ {
+ case Action.Delete:
+ case Action.Save:
+ await LoadUsers();
+ break;
+ }
+ }
+
+ private async Task LoadUsers()
+ {
+ //Users = (await UserService.GetUsersAsync() ?? Array.Empty()).ToList();
+ }
+
+ // Role
+ private async Task RoleActionBegin(ActionEventArgs args)
+ {
+ // if (args.RequestType.Equals(Action.Delete))
+ // {
+ // await RoleService.DeleteRoleAsync(args.Data.Id);
+ // }
+ // else if (args.RequestType.Equals(Action.Add))
+ // {
+ // args.Data.RowPointer = Guid.NewGuid();
+ // }
+ }
+
+ private async Task RoleActionComplete(ActionEventArgs args)
+ {
+ switch (args.RequestType)
+ {
+ case Action.Delete:
+ case Action.Save:
+ await LoadRoles();
+ break;
+ }
+ }
+
+ private async Task LoadRoles()
+ {
+ //Roles = (await RoleService.GetRolesAsync() ?? Array.Empty()).ToList();
+ }
+
+ // Funkcje
+ private async Task FunctionActionBegin(ActionEventArgs args)
+ {
+ if (args.RequestType.Equals(Action.Delete))
+ {
+ //await FunctionService.DeleteFunctionAsync(args.Data.Id);
+ }
+ else if (args.RequestType.Equals(Action.Add))
+ {
+ args.Data.RowPointer = Guid.NewGuid();
+ }
+ }
+
+ private async Task FunctionActionComplete(ActionEventArgs args)
+ {
+ switch (args.RequestType)
+ {
+ case Action.Delete:
+ case Action.Save:
+ await LoadFunctions();
+ break;
+ }
+ }
+
+ private async Task LoadFunctions()
+ {
+ //Functions = (await FunctionService.GetFunctionsAsync() ?? Array.Empty()).ToList();
+ }
+}
diff --git a/OrdersManagement/Components/Pages/ScheduleOrder.razor b/OrdersManagement/Components/Pages/ScheduleOrder.razor
index d797648..0eda881 100644
--- a/OrdersManagement/Components/Pages/ScheduleOrder.razor
+++ b/OrdersManagement/Components/Pages/ScheduleOrder.razor
@@ -57,7 +57,9 @@
AllowSelection="true"
TValue="ScheduleOrderDetailDetailDto"
DataSource="@_scheduleOrderDetailsDetails"
- EnableAdaptiveUI="true">
+ EnableAdaptiveUI="true"
+ AdaptiveUIMode="AdaptiveMode.Both">
+
@{
@@ -136,4 +138,11 @@
SelectOrderDetail(scheduleOrderDetail);
}
+ private void OnRowDataBound(RowDataBoundEventArgs args)
+ {
+ if (args.Data.QtyType == "83" || args.Data.QtyType == "84")
+ {
+ args.Row.AddClass(["highlight-red"]);
+ }
+ }
}
diff --git a/OrdersManagement/wwwroot/material.css b/OrdersManagement/wwwroot/material.css
index 22a7b77..de11d21 100644
--- a/OrdersManagement/wwwroot/material.css
+++ b/OrdersManagement/wwwroot/material.css
@@ -63420,3 +63420,12 @@ html, body {
height: calc(100vh - 150px) !important;
}
}
+.e-grid .e-row.highlight-red {
+ background-color: #ffcccc !important; /* Jasnoczerwone tło */
+ color: #333; /* Kontrastowy kolor tekstu */
+}
+
+/* Opcjonalnie, jeśli chcesz zmienić kolor tekstu w komórkach */
+.e-grid .e-row.highlight-red .e-rowcell {
+ background-color: #ffcccc !important;
+}
diff --git a/OrdersManagementDataModel/Dtos/FunctionDto.cs b/OrdersManagementDataModel/Dtos/FunctionDto.cs
new file mode 100644
index 0000000..138580c
--- /dev/null
+++ b/OrdersManagementDataModel/Dtos/FunctionDto.cs
@@ -0,0 +1,9 @@
+namespace OrdersManagementDataModel.Dtos;
+
+public class FunctionDto
+{
+ public int Id { get; set; }
+ public int RoleId { get; set; }
+ public string Name { get; set; }
+ public Guid RowPointer { get; set; }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Dtos/RoleDto.cs b/OrdersManagementDataModel/Dtos/RoleDto.cs
new file mode 100644
index 0000000..b593e9b
--- /dev/null
+++ b/OrdersManagementDataModel/Dtos/RoleDto.cs
@@ -0,0 +1,8 @@
+namespace OrdersManagementDataModel.Dtos;
+
+public class RoleDto
+{
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public Guid RowPointer { get; set; }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Dtos/UserDto.cs b/OrdersManagementDataModel/Dtos/UserDto.cs
new file mode 100644
index 0000000..3b6e92b
--- /dev/null
+++ b/OrdersManagementDataModel/Dtos/UserDto.cs
@@ -0,0 +1,23 @@
+namespace OrdersManagementDataModel.Dtos;
+
+public class UserDto
+{
+ public int Id { get; set; }
+ public string Login { get; set; }
+ public string PasswordHash { get; set; }
+ public bool IsTemporaryPassword { get; set; }
+ public bool IsActive { get; set; }
+ public DateTime? ActiveFrom { get; set; }
+ public DateTime? ActiveTo { get; set; }
+ public string Email { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public DateTime CreatedDate { get; set; }
+ public DateTime? LastLoginDate { get; set; }
+ public int FailedLoginAttempts { get; set; }
+ public bool IsLocked { get; set; }
+ public DateTime? LockoutEndDate { get; set; }
+ public Guid RowPointer { get; set; }
+
+ public ICollection UserRoles { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Dtos/UserRoleDto.cs b/OrdersManagementDataModel/Dtos/UserRoleDto.cs
new file mode 100644
index 0000000..d166f8c
--- /dev/null
+++ b/OrdersManagementDataModel/Dtos/UserRoleDto.cs
@@ -0,0 +1,12 @@
+namespace OrdersManagementDataModel.Dtos;
+
+public class UserRoleDto
+{
+ public int UserId { get; set; }
+ public int RoleId { get; set; }
+ public Guid RowPointer { get; set; }
+
+ public virtual UserDto User { get; set; }
+ public virtual RoleDto Role { get; set; }
+
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Entities/Function.cs b/OrdersManagementDataModel/Entities/Function.cs
new file mode 100644
index 0000000..80c4902
--- /dev/null
+++ b/OrdersManagementDataModel/Entities/Function.cs
@@ -0,0 +1,11 @@
+namespace OrdersManagementDataModel.Entities;
+
+public class Function
+{
+ public int Id { get; set; }
+ public int RoleId { get; set; }
+ public string Name { get; set; }
+ public Guid RowPointer { get; set; }
+
+ public Role Role { get; set; }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Entities/Role.cs b/OrdersManagementDataModel/Entities/Role.cs
new file mode 100644
index 0000000..ea95449
--- /dev/null
+++ b/OrdersManagementDataModel/Entities/Role.cs
@@ -0,0 +1,8 @@
+namespace OrdersManagementDataModel.Entities;
+
+public class Role
+{
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public Guid RowPointer { get; set; }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Entities/User.cs b/OrdersManagementDataModel/Entities/User.cs
new file mode 100644
index 0000000..bac9c41
--- /dev/null
+++ b/OrdersManagementDataModel/Entities/User.cs
@@ -0,0 +1,23 @@
+namespace OrdersManagementDataModel.Entities;
+
+public class User
+{
+ public int Id { get; set; }
+ public string Login { get; set; }
+ public string PasswordHash { get; set; }
+ public bool IsTemporaryPassword { get; set; }
+ public bool IsActive { get; set; }
+ public DateTime? ActiveFrom { get; set; }
+ public DateTime? ActiveTo { get; set; }
+ public string Email { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public DateTime CreatedDate { get; set; }
+ public DateTime? LastLoginDate { get; set; }
+ public int FailedLoginAttempts { get; set; }
+ public bool IsLocked { get; set; }
+ public DateTime? LockoutEndDate { get; set; }
+ public Guid RowPointer { get; set; }
+
+ public ICollection UserRoles { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Entities/UserRole.cs b/OrdersManagementDataModel/Entities/UserRole.cs
new file mode 100644
index 0000000..acb55c6
--- /dev/null
+++ b/OrdersManagementDataModel/Entities/UserRole.cs
@@ -0,0 +1,11 @@
+namespace OrdersManagementDataModel.Entities;
+
+public class UserRole
+{
+ public int UserId { get; set; }
+ public int RoleId { get; set; }
+ public Guid RowPointer { get; set; }
+
+ public virtual User User { get; set; }
+ public virtual Role Role { get; set; }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/MappingProfile.cs b/OrdersManagementDataModel/MappingProfile.cs
index b7cc21c..4b04bbb 100644
--- a/OrdersManagementDataModel/MappingProfile.cs
+++ b/OrdersManagementDataModel/MappingProfile.cs
@@ -11,5 +11,9 @@ public class MappingProfile : Profile
{
CreateMap().ReverseMap();
CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
}
}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/OrdersManagementDbContext.cs b/OrdersManagementDataModel/OrdersManagementDbContext.cs
index 3352784..da11759 100644
--- a/OrdersManagementDataModel/OrdersManagementDbContext.cs
+++ b/OrdersManagementDataModel/OrdersManagementDbContext.cs
@@ -25,6 +25,11 @@ public class OrdersManagementDbContext : DbContext
public DbSet TaskSchedulers { get; set; }
public DbSet TaskSchedulerDetails { get; set; }
+ public DbSet Users { get; set; }
+ public DbSet Roles { get; set; }
+ public DbSet Functions { get; set; }
+ public DbSet UserRoles { get; set; }
+
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -67,5 +72,80 @@ public class OrdersManagementDbContext : DbContext
.HasForeignKey(d => d.FkTaskScheduler)
.HasConstraintName("FK_TaskSchedulerDetails_TaskScheduler");
});
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.ToTable("User");
+
+ entity.HasKey(e => e.Id);
+ entity.Property(e => e.Id).HasColumnName("Id");
+ entity.Property(e => e.Login).HasColumnName("Login").HasMaxLength(50).IsRequired();
+ entity.Property(e => e.PasswordHash).HasColumnName("PasswordHash").HasMaxLength(256).IsRequired();
+ entity.Property(e => e.IsTemporaryPassword).HasColumnName("IsTemporaryPassword").IsRequired();
+ entity.Property(e => e.IsActive).HasColumnName("IsActive").IsRequired();
+ entity.Property(e => e.ActiveFrom).HasColumnName("ActiveFrom");
+ entity.Property(e => e.ActiveTo).HasColumnName("ActiveTo");
+ entity.Property(e => e.Email).HasColumnName("Email").HasMaxLength(100);
+ entity.Property(e => e.FirstName).HasColumnName("FirstName").HasMaxLength(50);
+ entity.Property(e => e.LastName).HasColumnName("LastName").HasMaxLength(50);
+ entity.Property(e => e.CreatedDate).HasColumnName("CreatedDate").IsRequired();
+ entity.Property(e => e.LastLoginDate).HasColumnName("LastLoginDate");
+ entity.Property(e => e.FailedLoginAttempts).HasColumnName("FailedLoginAttempts").IsRequired();
+ entity.Property(e => e.IsLocked).HasColumnName("IsLocked").IsRequired();
+ entity.Property(e => e.LockoutEndDate).HasColumnName("LockoutEndDate");
+ entity.Property(e => e.RowPointer).HasColumnName("RowPointer").IsRequired();
+ });
+
+ // Konfiguracja dla Role (już zdefiniowana wcześniej)
+ modelBuilder.Entity(entity =>
+ {
+ entity.ToTable("Role");
+
+ entity.HasKey(e => e.Id);
+ entity.Property(e => e.Id).HasColumnName("Id");
+ entity.Property(e => e.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
+ entity.Property(e => e.RowPointer).HasColumnName("RowPointer").IsRequired();
+ });
+
+ // Konfiguracja dla Function (już zdefiniowana wcześniej)
+ modelBuilder.Entity(entity =>
+ {
+ entity.ToTable("Function");
+
+ entity.HasKey(e => e.Id);
+ entity.Property(e => e.Id).HasColumnName("Id");
+ entity.Property(e => e.RoleId).HasColumnName("RoleId").IsRequired();
+ entity.Property(e => e.Name).HasColumnName("Name").HasMaxLength(100).IsRequired();
+ entity.Property(e => e.RowPointer).HasColumnName("RowPointer").IsRequired();
+
+ entity.HasOne(e => e.Role)
+ .WithMany()
+ .HasForeignKey(e => e.RoleId)
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("FK_Function_Role");
+ });
+
+ // Konfiguracja dla UserRole
+ modelBuilder.Entity(entity =>
+ {
+ entity.ToTable("UserRole");
+
+ entity.HasKey(e => new { e.UserId, e.RoleId });
+ entity.Property(e => e.UserId).HasColumnName("UserId").IsRequired();
+ entity.Property(e => e.RoleId).HasColumnName("RoleId").IsRequired();
+ entity.Property(e => e.RowPointer).HasColumnName("RowPointer").IsRequired();
+
+ entity.HasOne(e => e.User)
+ .WithMany()
+ .HasForeignKey(e => e.UserId)
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("FK_UserRole_User");
+
+ entity.HasOne(e => e.Role)
+ .WithMany()
+ .HasForeignKey(e => e.RoleId)
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("FK_UserRole_Role");
+ });
}
}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/FunctionService.cs b/OrdersManagementDataModel/Services/FunctionService.cs
new file mode 100644
index 0000000..840f73a
--- /dev/null
+++ b/OrdersManagementDataModel/Services/FunctionService.cs
@@ -0,0 +1,95 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using OrdersManagementDataModel.Dtos;
+using OrdersManagementDataModel.Entities;
+
+namespace OrdersManagementDataModel.Services;
+
+public class FunctionService(OrdersManagementDbContext context, IMapper mapper) : IFunctionService
+{
+ public async Task> GetFunctions()
+ {
+ IList functions = await context.Functions.Select(x => mapper.Map(x)).ToListAsync();
+
+ return functions;
+ }
+
+ public async Task GetFunctionById(Guid id)
+ {
+ FunctionDto? function = await context.Functions.Where(x => x.RowPointer == id)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return function;
+ }
+
+ public async Task GetFunctionByName(string name)
+ {
+ FunctionDto? function = await context.Functions.Where(x => x.Name == name)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return function;
+ }
+
+ public async Task AddFunction(FunctionDto functionDto)
+ {
+ Function function = new Function
+ {
+ Name = functionDto.Name,
+ RowPointer = Guid.NewGuid()
+ };
+
+ context.Functions.Add(function);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task DeleteFunction(Guid id)
+ {
+ Function? function = await context.Functions.Where(x => x.RowPointer == id).FirstOrDefaultAsync() ?? null;
+
+ if (function == null) return 0;
+
+ context.Functions.Remove(function);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task UpdateFunction(FunctionDto functionDto)
+ {
+ Function function = mapper.Map(functionDto);
+ context.Functions.Update(function);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task> GetFunctionsByRoleId(Guid roleId)
+ {
+ Role? role = await context.Roles.FirstOrDefaultAsync(x => x.RowPointer == roleId);
+
+ IList functions = await context.Functions.Where(x => role != null && x.RoleId == role.Id)
+ .Select(x => mapper.Map(x)).ToListAsync();
+
+ return functions;
+ }
+
+ public async Task AddFunctionToRole(Guid roleId, Guid functionId)
+ {
+ Role? role = await context.Roles.FirstOrDefaultAsync(x => x.RowPointer == roleId);
+ Function? function = await context.Functions.FirstOrDefaultAsync(x => x.RowPointer == functionId);
+
+ if (role == null || function == null) return 0;
+
+ function.RoleId = role.Id;
+ context.Functions.Update(function);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task RemoveFunctionFromRole(Guid roleId, Guid functionId)
+ {
+ Role? role = await context.Roles.FirstOrDefaultAsync(x => x.RowPointer == roleId);
+ Function? function = await context.Functions.FirstOrDefaultAsync(x => x.RowPointer == functionId);
+
+ if (role == null || function == null) return 0;
+
+ function.RoleId = 0;
+ context.Functions.Update(function);
+ return await context.SaveChangesAsync();
+ }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/IFunctionService.cs b/OrdersManagementDataModel/Services/IFunctionService.cs
new file mode 100644
index 0000000..baafe17
--- /dev/null
+++ b/OrdersManagementDataModel/Services/IFunctionService.cs
@@ -0,0 +1,16 @@
+using OrdersManagementDataModel.Dtos;
+
+namespace OrdersManagementDataModel.Services;
+
+public interface IFunctionService
+{
+ Task> GetFunctions();
+ Task GetFunctionById(Guid id);
+ Task GetFunctionByName(string name);
+ Task AddFunction(FunctionDto functionDto);
+ Task DeleteFunction(Guid id);
+ Task UpdateFunction(FunctionDto functionDto);
+ Task> GetFunctionsByRoleId(Guid roleId);
+ Task AddFunctionToRole(Guid roleId, Guid functionId);
+ Task RemoveFunctionFromRole(Guid roleId, Guid functionId);
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/IRoleService.cs b/OrdersManagementDataModel/Services/IRoleService.cs
new file mode 100644
index 0000000..418ec32
--- /dev/null
+++ b/OrdersManagementDataModel/Services/IRoleService.cs
@@ -0,0 +1,12 @@
+using OrdersManagementDataModel.Dtos;
+
+namespace OrdersManagementDataModel.Services;
+
+public interface IRoleService
+{
+ Task> GetRoles();
+ Task GetRoleById(Guid id);
+ Task GetRoleByName(string name);
+ Task AddRole(RoleDto roleDto);
+ Task DeleteRole(Guid id);
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/IUserRoleService.cs b/OrdersManagementDataModel/Services/IUserRoleService.cs
new file mode 100644
index 0000000..cf3f132
--- /dev/null
+++ b/OrdersManagementDataModel/Services/IUserRoleService.cs
@@ -0,0 +1,15 @@
+using OrdersManagementDataModel.Dtos;
+
+namespace OrdersManagementDataModel.Services;
+
+public interface IUserRoleService
+{
+ Task> GetUserRoles();
+ Task GetUserRoleById(Guid id);
+ Task AddUserRole(UserRoleDto userRoleDto);
+ Task DeleteUserRole(Guid id);
+ Task UpdateUserRole(UserRoleDto userRoleDto);
+ Task> GetUserRolesByUserId(Guid userId);
+ Task> GetUserRolesByRoleId(Guid roleId);
+ Task AddRoleToUser(Guid userId, Guid roleId);
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/IUserService.cs b/OrdersManagementDataModel/Services/IUserService.cs
new file mode 100644
index 0000000..f227bdb
--- /dev/null
+++ b/OrdersManagementDataModel/Services/IUserService.cs
@@ -0,0 +1,15 @@
+using OrdersManagementDataModel.Dtos;
+
+namespace OrdersManagementDataModel.Services;
+
+public interface IUserService
+{
+ Task> GetUsers();
+ Task GetUserById(Guid id);
+ Task GetUserByUsername(string username);
+ Task AddUser(UserDto userDto);
+ Task UpdateUser(UserDto userDto);
+ Task DeleteUser(Guid id);
+ Task> GetUserRoles(Guid userId);
+ Task GetUserByLoginAndPassword(string login, string password);
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/RoleService.cs b/OrdersManagementDataModel/Services/RoleService.cs
new file mode 100644
index 0000000..602ed40
--- /dev/null
+++ b/OrdersManagementDataModel/Services/RoleService.cs
@@ -0,0 +1,54 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using OrdersManagementDataModel.Dtos;
+using OrdersManagementDataModel.Entities;
+
+namespace OrdersManagementDataModel.Services;
+
+public class RoleService(OrdersManagementDbContext context, IMapper mapper) : IRoleService
+{
+ public async Task> GetRoles()
+ {
+ IList roles = await context.Roles.Select(x => mapper.Map(x)).ToListAsync();
+
+ return roles;
+ }
+
+ public async Task GetRoleById(Guid id)
+ {
+ RoleDto? role = await context.Roles.Where(x => x.RowPointer == id)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return role;
+ }
+
+ public async Task GetRoleByName(string name)
+ {
+ RoleDto? role = await context.Roles.Where(x => x.Name == name)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return role;
+ }
+
+ public async Task AddRole(RoleDto roleDto)
+ {
+ Role role = new Role
+ {
+ Name = roleDto.Name,
+ RowPointer = Guid.NewGuid()
+ };
+
+ context.Roles.Add(role);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task DeleteRole(Guid id)
+ {
+ Role? role = await context.Roles.Where(x => x.RowPointer == id).FirstOrDefaultAsync() ?? null;
+
+ if (role == null) return 0;
+
+ context.Roles.Remove(role);
+ return await context.SaveChangesAsync();
+ }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/UserRoleService.cs b/OrdersManagementDataModel/Services/UserRoleService.cs
new file mode 100644
index 0000000..29c82ed
--- /dev/null
+++ b/OrdersManagementDataModel/Services/UserRoleService.cs
@@ -0,0 +1,86 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using OrdersManagementDataModel.Dtos;
+using OrdersManagementDataModel.Entities;
+
+namespace OrdersManagementDataModel.Services;
+
+public class UserRoleService(OrdersManagementDbContext context, IMapper mapper) : IUserRoleService
+{
+ public async Task> GetUserRoles()
+ {
+ IList userRoles = await context.UserRoles.Select(x => mapper.Map(x)).ToListAsync();
+
+ return userRoles;
+ }
+
+ public async Task GetUserRoleById(Guid id)
+ {
+ UserRoleDto? userRole = await context.UserRoles.Where(x => x.RowPointer == id)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return userRole;
+ }
+
+ public Task AddUserRole(UserRoleDto userRoleDto)
+ {
+ UserRole userRole = mapper.Map(userRoleDto);
+ context.UserRoles.Add(userRole);
+ return context.SaveChangesAsync();
+ }
+
+ public async Task DeleteUserRole(Guid id)
+ {
+ UserRole? userRole = await context.UserRoles.Where(x => x.RowPointer == id).FirstOrDefaultAsync() ?? null;
+
+ if (userRole == null) return 0;
+
+ context.UserRoles.Remove(userRole);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task UpdateUserRole(UserRoleDto userRoleDto)
+ {
+ UserRole userRole = mapper.Map(userRoleDto);
+ context.UserRoles.Update(userRole);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task> GetUserRolesByUserId(Guid userId)
+ {
+ IList userRoles = await context.UserRoles
+ .Where(x => x.User.RowPointer == userId)
+ .Select(x => mapper.Map(x))
+ .ToListAsync();
+
+ return userRoles;
+ }
+
+ public async Task> GetUserRolesByRoleId(Guid roleId)
+ {
+ IList userRoles = await context.UserRoles
+ .Where(x => x.Role.RowPointer == roleId)
+ .Select(x => mapper.Map(x))
+ .ToListAsync();
+
+ return userRoles;
+ }
+
+ public async Task AddRoleToUser(Guid userId, Guid roleId)
+ {
+ User? user = await context.Users.FirstOrDefaultAsync(x => x.RowPointer == userId);
+ Role? role = await context.Roles.FirstOrDefaultAsync(x => x.RowPointer == roleId);
+
+ if (user == null || role == null) return 0;
+
+ UserRole userRole = new UserRole
+ {
+ User = user,
+ Role = role,
+ RowPointer = Guid.NewGuid()
+ };
+
+ context.UserRoles.Add(userRole);
+ return await context.SaveChangesAsync();
+ }
+}
\ No newline at end of file
diff --git a/OrdersManagementDataModel/Services/UserService.cs b/OrdersManagementDataModel/Services/UserService.cs
new file mode 100644
index 0000000..ed535d7
--- /dev/null
+++ b/OrdersManagementDataModel/Services/UserService.cs
@@ -0,0 +1,88 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using OrdersManagementDataModel.Dtos;
+using OrdersManagementDataModel.Entities;
+
+namespace OrdersManagementDataModel.Services;
+
+public class UserService(OrdersManagementDbContext context, IMapper mapper) : IUserService
+{
+ public async Task> GetUsers()
+ {
+ IList users = await context.Users.Select(x => mapper.Map(x)).ToListAsync();
+
+ return users;
+ }
+
+ public async Task GetUserById(Guid id)
+ {
+ UserDto? user = await context.Users.Where(x => x.RowPointer == id)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return user;
+ }
+
+ public async Task GetUserByUsername(string username)
+ {
+ UserDto? user = await context.Users.Where(x => x.Login == username)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return user;
+ }
+
+ public async Task AddUser(UserDto userDto)
+ {
+ User user = new User
+ {
+ Login = userDto.Login,
+ PasswordHash = userDto.PasswordHash,
+ IsTemporaryPassword = true,
+ IsActive = true,
+ Email = userDto.Email,
+ RowPointer = Guid.NewGuid(),
+ CreatedDate = DateTime.Now,
+ ActiveFrom = DateTime.Now,
+ FirstName = userDto.FirstName,
+ LastName = userDto.LastName
+ };
+
+ context.Users.Add(user);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task UpdateUser(UserDto userDto)
+ {
+ User user = mapper.Map(userDto);
+ context.Users.Update(user);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task DeleteUser(Guid id)
+ {
+ User? user = await context.Users.Where(x => x.RowPointer == id).FirstOrDefaultAsync() ?? null;
+
+ if (user == null) return 0;
+
+ context.Users.Remove(user);
+ return await context.SaveChangesAsync();
+ }
+
+ public async Task> GetUserRoles(Guid userId)
+ {
+ List userRoles = await context.Users
+ .Where(x => x.RowPointer == userId)
+ .SelectMany(x => x.UserRoles)
+ .Select(x => mapper.Map(x))
+ .ToListAsync();
+
+ return userRoles;
+ }
+
+ public async Task GetUserByLoginAndPassword(string login, string password)
+ {
+ UserDto? user = await context.Users.Where(x => x.Login == login && x.PasswordHash == password)
+ .Select(x => mapper.Map(x)).FirstOrDefaultAsync();
+
+ return user;
+ }
+}
\ No newline at end of file