Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
ProjectsStatusManagement
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hasan.bahjat
ProjectsStatusManagement
Commits
24de3ed6
Commit
24de3ed6
authored
Sep 05, 2024
by
hasan khaddour
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
final commit
parent
0b7ddf50
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
227 additions
and
37 deletions
+227
-37
DependencyInjection.cs
PSManagement.Api/DependencyInjection/DependencyInjection.cs
+9
-0
ExceptionHandlingMidllerware.cs
...ddleware/ExceptionHandler/ExceptionHandlingMidllerware.cs
+78
-0
PSManagement.Api.csproj
PSManagement.Api/PSManagement.Api.csproj
+0
-4
Startup.cs
PSManagement.Api/Startup.cs
+5
-0
fdgfga9cbfa7f-d706-4655-9ef7-725fc73efcc9.png
...oot/uploads/fdgfga9cbfa7f-d706-4655-9ef7-725fc73efcc9.png
+0
-0
دراسة الجدوى65f0868a-4109-4519-8eaf-1544e4f25f10.png
...oads/دراسة الجدوى65f0868a-4109-4519-8eaf-1544e4f25f10.png
+0
-0
دراسة الجدوى6995b7e2-7cd0-4892-a421-83ea5acfef0b.png
...oads/دراسة الجدوى6995b7e2-7cd0-4892-a421-83ea5acfef0b.png
+0
-0
متطلبات الجهة الطارحة59fd3b86-5237-4fd4-954c-261c7192b5ef.png
...بات الجهة الطارحة59fd3b86-5237-4fd4-954c-261c7192b5ef.png
+0
-0
FinanialSpendingDTOMapperConfiguration.cs
...rsConfiguration/FinanialSpendingDTOMapperConfiguration.cs
+5
-0
UpdateFinancialSpendItemCommandHandler.cs
...ialSpendingItem/UpdateFinancialSpendItemCommandHandler.cs
+9
-1
AddAttachmentCommandHandler.cs
...ses/Commands/AddAttachment/AddAttachmentCommandHandler.cs
+3
-1
AddParticipantCommandHandler.cs
...s/Commands/AddParticipant/AddParticipantCommandHandler.cs
+3
-1
CreateProjectCommandHandler.cs
...ses/Commands/CreateProject/CreateProjectCommandHandler.cs
+2
-0
RemoveTypeCommandHandler.cs
.../UseCases/Commands/RemoveType/RemoveTypeCommandHandler.cs
+5
-2
RolesNames.cs
PSManagement.Domain/Identity/Constants/RolesNames.cs
+1
-1
Project.cs
PSManagement.Domain/Projects/Entities/Project.cs
+6
-2
ProjectTypesErrors.cs
...t.Domain/ProjectsTypes/DomainErrors/ProjectTypesErrors.cs
+3
-1
FileService.cs
PSManagement.Infrastructure/Storage/FileService.cs
+21
-1
ProjectsController.cs
...t.Presentation/Controllers/Projects/ProjectsController.cs
+15
-1
TracksController.cs
...ement.Presentation/Controllers/Tracks/TracksController.cs
+41
-22
Readme.md
Readme.md
+21
-0
No files found.
PSManagement.Api/DependencyInjection/DependencyInjection.cs
View file @
24de3ed6
...
...
@@ -17,6 +17,7 @@ namespace PSManagement.Api.DI
services
.
AddApiSwagger
()
.
AddApiCors
()
.
AddMyMiddlewares
()
;
return
services
;
...
...
@@ -87,6 +88,14 @@ namespace PSManagement.Api.DI
}
#
endregion
Cors
#
region
Middlewares
private
static
IServiceCollection
AddMyMiddlewares
(
this
IServiceCollection
services
)
{
return
services
;
}
#
endregion
Middlewares
}
...
...
PSManagement.Api/Middleware/ExceptionHandler/ExceptionHandlingMidllerware.cs
0 → 100644
View file @
24de3ed6
using
Microsoft.AspNetCore.Http
;
using
Microsoft.AspNetCore.Mvc
;
using
Microsoft.Extensions.Logging
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
namespace
PSManagement.Api.Middleware.ExceptionHandler
{
public
class
ExceptionHandlingMidllerware
{
private
readonly
RequestDelegate
_next
;
private
readonly
ILogger
<
ExceptionHandlingMidllerware
>
_logger
;
public
ExceptionHandlingMidllerware
(
RequestDelegate
next
,
ILogger
<
ExceptionHandlingMidllerware
>
logger
)
{
_next
=
next
;
_logger
=
logger
;
}
public
async
Task
InvokeAsync
(
HttpContext
context
)
{
try
{
await
_next
(
context
);
}
catch
(
Exception
exception
)
{
_logger
.
LogError
(
exception
,
"Exception occurred: {Message}"
,
exception
.
Message
);
var
exceptionDetails
=
GetExceptionDetails
(
exception
);
var
problemDetails
=
new
ProblemDetails
{
Status
=
exceptionDetails
.
Status
,
Type
=
exceptionDetails
.
Type
,
Title
=
exceptionDetails
.
Title
,
Detail
=
exceptionDetails
.
Detail
};
if
(
exceptionDetails
.
Errors
is
not
null
)
{
problemDetails
.
Extensions
[
"errors"
]
=
exceptionDetails
.
Errors
;
}
context
.
Response
.
StatusCode
=
exceptionDetails
.
Status
;
await
context
.
Response
.
WriteAsJsonAsync
(
problemDetails
);
}
}
private
static
ExceptionDetails
GetExceptionDetails
(
Exception
exception
)
{
return
exception
switch
{
_
=>
new
ExceptionDetails
(
StatusCodes
.
Status500InternalServerError
,
"ServerError"
,
"Server error"
,
"An unexpected error has occurred"
,
null
)
};
}
internal
record
ExceptionDetails
(
int
Status
,
string
Type
,
string
Title
,
string
Detail
,
IEnumerable
<
object
>?
Errors
);
}
}
PSManagement.Api/PSManagement.Api.csproj
View file @
24de3ed6
...
...
@@ -32,8 +32,4 @@
<ProjectReference Include="..\PSManagement.SharedKernel\PSManagement.SharedKernel.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Middleware\ExceptionHandler\" />
</ItemGroup>
</Project>
PSManagement.Api/Startup.cs
View file @
24de3ed6
...
...
@@ -15,6 +15,7 @@ using System.Threading.Tasks;
using
PSManagement.Infrastructure.Persistence.DI
;
using
PSManagement.Api.DI
;
using
PSManagement.Presentation.DependencyInjection
;
using
PSManagement.Api.Middleware.ExceptionHandler
;
namespace
PSManagement.Api
{
...
...
@@ -50,6 +51,10 @@ namespace PSManagement.Api
app
.
UseSwagger
();
app
.
UseSwaggerUI
(
c
=>
c
.
SwaggerEndpoint
(
"/swagger/v1/swagger.json"
,
"PSManagement.Api v1"
));
}
else
{
app
.
UseMiddleware
<
ExceptionHandlingMidllerware
>();
}
app
.
UseHttpsRedirection
();
app
.
UseStaticFiles
();
...
...
PSManagement.Api/wwwroot/uploads/fdgfga9cbfa7f-d706-4655-9ef7-725fc73efcc9.png
0 → 100644
View file @
24de3ed6
144 KB
PSManagement.Api/wwwroot/uploads/دراسة الجدوى65f0868a-4109-4519-8eaf-1544e4f25f10.png
0 → 100644
View file @
24de3ed6
30 KB
PSManagement.Api/wwwroot/uploads/دراسة الجدوى6995b7e2-7cd0-4892-a421-83ea5acfef0b.png
0 → 100644
View file @
24de3ed6
30 KB
PSManagement.Api/wwwroot/uploads/متطلبات الجهة الطارحة59fd3b86-5237-4fd4-954c-261c7192b5ef.png
0 → 100644
View file @
24de3ed6
144 KB
PSManagement.Application/ApplicationMappersConfiguration/FinanialSpendingDTOMapperConfiguration.cs
View file @
24de3ed6
...
...
@@ -2,6 +2,7 @@
using
PSManagement.Application.FinancialSpends.Common
;
using
PSManagement.Application.FinancialSpends.UseCases.Commands.CreateFinancialSpendItem
;
using
PSManagement.Domain.FinancialSpends.Entities
;
using
PSManagement.Application.FinancialSpends.UseCases.Commands.UpateFinancialSpendingItem
;
namespace
PSManagement.Application.Mappers
{
...
...
@@ -27,6 +28,10 @@ namespace PSManagement.Application.Mappers
))
;
CreateMap
<
UpdateFinancialSpendItemCommand
,
FinancialSpending
>()
;
}
}
...
...
PSManagement.Application/FinancialSpends/UseCases/Commands/UpateFinancialSpendingItem/UpdateFinancialSpendItemCommandHandler.cs
View file @
24de3ed6
...
...
@@ -50,7 +50,15 @@ namespace PSManagement.Application.FinancialSpends.UseCases.Commands.UpateFinanc
{
return
Result
.
NotFound
();
}
await
_spendRepository
.
UpdateAsync
(
_mapper
.
Map
<
FinancialSpending
>(
request
));
// System.Console.WriteLine(request);
spending
.
ExternalPurchase
=
request
.
ExternalPurchase
;
spending
.
LocalPurchase
=
request
.
LocalPurchase
;
spending
.
CostType
=
request
.
CostType
;
spending
.
Description
=
request
.
Description
;
spending
.
ExpectedSpendingDate
=
request
.
ExpectedSpendingDate
;
await
_spendRepository
.
UpdateAsync
(
spending
);
await
_unitOfWork
.
SaveChangesAsync
();
return
Result
.
Success
();
...
...
PSManagement.Application/Projects/UseCases/Commands/AddAttachment/AddAttachmentCommandHandler.cs
View file @
24de3ed6
...
...
@@ -37,6 +37,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.AddAttachment
public
async
Task
<
Result
<
int
>>
Handle
(
AddAttachmentCommand
request
,
CancellationToken
cancellationToken
)
{
_unitOfWork
.
BeginTransaction
();
_specification
.
AddInclude
(
e
=>
e
.
Attachments
);
// save the file on the uploaded files
...
...
@@ -52,7 +53,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.AddAttachment
// checking if the project exist
if
(
project
is
null
)
{
await
_unitOfWork
.
Rollback
();
return
Result
.
Invalid
(
ProjectsErrors
.
InvalidEntryError
);
}
...
...
@@ -65,6 +66,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.AddAttachment
}
else
{
await
_unitOfWork
.
Rollback
();
return
Result
.
Invalid
(
pathResult
.
ValidationErrors
);
}
}
...
...
PSManagement.Application/Projects/UseCases/Commands/AddParticipant/AddParticipantCommandHandler.cs
View file @
24de3ed6
...
...
@@ -41,6 +41,8 @@ namespace PSManagement.Application.Projects.UseCases.Commands.AddParticipant
public
async
Task
<
Result
>
Handle
(
AddParticipantCommand
request
,
CancellationToken
cancellationToken
)
{
_unitOfWork
.
BeginTransaction
();
_specification
.
AddInclude
(
e
=>
e
.
EmployeeParticipates
);
Project
project
=
await
_projectsRepository
.
GetByIdAsync
(
request
.
ProjectId
,
_specification
);
...
...
@@ -51,7 +53,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.AddParticipant
if
(
project
.
HasParticipant
(
request
.
ParticipantId
))
{
await
_unitOfWork
.
Rollback
();
return
Result
.
Invalid
(
ProjectsErrors
.
ParticipantExistError
);
}
else
{
...
...
PSManagement.Application/Projects/UseCases/Commands/CreateProject/CreateProjectCommandHandler.cs
View file @
24de3ed6
...
...
@@ -33,6 +33,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
public
async
Task
<
Result
<
int
>>
Handle
(
CreateProjectCommand
request
,
CancellationToken
cancellationToken
)
{
_unitOfWork
.
BeginTransaction
();
var
type
=
await
_projectTypesRepository
.
GetByIdAsync
(
request
.
ProjectTypeId
);
if
(
type
is
null
)
{
...
...
@@ -67,6 +68,7 @@ namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
await
_unitOfWork
.
SaveChangesAsync
();
return
Result
.
Success
(
project
.
Id
);
}
...
...
PSManagement.Application/ProjectsTypes/UseCases/Commands/RemoveType/RemoveTypeCommandHandler.cs
View file @
24de3ed6
...
...
@@ -8,6 +8,7 @@ using PSManagement.SharedKernel.CQRS.Command;
using
PSManagement.SharedKernel.Specification
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
System.Linq
;
namespace
PSManagement.Application.ProjectsTypes.UseCases.Commands.CreateNewType
{
...
...
@@ -27,15 +28,17 @@ namespace PSManagement.Application.ProjectsTypes.UseCases.Commands.CreateNewType
public
async
Task
<
Result
>
Handle
(
RemoveTypeCommand
request
,
CancellationToken
cancellationToken
)
{
_specification
.
AddInclude
(
e
=>
e
.
Projects
);
var
result
=
await
_projectTypesRepository
.
GetByIdAsync
(
request
.
typeId
,
_specification
);
if
(
result
is
null
)
{
return
Result
.
Invalid
(
ProjectTypesErrors
.
InvalidEntryError
);
}
if
(
result
.
Projects
is
not
null
)
if
(
result
.
Projects
.
Count
()!=
0
)
{
return
Result
.
Invalid
(
ProjectTypesErrors
.
InvalidEntryError
);
return
Result
.
Invalid
(
ProjectTypesErrors
.
UnEmptyProjects
);
}
await
_projectTypesRepository
.
DeleteAsync
(
result
);
...
...
PSManagement.Domain/Identity/Constants/RolesNames.cs
View file @
24de3ed6
...
...
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace
PSManagement.Domain.Identity.Constants
{
/// <summary>
/// Provide a role n
ma
es
/// Provide a role n
am
es
/// </summary>
/// this classs provide a contant role names
/// gathering the roles source in a one place make change roles easier
...
...
PSManagement.Domain/Projects/Entities/Project.cs
View file @
24de3ed6
...
...
@@ -278,8 +278,12 @@ namespace PSManagement.Domain.Projects.Entities
var
participate
=
EmployeeParticipates
.
Where
(
e
=>
e
.
EmployeeId
==
participantId
).
FirstOrDefault
();
AddDomainEvent
(
new
ParticipationChangedEvent
(
participantId
,
participate
.
PartialTimeRatio
,
partialTimeRation
,
role
,
participate
.
Role
,
Id
,
DateTime
.
Now
));
participate
.
PartialTimeRatio
,
partialTimeRation
,
participate
.
Role
,
role
,
Id
,
DateTime
.
Now
));
participate
.
Role
=
role
;
...
...
PSManagement.Domain/ProjectsTypes/DomainErrors/ProjectTypesErrors.cs
View file @
24de3ed6
...
...
@@ -4,7 +4,9 @@ namespace PSManagement.Domain.Projects.DomainErrors
{
public
class
ProjectTypesErrors
{
public
static
DomainError
InvalidEntryError
{
get
;
}
=
new
(
"ProjectErrors.InvalidEntry."
,
"Invalid
Step
Data"
);
public
static
DomainError
InvalidEntryError
{
get
;
}
=
new
(
"ProjectErrors.InvalidEntry."
,
"Invalid
project type
Data"
);
public
static
DomainError
InvalidName
{
get
;
}
=
new
(
"ProjectErrors.InvalidEntry."
,
"the name is already exist"
);
public
static
DomainError
UnEmptyProjects
{
get
;
}
=
new
(
"ProjectErrors.InvalidEntry."
,
"the type already has a projects "
);
}
}
PSManagement.Infrastructure/Storage/FileService.cs
View file @
24de3ed6
...
...
@@ -57,6 +57,8 @@ namespace PSManagement.Infrastructure.Services.Storage
{
return
Result
.
Invalid
(
new
ValidationError
(
"File not found."
));
}
// Get the content type based on the file extension
var
contentType
=
GetContentType
(
filePath
);
var
memoryStream
=
new
MemoryStream
();
using
(
var
stream
=
new
FileStream
(
filePath
,
FileMode
.
Open
))
...
...
@@ -69,10 +71,28 @@ namespace PSManagement.Infrastructure.Services.Storage
IFormFile
formFile
=
new
FormFile
(
memoryStream
,
0
,
memoryStream
.
Length
,
null
,
Path
.
GetFileName
(
filePath
))
{
Headers
=
new
HeaderDictionary
(),
ContentType
=
"application/octet-stream"
ContentType
=
contentType
};
return
Result
.
Success
(
formFile
);
}
private
string
GetContentType
(
string
filePath
)
{
var
extension
=
Path
.
GetExtension
(
filePath
).
ToLowerInvariant
();
return
extension
switch
{
".pdf"
=>
"application/pdf"
,
".jpg"
or
".jpeg"
=>
"image/jpeg"
,
".png"
=>
"image/png"
,
".doc"
or
".docx"
=>
"application/msword"
,
".xls"
or
".xlsx"
=>
"application/vnd.ms-excel"
,
".txt"
=>
"text/plain"
,
_
=>
"application/octet-stream"
,
};
}
}
}
PSManagement.Presentation/Controllers/Projects/ProjectsController.cs
View file @
24de3ed6
using
AutoMapper
;
using
MediatR
;
using
System.IO
;
using
Microsoft.AspNetCore.Http
;
using
Microsoft.Extensions.Options
;
using
Microsoft.AspNetCore.Mvc
;
using
PSManagement.Application.Projects.UseCases.Commands.AddAttachment
;
using
PSManagement.Application.Projects.UseCases.Commands.CreateProject
;
...
...
@@ -343,9 +346,20 @@ namespace PSManagement.Presentation.Controllers.Projects
{
var
query
=
_mapper
.
Map
<
GetFileByUrlQuery
>(
request
);
var
result
=
await
_sender
.
Send
(
query
);
if
(
result
.
IsSuccess
){
return
HandleResult
(
_mapper
.
Map
<
Result
<
FileAttachmentResponse
>>(
result
));
var
fileAttachment
=
result
.
Value
;
// Return the file with the correct content type and file name
var
memoryStream
=
new
MemoryStream
();
await
fileAttachment
.
File
.
CopyToAsync
(
memoryStream
);
memoryStream
.
Position
=
0
;
// Reset the stream position to the beginning
// Return the file with the correct content type and file name
return
File
(
memoryStream
,
fileAttachment
.
File
.
ContentType
,
fileAttachment
.
AttachmentName
);
}
return
BadRequest
();
}
#
endregion
Attachments
Management
}
...
...
PSManagement.Presentation/Controllers/Tracks/TracksController.cs
View file @
24de3ed6
...
...
@@ -22,19 +22,25 @@ using System.Threading.Tasks;
using
PSManagement.Application.Tracks.UseCaes.Queries.GetTracksByFilter
;
namespace
PSManagement.Presentation.Controllers.Tracks
{
[
Route
(
"api/[controller]"
)]
public
class
TracksController
:
APIController
{
#
region
Dependencies
private
readonly
IMapper
_mapper
;
private
readonly
IMediator
_sender
;
#
endregion
Dependencies
#
region
Constructor
public
TracksController
(
IMediator
sender
,
IMapper
mapper
)
{
_sender
=
sender
;
_mapper
=
mapper
;
}
#
endregion
Constructor
#
region
Queries
On
Tracks
[
HttpGet
(
"{id}"
)]
public
async
Task
<
IActionResult
>
Get
(
int
id
)
{
...
...
@@ -97,7 +103,9 @@ namespace PSManagement.Presentation.Controllers.Tracks
return
HandleResult
(
result
);
}
#
endregion
Queries
On
Tracks
#
region
Step
Tracks
[
HttpPost
(
"AddStepTrack"
)]
public
async
Task
<
IActionResult
>
PostStepTrack
(
AddStepTrackRequest
request
)
{
...
...
@@ -108,6 +116,21 @@ namespace PSManagement.Presentation.Controllers.Tracks
return
HandleResult
(
result
);
}
[
HttpPut
(
"UpdateStepTrack"
)]
public
async
Task
<
IActionResult
>
PutStepTrack
(
UpdateStepTrackRequest
request
)
{
var
command
=
_mapper
.
Map
<
UpdateStepTrackCommand
>(
request
);
var
result
=
await
_sender
.
Send
(
command
);
return
HandleResult
(
result
);
}
#
endregion
Step
Tracks
#
region
Employee
Tracks
[
HttpPost
(
"AddEmployeeTrack"
)]
public
async
Task
<
IActionResult
>
PostEmployeeTrack
(
AddEmployeeTrackRequest
request
)
{
...
...
@@ -118,6 +141,23 @@ namespace PSManagement.Presentation.Controllers.Tracks
return
HandleResult
(
result
);
}
[
HttpPut
(
"UpdateEmployeeWorkTrack"
)]
public
async
Task
<
IActionResult
>
PutEmployeeWorkTrack
(
UpdateEmployeeWorkTrackRequest
request
)
{
var
command
=
_mapper
.
Map
<
UpdateEmployeeWorkTrackCommand
>(
request
);
var
result
=
await
_sender
.
Send
(
command
);
return
HandleResult
(
result
);
}
#
endregion
Employee
Tracks
#
region
Tracks
Management
[
HttpPost
(
"CompleteTrack"
)]
public
async
Task
<
IActionResult
>
PostCompleteTrack
(
CompleteTrackRequest
request
)
{
...
...
@@ -161,28 +201,7 @@ namespace PSManagement.Presentation.Controllers.Tracks
}
}
[
HttpPut
(
"UpdateEmployeeWorkTrack"
)]
public
async
Task
<
IActionResult
>
PutEmployeeWorkTrack
(
UpdateEmployeeWorkTrackRequest
request
)
{
var
command
=
_mapper
.
Map
<
UpdateEmployeeWorkTrackCommand
>(
request
);
var
result
=
await
_sender
.
Send
(
command
);
return
HandleResult
(
result
);
}
[
HttpPut
(
"UpdateStepTrack"
)]
public
async
Task
<
IActionResult
>
PutStepTrack
(
UpdateStepTrackRequest
request
)
{
var
command
=
_mapper
.
Map
<
UpdateStepTrackCommand
>(
request
);
var
result
=
await
_sender
.
Send
(
command
);
return
HandleResult
(
result
);
}
#
endregion
Tracks
Management
}
}
Readme.md
0 → 100644
View file @
24de3ed6
# Project Status Managment Server
> in this file we will explain the solution\
> and discuss the used patterns and architecture
__
_
## Table Of Contents
1.
Theoretical Introduction
2.
Sotuion Components
3.
Shared Kernel
4.
Domain Layer
5.
Applciation Layer
6.
Presentaion Layer
7.
Infratstucture Layer
8.
Architecture Tests
9.
Integeration With LDAP Explaination
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment