commit codes befor new features and bugs

master
Amir Hossein Khademi 2024-06-30 22:29:57 +03:30
parent 97cb9ae82b
commit 3034cb6d65
21 changed files with 129 additions and 5078 deletions

View File

@ -1 +1 @@
1.0.0.1 1.0.1.2

View File

@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath> <DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
<AssemblyVersion>1.0.0.1</AssemblyVersion> <AssemblyVersion>1.0.1.2</AssemblyVersion>
<FileVersion>1.0.0.1</FileVersion> <FileVersion>1.0.1.2</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -112,8 +112,28 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Services\" /> <Folder Include="Services\" />
<Folder Include="wwwroot\" /> </ItemGroup>
<Folder Include="wwwroot\assets\vendor\bootstrap\css\" /> <ItemGroup>
<None Include="wwwroot\assets\vendor\aos\aos.js" />
<None Include="wwwroot\assets\vendor\bootstrap\css\bootstrap.css.map" />
<None Include="wwwroot\assets\vendor\bootstrap\css\bootstrap.min.css.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.bundle.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.bundle.js.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.bundle.min.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.bundle.min.js.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.esm.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.esm.js.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.esm.min.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.esm.min.js.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.js.map" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.min.js" />
<None Include="wwwroot\assets\vendor\bootstrap\js\bootstrap.min.js.map" />
<None Include="wwwroot\assets\vendor\boxicons\fonts\boxicons.svg" />
<None Include="wwwroot\assets\vendor\boxicons\fonts\boxicons.woff2" />
<None Include="wwwroot\assets\vendor\glightbox\js\glightbox.js" />
<None Include="wwwroot\assets\vendor\glightbox\js\glightbox.min.js" />
<None Include="wwwroot\assets\vendor\waypoints\noframework.waypoints.js" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Brizco.Infrastructure\Brizco.Infrastructure.csproj" /> <ProjectReference Include="..\Brizco.Infrastructure\Brizco.Infrastructure.csproj" />

View File

@ -0,0 +1,41 @@
using Brizco.Core.MartenServices.Abstracts;
using System.Text.Json;
namespace Brizco.Api.Controllers;
public class BrewController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Brews")
.MapGroup("api/brew")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("{brewName}/latest", GetLatestBrewAsync)
.WithDisplayName("Get Latest Brew")
.WithDescription("Get latest brew that has been set for day , you have pass recipe name in route")
.HasApiVersion(1.0);
group.MapGet("{brewName}", GetBrewAsync)
.WithDisplayName("Get Brew")
.WithDescription("Get brew that has been set for days , you have pass recipe name in route")
.HasApiVersion(1.0);
group.MapPost("{brewName}", AddBrewAsync)
.WithDisplayName("Add Brew")
.WithDescription("Add latest brew that has been set for day , you have pass recipe model")
.HasApiVersion(1.0);
}
private async Task<IResult> GetLatestBrewAsync([FromRoute] string brewName, [FromServices] IBrewService brewService, CancellationToken cancellationToken)
=> TypedResults.Ok(await brewService.GetLastBrewAsync(brewName, cancellationToken));
private async Task<IResult> GetBrewAsync([FromRoute] string brewName, [FromServices] IBrewService brewService, CancellationToken cancellationToken)
=> TypedResults.Ok(await brewService.GetBrewAsync(brewName, cancellationToken));
private async Task<IResult> AddBrewAsync([FromRoute] string brewName, [FromBody] JsonDocument recipeObj, [FromServices] IBrewService brewService, CancellationToken cancellationToken)
{
await brewService.AddBrewAsync(brewName, recipeObj, cancellationToken);
return TypedResults.Ok();
}
}

View File

@ -1,36 +0,0 @@
using Brizco.Core.MartenServices.Abstracts;
using Marten;
using System.Text.Json;
namespace Brizco.Api.Controllers;
public class RecipeController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Brews")
.MapGroup("api/brew");
group.MapGet("{recipeName}/latest", GetLatestBrewAsync)
.WithDisplayName("Get Latest Brew")
.WithDescription("Get latest brew that has been set for day , you have pass recipe name in route")
.HasApiVersion(1.0);
group.MapPost("{recipeName}", AddBrewAsync)
.WithDisplayName("Add Brew")
.WithDescription("Add latest brew that has been set for day , you have pass recipe model")
.HasApiVersion(1.0);
}
private async Task<IResult> GetLatestBrewAsync([FromRoute] string recipeName,
[FromServices] IBrewService brewService, CancellationToken cancellationToken)
=> TypedResults.Ok(await brewService.GetLastBrewAsync(recipeName, cancellationToken));
private async Task<IResult> AddBrewAsync([FromRoute] string recipeName,
[FromBody] JsonDocument recipeObj, [FromServices] IBrewService brewService,
CancellationToken cancellationToken)
{
await brewService.AddBrewAsync(recipeName, recipeObj, cancellationToken);
return TypedResults.Ok();
}
}

