feat : shift plan , activites

add complete shift plan , add complete actevities
master
Amir Hossein Khademi 2023-12-11 14:32:29 +03:30
parent 7fd9ce03ca
commit 504744da7d
48 changed files with 3784 additions and 183 deletions

View File

@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"mapster.tool": {
"version": "8.3.0",
"version": "8.4.0",
"commands": [
"dotnet-mapster"
]

View File

@ -21,6 +21,10 @@ public class ActivityController : ICarterModule
.WithDisplayName("DoneActivity")
.HasApiVersion(1.0);
group.MapPost("complete", CompleteActivityAsync)
.WithDisplayName("DoneActivity")
.HasApiVersion(1.0);
group.MapPost("undone/{id:guid}", UnDoneActivityAsync)
.WithDisplayName("UnDoneActivity")
.HasApiVersion(1.0);
@ -39,13 +43,16 @@ public class ActivityController : ICarterModule
// GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int page, ISender sender, CancellationToken cancellationToken)
=> TypedResults.Ok(await sender.Send(new GetActivitiesQuery(page), cancellationToken));
public async Task<IResult> GetAllAsync([FromQuery] int page, [FromQuery] long? selectedDate, [FromQuery] Guid? selectedShift, ISender sender, CancellationToken cancellationToken)
=> TypedResults.Ok(await sender.Send(new GetActivitiesQuery(Page: page, SelectedDate: selectedDate ?? 0 , SelectedShift: selectedShift ?? default), cancellationToken));
// GET:Get An Entity By Id
public async Task<IResult> GetAsync(Guid id, IActivityService activityService, CancellationToken cancellationToken)
=> TypedResults.Ok(await activityService.DoneActivityAsync(id,cancellationToken));
public async Task<IResult> CompleteActivityAsync([FromBody]List<CompleteActivityRequestDto> requestDtos, [FromServices] IActivityService activityService, CancellationToken cancellationToken)
=> TypedResults.Ok(await activityService.CompleteActivitiesAsync(requestDtos, cancellationToken));
public async Task<IResult> DoneActivityAsync(Guid id, [FromServices] IActivityService activityService, CancellationToken cancellationToken)
=> TypedResults.Ok(await activityService.DoneActivityAsync(id, cancellationToken));

View File

@ -29,8 +29,8 @@ public class ShiftController : ICarterModule
}
// GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int page,ISender sender, CancellationToken cancellationToken)
=> TypedResults.Ok(await sender.Send(new GetShiftsQuery(page), cancellationToken));
public async Task<IResult> GetAllAsync([FromQuery] int page,ISender sender, CancellationToken cancellationToken, [FromQuery] long? selectedDate)
=> TypedResults.Ok(await sender.Send(new GetShiftsQuery(Page: page, SelectedDate: selectedDate ?? 0), cancellationToken));
// GET:Get An Entity By Id
public async Task<IResult> GetAsync(Guid id, ISender sender, CancellationToken cancellationToken)

View File

@ -17,6 +17,10 @@ public class ShiftPlanController : ICarterModule
.WithDisplayName("GetShiftPlan")
.HasApiVersion(1.0);
group.MapPost("{id:guid}/complete", CompletePlanAsync)
.WithDisplayName("DoneActivity")
.HasApiVersion(1.0);
group.MapPost("", Post)
.HasApiVersion(1.0);
@ -28,10 +32,13 @@ public class ShiftPlanController : ICarterModule
}
public async Task<IResult> CompletePlanAsync(Guid id,[FromBody] CompleteShiftPlanRequestDto requestDtos, [FromServices] IShiftPlanService shiftPlanService, CancellationToken cancellationToken)
=> TypedResults.Ok(await shiftPlanService.CompleteShiftPlanAsync(id,requestDtos, cancellationToken));
// GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int page, ISender sender, CancellationToken cancellationToken)
=> TypedResults.Ok(await sender.Send(new GetShiftPlansQuery(page), cancellationToken));
public async Task<IResult> GetAllAsync([FromQuery] int page, [FromQuery] long? selectedDate, ISender sender, CancellationToken cancellationToken)
=> TypedResults.Ok(await sender.Send(new GetShiftPlansQuery(page , selectedDate ?? 0), cancellationToken));
// GET:Get An Entity By Id
public async Task<IResult> GetAsync(Guid id, ISender sender, CancellationToken cancellationToken)

View File

@ -23,6 +23,10 @@ public class UserController : ICarterModule
.WithDisplayName("GetUserProfile")
.HasApiVersion(1.0);
group.MapPost("/role/change/{roleId}", ChangeUserRoleAsync)
.WithDisplayName("GetUserProfile")
.HasApiVersion(1.0);
group.MapPost("", Post)
.HasApiVersion(1.0);
@ -33,6 +37,11 @@ public class UserController : ICarterModule
.HasApiVersion(1.0);
}
public async Task<IResult> ChangeUserRoleAsync(Guid roleId,IUserService userService, CancellationToken cancellationToken)
=> TypedResults.Ok(await userService.ChangeUserRoleAsync(roleId,cancellationToken));
public async Task<IResult> GetUserProfileAsync(IUserService userService, CancellationToken cancellationToken)
=> TypedResults.Ok(await userService.GetUserProfileAsync(cancellationToken));

View File

@ -15,4 +15,6 @@ public class CurrentUserService : ICurrentUserService
public string? RoleName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Role);
public string? UserName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
public string? ComplexId => _httpContextAccessor.HttpContext?.User?.FindFirstValue("ComplexId");
public string? RoleId => _httpContextAccessor.HttpContext?.User?.FindFirstValue("RoleId");
public List<string>? Permissions => _httpContextAccessor.HttpContext?.User?.FindAll("Permission")?.Select(c=>c.Value)?.ToList();
}

View File

@ -2,11 +2,14 @@
using Asp.Versioning;
using AspNetCoreRateLimit;
using AspNetCoreRateLimit.Redis;
using Brizco.Common.Models.Api;
using Brizco.Core.Models.Api;
using Brizco.Domain.Entities.User;
using Brizco.Domain.Models.Settings;
using Brizco.Repository.Extensions;
using Brizco.Repository.Models;
using Microsoft.AspNetCore.ResponseCompression;
using Newtonsoft.Json.Serialization;
using StackExchange.Redis.Extensions.Core.Configuration;
using StackExchange.Redis.Extensions.Newtonsoft;
using Task = System.Threading.Tasks.Task;
@ -160,7 +163,28 @@ public static class ServiceExtensions
// Read the token out of the query string
context.Token = accessToken.ToString();
return Task.CompletedTask;
},
OnChallenge = async context =>
{
// Call this to skip the default logic and avoid using the default response
context.HandleResponse();
// Write to the response in any way you wish
context.Response.StatusCode = (int)ApiResultStatusCode.UnAuthorized;
context.Response.ContentType = "application/json";
var result = new ApiResult(false, ApiResultStatusCode.UnAuthorized, "You are not authorized!");
var contractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings
{
ContractResolver = contractResolver,
Formatting = Formatting.Indented
});
await context.Response.WriteAsync(json);
}
};
});
}

View File

@ -74,7 +74,8 @@ public class ExceptionHandlerMiddleware
{
message = exception.Message;
}
if(exception.AdditionalData==null)
if (exception.AdditionalData == null)
await WriteToResponseAsync();
else
await WriteToResponseWithObjectAsync(exception.AdditionalData);
@ -114,7 +115,8 @@ public class ExceptionHandlerMiddleware
async Task WriteToResponseAsync()
{
if (context.Response.HasStarted)
throw new InvalidOperationException("The response has already started, the http status code middleware will not be executed.");
throw new InvalidOperationException(
"The response has already started, the http status code middleware will not be executed.");
var result = new ApiResult(false, apiStatusCode, message);
@ -135,7 +137,6 @@ public class ExceptionHandlerMiddleware
}
async Task WriteToResponseWithObjectAsync(object additionalData)
{
if (context.Response.HasStarted)

View File

@ -1,12 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--<PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
</ItemGroup>
<!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
@ -14,20 +28,6 @@
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
</ItemGroup>-->
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
</ItemGroup>
<ItemGroup>
<Using Include="MD.PersianDateTime.Standard" />
<Using Include="System.ComponentModel.DataAnnotations" />

View File

@ -30,7 +30,7 @@ namespace Brizco.Common.Extensions
public static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
{
// Unix timestamp is seconds past epoch
var dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var dtDateTime = new DateTime(1970, 1, 1, 3, 30, 0, 0, DateTimeKind.Utc);
dtDateTime = dtDateTime.AddMilliseconds(unixTimeStamp).ToLocalTime();
return dtDateTime;
}

View File

@ -7,7 +7,8 @@ public interface IJwtService : IScopedDependency
Task<AccessToken<TUser>> Generate<TUser>(TUser user) where TUser : ApplicationUser;
Task<AccessToken<TUserDto>> Generate<TUserDto, TUser>(TUser user, Guid complexId, Guid roleId) where TUser : ApplicationUser;
Task<AccessToken<TUserDto,TRole>> Generate<TUserDto, TUser, TRole>(TUser user, Guid complexId, Guid roleId) where TUser : ApplicationUser;
Task<AccessToken<TUserDto>> Generate<TUserDto, TUser>(TUser user, Guid complexId) where TUser : ApplicationUser;
Task<AccessToken<TUserDto>> Generate<TUserDto, TUser>(TUser user) where TUser : ApplicationUser;
Task<AccessToken<TUserDto, TRole>> Generate<TUserDto, TUser, TRole>(TUser user, Guid complexId, Guid roleId) where TUser : ApplicationUser;
}

View File

@ -179,6 +179,7 @@ public class JwtService : IJwtService
claims.Add(new Claim(ClaimTypes.Name, baseUser.UserName));
claims.Add(new Claim(ClaimTypes.NameIdentifier, baseUser.Id.ToString()));
claims.Add(new Claim(ClaimTypes.Role,applicationRole.EnglishName));
claims.Add(new Claim("RoleId", applicationRole.Id.ToString()));
if (baseUser.Email != null)
claims.Add(new Claim(ClaimTypes.Email, baseUser.Email));
claims.AddRange(roleClaims);

View File

@ -1,4 +1,8 @@
using Brizco.Domain.Entities.Task;
using System.Linq;
using Brizco.Domain.Entities.Routine;
using Brizco.Domain.Entities.Shift;
using Task = Brizco.Domain.Entities.Task.Task;
namespace Brizco.Core.CoreServices;
@ -6,11 +10,16 @@ public class PageService : IPageService
{
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly RoleManager<ApplicationRole> _roleManager;
public PageService(ICurrentUserService currentUserService,IRepositoryWrapper repositoryWrapper)
public PageService(
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
RoleManager<ApplicationRole> roleManager)
{
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
_roleManager = roleManager;
}
public async Task<AppDashboardPageDto> GetAppDashboardAsync(CancellationToken cancellationToken)
{
@ -18,17 +27,129 @@ public class PageService : IPageService
throw new AppException("User id is null ");
if (Guid.TryParse(_currentUserService.UserId, out Guid userId)!)
throw new AppException("User id is wrong");
if (Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)!)
throw new AppException("Complex id is wrong");
var todayTasks = await _repositoryWrapper.SetRepository<Activity>()
.TableNoTracking
.Where(a => a.UserId == userId)
.ToListAsync(cancellationToken);
return new AppDashboardPageDto
var page = new AppDashboardPageDto
{
DoneActivitiesToday = todayTasks.Count(t => t.IsDone),
TotalActivitiesToday = todayTasks.Count,
UnDoneActivitiesToday = todayTasks.Count(t => t.IsDone!)
};
if (_currentUserService.Permissions != null)
{
int totalStepCount = 0;
int completeStepCount = 0;
string currentStep = string.Empty;
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageRoutines))
{
totalStepCount++;
var hasRoutine = await _repositoryWrapper.SetRepository<Routine>()
.TableNoTracking
.AnyAsync(r=>r.ComplexId== complexId, cancellationToken);
if(hasRoutine)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش روتین ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageSections))
{
totalStepCount++;
var hasSection = await _repositoryWrapper.SetRepository<Section>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasSection)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش سکشن ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManagePositions))
{
totalStepCount++;
var hasPosition = await _repositoryWrapper.SetRepository<Position>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasPosition)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش پوزیشن ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageStaffs))
{
totalStepCount++;
var hasStaff = await _repositoryWrapper.SetRepository<ComplexUser>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasStaff)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش کاربر ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageShifts))
{
totalStepCount++;
var hasShift = await _repositoryWrapper.SetRepository<Shift>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasShift)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش شیفت ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageTasks))
{
totalStepCount++;
var hasTask = await _repositoryWrapper.SetRepository<Task>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasTask)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش تسک ها";
}
}
if (_currentUserService.Permissions.Exists(s => s == ApplicationPermission.ManageShiftPlans))
{
totalStepCount++;
var hasStaff = await _repositoryWrapper.SetRepository<ShiftPlan>()
.TableNoTracking
.AnyAsync(r => r.ComplexId == complexId, cancellationToken);
if (hasStaff)
completeStepCount++;
else
{
if (currentStep.IsNullOrEmpty())
currentStep = "تکمیل بخش شیفت بندی ها";
}
}
page.SignUpCompletePercent = ((totalStepCount * 100) / completeStepCount);
page.CurrentSignUpStep = currentStep;
}
return page;
}
}

View File

@ -4,5 +4,6 @@ public interface IActivityService : IScopedDependency
{
Task<bool> CreateActivitiesByShiftPlan(Guid shiftPlanId, CancellationToken cancellationToken);
Task<bool> DoneActivityAsync(Guid activityId, CancellationToken cancellationToken);
Task<bool> CompleteActivitiesAsync(List<CompleteActivityRequestDto> requestDtos, CancellationToken cancellationToken);
Task<bool> UnDoneActivityAsync(Guid activityId, string undoneReason, CancellationToken cancellationToken);
}

View File

@ -4,4 +4,5 @@ public interface IShiftPlanService : IScopedDependency
{
Task ChangeShiftPlanTaskStatusAsync(Guid shiftPlanId,bool isChangeToShift , bool isDisable);
Task<bool> CreateAsync(CreateShiftPlanCommand createShiftPlanCommand,CancellationToken cancellationToken);
Task<bool> CompleteShiftPlanAsync(Guid id,CompleteShiftPlanRequestDto requestDtos, CancellationToken cancellationToken);
}

View File