View File

@ -91,7 +91,7 @@ var app = builder.Build();
app.UseCors("CorsPolicy"); app.UseCors("CorsPolicy");
app.UseSwagger(); app.UseCustomSwagger(siteSetting.BaseUrl);
app.MapScalarUi(); app.MapScalarUi();
app.UseAuthorization(); app.UseAuthorization();

View File

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

View File

@ -131,6 +131,10 @@ public class ExceptionHandlerMiddleware
Formatting = Formatting.Indented Formatting = Formatting.Indented
}); });
if (httpStatusCode == HttpStatusCode.InternalServerError)
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
else
context.Response.StatusCode = (int)httpStatusCode; context.Response.StatusCode = (int)httpStatusCode;
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
await context.Response.WriteAsync(json); await context.Response.WriteAsync(json);

View File

@ -27,7 +27,7 @@ public static class ScalarUiConfiguration
<!-- Optional: You can set a full configuration object like this: --> <!-- Optional: You can set a full configuration object like this: -->
<script> <script>
var configuration = { var configuration = {
theme: 'purple', theme: 'bluePlanet',
} }
document.getElementById('api-reference').dataset.configuration = document.getElementById('api-reference').dataset.configuration =

View File

@ -1,7 +0,0 @@
<!DOCTYPE html>
<div class="sidebar">
<a class="active" href="#home">Home</a>
<a href="#news">News</a>
<a href="#contact">Contact</a>
<a href="#about">About</a>
</div>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
namespace Brizco.Common.Models.Claims; namespace Brizco.Common.Models.Claims;
public static class ApplicationPermission public static class ApplicationPermission
{ {
public const string ManageCoffeeBrew = nameof(ManageCoffeeBrew);
public const string ViewRecipes = nameof(ViewRecipes); public const string ViewRecipes = nameof(ViewRecipes);
public const string ManageRecipes = nameof(ManageRecipes); public const string ManageRecipes = nameof(ManageRecipes);

View File

@ -2,6 +2,6 @@
public interface IPageService : IScopedDependency public interface IPageService : IScopedDependency
{ {
Task<AppDashboardPageDto> GetAppDashboardAsync(CancellationToken cancellationToken); Task<AppDashboardPageDto> GetAppDashboardAsync(CancellationToken cancellationToken = default);
Task<List<AppShiftingPageDayDto>> GetShiftingPageAsync(Guid routineId,CancellationToken cancellationToken); Task<List<AppShiftingPageDayDto>> GetShiftingPageAsync(Guid routineId,CancellationToken cancellationToken = default);
} }

View File

@ -158,6 +158,7 @@ public class JwtService : IJwtService
if (baseUser.Email != null) if (baseUser.Email != null)
claims.Add(new Claim(ClaimTypes.Email, baseUser.Email)); claims.Add(new Claim(ClaimTypes.Email, baseUser.Email));
claims.Add(new Claim(ClaimTypes.Gender, baseUser.Gender == 0 ? "Female" : "Mail")); claims.Add(new Claim(ClaimTypes.Gender, baseUser.Gender == 0 ? "Female" : "Mail"));
claims.Add(new Claim("FullName", baseUser.FirstName + " " + baseUser.LastName));
return claims; return claims;
} }
@ -177,6 +178,7 @@ public class JwtService : IJwtService
claims.AddRange(roleClaims); claims.AddRange(roleClaims);
claims.Add(new Claim("JwtID", jwtId)); claims.Add(new Claim("JwtID", jwtId));
claims.Add(new Claim(ClaimTypes.Gender, baseUser.Gender == 0 ? "Female" : "Mail")); claims.Add(new Claim(ClaimTypes.Gender, baseUser.Gender == 0 ? "Female" : "Mail"));
claims.Add(new Claim("FullName",baseUser.FirstName+ " " +baseUser.LastName));
return claims; return claims;
} }

View File