@ -3,6 +3,7 @@
public interface IUserService : IScopedDependency
{
Task<ProfileResponseDto> GetUserProfileAsync(CancellationToken cancellationToken);
Task<AccessToken<ApplicationUserSDto, ComplexUserRoleSDto>> ChangeUserRoleAsync(Guid roleId,CancellationToken cancellationToken);
Task<List<ComplexUserRoleSDto>> GetUserRolesAsync(CancellationToken cancellationToken);
Task<List<ComplexUserRoleSDto>> GetUserRolesAsync(Guid userId, CancellationToken cancellationToken);
Task<List<ComplexUserSDto>> GetUsersAsync(int page = 0, CancellationToken cancellationToken = default);

View File

@ -1,7 +1,6 @@
using Brizco.Domain.CommandQueries.Queries;
using Brizco.Domain.Entities.Shift;
using Brizco.Domain.Entities.Task;
using System.Threading.Tasks;
namespace Brizco.Core.EntityServices;
@ -31,6 +30,23 @@ public class ActivityService : IActivityService
return true;
}
public async Task<bool> CompleteActivitiesAsync(List<CompleteActivityRequestDto> requestDtos, CancellationToken cancellationToken)
{
foreach (var activityRequestDto in requestDtos)
{
var activity = await _repositoryWrapper.SetRepository<Activity>().TableNoTracking
.FirstOrDefaultAsync(a => a.Id == activityRequestDto.ActivityId, cancellationToken);
if(activity==null)
continue;
activity.CompleteActivity(activityRequestDto.IsCompleted,activityRequestDto.PerformanceDescription);
_repositoryWrapper.SetRepository<Activity>().Update(activity);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
}
return true;
}
public async Task<bool> UnDoneActivityAsync(Guid activityId,string undoneReason, CancellationToken cancellationToken)
{
@ -85,7 +101,7 @@ GROUP BY t.""Id""").ToListAsync(cancellationToken);
if (fundedUser != null)
{
await _mediator.Send(new CreateActivityCommand(task.Type, task.Title, task.Description, task.IsDisposable,
task.SetFor, task.HasDisposed, task.Amount, task.AmountType,
shiftPlan.PlanFor, task.HasDisposed, task.Amount, task.AmountType,
task.ScheduleType, shiftPlan.ShiftId, new List<Guid> { fundedUser.UserId }),cancellationToken);
}
}

View File

@ -1,4 +1,5 @@
using Brizco.Domain.CommandQueries.Queries;
using Brizco.Domain.Entities.Shift;
namespace Brizco.Core.EntityServices;
@ -6,11 +7,13 @@ public class ShiftPlanService : IShiftPlanService
{
private readonly ISender _sender;
private readonly IActivityService _activityService;
private readonly IRepositoryWrapper _repositoryWrapper;
public ShiftPlanService(ISender sender,IActivityService activityService)
public ShiftPlanService(ISender sender,IActivityService activityService,IRepositoryWrapper repositoryWrapper)
{
_sender = sender;
_activityService = activityService;
_repositoryWrapper = repositoryWrapper;
}
public async Task ChangeShiftPlanTaskStatusAsync(Guid shiftPlanId, bool isChangeToShift, bool isDisable)
{
@ -24,4 +27,18 @@ public class ShiftPlanService : IShiftPlanService
await _activityService.CreateActivitiesByShiftPlan(shiftPlan.Id, cancellationToken);
return true;
}
public async Task<bool> CompleteShiftPlanAsync(Guid id, CompleteShiftPlanRequestDto requestDtos, CancellationToken cancellationToken)
{
var shiftPlan = await _repositoryWrapper.SetRepository<ShiftPlan>()
.TableNoTracking.FirstOrDefaultAsync(s => s.Id == id, cancellationToken);
if (shiftPlan == null)
throw new AppException("Shift plan not found", ApiResultStatusCode.NotFound);
shiftPlan.CompletePlan(requestDtos.CompleteDescription,requestDtos.CompletePercent);
_repositoryWrapper.SetRepository<ShiftPlan>().Update(shiftPlan);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
await _activityService.CompleteActivitiesAsync(requestDtos.CompleteActivities, cancellationToken);
return true;
}
}

View File

@ -12,18 +12,21 @@ public class UserService : IUserService
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly ISender _sender;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IJwtService _jwtService;
public UserService(ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
ISender sender,
IRepositoryWrapper repositoryWrapper)
IRepositoryWrapper repositoryWrapper,
IJwtService jwtService)
{
_currentUserService = currentUserService;
_userManager = userManager;
_roleManager = roleManager;
_sender = sender;
_repositoryWrapper = repositoryWrapper;
_jwtService = jwtService;
}
@ -47,7 +50,8 @@ public class UserService : IUserService
userSDto.SelectedComplexName = complexUserRole!.ComplexName;
userSDto.SelectedRoleName = complexUserRole!.RoleName;
var role = await _roleManager.FindByIdAsync(complexUserRole.RoleId.ToString());
response.User.SelectedRoleId = complexUserRole!.Id;
var role = await _roleManager.FindByIdAsync(complexUserRole.RoleId.ToString());
if (role != null)
{
var roleClaims = await _roleManager.GetClaimsAsync(role);
@ -59,6 +63,43 @@ public class UserService : IUserService
return response;
}
public async Task<AccessToken<ApplicationUserSDto, ComplexUserRoleSDto>> ChangeUserRoleAsync(Guid roleId, CancellationToken cancellationToken)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
AccessToken<ApplicationUserSDto, ComplexUserRoleSDto> jwt;
var complexUserRole = await _repositoryWrapper.SetRepository<ComplexUserRole>()
.TableNoTracking
.Where(c => c.Id == roleId)
.Select(ComplexUserRoleMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
if (complexUserRole == null)
throw new AppException("Role not found", ApiResultStatusCode.NotFound);
var complexUser = await _repositoryWrapper.SetRepository<ComplexUser>()
.TableNoTracking
.Where(mcu => mcu.Id == complexUserRole.ComplexUserId)
.Select(ComplexUserMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
if (complexUser?.UserId != user.Id)
throw new AppException("User role is wrong", ApiResultStatusCode.BadRequest);
user.SelectedComplexUserRoleId = complexUserRole.Id;
await _userManager.UpdateAsync(user);
jwt = (await _jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, complexUser.ComplexId, complexUserRole.RoleId)).Adapt<AccessToken<ApplicationUserSDto, ComplexUserRoleSDto>>();
jwt.User.SelectedComplexName = complexUser.ComplexName;
jwt.User.SelectedRoleName = complexUserRole.RoleName;
jwt.User.SelectedRoleId = complexUserRole.Id;
jwt.Roles = await GetUserRolesAsync(cancellationToken);
return jwt;
}
public async Task<List<ComplexUserRoleSDto>> GetUserRolesAsync(CancellationToken cancellationToken)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
@ -122,6 +163,7 @@ public class UserService : IUserService
return response;
}
public async Task<List<ComplexUserSDto>> GetUsersAsync(int page = 0, CancellationToken cancellationToken = default)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())

View File

@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--<PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
@ -12,10 +13,10 @@
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup>-->
</ItemGroup>
<PropertyGroup>
<!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
@ -31,11 +32,11 @@
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup>
</ItemGroup>-->
<Target Name="Mapster">
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet build" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet build -p:CopyLocalLockFileAssemblies=true" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster extension -a &quot;$(TargetDir)$(ProjectName).dll&quot; -n Brizco.Domain.Mappers -o Mappers" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a &quot;$(TargetDir)$(ProjectName).dll&quot; -n Brizco.Domain.Mappers -o Mappers" />
@ -72,7 +73,6 @@
<ItemGroup>
<Folder Include="Dtos\PageDto\" />
<Folder Include="Dtos\RequestDtos\" />
<Folder Include="Models\Settings\" />
</ItemGroup>

View File

@ -1,6 +1,6 @@
namespace Brizco.Domain.CommandQueries.Queries;
public sealed record GetActivitiesQuery(int Page = 0) :
public sealed record GetActivitiesQuery(int Page = 0 , long SelectedDate = 0 , Guid SelectedShift = default) :
IRequest<List<ActivitySDto>>;
public sealed record GetActivityQuery(Guid Id) :

View File

@ -1,6 +1,6 @@
namespace Brizco.Domain.CommandQueries.Queries;
public sealed record GetShiftPlansQuery(int Page = 0) :
public sealed record GetShiftPlansQuery(int Page = 0 , long SelectedDate = 0) :
IRequest<List<ShiftPlanSDto>>;
public sealed record GetShiftPlanQuery(Guid Id) :

View File

@ -1,6 +1,6 @@
namespace Brizco.Domain.CommandQueries.Queries;
public sealed record GetShiftsQuery(int Page = 0) :
public sealed record GetShiftsQuery(int Page = 0,long SelectedDate = 0) :
IRequest<List<ShiftSDto>>;
public sealed record GetShiftQuery(Guid Id) :

View File

@ -6,6 +6,9 @@ public class ShiftPlanLDto : BaseDto<ShiftPlanLDto , ShiftPlan>
{
public DateTime PlanFor { get; set; }
public Guid RoutineId { get; set; }
public bool IsCompleted { get; internal set; }
public int CompletePercent { get; internal set; }
public string CompleteDescription { get; internal set; } = string.Empty;
public Guid ShiftId { get; set; }
public List<ShiftPlanUserSDto> Users { get; set; } = new();
}

View File

@ -5,4 +5,9 @@ public class AppDashboardPageDto
public int UnDoneActivitiesToday { get; set; }
public int DoneActivitiesToday { get; set; }
public int TotalActivitiesToday { get; set; }
public int TotalStaffToday { get; set; }
public string CurrentSignUpStep { get; set; } = string.Empty;
public int SignUpCompletePercent { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace Brizco.Domain.Dtos.RequestDtos;
public class CompleteActivityRequestDto
{
public Guid ActivityId { get; set; }
public bool IsCompleted { get; set; }
public string PerformanceDescription { get; set; } = string.Empty;
}

View File

@ -0,0 +1,8 @@
namespace Brizco.Domain.Dtos.RequestDtos;
public class CompleteShiftPlanRequestDto
{
public string CompleteDescription { get; set; } = string.Empty;
public List<CompleteActivityRequestDto> CompleteActivities { get; set; } = new();
public int CompletePercent { get; internal set; }
}

View File

@ -16,8 +16,12 @@ public class ActivitySDto : BaseDto<ActivitySDto , Activity>
public DateTime DoneAt { get; internal set; }
public bool IsDone { get; set; }
public string PerformanceDescription { get; internal set; } = string.Empty;
public string UserFirstName { get; set; } = string.Empty;
public string UserLastName { get; set; } = string.Empty;
public string UserFullName => UserFirstName + " " + UserLastName;
public int Amount { get; internal set; }
public Guid ShiftId { get; internal set; }
public PurchaseAmountType AmountType { get; internal set; }
}

View File

@ -12,6 +12,7 @@ public class ApplicationUserSDto : BaseDto<ApplicationUserSDto,ApplicationUser>
public SignUpStatus SignUpStatus { get; set; }
public string SelectedRoleName { get; set; } = string.Empty;
public string SelectedComplexName { get; set; } = string.Empty;
public Guid SelectedRoleId { get; set; }
public string NationalId { get; set; } = string.Empty;
public List<Guid> RoleIds { get; set; } = new();

View File

@ -4,8 +4,13 @@ namespace Brizco.Domain.Dtos.SmallDtos;
public class ShiftPlanSDto : BaseDto<ShiftPlanSDto,ShiftPlan>
{
public DateTime StartAt { get; set; }
public DateTime EndAt { get; set; }
public DateTime PlanFor { get; internal set; }
public bool IsCompleted { get; internal set; }
public int UndoneActivitiesCount { get; set; }
public int DoneActivitiesCount { get; set; }
public int TotalActivitiesCount { get; set; }
public int CompletePercent { get; internal set; }
public string CompleteDescription { get; internal set; } = string.Empty;
public Guid ShiftId { get; set; }
public string ShiftTitle { get; internal set; } = string.Empty;
}

View File

@ -5,6 +5,10 @@ public class ShiftSDto : BaseDto<ShiftSDto,Shift>
{
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public int UndoneActivitiesCount { get; set; }
public int DoneActivitiesCount { get; set; }
public int TotalActivitiesCount { get; set; }
public bool IsCompleted { get; set; }
public TimeSpan StartAt { get; set; }
public TimeSpan EndAt { get; set; }
public Guid ComplexId { get; set; }

View File

@ -16,7 +16,7 @@ public partial class Shift
}
public ShiftPlan AddPlan(DateTime planDate,Guid routineId)
{
var plan = new ShiftPlan(planDate , routineId, Id);
var plan = new ShiftPlan(planDate , routineId, Id ,this.ComplexId);
Plans.Add(plan);
return plan;
}
@ -37,4 +37,11 @@ public partial class ShiftPlan
Users.Add(planUser);
return planUser;
}
public void CompletePlan(string completeDescription,int completePercent)
{
IsCompleted = true;
CompleteDescription = completeDescription;
CompletePercent = completePercent;
}
}

View File

@ -10,19 +10,27 @@ public partial class ShiftPlan : ApiEntity
}
internal ShiftPlan(DateTime planFor, Guid routineId,Guid shiftId)
internal ShiftPlan(DateTime planFor, Guid routineId,Guid shiftId, Guid complexId)
{
PlanFor = planFor;
RoutineId = routineId;
ShiftId = shiftId;
ComplexId = complexId;
}
public DateTime PlanFor { get; internal set; }
public bool IsCompleted { get; internal set; }
public int CompletePercent { get; internal set; }
public string CompleteDescription { get; internal set; } = string.Empty;
public Guid ShiftId { get; internal set; }
public virtual Shift? Shift { get; internal set; }
public Guid RoutineId { get; internal set; }
public virtual Routine.Routine? Routine { get; internal set; }
public Guid ComplexId { get; internal set; }
public Complex.Complex? Complex { get; internal set; }
public List<ShiftPlanUser> Users { get; internal set; } = new();
}

View File

@ -65,13 +65,13 @@ public partial class Task
{
foreach (var positionId in positionIds)
{
var position = new TaskPosition(positionId,Id);
var position = new TaskPosition(positionId, Id);
Positions.Add(position);
}
}
public TaskPosition AddPosition(Guid positionId)
{
var position = new TaskPosition(positionId,Id);
var position = new TaskPosition(positionId, Id);
Positions.Add(position);
return position;
}
@ -82,13 +82,13 @@ public partial class Task
{
foreach (var routineId in routineIds)
{
var routine = new TaskRoutine(routineId,Id);
var routine = new TaskRoutine(routineId, Id);
Routines.Add(routine);
}
}
public TaskRoutine AddRoutine(Guid routineId)
{
var routine = new TaskRoutine(routineId,Id);
var routine = new TaskRoutine(routineId, Id);
Routines.Add(routine);
return routine;
}
@ -146,6 +146,16 @@ public partial class Activity
Status = ActivityStatus.Done;
}
public void CompleteActivity(bool isDone, string performanceDescription)
{
if (!isDone)
Status = ActivityStatus.UnDone;
else
Status = ActivityStatus.Complete;
IsDone = isDone;
PerformanceDescription = performanceDescription;
}
public void UnDoneActivity(string undoneReason)
{
IsDone = false;

View File

@ -2,7 +2,10 @@ using System;
using System.Linq.Expressions;
using Brizco.Domain.Dtos.LargDtos;
using Brizco.Domain.Dtos.SmallDtos;
using Brizco.Domain.Entities.Shift;
using Brizco.Domain.Entities.Task;
using Brizco.Domain.Entities.User;
using Mapster.Models;
namespace Brizco.Domain.Mappers
{
@ -17,6 +20,13 @@ namespace Brizco.Domain.Mappers
IsDone = p1.IsDone,
UnDoneReason = p1.UnDoneReason,
PerformanceDescription = p1.PerformanceDescription,
User = new ApplicationUser()
{
FirstName = p1.UserFirstName,
LastName = p1.UserLastName
},
ShiftId = p1.ShiftId,
Shift = new Shift() {Id = p1.ShiftId},
Type = p1.Type,
Title = p1.Title,
Description = p1.Description,
@ -42,6 +52,9 @@ namespace Brizco.Domain.Mappers
result.IsDone = p2.IsDone;
result.UnDoneReason = p2.UnDoneReason;
result.PerformanceDescription = p2.PerformanceDescription;
result.User = funcMain1(new Never(), result.User, p2);
result.ShiftId = p2.ShiftId;
result.Shift = funcMain2(new Never(), result.Shift, p2);
result.Type = p2.Type;
result.Title = p2.Title;
result.Description = p2.Description;
@ -55,73 +68,20 @@ namespace Brizco.Domain.Mappers
return result;
}
public static Expression<Func<ActivitySDto, Activity>> ProjectToActivity => p4 => new Activity()
public static Expression<Func<ActivitySDto, Activity>> ProjectToActivity => p8 => new Activity()
{
Status = p4.Status,
DoneAt = p4.DoneAt,
IsDone = p4.IsDone,
UnDoneReason = p4.UnDoneReason,
PerformanceDescription = p4.PerformanceDescription,
Type = p4.Type,
Title = p4.Title,
Description = p4.Description,
IsDisposable = p4.IsDisposable,
SetFor = p4.SetFor,
HasDisposed = p4.HasDisposed,
ScheduleType = p4.ScheduleType,
Amount = p4.Amount,
AmountType = p4.AmountType,
Id = p4.Id
};
public static ActivitySDto AdaptToSDto(this Activity p5)
{
return p5 == null ? null : new ActivitySDto()
Status = p8.Status,
DoneAt = p8.DoneAt,
IsDone = p8.IsDone,
UnDoneReason = p8.UnDoneReason,
PerformanceDescription = p8.PerformanceDescription,
User = new ApplicationUser()
{
Type = p5.Type,
Title = p5.Title,
Description = p5.Description,
IsDisposable = p5.IsDisposable,
SetFor = p5.SetFor,
HasDisposed = p5.HasDisposed,
ScheduleType = p5.ScheduleType,
UnDoneReason = p5.UnDoneReason,
Status = p5.Status,
DoneAt = p5.DoneAt,
IsDone = p5.IsDone,
PerformanceDescription = p5.PerformanceDescription,
Amount = p5.Amount,
AmountType = p5.AmountType,
Id = p5.Id
};
}
public static ActivitySDto AdaptTo(this Activity p6, ActivitySDto p7)
{
if (p6 == null)
{
return null;
}
ActivitySDto result = p7 ?? new ActivitySDto();
result.Type = p6.Type;
result.Title = p6.Title;
result.Description = p6.Description;
result.IsDisposable = p6.IsDisposable;
result.SetFor = p6.SetFor;
result.HasDisposed = p6.HasDisposed;
result.ScheduleType = p6.ScheduleType;
result.UnDoneReason = p6.UnDoneReason;
result.Status = p6.Status;
result.DoneAt = p6.DoneAt;
result.IsDone = p6.IsDone;
result.PerformanceDescription = p6.PerformanceDescription;
result.Amount = p6.Amount;
result.AmountType = p6.AmountType;
result.Id = p6.Id;
return result;
}
public static Expression<Func<Activity, ActivitySDto>> ProjectToSDto => p8 => new ActivitySDto()
{
FirstName = p8.UserFirstName,
LastName = p8.UserLastName
},
ShiftId = p8.ShiftId,
Shift = new Shift() {Id = p8.ShiftId},
Type = p8.Type,
Title = p8.Title,
Description = p8.Description,
@ -129,132 +89,220 @@ namespace Brizco.Domain.Mappers
SetFor = p8.SetFor,
HasDisposed = p8.HasDisposed,
ScheduleType = p8.ScheduleType,
UnDoneReason = p8.UnDoneReason,
Status = p8.Status,
DoneAt = p8.DoneAt,
IsDone = p8.IsDone,
PerformanceDescription = p8.PerformanceDescription,
Amount = p8.Amount,
AmountType = p8.AmountType,
Id = p8.Id
};
public static Activity AdaptToActivity(this ActivityLDto p9)
public static ActivitySDto AdaptToSDto(this Activity p9)
{
return p9 == null ? null : new Activity()
return p9 == null ? null : new ActivitySDto()
{
Status = p9.Status,
DoneAt = p9.DoneAt,
IsDone = p9.IsDone,
PerformanceDescription = p9.PerformanceDescription,
Type = p9.Type,
Title = p9.Title,
Description = p9.Description,
IsDisposable = p9.IsDisposable,
SetFor = p9.SetFor,
HasDisposed = p9.HasDisposed,
ScheduleType = p9.ScheduleType,
UnDoneReason = p9.UnDoneReason,
Status = p9.Status,
DoneAt = p9.DoneAt,
IsDone = p9.IsDone,
PerformanceDescription = p9.PerformanceDescription,
UserFirstName = p9.User != null ? p9.User.FirstName : string.Empty,
UserLastName = p9.User != null ? p9.User.LastName : string.Empty,
Amount = p9.Amount,
ShiftId = p9.ShiftId,
AmountType = p9.AmountType,
Id = p9.Id
};
}
public static Activity AdaptTo(this ActivityLDto p10, Activity p11)
public static ActivitySDto AdaptTo(this Activity p10, ActivitySDto p11)
{
if (p10 == null)
{
return null;
}
Activity result = p11 ?? new Activity();
ActivitySDto result = p11 ?? new ActivitySDto();
result.Status = p10.Status;
result.DoneAt = p10.DoneAt;
result.IsDone = p10.IsDone;
result.PerformanceDescription = p10.PerformanceDescription;
result.Type = p10.Type;
result.Title = p10.Title;
result.Description = p10.Description;
result.IsDisposable = p10.IsDisposable;
result.SetFor = p10.SetFor;
result.HasDisposed = p10.HasDisposed;
result.ScheduleType = p10.ScheduleType;
result.UnDoneReason = p10.UnDoneReason;
result.Status = p10.Status;
result.DoneAt = p10.DoneAt;
result.IsDone = p10.IsDone;
result.PerformanceDescription = p10.PerformanceDescription;
result.UserFirstName = p10.User != null ? p10.User.FirstName : string.Empty;
result.UserLastName = p10.User != null ? p10.User.LastName : string.Empty;
result.Amount = p10.Amount;
result.ShiftId = p10.ShiftId;
result.AmountType = p10.AmountType;
result.Id = p10.Id;
return result;
}
public static Expression<Func<ActivityLDto, Activity>> ProjectLDtoToActivity => p12 => new Activity()
public static Expression<Func<Activity, ActivitySDto>> ProjectToSDto => p12 => new ActivitySDto()
{
Status = p12.Status,
DoneAt = p12.DoneAt,
IsDone = p12.IsDone,
PerformanceDescription = p12.PerformanceDescription,
Type = p12.Type,
Title = p12.Title,
Description = p12.Description,
IsDisposable = p12.IsDisposable,
SetFor = p12.SetFor,
HasDisposed = p12.HasDisposed,
ScheduleType = p12.ScheduleType,
UnDoneReason = p12.UnDoneReason,
Status = p12.Status,
DoneAt = p12.DoneAt,
IsDone = p12.IsDone,
PerformanceDescription = p12.PerformanceDescription,
UserFirstName = p12.User != null ? p12.User.FirstName : string.Empty,
UserLastName = p12.User != null ? p12.User.LastName : string.Empty,
Amount = p12.Amount,
ShiftId = p12.ShiftId,
AmountType = p12.AmountType,
Id = p12.Id
};
public static ActivityLDto AdaptToLDto(this Activity p13)
public static Activity AdaptToActivity(this ActivityLDto p13)
{
return p13 == null ? null : new ActivityLDto()
return p13 == null ? null : new Activity()
{
Status = p13.Status,
DoneAt = p13.DoneAt,
IsDone = p13.IsDone,
PerformanceDescription = p13.PerformanceDescription,
Type = p13.Type,
Title = p13.Title,
Description = p13.Description,
IsDisposable = p13.IsDisposable,
SetFor = p13.SetFor,
HasDisposed = p13.HasDisposed,
Status = p13.Status,
DoneAt = p13.DoneAt,
IsDone = p13.IsDone,
PerformanceDescription = p13.PerformanceDescription,
Amount = p13.Amount,
AmountType = p13.AmountType,
Id = p13.Id
};
}
public static ActivityLDto AdaptTo(this Activity p14, ActivityLDto p15)
public static Activity AdaptTo(this ActivityLDto p14, Activity p15)
{
if (p14 == null)
{
return null;
}
ActivityLDto result = p15 ?? new ActivityLDto();
Activity result = p15 ?? new Activity();
result.Status = p14.Status;
result.DoneAt = p14.DoneAt;
result.IsDone = p14.IsDone;
result.PerformanceDescription = p14.PerformanceDescription;
result.Type = p14.Type;
result.Title = p14.Title;
result.Description = p14.Description;
result.IsDisposable = p14.IsDisposable;
result.SetFor = p14.SetFor;
result.HasDisposed = p14.HasDisposed;
result.Status = p14.Status;
result.DoneAt = p14.DoneAt;
result.IsDone = p14.IsDone;
result.PerformanceDescription = p14.PerformanceDescription;
result.Amount = p14.Amount;
result.AmountType = p14.AmountType;
result.Id = p14.Id;
return result;
}
public static Expression<Func<Activity, ActivityLDto>> ProjectToLDto => p16 => new ActivityLDto()
public static Expression<Func<ActivityLDto, Activity>> ProjectLDtoToActivity => p16 => new Activity()
{
Status = p16.Status,
DoneAt = p16.DoneAt,
IsDone = p16.IsDone,
PerformanceDescription = p16.PerformanceDescription,
Type = p16.Type,
Title = p16.Title,
Description = p16.Description,
IsDisposable = p16.IsDisposable,
SetFor = p16.SetFor,
HasDisposed = p16.HasDisposed,
Status = p16.Status,
DoneAt = p16.DoneAt,
IsDone = p16.IsDone,
PerformanceDescription = p16.PerformanceDescription,
Amount = p16.Amount,
AmountType = p16.AmountType,
Id = p16.Id
};
public static ActivityLDto AdaptToLDto(this Activity p17)
{
return p17 == null ? null : new ActivityLDto()
{
Type = p17.Type,
Title = p17.Title,
Description = p17.Description,
IsDisposable = p17.IsDisposable,
SetFor = p17.SetFor,
HasDisposed = p17.HasDisposed,
Status = p17.Status,
DoneAt = p17.DoneAt,
IsDone = p17.IsDone,
PerformanceDescription = p17.PerformanceDescription,
Amount = p17.Amount,
AmountType = p17.AmountType,
Id = p17.Id
};
}
public static ActivityLDto AdaptTo(this Activity p18, ActivityLDto p19)
{
if (p18 == null)
{
return null;
}
ActivityLDto result = p19 ?? new ActivityLDto();
result.Type = p18.Type;
result.Title = p18.Title;
result.Description = p18.Description;
result.IsDisposable = p18.IsDisposable;
result.SetFor = p18.SetFor;
result.HasDisposed = p18.HasDisposed;
result.Status = p18.Status;
result.DoneAt = p18.DoneAt;
result.IsDone = p18.IsDone;
result.PerformanceDescription = p18.PerformanceDescription;
result.Amount = p18.Amount;
result.AmountType = p18.AmountType;
result.Id = p18.Id;
return result;
}
public static Expression<Func<Activity, ActivityLDto>> ProjectToLDto => p20 => new ActivityLDto()
{
Type = p20.Type,
Title = p20.Title,
Description = p20.Description,
IsDisposable = p20.IsDisposable,
SetFor = p20.SetFor,
HasDisposed = p20.HasDisposed,
Status = p20.Status,
DoneAt = p20.DoneAt,
IsDone = p20.IsDone,
PerformanceDescription = p20.PerformanceDescription,
Amount = p20.Amount,
AmountType = p20.AmountType,
Id = p20.Id
};
private static ApplicationUser funcMain1(Never p4, ApplicationUser p5, ActivitySDto p2)
{
ApplicationUser result = p5 ?? new ApplicationUser();
result.FirstName = p2.UserFirstName;
result.LastName = p2.UserLastName;
return result;
}
private static Shift funcMain2(Never p6, Shift p7, ActivitySDto p2)
{
Shift result = p7 ?? new Shift();
result.Id = p2.ShiftId;
return result;
}
}
}

View File

@ -14,6 +14,9 @@ namespace Brizco.Domain.Mappers
{
return p1 == null ? null : new ShiftPlan()
{
IsCompleted = p1.IsCompleted,
CompletePercent = p1.CompletePercent,
CompleteDescription = p1.CompleteDescription,
ShiftId = p1.ShiftId,
Id = p1.Id
};
@ -26,6 +29,9 @@ namespace Brizco.Domain.Mappers
}
ShiftPlan result = p3 ?? new ShiftPlan();
result.IsCompleted = p2.IsCompleted;
result.CompletePercent = p2.CompletePercent;
result.CompleteDescription = p2.CompleteDescription;
result.ShiftId = p2.ShiftId;
result.Id = p2.Id;
return result;
@ -33,6 +39,9 @@ namespace Brizco.Domain.Mappers
}
public static Expression<Func<ShiftPlanSDto, ShiftPlan>> ProjectToShiftPlan => p4 => new ShiftPlan()
{
IsCompleted = p4.IsCompleted,
CompletePercent = p4.CompletePercent,
CompleteDescription = p4.CompleteDescription,
ShiftId = p4.ShiftId,
Id = p4.Id
};
@ -40,6 +49,9 @@ namespace Brizco.Domain.Mappers
{
return p5 == null ? null : new ShiftPlanSDto()
{
IsCompleted = p5.IsCompleted,
CompletePercent = p5.CompletePercent,
CompleteDescription = p5.CompleteDescription,
ShiftId = p5.ShiftId,
ShiftTitle = p5.Shift == null ? null : p5.Shift.Title,
Id = p5.Id
@ -53,6 +65,9 @@ namespace Brizco.Domain.Mappers
}
ShiftPlanSDto result = p7 ?? new ShiftPlanSDto();
result.IsCompleted = p6.IsCompleted;
result.CompletePercent = p6.CompletePercent;
result.CompleteDescription = p6.CompleteDescription;
result.ShiftId = p6.ShiftId;
result.ShiftTitle = p6.Shift == null ? null : p6.Shift.Title;
result.Id = p6.Id;
@ -61,6 +76,9 @@ namespace Brizco.Domain.Mappers
}
public static Expression<Func<ShiftPlan, ShiftPlanSDto>> ProjectToSDto => p8 => new ShiftPlanSDto()
{
IsCompleted = p8.IsCompleted,
CompletePercent = p8.CompletePercent,
CompleteDescription = p8.CompleteDescription,
ShiftId = p8.ShiftId,
ShiftTitle = p8.Shift.Title,
Id = p8.Id
@ -70,6 +88,9 @@ namespace Brizco.Domain.Mappers
return p9 == null ? null : new ShiftPlan()
{
PlanFor = p9.PlanFor,
IsCompleted = p9.IsCompleted,
CompletePercent = p9.CompletePercent,
CompleteDescription = p9.CompleteDescription,
ShiftId = p9.ShiftId,
RoutineId = p9.RoutineId,
Users = funcMain1(p9.Users),
@ -85,6 +106,9 @@ namespace Brizco.Domain.Mappers
ShiftPlan result = p12 ?? new ShiftPlan();
result.PlanFor = p11.PlanFor;
result.IsCompleted = p11.IsCompleted;
result.CompletePercent = p11.CompletePercent;
result.CompleteDescription = p11.CompleteDescription;
result.ShiftId = p11.ShiftId;
result.RoutineId = p11.RoutineId;
result.Users = funcMain2(p11.Users, result.Users);
@ -95,6 +119,9 @@ namespace Brizco.Domain.Mappers
public static Expression<Func<ShiftPlanLDto, ShiftPlan>> ProjectLDtoToShiftPlan => p15 => new ShiftPlan()
{
PlanFor = p15.PlanFor,
IsCompleted = p15.IsCompleted,
CompletePercent = p15.CompletePercent,
CompleteDescription = p15.CompleteDescription,
ShiftId = p15.ShiftId,
RoutineId = p15.RoutineId,
Users = p15.Users.Select<ShiftPlanUserSDto, ShiftPlanUser>(p16 => new ShiftPlanUser()
@ -112,6 +139,9 @@ namespace Brizco.Domain.Mappers
{
PlanFor = p17.PlanFor,
RoutineId = p17.RoutineId,
IsCompleted = p17.IsCompleted,
CompletePercent = p17.CompletePercent,
CompleteDescription = p17.CompleteDescription,
ShiftId = p17.ShiftId,
Users = funcMain3(p17.Users),
Id = p17.Id
@ -127,6 +157,9 @@ namespace Brizco.Domain.Mappers
result.PlanFor = p19.PlanFor;
result.RoutineId = p19.RoutineId;
result.IsCompleted = p19.IsCompleted;
result.CompletePercent = p19.CompletePercent;
result.CompleteDescription = p19.CompleteDescription;
result.ShiftId = p19.ShiftId;
result.Users = funcMain4(p19.Users, result.Users);
result.Id = p19.Id;
@ -137,6 +170,9 @@ namespace Brizco.Domain.Mappers
{
PlanFor = p23.PlanFor,
RoutineId = p23.RoutineId,
IsCompleted = p23.IsCompleted,
CompletePercent = p23.CompletePercent,
CompleteDescription = p23.CompleteDescription,
ShiftId = p23.ShiftId,
Users = p23.Users.Select<ShiftPlanUser, ShiftPlanUserSDto>(p24 => new ShiftPlanUserSDto()
{

View File

@ -1,7 +1,4 @@
using Brizco.Domain.Entities.Complex;
using Brizco.Domain.Entities.Shift;
using Mapster;
using Task = Brizco.Domain.Entities.Task.Task;
using Task = Brizco.Domain.Entities.Task.Task;
namespace Brizco.Domain;
@ -16,6 +13,10 @@ public class MapsterRegister : IRegister
.Map("Positions", o => o.Positions.Select(d => d.Position != null ? d.Position.Name : string.Empty))
.TwoWays();
config.NewConfig<Activity, ActivitySDto>()
.Map("UserFirstName", o => o.User !=null ? o.User.FirstName : string.Empty)
.Map("UserLastName", o => o.User != null ? o.User.LastName : string.Empty)
.TwoWays();
config.NewConfig<Task, TaskLDto>()
.Map("SetFor", o => DateTimeExtensions.DateTimeToUnixTimeStamp(o.SetFor))

View File

@ -45,6 +45,13 @@ public class SmsService : ISmsService
else
_logger.LogError(apiException.Message);
}
catch (Exception apiException)
{
if (_environment.IsProduction())
throw;
else
_logger.LogError(apiException.Message);
}
}
}

View File

@ -6,4 +6,6 @@ public interface ICurrentUserService : IScopedDependency
string? RoleName { get; }
string? ComplexId { get; }
string? UserName { get; }
string? RoleId { get; }
List<string>? Permissions { get; }
}

View File

@ -17,18 +17,32 @@ public class GetActivitiesQueryHandler : IRequestHandler<GetActivitiesQuery, Lis
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("ComplexId is wrong", ApiResultStatusCode.NotFound);
if(_currentUserService.UserId==null)
if (_currentUserService.UserId == null)
throw new AppException("UserId is null", ApiResultStatusCode.NotFound);
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("UserId is wrong", ApiResultStatusCode.NotFound);
var tasks = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>().TableNoTracking
.Where(a=>a.UserId == userId)
.OrderByDescending(s => s.CreatedAt)
IQueryable<Domain.Entities.Task.Activity> activites = _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>().TableNoTracking;
if (request.SelectedDate > 0)
{
var selectedDate = DateTimeExtensions.UnixTimeStampToDateTime(request.SelectedDate);
activites = activites.Where(a => a.ComplexId == complexId && a.SetFor.Date == selectedDate.Date);
}
if (request.SelectedShift != default)
activites = activites.Where(a => a.ComplexId == complexId && a.ShiftId == request.SelectedShift);
if (request.SelectedDate == 0 && request.SelectedShift == default)
activites = activites.Where(a => a.UserId == userId);
return await activites.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ActivityMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
return tasks;
}
}

View File

@ -1,4 +1,6 @@
namespace Brizco.Repository.Handlers.Shift;
using Brizco.Domain.Entities.Shift;
namespace Brizco.Repository.Handlers.Shift;
public class GetShiftPlansQueryHandler : IRequestHandler<GetShiftsQuery, List<ShiftSDto>>
{
@ -16,13 +18,49 @@ public class GetShiftPlansQueryHandler : IRequestHandler<GetShiftsQuery, List<Sh
throw new AppException("ComplexId is null", ApiResultStatusCode.NotFound);
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("ComplexId is wrong", ApiResultStatusCode.NotFound);
List<ShiftSDto> shifts = new List<ShiftSDto>();
if (request.SelectedDate > 0)
{
var selectedDate = DateTimeExtensions.UnixTimeStampToDateTime(request.SelectedDate);
var originalShifts = from shiftDay in _repositoryWrapper.SetRepository<ShiftDay>().Entities
join shift in _repositoryWrapper.SetRepository<Domain.Entities.Shift.Shift>().Entities on shiftDay .ShiftId equals shift.Id
where shiftDay.DayOfWeek == selectedDate.DayOfWeek && shift.ComplexId == complexId
select shift;
shifts = await originalShifts.AsNoTracking().Select(ShiftMapper.ProjectToSDto).ToListAsync(cancellationToken);
foreach (var shift in shifts)
{
var activitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.SetFor.Date == selectedDate.Date && a.ShiftId == shift.Id, cancellationToken);
var doneActivitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.Status == ActivityStatus.Done && a.SetFor.Date == selectedDate.Date && a.ShiftId == shift.Id, cancellationToken);
var undoneActivitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.Status == ActivityStatus.UnDone && a.SetFor.Date == selectedDate.Date && a.ShiftId == shift.Id, cancellationToken);
shift.UndoneActivitiesCount = undoneActivitiesCount;
shift.DoneActivitiesCount = doneActivitiesCount;
shift.TotalActivitiesCount = activitiesCount;
var existedShiftPlan = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>()
.TableNoTracking
.FirstOrDefaultAsync(s => s.ShiftId == shift.Id && s.PlanFor.Date == selectedDate.Date, cancellationToken);
shift.IsCompleted = existedShiftPlan is { IsCompleted : true };
}
}
else
{
shifts = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.Shift>().TableNoTracking
.Where(s => s.ComplexId == complexId)
.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ShiftMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
}
var shifts = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.Shift>().TableNoTracking
.Where(s=>s.ComplexId==complexId)
.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ShiftMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
return shifts;

View File

@ -3,9 +3,12 @@
public class CreateShiftPlanCommandHandler : IRequestHandler<CreateShiftPlanCommand, ShiftPlanLDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public CreateShiftPlanCommandHandler(IRepositoryWrapper repositoryWrapper)
private readonly ICurrentUserService _currentUserService;
public CreateShiftPlanCommandHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<ShiftPlanLDto> Handle(CreateShiftPlanCommand request, CancellationToken cancellationToken)
{
@ -15,11 +18,18 @@ public class CreateShiftPlanCommandHandler : IRequestHandler<CreateShiftPlanComm
if (shift == null)
throw new AppException("Shift not found", ApiResultStatusCode.NotFound);
var planFor = DateTimeExtensions.UnixTimeStampToDateTime(request.PlanDate);
var existedShiftPlan = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>()
.TableNoTracking
.FirstOrDefaultAsync(s => s.ShiftId == request.ShiftId && s.PlanFor.Date == planFor.Date, cancellationToken);
if (existedShiftPlan != null)
throw new AppException("Shift plan is exist for this date , you can update existed shift plan", ApiResultStatusCode.BadRequest);
try
{
await _repositoryWrapper.BeginTransaction(cancellationToken);
var shiftPlan = shift.AddPlan(DateTimeExtensions.UnixTimeStampToDateTime(request.PlanDate),request.RoutineId);
var shiftPlan = shift.AddPlan(planFor , request.RoutineId);
if (request.UserAndPositionIds.Count == 0)
throw new AppException("شیفت بندی مورد نظر باید حداقل متشکل از یک فرد باشد", ApiResultStatusCode.BadRequest);

View File

@ -1,4 +1,6 @@
namespace Brizco.Repository.Handlers.ShiftPlan;
using Brizco.Domain.Entities.Shift;
namespace Brizco.Repository.Handlers.ShiftPlan;
public class GetShiftPlansQueryHandler : IRequestHandler<GetShiftPlansQuery, List<ShiftPlanSDto>>
{
@ -12,14 +14,43 @@ public class GetShiftPlansQueryHandler : IRequestHandler<GetShiftPlansQuery, Lis
}
public async Task<List<ShiftPlanSDto>> Handle(GetShiftPlansQuery request, CancellationToken cancellationToken)
{
throw new NotImplementedException();
List<ShiftPlanSDto> shiftPlans;
if (request.SelectedDate > 0)
{
var selectedDate = DateTimeExtensions.UnixTimeStampToDateTime(request.SelectedDate);
shiftPlans = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>()
.TableNoTracking
.Where(s => s.PlanFor.Date == selectedDate.Date)
.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ShiftPlanMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
foreach (var shiftPlan in shiftPlans)
{
var activitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.SetFor.Date == selectedDate.Date && a.ShiftId == shiftPlan.Id, cancellationToken);
var doneActivitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.Status == ActivityStatus.Done && a.SetFor.Date == selectedDate.Date && a.ShiftId == shiftPlan.Id, cancellationToken);
var undoneActivitiesCount = await _repositoryWrapper.SetRepository<Domain.Entities.Task.Activity>()
.TableNoTracking
.CountAsync(a => a.Status == ActivityStatus.UnDone && a.SetFor.Date == selectedDate.Date && a.ShiftId == shiftPlan.Id, cancellationToken);
shiftPlan.UndoneActivitiesCount = undoneActivitiesCount;
shiftPlan.DoneActivitiesCount = doneActivitiesCount;
shiftPlan.TotalActivitiesCount = activitiesCount;
}
var shifts = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>().TableNoTracking
.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ShiftPlanMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
}
else
{
shiftPlans = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>().TableNoTracking
.OrderByDescending(s => s.CreatedAt)
.Skip(request.Page * 15).Take(15)
.Select(ShiftPlanMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
}
return shifts;
return shiftPlans;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Brizco.Repository.Migrations
{
/// <inheritdoc />
public partial class editShiftPlanAddComplexId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "ComplexId",
schema: "public",
table: "ShiftPlans",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.CreateIndex(
name: "IX_ShiftPlans_ComplexId",
schema: "public",
table: "ShiftPlans",
column: "ComplexId");
migrationBuilder.AddForeignKey(
name: "FK_ShiftPlans_Complexes_ComplexId",
schema: "public",
table: "ShiftPlans",
column: "ComplexId",
principalSchema: "public",
principalTable: "Complexes",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ShiftPlans_Complexes_ComplexId",
schema: "public",
table: "ShiftPlans");
migrationBuilder.DropIndex(
name: "IX_ShiftPlans_ComplexId",
schema: "public",
table: "ShiftPlans");
migrationBuilder.DropColumn(
name: "ComplexId",
schema: "public",
table: "ShiftPlans");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Brizco.Repository.Migrations
{
/// <inheritdoc />
public partial class editShiftPlanAddComplete : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "CompleteDescription",
schema: "public",
table: "ShiftPlans",
type: "text",
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<int>(
name: "CompletePercent",
schema: "public",
table: "ShiftPlans",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<bool>(
name: "IsCompleted",
schema: "public",
table: "ShiftPlans",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CompleteDescription",
schema: "public",
table: "ShiftPlans");
migrationBuilder.DropColumn(
name: "CompletePercent",
schema: "public",
table: "ShiftPlans");
migrationBuilder.DropColumn(
name: "IsCompleted",
schema: "public",
table: "ShiftPlans");
}
}
}

View File

@ -412,6 +412,16 @@ namespace Brizco.Repository.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CompleteDescription")
.IsRequired()
.HasColumnType("text");
b.Property<int>("CompletePercent")
.HasColumnType("integer");
b.Property<Guid>("ComplexId")
.HasColumnType("uuid");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp without time zone");
@ -419,6 +429,9 @@ namespace Brizco.Repository.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCompleted")
.HasColumnType("boolean");
b.Property<bool>("IsRemoved")
.HasColumnType("boolean");
@ -447,6 +460,8 @@ namespace Brizco.Repository.Migrations
b.HasKey("Id");
b.HasIndex("ComplexId");
b.HasIndex("RoutineId");
b.HasIndex("ShiftId");
@ -1181,6 +1196,12 @@ namespace Brizco.Repository.Migrations
modelBuilder.Entity("Brizco.Domain.Entities.Shift.ShiftPlan", b =>
{
b.HasOne("Brizco.Domain.Entities.Complex.Complex", "Complex")
.WithMany()
.HasForeignKey("ComplexId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Brizco.Domain.Entities.Routine.Routine", "Routine")
.WithMany()
.HasForeignKey("RoutineId")
@ -1193,6 +1214,8 @@ namespace Brizco.Repository.Migrations
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Complex");
b.Navigation("Routine");
b.Navigation("Shift");