@ -2,6 +2,7 @@
using Brizco.Domain.Entities.Routine; using Brizco.Domain.Entities.Routine;
using Brizco.Domain.Entities.Shift; using Brizco.Domain.Entities.Shift;
using Task = Brizco.Domain.Entities.Task.Task; using Task = Brizco.Domain.Entities.Task.Task;
using System.Linq;
namespace Brizco.Core.CoreServices; namespace Brizco.Core.CoreServices;
@ -23,7 +24,7 @@ public class PageService : IPageService
_roleManager = roleManager; _roleManager = roleManager;
_mediator = mediator; _mediator = mediator;
} }
public async Task<AppDashboardPageDto> GetAppDashboardAsync(CancellationToken cancellationToken) public async Task<AppDashboardPageDto> GetAppDashboardAsync(CancellationToken cancellationToken = default)
{ {
if (_currentUserService.UserId == null) if (_currentUserService.UserId == null)
throw new AppException("User id is null "); throw new AppException("User id is null ");
@ -32,7 +33,7 @@ public class PageService : IPageService
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Complex id is wrong"); throw new AppException("Complex id is wrong");
var todayTasks = await _repositoryWrapper.SetRepository<Activity>() var todayActivities = await _repositoryWrapper.SetRepository<Activity>()
.TableNoTracking .TableNoTracking
.Where(a => a.ComplexId == complexId && a.SetFor.Date == DateTime.Today.Date) .Where(a => a.ComplexId == complexId && a.SetFor.Date == DateTime.Today.Date)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@ -42,22 +43,31 @@ public class PageService : IPageService
.Select(ShiftPlanMapper.ProjectToSDto) .Select(ShiftPlanMapper.ProjectToSDto)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
foreach (var shiftPlan in todayShiftPlans)
{
shiftPlan.DoneActivitiesCount = todayActivities.Count(a=>a.ShiftPlanId == shiftPlan.Id && a.IsDone);
shiftPlan.UndoneActivitiesCount = todayActivities.Count(a=>a.ShiftPlanId == shiftPlan.Id && !a.IsDone);
shiftPlan.TotalActivitiesCount = todayActivities.Count(a=>a.ShiftPlanId == shiftPlan.Id );
}
var names = new List<string>(); var names = new List<string>();
names.AddRange(todayShiftPlans.SelectMany(sp => sp.Users).Select(s => s.UserFullName).ToList()); names.AddRange(todayShiftPlans.SelectMany(sp => sp.Users).Select(s => s.UserFullName).ToList());
var page = new AppDashboardPageDto var page = new AppDashboardPageDto
{ {
DoneActivitiesToday = todayTasks.Count(t => t.IsDone), DoneActivitiesToday = todayActivities.Count(t => t.IsDone),
TotalActivitiesToday = todayTasks.Count, TotalActivitiesToday = todayActivities.Count,
UnDoneActivitiesToday = todayTasks.Count(t => t.IsDone!), UnDoneActivitiesToday = todayActivities.Count(t => t.IsDone!),
TotalShiftToday = todayShiftPlans.Count, TotalShiftToday = todayShiftPlans.Count,
TodayStaffNames = names, TodayStaffNames = names,
TotalStaffToday = todayShiftPlans.SelectMany(sp => sp.Users).GroupBy(u=>u.UserId).Count() TotalStaffToday = todayShiftPlans.SelectMany(sp => sp.Users).GroupBy(u=>u.UserId).Count(),
ShiftPlans = todayShiftPlans
}; };
var currentShift = todayShiftPlans.FirstOrDefault(s => s.EndAt >= DateTime.Now.TimeOfDay && s.StartAt <= DateTime.Now.TimeOfDay); var currentShift = todayShiftPlans.FirstOrDefault(s => s.EndAt >= DateTime.Now.TimeOfDay && s.StartAt <= DateTime.Now.TimeOfDay);
if (currentShift != null) if (currentShift != null)
{ {
page.CurrentShift = currentShift.ShiftTitle; page.CurrentShift = currentShift.ShiftTitle;
page.CurrentShiftId = currentShift.Id;
page.CurrentPosition = currentShift.Users.FirstOrDefault(f => f.UserId == userId)?.PositionName ?? string.Empty; page.CurrentPosition = currentShift.Users.FirstOrDefault(f => f.UserId == userId)?.PositionName ?? string.Empty;
} }
@ -173,7 +183,7 @@ public class PageService : IPageService
return page; return page;
} }
public async Task<List<AppShiftingPageDayDto>> GetShiftingPageAsync(Guid routineId,CancellationToken cancellationToken) public async Task<List<AppShiftingPageDayDto>> GetShiftingPageAsync(Guid routineId,CancellationToken cancellationToken = default)
{ {
if (_currentUserService.ComplexId == null) if (_currentUserService.ComplexId == null)
throw new AppException("ComplexId is null", ApiResultStatusCode.NotFound); throw new AppException("ComplexId is null", ApiResultStatusCode.NotFound);

View File

@ -15,7 +15,7 @@ public class BrewService : IBrewService
} }
public async Task<object> GetLastBrewAsync(string recipeName, CancellationToken cancellationToken = default) public async Task<object> GetLastBrewAsync(string recipeName, CancellationToken cancellationToken = default)
{ {
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Brews.{recipeName}");
if (type == null) if (type == null)
throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); throw new AppException("Recipe not found", ApiResultStatusCode.NotFound);
if (_currentUserService.ComplexId == null) if (_currentUserService.ComplexId == null)
@ -39,7 +39,7 @@ public class BrewService : IBrewService
public async Task<BaseRecipeLDto> GetBrewAsync(string recipeName, CancellationToken cancellationToken = default) public async Task<BaseRecipeLDto> GetBrewAsync(string recipeName, CancellationToken cancellationToken = default)
{ {
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Brews.{recipeName}");
if (type == null) if (type == null)
throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); throw new AppException("Recipe not found", ApiResultStatusCode.NotFound);
if (_currentUserService.ComplexId == null) if (_currentUserService.ComplexId == null)
@ -81,7 +81,7 @@ public class BrewService : IBrewService
public async Task AddBrewAsync(string recipeName, JsonDocument recipeObj, CancellationToken cancellationToken = default) public async Task AddBrewAsync(string recipeName, JsonDocument recipeObj, CancellationToken cancellationToken = default)
{ {
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Recipes.{recipeName}"); var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Brizco.Domain.MartenEntities.Brews.{recipeName}");
if (type == null) if (type == null)
throw new AppException("Recipe not found", ApiResultStatusCode.NotFound); throw new AppException("Recipe not found", ApiResultStatusCode.NotFound);
@ -90,6 +90,9 @@ public class BrewService : IBrewService
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
if (_currentUserService.FullName == null)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Full name is null");
var baseRecipe = await _martenRepositoryWrapper.SetRepository<BaseBrew>() var baseRecipe = await _martenRepositoryWrapper.SetRepository<BaseBrew>()
.GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken); .GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken);
@ -97,16 +100,28 @@ public class BrewService : IBrewService
{ {
baseRecipe = new BaseBrew() baseRecipe = new BaseBrew()
{ {
CurrentBrewJson = JsonConvert.SerializeObject(recipeObj.Deserialize(type)),
Name = recipeName, Name = recipeName,
DotnetType = type.FullName ?? $"Brizco.Domain.MartenEntities.Recipes.{recipeName}", DotnetType = type.FullName ?? $"Brizco.Domain.MartenEntities.Brews.{recipeName}",
ComplexId = complexId ComplexId = complexId
}; };
var current = recipeObj.Deserialize(type, new JsonSerializerOptions(JsonSerializerDefaults.Web));
if (current is IBaseBrew brew)
{
brew.LogAt = DateTime.Now;
brew.LogBy = _currentUserService.FullName;
baseRecipe.CurrentBrewJson = JsonConvert.SerializeObject(current);
}
} }
else else
{ {
baseRecipe.PastBrewsJson.Add(baseRecipe.CurrentBrewJson); var current = recipeObj.Deserialize(type,new JsonSerializerOptions(JsonSerializerDefaults.Web));
baseRecipe.CurrentBrewJson = JsonConvert.SerializeObject(recipeObj.Deserialize(type)); if (current is IBaseBrew brew)
{
brew.LogAt = DateTime.Now;
brew.LogBy = _currentUserService.FullName;
baseRecipe.PastBrewsJson.Insert(0,baseRecipe.CurrentBrewJson);
baseRecipe.CurrentBrewJson = JsonConvert.SerializeObject(current);
}
} }
await _martenRepositoryWrapper.SetRepository<BaseBrew>() await _martenRepositoryWrapper.SetRepository<BaseBrew>()

View File

@ -10,6 +10,8 @@ public class AppDashboardPageDto
public List<string> TodayStaffNames { get; set; } = new(); public List<string> TodayStaffNames { get; set; } = new();
public string CurrentPosition { get; set; } = string.Empty; public string CurrentPosition { get; set; } = string.Empty;
public string CurrentShift { get; set; } = string.Empty; public string CurrentShift { get; set; } = string.Empty;
public Guid CurrentShiftId { get; set; }
public List<ShiftPlanSDto> ShiftPlans { get; set; } = new();
public string CurrentSignUpStep { get; set; } = string.Empty; public string CurrentSignUpStep { get; set; } = string.Empty;

View File

@ -7,3 +7,9 @@ public class BaseBrew : MartenEntity
public string DotnetType { get; set; } = string.Empty; public string DotnetType { get; set; } = string.Empty;
public List<string> PastBrewsJson { get; set; } = new(); public List<string> PastBrewsJson { get; set; } = new();
} }
public interface IBaseBrew
{
DateTime LogAt { get; set; }
string LogBy { get; set; }
}

View File

@ -1,6 +1,6 @@
namespace Brizco.Domain.MartenEntities.Brews; namespace Brizco.Domain.MartenEntities.Brews;
public class CoffeeBrew public class CoffeeBrew : IBaseBrew
{ {
public DateTime LogAt { get; set; } public DateTime LogAt { get; set; }
public string LogBy { get; set; } = string.Empty; public string LogBy { get; set; } = string.Empty;

View File

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