Compare commits

..

84 Commits

Author SHA1 Message Date
9b22249a89 added log changes to store in a file 2024-01-23 15:21:59 -05:00
947ee16281 Merged PR 112: Group by issue in responses
Group by issue in responses
2024-01-22 21:16:45 +00:00
2a2418c85e Group by issue in responses 2024-01-22 12:11:07 -05:00
9353d6ab2c Merged PR 110: fixed region issue
fixed region issue
2024-01-18 16:50:01 +00:00
5644762e00 fixed region issue 2024-01-18 11:43:03 -05:00
1b638d9367 Merged PR 106: Dadeschools token offline
Related work items: #155
2024-01-09 03:52:26 +00:00
073fbac743 Update UserAccess microservice to read Employee Code from token when retreiving App token. Update dadeschools Authorization policy to work offline 2024-01-08 22:31:52 -05:00
5eb9314e96 Moving password and mode settings to configuration file for dadeschools offline Token service 2024-01-08 00:11:08 -05:00
34b4adf0bf Add endpoint to login from mobile 2023-12-21 16:10:30 -05:00
4b863687d3 Adding endpoint to autheticate from mobile 2023-12-21 16:05:50 -05:00
735a5ee62c Merged PR 102: commented Dadeschool token
commented Dadeschool token
2023-12-21 19:13:36 +00:00
eb28885f00 commented Dadeschool token 2023-12-21 14:12:15 -05:00
6d3f5dd5b8 Merged PR 101: enabled dade school token in user access module
enabled dade school token in user access module
2023-12-21 18:26:32 +00:00
2baf4b9dad enabled dade school token in user access module 2023-12-21 13:22:16 -05:00
4f478585cf Merged PR 99: added active and in active survey endpoints
added active and in active survey endpoints
2023-12-19 18:21:07 +00:00
556dc5e4e7 added active and in active survey endpoints 2023-12-19 13:16:17 -05:00
01bfa9c4b5 Merged PR 93: fixed user update issue
fixed user update issue
2023-12-18 02:12:44 +00:00
6bdbcb8e57 fixed user update issue 2023-12-17 21:06:20 -05:00
2a73324ff7 Merged PR 92: Modified logic to get latest response based on survetid, locationId, ane empl...
Modified logic to get latest response based on survetid, locationId, ane employee id
2023-12-16 21:00:13 +00:00
9b8e8ffad2 Modified logic to get latest response based on survetid, locationId, ane employee id 2023-12-16 12:40:33 -05:00
dd5351665e Merged PR 91: added additional fields in user method
added additional fields in user method
2023-12-14 17:55:33 +00:00
ff4e8de3f3 added additional fields in user method 2023-12-14 10:21:14 -05:00
c014739fc0 Merged PR 89: added survey start and end date validation
added survey start and end date validation
2023-12-13 22:20:24 +00:00
70d0043e25 added survey start and end date validation 2023-12-13 17:10:14 -05:00
ff3847ecae Merged PR 88: commented token in employee miceoservice to get emp inforamtion in user access module
commented token in employee miceoservice to get emp inforamtion in user access module
2023-12-13 18:38:26 +00:00
7baff934ab commented token in employee miceoservice to get emp inforamtion in user access module 2023-12-13 10:58:35 -05:00
28de758da0 Merged PR 85: user access module changes for populating employee Information 2023-12-12 23:15:03 +00:00
bb87f1c8e0 user access module changes for populating employee Information 2023-12-12 17:18:18 -05:00
52869afc3f adding multiple questions for survey id 2023-12-07 09:54:56 -05:00
71b8031577 Merged PR 78: changed download url format and added new endpoint for doculink isactive update
changed download url format and added new endpoint for doculink isactive update
2023-12-04 19:53:40 +00:00
4936e3e6f1 changed download url format and added new endpoint for doculink isactive update 2023-12-04 14:37:53 -05:00
30b8d1ff9f Merged PR 75: added IsActive flag in doculinks request
added IsActive flag in doculinks request
2023-12-04 14:48:05 +00:00
79beaf55fa added IsActive flag in doculinks request 2023-12-04 09:28:24 -05:00
8c12477763 Merged PR 73: attachment and doculinks url changes
attachment and doculinks url changes
2023-12-01 22:49:28 +00:00
cc9ce4dbe5 attachment and doculinks url changes 2023-12-01 17:36:15 -05:00
3cd0c5f39e added multi language support for doculink attachments 2023-11-30 19:13:23 -05:00
334c327559 Return Employee ID for POST 2023-11-28 12:06:22 -05:00
87fa29d9d4 Updated CORS statements Policy 2023-11-25 23:08:04 -05:00
2ab8f37489 Merge branch 'sql-useraccess-NT' of https://dev.azure.com/MDCSB-Telecommuters/Emergency%20Preparedness%20Disaster%20Recovery%20Project%20%28EPDRP%29/_git/Backend-API-Services into sql-useraccess-NT 2023-11-22 18:46:20 -05:00
500582020b disabled auth for user access 2023-11-22 18:34:38 -05:00
ede178042f Deleted DamageAssesment.Responses.Test 2023-11-22 22:34:50 +00:00
6575c2f219 Merged PR 69: fixed attachment test case issues
fixed attachment test case issues
2023-11-22 21:54:53 +00:00
69584e6c91 fixed attachment test case issues 2023-11-22 16:40:23 -05:00
1cbd6893d8 Error fix and updated Migration script 2023-11-22 15:47:15 -05:00
79a3073bea changed connection string to 207 server 2023-11-22 14:44:15 -05:00
bdde55b3e5 commented dadeschool authencation logic 2023-11-21 13:30:30 -05:00
cd982d160a fixed question translation issue 2023-11-15 12:36:13 -05:00
9b88029a09 Added new endpoint for creating multiple questions 2023-11-14 15:36:33 -05:00
3b9e13ad35 added new endpoint to generate dade school token 2023-11-13 15:41:53 -05:00
dca119758a fixed survey issue in response level, and added logic for start and end
date as optional date.
2023-11-05 13:58:01 -05:00
8285588db9 fixed survey issue in response level, and added logic for start and end date as optional date. 2023-11-01 14:29:47 -04:00
fc166e65c9 fixed survey put issue, amd added export excel in responses 2023-10-31 16:40:46 -04:00
ae6b306290 reverted doculinks grouping by linktype 2023-10-24 12:22:59 -04:00
d3a751a6ad added status field in survey micro service 2023-10-23 11:56:39 -04:00
2182b9a6b3 added status field in survey micro service 2023-10-23 11:39:56 -04:00
e2bed66428 merged user access module with latest changes for sql database 2023-10-19 15:59:02 -04:00
8624eeeb97 Merge branch 'docker-sql' of https://dev.azure.com/MDCSB-Telecommuters/Emergency%20Preparedness%20Disaster%20Recovery%20Project%20%28EPDRP%29/_git/Backend-API-Services into docker-sql 2023-10-16 22:45:08 -04:00
16d45d6632 docker-compose.acr added 2023-10-16 22:44:08 -04:00
c77e0452c4 added logic to get active surveys from survey responses 2023-10-16 14:13:20 -04:00
6ad5bb1572 merged latest changes from docker to dev 2023-10-13 14:48:08 -04:00
8e0a7df68b added muilti language return format for question categories for question by survey 2023-10-13 13:29:21 -04:00
cb3c7f8f6a added muilti language return format for question categories for question by survey 2023-10-13 13:21:33 -04:00
01ccd97528 table update tested 2023-10-13 13:17:00 -04:00
26b360e0a9 Merge branch 'docker-sql' of https://dev.azure.com/MDCSB-Telecommuters/Emergency%20Preparedness%20Disaster%20Recovery%20Project%20%28EPDRP%29/_git/Backend-API-Services into docker-sql 2023-10-13 08:58:24 -04:00
360a58c026 Merge branch 'docker-branch' into docker-sql 2023-10-12 16:03:21 -04:00
26e79432e2 table name changes 2023-10-12 16:01:24 -04:00
11c6fc0dc9 Merge branch 'docker-sql' of https://dev.azure.com/MDCSB-Telecommuters/Emergency%20Preparedness%20Disaster%20Recovery%20Project%20%28EPDRP%29/_git/Backend-API-Services into docker-sql 2023-10-11 21:26:04 -04:00
99633d8dda Connection string sql dev server updated 2023-10-11 21:23:47 -04:00
8e3f6674c6 Merge branch 'docker-branch' into docker-sql 2023-10-11 19:25:09 -04:00
885fdeb117 updated question category 2023-10-11 19:24:50 -04:00
14956057cd Merge branch 'docker-branch' into docker-sql 2023-10-11 15:34:42 -04:00
fa3e3bbd99 added seed data for questions and surveys for demo 2023-10-11 15:33:21 -04:00
340ba6fa6d removed all migrations 2023-10-10 16:34:56 -04:00
46794057c4 Added sql docker logic 2023-10-10 16:28:30 -04:00
71d4b524e7 doculinks changes for grouping 2023-10-09 13:29:01 -04:00
c7a2dc5910 seed changes for doculinks 2023-10-06 15:53:09 -04:00
643bc0c76a Merged docker with docker sql branch 2023-10-06 15:14:13 -04:00
d0023114a3 updated doculink changes 2023-09-26 12:40:55 -04:00
465bf4b081 Merge branch 'dev' into Database-Integration 2023-09-13 16:52:43 -04:00
e04bccfffd Merged new dev changes 2023-09-13 13:16:42 -04:00
0544c7397d 314: updated document multi language output format 2023-09-11 13:34:50 -04:00
9c536a1c52 Modified Documents api for InMemory Logic 2023-09-11 13:34:50 -04:00
48be1a74c9 Merge branch 'DocumentsAPI' into Database-Integration 2023-08-31 19:02:47 -04:00
eb07c31ff6 Database integration 2023-08-18 17:14:41 -04:00
163 changed files with 3528 additions and 756 deletions

Binary file not shown.

View File

@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\DamageAssesment.sln",
"PreviewInSolutionExplorer": false
}

View File

@ -395,4 +395,5 @@ FodyWeavers.xsd
*.msp *.msp
# JetBrains Rider # JetBrains Rider
*.sln.iml *.sln.iml
**/migrations/

View File

@ -1,7 +1,6 @@
using DamageAssesment.Api.Answers.Interfaces; using DamageAssesment.Api.Answers.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Any;
namespace DamageAssesment.Api.Answers.Controllers namespace DamageAssesment.Api.Answers.Controllers
{ {
@ -16,7 +15,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Get all answers /// Get all answers
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("answers")] [HttpGet("answers")]
public async Task<ActionResult> GetAnswersAsync() { public async Task<ActionResult> GetAnswersAsync() {
@ -32,7 +31,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// Get an answer based on answerId. /// Get an answer based on answerId.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("answers/{id}")] [HttpGet("answers/{id}")]
public async Task<ActionResult> GetAnswerByIdAsync(int id) public async Task<ActionResult> GetAnswerByIdAsync(int id)
{ {
@ -48,6 +47,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Get all answers based on responseId. /// Get all answers based on responseId.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("answers/byresponse/{responseid}")] [HttpGet("answers/byresponse/{responseid}")]
public async Task<IActionResult> GetAnswersByResponseId(int responseid) public async Task<IActionResult> GetAnswersByResponseId(int responseid)
{ {
@ -61,7 +61,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Get all answers based on questionId. /// Get all answers based on questionId.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("answers/byquestion/{questionid}")] [HttpGet("answers/byquestion/{questionid}")]
public async Task<IActionResult> AnswersByQuestionId(int questionid) public async Task<IActionResult> AnswersByQuestionId(int questionid)
{ {
@ -75,7 +75,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Update an existing answer. /// Update an existing answer.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut("answers")] [HttpPut("answers")]
public async Task<IActionResult> UpdateAnswer(Models.Answer answer) public async Task<IActionResult> UpdateAnswer(Models.Answer answer)
{ {
@ -96,7 +96,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Save a new answer. /// Save a new answer.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("answers")] [HttpPost("answers")]
public async Task<IActionResult> CreateAnswer(Models.Answer answer) public async Task<IActionResult> CreateAnswer(Models.Answer answer)
{ {
@ -114,7 +114,7 @@ namespace DamageAssesment.Api.Answers.Controllers
/// <summary> /// <summary>
/// Delete an existing answer. /// Delete an existing answer.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("answers/{id}")] [HttpDelete("answers/{id}")]
public async Task<IActionResult> DeleteAnswer(int id) public async Task<IActionResult> DeleteAnswer(int id)
{ {

View File

@ -13,8 +13,16 @@
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Answers.Db namespace DamageAssesment.Api.Answers.Db
{ {
[Table("Answers")]
public class Answer public class Answer
{ {
[Key] [Key]

View File

@ -1,13 +1,19 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace DamageAssesment.Api.Answers.Db namespace DamageAssesment.Api.Answers.Db
{ {
public class AnswerDbContext:DbContext public class AnswerDbContext:DbContext
{ {
private IConfiguration _Configuration { get; set; }
public AnswerDbContext(DbContextOptions options):base(options) public AnswerDbContext(DbContextOptions options,IConfiguration configuration):base(options)
{ {
_Configuration= configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("AnswerConnection"));
} }
public DbSet<Db.Answer> Answers { get; set; } public DbSet<Db.Answer> Answers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)

View File

@ -1,29 +1,88 @@
using DamageAssesment.Api.Answers.Db; using DamageAssesment.Api.Answers.Db;
using DamageAssesment.Api.Answers.Interfaces; using DamageAssesment.Api.Answers.Interfaces;
using DamageAssesment.Api.Answers.Providers; using DamageAssesment.Api.Answers.Providers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection; using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/answers-{Date}.txt"); // Specify the file path and format
});
// Add services to the container. // Add services to the container.
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddScoped<IAnswersProvider, AnswersProvider>(); builder.Services.AddScoped<IAnswersProvider, AnswersProvider>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
builder.Services.AddDbContext<AnswerDbContext>(option => builder.Services.AddDbContext<AnswerDbContext>(option =>
{ {
option.UseInMemoryDatabase("Answers"); option.UseSqlServer("AnswerConnection");
}); });
var app = builder.Build(); var app = builder.Build();
@ -35,7 +94,8 @@ if (app.Environment.IsDevelopment())
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@ -198,13 +198,12 @@ namespace DamageAssesment.Api.Answers.Providers
{ {
if (!answerDbContext.Answers.Any()) if (!answerDbContext.Answers.Any())
{ {
answerDbContext.Answers.Add(new Db.Answer() { Id = 1, AnswerText = "Yes", Comment = "Comment test 4", QuestionId = 1, SurveyResponseId = 1 }); answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "Yes", Comment = "", QuestionId = 1, SurveyResponseId = 1 });
answerDbContext.Answers.Add(new Db.Answer() { Id = 2, AnswerText = "No", Comment = "Comment test 5", QuestionId = 2, SurveyResponseId = 1 }); answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "No", Comment = "myComment", QuestionId = 2, SurveyResponseId = 1 });
// Uncomment the lines below to add more initial data if needed //answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "No", Comment = "No Comment", QuestionId = 3, SurveyResponseId = 1 });
//answerDbContext.Answers.Add(new Db.Answer() { Id = 3, AnswerText = "No", Comment = "No Comment", QuestionId = 3, SurveyResponseId = 1 }); //answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "Yes", Comment = "No Comment", QuestionId = 1, SurveyResponseId = 2 });
//answerDbContext.Answers.Add(new Db.Answer() { Id = 4, AnswerText = "Yes", Comment = "No Comment", QuestionId = 1, SurveyResponseId = 2 }); //answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "No", Comment = "No Comment", QuestionId = 2, SurveyResponseId = 2 });
//answerDbContext.Answers.Add(new Db.Answer() { Id = 5, AnswerText = "No", Comment = "No Comment", QuestionId = 2, SurveyResponseId = 2 }); //answerDbContext.Answers.Add(new Db.Answer() { AnswerText = "No", Comment = "No Comment", QuestionId = 3, SurveyResponseId = 2 });
//answerDbContext.Answers.Add(new Db.Answer() { Id = 6, AnswerText = "No", Comment = "No Comment", QuestionId = 3, SurveyResponseId = 2 });
answerDbContext.SaveChanges(); answerDbContext.SaveChanges();
} }
} }

View File

@ -8,5 +8,10 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
//"AnswerConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"AnswerConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
}
} }

View File

@ -79,8 +79,8 @@ namespace DamageAssesment.Api.Attachments.Test
var mockInputAttachment = await MockData.getInputAttachmentData(); var mockInputAttachment = await MockData.getInputAttachmentData();
mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse); mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse);
var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object);
var result = (NoContentResult) await AttachmentProvider.UploadAttachmentAsync(AttachmentResponse); var result = (NoContentResult)await AttachmentProvider.UploadAttachmentAsync(AttachmentResponse);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -95,8 +95,8 @@ namespace DamageAssesment.Api.Attachments.Test
mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse); mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse);
var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object);
AttachmentInfo attachmentInfo=new AttachmentInfo(); AttachmentInfo attachmentInfo = new AttachmentInfo();
var result = (BadRequestObjectResult) await AttachmentProvider.UploadAttachmentAsync(attachmentInfo); var result = (BadRequestObjectResult)await AttachmentProvider.UploadAttachmentAsync(attachmentInfo);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }
@ -112,7 +112,7 @@ namespace DamageAssesment.Api.Attachments.Test
mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse); mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse);
var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object);
var result = (NoContentResult) await AttachmentProvider.UpdateAttachmentAsync(AttachmentResponse); var result = (NoContentResult)await AttachmentProvider.UpdateAttachmentAsync(AttachmentResponse);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -128,7 +128,7 @@ namespace DamageAssesment.Api.Attachments.Test
var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object);
AttachmentInfo attachmentInfo = new AttachmentInfo(); AttachmentInfo attachmentInfo = new AttachmentInfo();
var result = (BadRequestObjectResult) await AttachmentProvider.UpdateAttachmentAsync(attachmentInfo); var result = (BadRequestObjectResult)await AttachmentProvider.UpdateAttachmentAsync(attachmentInfo);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }

View File

@ -1,6 +1,7 @@
using Azure; using Azure;
using DamageAssesment.Api.Attachments.Interfaces; using DamageAssesment.Api.Attachments.Interfaces;
using DamageAssesment.Api.Attachments.Models; using DamageAssesment.Api.Attachments.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers; using System.Net.Http.Headers;
@ -12,16 +13,17 @@ namespace DamageAssesment.Api.Attachments.Controllers
{ {
private IAttachmentsProvider AttachmentProvider; private IAttachmentsProvider AttachmentProvider;
private IUploadService UploadService; private IUploadService UploadService;
private IAzureBlobService azureBlobService;
public AttachmentsController(IAttachmentsProvider AttachmentsProvider, IUploadService uploadService) public AttachmentsController(IAttachmentsProvider AttachmentsProvider, IUploadService UploadService)
{ {
this.AttachmentProvider = AttachmentsProvider; this.AttachmentProvider = AttachmentsProvider;
this.UploadService = uploadService; this.UploadService = UploadService;
} }
/// <summary> /// <summary>
/// Get all attachments. /// Get all attachments.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("attachments")] [HttpGet("attachments")]
public async Task<ActionResult> GetAttachmentsAsync() public async Task<ActionResult> GetAttachmentsAsync()
{ {
@ -37,6 +39,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
/// <summary> /// <summary>
/// Get all attachments by attachmentId. /// Get all attachments by attachmentId.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("attachments/{id}")] [HttpGet("attachments/{id}")]
public async Task<ActionResult> GetAttachmentbyIdAsync(int id) public async Task<ActionResult> GetAttachmentbyIdAsync(int id)
{ {
@ -80,7 +83,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
/// <summary> /// <summary>
/// Save new Attachment(s) /// Save new Attachment(s)
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("attachments"), DisableRequestSizeLimit] [HttpPost("attachments"), DisableRequestSizeLimit]
public async Task<IActionResult> UploadAttachmentAsync(AttachmentInfo attachmentInfo) public async Task<IActionResult> UploadAttachmentAsync(AttachmentInfo attachmentInfo)
{ {
@ -89,7 +92,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
if (attachmentInfo.Answers.Count > 0) if (attachmentInfo.Answers.Count > 0)
{ {
var Attachments = await this.AttachmentProvider.GetAttachmentCounter(); var Attachments = await this.AttachmentProvider.GetAttachmentCounter();
List<Models.Attachment> attachments = UploadService.UploadAttachment(attachmentInfo.ResponseId, Attachments.counter, attachmentInfo.Answers); List<Models.Attachment> attachments = UploadService.UploadAttachment(attachmentInfo.ResponseId, Attachments.counter, attachmentInfo.Answers);
var result = await this.AttachmentProvider.PostAttachmentAsync(attachments); var result = await this.AttachmentProvider.PostAttachmentAsync(attachments);
if (result.IsSuccess) if (result.IsSuccess)
{ {
@ -107,7 +110,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
/// <summary> /// <summary>
/// Modify an new attachment. /// Modify an new attachment.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut("attachments"), DisableRequestSizeLimit] [HttpPut("attachments"), DisableRequestSizeLimit]
public async Task<IActionResult> UpdateAttachmentAsync(AttachmentInfo attachmentInfo) public async Task<IActionResult> UpdateAttachmentAsync(AttachmentInfo attachmentInfo)
{ {
@ -118,7 +121,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
var res = await this.AttachmentProvider.GetAttachmentInfo(attachmentInfo.Answers); var res = await this.AttachmentProvider.GetAttachmentInfo(attachmentInfo.Answers);
if (res.IsSuccess) if (res.IsSuccess)
{ {
List<Models.Attachment> attachments = UploadService.UpdateAttachments(attachmentInfo.ResponseId, attachmentInfo.Answers, res.Attachments); List<Models.Attachment> attachments = UploadService.UpdateAttachments(attachmentInfo.ResponseId, attachmentInfo.Answers, res.Attachments);
var result = await this.AttachmentProvider.PutAttachmentAsync(attachments); var result = await this.AttachmentProvider.PutAttachmentAsync(attachments);
if (result.IsSuccess) if (result.IsSuccess)
{ {
@ -138,6 +141,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
/// <summary> /// <summary>
/// download an existing attachment. /// download an existing attachment.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("attachments/download/{id}")] [HttpGet("attachments/download/{id}")]
public async Task<IActionResult> downloadfile(int id) public async Task<IActionResult> downloadfile(int id)
{ {
@ -212,6 +216,7 @@ namespace DamageAssesment.Api.Attachments.Controllers
/// <summary> /// <summary>
/// Delete an existing attachment. /// Delete an existing attachment.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("attachments/{id}")] [HttpDelete("attachments/{id}")]
public async Task<IActionResult> DeleteAttachment(int id) public async Task<IActionResult> DeleteAttachment(int id)
{ {

View File

@ -14,9 +14,23 @@
<PackageReference Include="Azure.Storage.Blobs" Version="12.16.0" /> <PackageReference Include="Azure.Storage.Blobs" Version="12.16.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" /> <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Attachments.Db namespace DamageAssesment.Api.Attachments.Db
{ {
[Table("AnswerAttachments")]
public class Attachment public class Attachment
{ {
[Key] [Key]

View File

@ -1,11 +1,19 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace DamageAssesment.Api.Attachments.Db namespace DamageAssesment.Api.Attachments.Db
{ {
public class AttachmentsDbContext:DbContext public class AttachmentsDbContext:DbContext
{ {
public AttachmentsDbContext(DbContextOptions options) : base(options) private IConfiguration _Configuration { get; set; }
public AttachmentsDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
{ {
_Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("AttachmentConnection"));
} }
public DbSet<Db.Attachment> Attachments { get; set; } public DbSet<Db.Attachment> Attachments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)

View File

@ -1,10 +1,15 @@
using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Models;
using DamageAssesment.Api.Attachments.Models;
namespace DamageAssesment.Api.Attachments.Interfaces namespace DamageAssesment.Api.Attachments.Interfaces
{ {
public interface IAzureBlobService public interface IAzureBlobService
{ {
Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files); Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files);
void DeleteFile(string path); Task<List<Attachment>> UploadAttachment(int responseId, int answerId, int counter, List<IFormFile> postedFile);
Task<List<Attachment>> UploadAttachment(int responseId, int counter, List<AnswerInfo> answers);
Task<List<Attachment>> UpdateAttachments(int responseId, List<AnswerInfo> answers, IEnumerable<Models.Attachment> attachments);
void Deletefile(string path);
void Movefile(string path);
} }
} }

View File

@ -1,25 +1,84 @@
using DamageAssesment.Api.Attachments.Db; using DamageAssesment.Api.Attachments.Db;
using DamageAssesment.Api.Attachments.Interfaces; using DamageAssesment.Api.Attachments.Interfaces;
using DamageAssesment.Api.Attachments.Providers; using DamageAssesment.Api.Attachments.Providers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection; using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/attachments-{Date}.txt"); // Specify the file path and format
});
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
// Add services to the container. // Add services to the container.
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddScoped<IAttachmentsProvider, AttachmentsProvider>(); builder.Services.AddScoped<IAttachmentsProvider, AttachmentsProvider>();
@ -28,7 +87,7 @@ builder.Services.AddScoped<IAzureBlobService,AzureBlobService>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
builder.Services.AddDbContext<AttachmentsDbContext>(option => builder.Services.AddDbContext<AttachmentsDbContext>(option =>
{ {
option.UseInMemoryDatabase("Attachments"); option.UseSqlServer("AttachmentConnection");
}); });
builder.Services.Configure<FormOptions>(o => builder.Services.Configure<FormOptions>(o =>
{ {
@ -45,7 +104,8 @@ if (app.Environment.IsDevelopment())
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.UseHttpsRedirection(); app.UseHttpsRedirection();

View File

@ -25,7 +25,7 @@ namespace DamageAssesment.Api.Attachments.Providers
this.httpContextAccessor = httpContextAccessor; this.httpContextAccessor = httpContextAccessor;
baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}";
baseUrl = baseUrl + "/attachments/download"; baseUrl = baseUrl + "/attachments/download";
SeedData(); // SeedData();
} }
public async Task<(bool IsSuccess, IEnumerable<Models.Attachment> Attachments, string ErrorMessage)> GetAttachmentsAsync() public async Task<(bool IsSuccess, IEnumerable<Models.Attachment> Attachments, string ErrorMessage)> GetAttachmentsAsync()
{ {

View File

@ -3,6 +3,9 @@ using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized; using Azure.Storage.Blobs.Specialized;
using DamageAssesment.Api.Attachments.Interfaces; using DamageAssesment.Api.Attachments.Interfaces;
using DamageAssesment.Api.Attachments.Models;
using System.Diagnostics.Metrics;
using System.Text;
namespace DamageAssesment.Api.Attachments.Providers namespace DamageAssesment.Api.Attachments.Providers
{ {
@ -10,11 +13,95 @@ namespace DamageAssesment.Api.Attachments.Providers
{ {
BlobServiceClient _blobClient; BlobServiceClient _blobClient;
BlobContainerClient _containerClient; BlobContainerClient _containerClient;
string azureConnectionString = "<Primary Connection String>"; string azureConnectionString;
public AzureBlobService() private string uploadpath = "";
private string Deletepath = "";
public AzureBlobService(IConfiguration configuration)
{ {
_blobClient = new BlobServiceClient(azureConnectionString); uploadpath = configuration.GetValue<string>("Fileupload:folderpath");
_containerClient = _blobClient.GetBlobContainerClient("apiimages"); Deletepath = configuration.GetValue<string>("Fileupload:Deletepath");
_blobClient = new BlobServiceClient(configuration.GetValue<string>("Fileupload:BlobConnectionString"));
_containerClient = _blobClient.GetBlobContainerClient(configuration.GetValue<string>("Fileupload:BlobContainerName"));
}
public async Task<List<Attachment>> UploadAttachment(int responseId, int answerId, int counter, List<IFormFile> postedFile)
{
var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
List<Models.Attachment> attachments = new List<Models.Attachment>();
foreach (IFormFile item in postedFile)
{
counter++;
var UserfileName = Path.GetFileName(item.FileName);
var extension = System.IO.Path.GetExtension(UserfileName);
var fileName = String.Format("Attachment_{0}{1}", counter, extension);
var stream = item.OpenReadStream();
BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
string dbPath = fullDirectoryPath + "/" + fileName;
var result = await client.UploadAsync(stream, true);
attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
}
return attachments;
}
public async Task<List<Attachment>> UploadAttachment(int responseId, int counter, List<AnswerInfo> answers)
{
List<Models.Attachment> attachments = new List<Models.Attachment>();
try
{
foreach (var item in answers)
{
int answerId = item.AnswerId;
var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
foreach (var file in item.postedFiles)
{
counter++;
var UserfileName = Path.GetFileName(file.FileName);
var fileName = String.Format("Attachment_{0}{1}", counter, file.FileExtension);
byte[] byteArray = Convert.FromBase64String(file.FileContent);
MemoryStream stream = new MemoryStream(byteArray);
BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
string dbPath = fullDirectoryPath + "/" + fileName;
var result = await client.UploadAsync(stream, true);
attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
}
}
return attachments;
}
catch (Exception ex)
{
return new List<Models.Attachment>();
}
}
public async Task<List<Attachment>> UpdateAttachments(int responseId, List<AnswerInfo> answers, IEnumerable<Models.Attachment> attachments)
{
List<Models.Attachment> Dbattachments = new List<Models.Attachment>();
foreach (Models.Attachment searchFile in attachments)
{
Movefile(searchFile.URI);
}
foreach (var item in answers)
{
int answerId = item.AnswerId;
var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
foreach (var file in item.postedFiles)
{
Models.Attachment attachment = attachments.Where(a => a.Id == file.AttachmentId).FirstOrDefault();
var UserfileName = Path.GetFileName(file.FileName);
var fileName = String.Format("Attachment_{0}{1}", attachment?.Id, file.FileExtension);
byte[] byteArray = Convert.FromBase64String(file.FileContent);
MemoryStream stream = new MemoryStream(byteArray);
BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
string dbPath = fullDirectoryPath + "/" + fileName;
var result = await client.UploadAsync(stream, true);
Dbattachments.Add(new Models.Attachment { Id = attachment.Id, AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
}
}
return Dbattachments;
} }
public async Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files) public async Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files)
@ -35,10 +122,52 @@ namespace DamageAssesment.Api.Attachments.Providers
return azureResponse; return azureResponse;
} }
public void DeleteFile(string url) public string getMovefilename(string movefilename)
{ {
var blob = _containerClient.GetBlockBlobClient(url); var list = movefilename.Split('.');
blob.DeleteIfExists(); if (list.Length > 0)
list[list.Length - 1] = DateTime.Now.ToShortDateString().Replace("/", "_") + "_" + DateTime.Now.ToShortTimeString().Replace("/", "_") + "." + list[list.Length - 1];
return string.Join("_", list);
}
public void Movefile(string path)
{
try
{
if (path != "")
{
string MovePath = getMovefilename(path.Replace(uploadpath, Deletepath));
// Get references to the source and destination blobs
BlobClient sourceBlobClient = _containerClient.GetBlobClient(path);
BlobClient destinationBlobClient = _containerClient.GetBlobClient(MovePath);
// Start the copy operation from the source to the destination
destinationBlobClient.StartCopyFromUri(sourceBlobClient.Uri);
// Check if the copy operation completed successfully
WaitForCopyToComplete(destinationBlobClient);
// Delete the source blob after a successful copy
sourceBlobClient.DeleteIfExists();
}
}
catch (Exception ex)
{
}
}
static void WaitForCopyToComplete(BlobClient blobClient)
{
BlobProperties properties = blobClient.GetProperties();
while (properties.CopyStatus == CopyStatus.Pending)
{
Task.Delay(TimeSpan.FromSeconds(1));
properties = blobClient.GetProperties();
}
}
public void Deletefile(string url)
{
BlobClient sourceBlobClient = _containerClient.GetBlobClient(url);
sourceBlobClient.DeleteIfExists();
} }
} }
} }

View File

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

View File

@ -11,6 +11,14 @@
"AllowedHosts": "*", "AllowedHosts": "*",
"Fileupload": { "Fileupload": {
"folderpath": "DMS_Attachments/Active", "folderpath": "DMS_Attachments/Active",
"Deletepath": "DMS_Attachments/Deleted" "Deletepath": "DMS_Attachments/Deleted",
"BlobConnectionString": "DefaultEndpointsProtocol=https;AccountName=damagedoculink;AccountKey=blynpwrAQtthEneXC5f4vFewJ3tPV+QZUt1AX3nefZScPPjkr5hMoC18B9ni6/ZYdhRiERPQw+hB+AStonf+iw==;EndpointSuffix=core.windows.net",
"BlobContainerName": "doculinks"
},
"ConnectionStrings": {
//"AttachmentConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"AttachmentConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
} }
} }

View File

@ -44,10 +44,10 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockDocumentService = new Mock<IDoculinkProvider>(); var mockDocumentService = new Mock<IDoculinkProvider>();
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await MockData.getOkResponses(); var mockResponse = await MockData.getOkResponses();
mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms","en", null)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms", "en", null)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (OkObjectResult)await DocumentProvider.GetDocumentsAsync("forms","en", null); var result = (OkObjectResult)await DocumentProvider.GetDocumentsAsync("forms", "en", null);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -97,7 +97,7 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockDocumentService = new Mock<IDoculinkProvider>(); var mockDocumentService = new Mock<IDoculinkProvider>();
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await MockData.getOkResponse(1); var mockResponse = await MockData.getOkResponse(1);
mockDocumentService.Setup(service => service.GetDocumentAsync(1,"forms","en")).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.GetDocumentAsync(1, "forms", "en")).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (OkObjectResult)await DocumentProvider.GetDocumentAsync(1, "forms", "en"); var result = (OkObjectResult)await DocumentProvider.GetDocumentAsync(1, "forms", "en");
@ -154,9 +154,9 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockResponse = await MockData.getOkResponse(1); var mockResponse = await MockData.getOkResponse(1);
var mockInputDocument = await MockData.getInputDocumentData(); var mockInputDocument = await MockData.getInputDocumentData();
var DocumentResponse = await MockData.GetDocuLinksInfo(1); var DocumentResponse = await MockData.GetDocuLinksInfo(1);
mockDocumentService.Setup(service => service.UpdateDocumentAsync(1,mockInputDocument)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.UpdateDocumentAsync(1, mockInputDocument)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (NotFoundResult)await DocumentProvider.UpdateDocument(1,DocumentResponse); var result = (NotFoundResult)await DocumentProvider.UpdateDocument(1, DocumentResponse);
Assert.Equal(404, result.StatusCode); Assert.Equal(404, result.StatusCode);
} }
@ -168,9 +168,9 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await MockData.getBadRequestResponse(); var mockResponse = await MockData.getBadRequestResponse();
var mockInputDocument = await MockData.getInputDocumentData(); var mockInputDocument = await MockData.getInputDocumentData();
mockDocumentService.Setup(service => service.UpdateDocumentAsync(99,mockInputDocument)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.UpdateDocumentAsync(99, mockInputDocument)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (BadRequestObjectResult)await DocumentProvider.UpdateDocument(99,null); var result = (BadRequestObjectResult)await DocumentProvider.UpdateDocument(99, null);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }
@ -257,7 +257,7 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockDocumentService = new Mock<IDoculinkProvider>(); var mockDocumentService = new Mock<IDoculinkProvider>();
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await LinkTypeMockData.getOkResponse(1); var mockResponse = await LinkTypeMockData.getOkResponse(1);
mockDocumentService.Setup(service => service.GetLinkTypeAsync(1,"en")).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.GetLinkTypeAsync(1, "en")).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (OkObjectResult)await DocumentProvider.GetLinkTypeAsync(1, "en"); var result = (OkObjectResult)await DocumentProvider.GetLinkTypeAsync(1, "en");
@ -312,9 +312,9 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await LinkTypeMockData.getOkResponse(1); var mockResponse = await LinkTypeMockData.getOkResponse(1);
var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); var mockInputDocument = await LinkTypeMockData.getInputLinkData(1);
mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1,mockInputDocument)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1, mockInputDocument)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (OkObjectResult)await DocumentProvider.UpdateLinkType(1,mockInputDocument); var result = (OkObjectResult)await DocumentProvider.UpdateLinkType(1, mockInputDocument);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -326,9 +326,9 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await LinkTypeMockData.getNotFoundResponse(); var mockResponse = await LinkTypeMockData.getNotFoundResponse();
var mockInputDocument = await LinkTypeMockData.getInputLinkData(99); var mockInputDocument = await LinkTypeMockData.getInputLinkData(99);
mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(99,mockInputDocument)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(99, mockInputDocument)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (NotFoundObjectResult)await DocumentProvider.UpdateLinkType(99,mockInputDocument); var result = (NotFoundObjectResult)await DocumentProvider.UpdateLinkType(99, mockInputDocument);
Assert.Equal(404, result.StatusCode); Assert.Equal(404, result.StatusCode);
} }
@ -340,7 +340,7 @@ namespace DamageAssesment.Api.DocuLinks.Test
var mockUploadService = new Mock<IUploadService>(); var mockUploadService = new Mock<IUploadService>();
var mockResponse = await LinkTypeMockData.getBadRequestResponse(); var mockResponse = await LinkTypeMockData.getBadRequestResponse();
var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); var mockInputDocument = await LinkTypeMockData.getInputLinkData(1);
mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1,mockInputDocument)).ReturnsAsync(mockResponse); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1, mockInputDocument)).ReturnsAsync(mockResponse);
var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object);
var result = (BadRequestObjectResult)await DocumentProvider.UpdateLinkType(1, mockInputDocument); var result = (BadRequestObjectResult)await DocumentProvider.UpdateLinkType(1, mockInputDocument);

View File

@ -14,19 +14,19 @@ namespace DamageAssesment.Api.DocuLinks.Test
public static async Task<(bool, List<DocuLinks.Models.ResDoculink>, string)> getOkResponses() public static async Task<(bool, List<DocuLinks.Models.ResDoculink>, string)> getOkResponses()
{ {
List<DocuLinks.Models.ResDoculink> list = new List<DocuLinks.Models.ResDoculink>(); List<DocuLinks.Models.ResDoculink> list = new List<DocuLinks.Models.ResDoculink>();
for (int i = 1; i < 4; i++) for (int i = 1; i < 4; i++)
{ {
Dictionary<string, string> dicttitle = new Dictionary<string, string>(); Dictionary<string, string> dicttitle = new Dictionary<string, string>();
Dictionary<string, string> dictdesc = new Dictionary<string, string>(); Dictionary<string, string> dictdesc = new Dictionary<string, string>();
dicttitle.Add("en", "test"); dicttitle.Add("fr", "tester"); dicttitle.Add("en", "test"); dicttitle.Add("fr", "tester");
dictdesc.Add("en", "test"); dictdesc.Add("fr", "tester"); dictdesc.Add("en", "test"); dictdesc.Add("fr", "tester");
List<DoculinkTranslation> DocuLinksTranslations = new List<DoculinkTranslation>(); List<DoculinkTranslation> DocuLinksTranslations = new List<DoculinkTranslation>();
DocuLinksTranslations.Add(new DoculinkTranslation() DocuLinksTranslations.Add(new DoculinkTranslation()
{ {
Language = "en", Language = "en",
title = "tel"+i, title = "tel" + i,
description = "Sample"+i description = "Sample" + i
}); });
List<DoculinkAttachments> doclinksAttachments = new List<DoculinkAttachments>(); List<DoculinkAttachments> doclinksAttachments = new List<DoculinkAttachments>();
doclinksAttachments.Add(new DoculinkAttachments() doclinksAttachments.Add(new DoculinkAttachments()
@ -41,10 +41,10 @@ namespace DamageAssesment.Api.DocuLinks.Test
Id = i, Id = i,
linkTypeId = i, linkTypeId = i,
IsActive = true, IsActive = true,
titles= dicttitle, titles = dicttitle,
description=dictdesc, description = dictdesc,
CustomOrder=i, CustomOrder = i,
doclinksAttachments= doclinksAttachments doclinksAttachments = doclinksAttachments
}); });
} }
// List<ResDoculinks> doculinks = list.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); // List<ResDoculinks> doculinks = list.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList();
@ -122,8 +122,8 @@ namespace DamageAssesment.Api.DocuLinks.Test
{ {
List<FileModel> fileModels = new List<FileModel>(); List<FileModel> fileModels = new List<FileModel>();
fileModels.Add( new FileModel() { FileName = "Sample", FileContent = "c2FtcGxl", FileExtension = ".txt",IsAttachments=true,CustomOrder=1 }); fileModels.Add(new FileModel() { FileName = "Sample", FileContent = "c2FtcGxl", FileExtension = ".txt", IsAttachments = true, CustomOrder = 1 });
return new ReqDoculink() { Id=id, linkTypeId = 1, CustomOrder = 1, Files = fileModels }; return new ReqDoculink() { Id = id, linkTypeId = 1, CustomOrder = 1, Files = fileModels };
} }
public static async Task<DocuLinks.Models.Doculink> getInputDocumentData() public static async Task<DocuLinks.Models.Doculink> getInputDocumentData()
{ {
@ -133,7 +133,7 @@ namespace DamageAssesment.Api.DocuLinks.Test
Language = "en", Language = "en",
title = "tel", title = "tel",
description = "Sample" description = "Sample"
}); });
List<DoculinkAttachments> doclinksAttachments = new List<DoculinkAttachments>(); List<DoculinkAttachments> doclinksAttachments = new List<DoculinkAttachments>();
doclinksAttachments.Add(new DoculinkAttachments() doclinksAttachments.Add(new DoculinkAttachments()
{ {
@ -148,9 +148,9 @@ namespace DamageAssesment.Api.DocuLinks.Test
Id = 1, Id = 1,
linkTypeId = 1, linkTypeId = 1,
IsActive = true, IsActive = true,
CustomOrder=1, CustomOrder = 1,
documentsTranslations = DocuLinksTranslations, documentsTranslations = DocuLinksTranslations,
doclinksAttachments= doclinksAttachments doclinksAttachments = doclinksAttachments
}; };
} }
public static async Task<List<DocuLinks.Models.Doculink>> getInputDocuLinksData() public static async Task<List<DocuLinks.Models.Doculink>> getInputDocuLinksData()

View File

@ -2,6 +2,7 @@
using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Interfaces;
using DamageAssesment.Api.DocuLinks.Models; using DamageAssesment.Api.DocuLinks.Models;
using DamageAssesment.Api.DocuLinks.Providers; using DamageAssesment.Api.DocuLinks.Providers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -12,6 +13,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
{ {
private readonly IDoculinkProvider documentsProvider; private readonly IDoculinkProvider documentsProvider;
private readonly IUploadService uploadService; private readonly IUploadService uploadService;
private readonly IAzureBlobService azureBlobService;
public DoculinkController(IDoculinkProvider documentsProvider, IUploadService uploadService) public DoculinkController(IDoculinkProvider documentsProvider, IUploadService uploadService)
{ {
@ -24,6 +26,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// Get all Doculink type. /// Get all Doculink type.
/// </summary> /// </summary>
[HttpGet] [HttpGet]
[Authorize(Roles = "admin")]
[Route("doculinks/types")] [Route("doculinks/types")]
[Route("doculinks/types/{language:alpha}")] [Route("doculinks/types/{language:alpha}")]
public async Task<IActionResult> GetLinkTypesAsync(string? language) public async Task<IActionResult> GetLinkTypesAsync(string? language)
@ -38,6 +41,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Get a Doculink type by id. /// Get a Doculink type by id.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet] [HttpGet]
[Route("doculinks/types/{id}")] [Route("doculinks/types/{id}")]
[Route("doculinks/types/{id}/{language:alpha}")] [Route("doculinks/types/{id}/{language:alpha}")]
@ -53,6 +57,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Update a existing Doculink type. /// Update a existing Doculink type.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut] [HttpPut]
[Route("doculinks/types/{id}")] [Route("doculinks/types/{id}")]
public async Task<IActionResult> UpdateLinkType(int id, Models.LinkType linkType) public async Task<IActionResult> UpdateLinkType(int id, Models.LinkType linkType)
@ -74,6 +79,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Create a new Doculink type. /// Create a new Doculink type.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost] [HttpPost]
[Route("doculinks/types")] [Route("doculinks/types")]
public async Task<IActionResult> CreateLinkType(Models.LinkType linkType) public async Task<IActionResult> CreateLinkType(Models.LinkType linkType)
@ -92,6 +98,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Delete a existing Doculink type by id. /// Delete a existing Doculink type by id.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete] [HttpDelete]
[Route("doculinks/types/{id}")] [Route("doculinks/types/{id}")]
public async Task<IActionResult> DeleteLinkType(int id) public async Task<IActionResult> DeleteLinkType(int id)
@ -106,6 +113,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// download an existing attachment. /// download an existing attachment.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("doculinks/download/{id}")] [HttpGet("doculinks/download/{id}")]
public async Task<IActionResult> downloadfile(int id) public async Task<IActionResult> downloadfile(int id)
{ {
@ -180,7 +188,8 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Get all Doculink. /// Get all Doculink.
/// </summary> /// </summary>
///
[Authorize(Roles = "admin")]
[Route("doculinks")] [Route("doculinks")]
[Route("doculinks/{linktype:alpha}")] [Route("doculinks/{linktype:alpha}")]
[Route("doculinks/{linktype:alpha}/{language:alpha}")] [Route("doculinks/{linktype:alpha}/{language:alpha}")]
@ -228,6 +237,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Get a Doculink by id. /// Get a Doculink by id.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet] [HttpGet]
[Route("doculinks/{id}")] [Route("doculinks/{id}")]
[Route("doculinks/{id}/{linktype:alpha}")] [Route("doculinks/{id}/{linktype:alpha}")]
@ -244,6 +254,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// update existing doclink. /// update existing doclink.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut] [HttpPut]
[Route("doculinks/{id}")] [Route("doculinks/{id}")]
public async Task<IActionResult> UpdateDocument(int id, ReqDoculink documentInfo) public async Task<IActionResult> UpdateDocument(int id, ReqDoculink documentInfo)
@ -283,6 +294,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Create new doclink. /// Create new doclink.
/// </summary> /// </summary>
// [Authorize(Roles = "admin")]
[HttpPost] [HttpPost]
[Route("doculinks")] [Route("doculinks")]
public async Task<IActionResult> CreateDocument(ReqDoculink documentInfo) public async Task<IActionResult> CreateDocument(ReqDoculink documentInfo)
@ -310,6 +322,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers
/// <summary> /// <summary>
/// Delete Doculink by id. /// Delete Doculink by id.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete] [HttpDelete]
[Route("doculinks/{id}")] [Route("doculinks/{id}")]
public async Task<IActionResult> DeleteDocument(int id) public async Task<IActionResult> DeleteDocument(int id)

View File

@ -11,7 +11,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.16.0" /> <PackageReference Include="Azure.Storage.Blobs" Version="12.18.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" /> <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
@ -24,7 +25,10 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.DocuLinks.Db namespace DamageAssesment.Api.DocuLinks.Db
{ {
[Table("Doculinks")]
public class Doculink public class Doculink
{ {
[Key] [Key]

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.DocuLinks.Db namespace DamageAssesment.Api.DocuLinks.Db
{ {
[Table("DoculinkAttachments")]
public class DoculinkAttachments public class DoculinkAttachments
{ {

View File

@ -7,8 +7,15 @@ namespace DamageAssesment.Api.DocuLinks.Db
{ {
public class DoculinkDbContext : DbContext public class DoculinkDbContext : DbContext
{ {
public DoculinkDbContext(DbContextOptions options) : base(options) private IConfiguration _Configuration { get; set; }
public DoculinkDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
{ {
_Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("DoculinkConnection"));
} }
public DbSet<Db.Doculink> Documents { get; set; } public DbSet<Db.Doculink> Documents { get; set; }
public DbSet<Db.LinkType> LinkTypes { get; set; } public DbSet<Db.LinkType> LinkTypes { get; set; }

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.DocuLinks.Db namespace DamageAssesment.Api.DocuLinks.Db
{ {
[Table("DoculinkTrans")]
public class DoculinkTranslation public class DoculinkTranslation
{ {
[Key] [Key]

View File

@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.DocuLinks.Db namespace DamageAssesment.Api.DocuLinks.Db
{ {
[Table("DoculinkTypes")]
public class LinkType public class LinkType
{ {
[Key] [Key]

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.DocuLinks.Db namespace DamageAssesment.Api.DocuLinks.Db
{ {
[Table("DoculinkTypeTrans")]
public class LinksTranslation public class LinksTranslation
{ {
[Key] [Key]

View File

@ -1,10 +1,14 @@
using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Models;
using DamageAssesment.Api.DocuLinks.Models;
namespace DamageAssesment.Api.DocuLinks.Interfaces namespace DamageAssesment.Api.DocuLinks.Interfaces
{ {
public interface IAzureBlobService public interface IAzureBlobService
{ {
Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files); Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files);
Task<Models.Doculink> UploadDocument(int counter, ReqDoculink documentInfo);
Task<Models.Doculink> UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo);
void DeleteFile(string path); void DeleteFile(string path);
void Movefile(string path);
} }
} }

View File

@ -7,6 +7,7 @@ namespace DamageAssesment.Api.DocuLinks.Models
public int Id { get; set; } public int Id { get; set; }
public int linkTypeId { get; set; } public int linkTypeId { get; set; }
public List<DoculinkTranslation> documentsTranslations { get; set; } public List<DoculinkTranslation> documentsTranslations { get; set; }
public bool IsActive { get; set; }
public int CustomOrder { get; set; } public int CustomOrder { get; set; }
public List<FileModel>? Files { get; set; } public List<FileModel>? Files { get; set; }
} }

View File

@ -2,19 +2,76 @@ using DamageAssesment.Api.DocuLinks.Db;
using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Interfaces;
using DamageAssesment.Api.DocuLinks.Providers; using DamageAssesment.Api.DocuLinks.Providers;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Reflection; using System.Reflection;
using System.Text;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
// Add services to the container. // Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/DocuLinks-{Date}.txt"); // Specify the file path and format
});
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
@ -26,7 +83,7 @@ builder.Services.AddScoped<IAzureBlobService, AzureBlobService>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
builder.Services.AddDbContext<DoculinkDbContext>(option => builder.Services.AddDbContext<DoculinkDbContext>(option =>
{ {
option.UseInMemoryDatabase("DocumentConnection"); option.UseSqlServer("DoculinkConnection");
}); });
var app = builder.Build(); var app = builder.Build();
@ -36,7 +93,8 @@ if (app.Environment.IsDevelopment())
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@ -1,8 +1,17 @@
 
using Azure;
using Azure.Storage.Blobs; using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized; using Azure.Storage.Blobs.Specialized;
using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Interfaces;
using DamageAssesment.Api.DocuLinks.Models;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualBasic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace DamageAssesment.Api.DocuLinks.Providers namespace DamageAssesment.Api.DocuLinks.Providers
{ {
@ -10,11 +19,111 @@ namespace DamageAssesment.Api.DocuLinks.Providers
{ {
BlobServiceClient _blobClient; BlobServiceClient _blobClient;
BlobContainerClient _containerClient; BlobContainerClient _containerClient;
string azureConnectionString = "<Primary Connection String>"; string azureConnectionString;
public AzureBlobService() private string uploadpath = "";
private string Deletepath = "";
public AzureBlobService(IConfiguration configuration)
{ {
_blobClient = new BlobServiceClient(azureConnectionString); uploadpath = configuration.GetValue<string>("Fileupload:folderpath");
_containerClient = _blobClient.GetBlobContainerClient("apiimages"); Deletepath = configuration.GetValue<string>("Fileupload:Deletepath");
_blobClient = new BlobServiceClient(configuration.GetValue<string>("Fileupload:BlobConnectionString"));
_containerClient = _blobClient.GetBlobContainerClient(configuration.GetValue<string>("Fileupload:BlobContainerName"));
}
public async Task<Models.Doculink> UploadDocument(int counter, ReqDoculink documentInfo)
{
Models.Doculink Documents = new Models.Doculink();
List <Models.DoculinkAttachments> attachments = new List<Models.DoculinkAttachments>();
try
{
string path = "", UserfileName = "";
if (documentInfo.Files != null)
{
int counter1 = 1;
foreach (var item in documentInfo.Files)
{
if (item.IsAttachments)
{
UserfileName = Path.GetFileName(item.FileName);
var fileName = String.Format("Document_{0}_{1}{2}", counter, counter1, item.FileExtension);
byte[] byteArray = Convert.FromBase64String(item.FileContent);
MemoryStream stream = new MemoryStream(byteArray);
BlobClient client = _containerClient.GetBlobClient(uploadpath + "/" + fileName);
var result = await client.UploadAsync(stream, true);
path = uploadpath + "/" + fileName;
counter1++;
}
else
path = item.url;
attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path, IsAttachments = item.IsAttachments, CustomOrder = item.CustomOrder });
}
}
Documents = new Models.Doculink()
{
linkTypeId = documentInfo.linkTypeId,
documentsTranslations = documentInfo.documentsTranslations,
doclinksAttachments = attachments,
IsDeleted = false,
CustomOrder = documentInfo.CustomOrder,
IsActive = true
};
return Documents;
}
catch (Exception ex)
{
return new Models.Doculink();
}
}
public async Task<Models.Doculink> UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo)
{
try
{
foreach (var item in document.doclinksAttachments)
{
Movefile(item.Path);
}
string path = "", UserfileName = "";
List<Models.DoculinkAttachments> attachments = new List<Models.DoculinkAttachments>();
int counter1 = 1;
foreach (var item in documentInfo.Files)
{
if (item.IsAttachments)
{
UserfileName = Path.GetFileName(item.FileName);
var fileName = String.Format("Document_{0}_{1}{2)", document.Id, counter1, item.FileExtension);
byte[] byteArray = Encoding.UTF8.GetBytes(item.FileContent);
MemoryStream stream = new MemoryStream(byteArray);
BlobClient client = _containerClient.GetBlobClient(uploadpath + "/" + fileName);
path = uploadpath + "/" + fileName;
var result = await client.UploadAsync(stream, true);
counter1++;
}
else
path = item.url;
attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path, IsAttachments = item.IsAttachments, CustomOrder = item.CustomOrder });
}
Models.Doculink Documents = new Models.Doculink()
{
Id = documentInfo.Id,
linkTypeId = documentInfo.linkTypeId,
documentsTranslations = documentInfo.documentsTranslations,
IsActive = true,
IsDeleted = false,
CustomOrder = documentInfo.CustomOrder,
doclinksAttachments = attachments
};
return Documents;
}
catch (Exception ex)
{
return new Models.Doculink();
}
} }
public async Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files) public async Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files)
@ -35,10 +144,52 @@ namespace DamageAssesment.Api.DocuLinks.Providers
return azureResponse; return azureResponse;
} }
public string getMovefilename(string movefilename)
{
var list = movefilename.Split('.');
if (list.Length > 0)
list[list.Length - 1] = DateTime.Now.ToShortDateString().Replace("/", "_") +"_"+ DateTime.Now.ToShortTimeString().Replace("/", "_")+"." + list[list.Length - 1];
return string.Join("_", list);
}
public void Movefile(string path)
{
try
{
if (path != "")
{
string MovePath = getMovefilename(path.Replace(uploadpath, Deletepath));
// Get references to the source and destination blobs
BlobClient sourceBlobClient = _containerClient.GetBlobClient(path);
BlobClient destinationBlobClient = _containerClient.GetBlobClient(MovePath);
// Start the copy operation from the source to the destination
destinationBlobClient.StartCopyFromUri(sourceBlobClient.Uri);
// Check if the copy operation completed successfully
WaitForCopyToComplete(destinationBlobClient);
// Delete the source blob after a successful copy
sourceBlobClient.DeleteIfExists();
}
}
catch(Exception ex)
{
}
}
static void WaitForCopyToComplete(BlobClient blobClient)
{
BlobProperties properties = blobClient.GetProperties();
while (properties.CopyStatus == CopyStatus.Pending)
{
Task.Delay(TimeSpan.FromSeconds(1));
properties = blobClient.GetProperties();
}
}
public void DeleteFile(string url) public void DeleteFile(string url)
{ {
var blob = _containerClient.GetBlockBlobClient(url); BlobClient sourceBlobClient = _containerClient.GetBlobClient(url);
blob.DeleteIfExists(); sourceBlobClient.DeleteIfExists();
} }
} }
} }

View File

@ -24,11 +24,12 @@ namespace DamageAssesment.Api.DocuLinks.Providers
private DoculinkDbContext DocumentDbContext; private DoculinkDbContext DocumentDbContext;
private ILogger<DoculinkProvider> logger; private ILogger<DoculinkProvider> logger;
private IUploadService uploadservice; private IUploadService uploadservice;
private IAzureBlobService azureBlobService;
private IMapper mapper; private IMapper mapper;
private readonly IHttpContextAccessor httpContextAccessor; private readonly IHttpContextAccessor httpContextAccessor;
private string baseUrl; private string baseUrl;
public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger<DoculinkProvider> logger, IMapper mapper, IUploadService uploadservice, IHttpContextAccessor httpContextAccessor) public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger<DoculinkProvider> logger, IMapper mapper, IUploadService uploadservice, IAzureBlobService azureBlobService, IHttpContextAccessor httpContextAccessor)
{ {
this.DocumentDbContext = DocumentDbContext; this.DocumentDbContext = DocumentDbContext;
this.logger = logger; this.logger = logger;
@ -37,12 +38,13 @@ namespace DamageAssesment.Api.DocuLinks.Providers
this.httpContextAccessor = httpContextAccessor; this.httpContextAccessor = httpContextAccessor;
baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}";
baseUrl = baseUrl + "/doculinks/download"; baseUrl = baseUrl + "/doculinks/download";
SeedData(); this.azureBlobService = azureBlobService;
//SeedData();
} }
private void SeedData() private async Task SeedDataAsync()
{ {
if (!DocumentDbContext.LinkTypes.Any()) if (!DocumentDbContext.LinkTypes.Any())
{ {

View File

@ -91,7 +91,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers
} }
Documents=new Models.Doculink (){ linkTypeId = documentInfo.linkTypeId, Documents=new Models.Doculink (){ linkTypeId = documentInfo.linkTypeId,
documentsTranslations = documentInfo.documentsTranslations,doclinksAttachments=attachments, documentsTranslations = documentInfo.documentsTranslations,doclinksAttachments=attachments,
IsDeleted=false,CustomOrder=documentInfo.CustomOrder, IsActive =true}; IsDeleted=false,CustomOrder=documentInfo.CustomOrder, IsActive =documentInfo.IsActive
};
return Documents; return Documents;
} }
@ -115,15 +116,16 @@ namespace DamageAssesment.Api.DocuLinks.Providers
string path = "", UserfileName = ""; string path = "", UserfileName = "";
List<Models.DoculinkAttachments> attachments = new List<Models.DoculinkAttachments>(); List<Models.DoculinkAttachments> attachments = new List<Models.DoculinkAttachments>();
int counter1 = 1;
foreach (var item in documentInfo.Files) foreach (var item in documentInfo.Files)
{ {
counter++;
if (item.IsAttachments) if (item.IsAttachments)
{ {
UserfileName = Path.GetFileName(item.FileName+item.FileExtension); UserfileName = Path.GetFileName(item.FileName+item.FileExtension);
var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); var fileName = String.Format("Document_{0}{1}", counter1, item.FileExtension);
path = Path.Combine(fullDirectoryPath, fileName); path = Path.Combine(fullDirectoryPath, fileName);
File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent)); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent));
counter1++;
} }
else else
path = item.url; path = item.url;
@ -134,7 +136,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers
Id = documentInfo.Id, Id = documentInfo.Id,
linkTypeId = documentInfo.linkTypeId, linkTypeId = documentInfo.linkTypeId,
documentsTranslations=documentInfo.documentsTranslations, documentsTranslations=documentInfo.documentsTranslations,
IsActive = true, IsActive = documentInfo.IsActive,
IsDeleted=false, IsDeleted=false,
CustomOrder = documentInfo.CustomOrder, CustomOrder = documentInfo.CustomOrder,
doclinksAttachments = attachments doclinksAttachments = attachments

View File

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

View File

@ -1,4 +1,7 @@
{ {
"JwtSettings": {
"securitykey": "bWlhbWkgZGFkZSBzY2hvb2xzIHNlY3JldCBrZXk="
},
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
@ -6,8 +9,15 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": {
//"DoculinkConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"DoculinkConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
},
"Fileupload": { "Fileupload": {
"folderpath": "DASA_Documents/Active", "folderpath": "DASA_Documents/Active",
"Deletepath": "DASA_Documents/Deleted" "Deletepath": "DASA_Documents/Deleted",
"BlobConnectionString": "DefaultEndpointsProtocol=https;AccountName=damagedoculink;AccountKey=blynpwrAQtthEneXC5f4vFewJ3tPV+QZUt1AX3nefZScPPjkr5hMoC18B9ni6/ZYdhRiERPQw+hB+AStonf+iw==;EndpointSuffix=core.windows.net",
"BlobContainerName": "doculinks"
} }
} }

View File

@ -1,4 +1,5 @@
using DamageAssesment.Api.Employees.Interfaces; using DamageAssesment.Api.Employees.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -18,7 +19,7 @@ namespace DamageAssesment.Api.Employees.Controllers
/// <summary> /// <summary>
/// GET request for retrieving employees. /// GET request for retrieving employees.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("employees")] [HttpGet("employees")]
public async Task<ActionResult> GetEmployeesAsync() public async Task<ActionResult> GetEmployeesAsync()
{ {
@ -35,7 +36,7 @@ namespace DamageAssesment.Api.Employees.Controllers
/// <summary> /// <summary>
/// GET request for retrieving an employee by ID. /// GET request for retrieving an employee by ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("employees/{id}")] [HttpGet("employees/{id}")]
public async Task<ActionResult> GetEmployeeByIdAsync(int id) public async Task<ActionResult> GetEmployeeByIdAsync(int id)
{ {
@ -48,11 +49,12 @@ namespace DamageAssesment.Api.Employees.Controllers
return NotFound(); return NotFound();
} }
/// <summary> /// <summary>
/// PUT request for updating an existing employee. /// PUT request for updating an existing employee.
/// </summary> /// </summary>
/// <param name="Employee">The updated employee object.</param> /// <param name="Employee">The updated employee object.</param>
[Authorize(Roles = "admin")]
[HttpPut("employees/{id}")] [HttpPut("employees/{id}")]
public async Task<IActionResult> UpdateEmployee(int id, Models.Employee Employee) public async Task<IActionResult> UpdateEmployee(int id, Models.Employee Employee)
{ {
@ -75,6 +77,7 @@ namespace DamageAssesment.Api.Employees.Controllers
/// POST request for creating a new employee. /// POST request for creating a new employee.
/// </summary> /// </summary>
/// <param name="Employee">The employee information for creating a new employee.</param> /// <param name="Employee">The employee information for creating a new employee.</param>
[Authorize(Roles = "admin")]
[HttpPost("employees")] [HttpPost("employees")]
public async Task<IActionResult> CreateEmployee(Models.Employee Employee) public async Task<IActionResult> CreateEmployee(Models.Employee Employee)
{ {
@ -93,6 +96,7 @@ namespace DamageAssesment.Api.Employees.Controllers
/// DELETE request for deleting an existing employee. /// DELETE request for deleting an existing employee.
/// </summary> /// </summary>
/// <param name="id">The ID of the employee to be deleted.</param> /// <param name="id">The ID of the employee to be deleted.</param>
[Authorize(Roles = "admin")]
[HttpDelete("employees/{id}")] [HttpDelete("employees/{id}")]
public async Task<IActionResult> DeleteEmployee(int id) public async Task<IActionResult> DeleteEmployee(int id)
{ {

View File

@ -12,9 +12,22 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Employees.Db namespace DamageAssesment.Api.Employees.Db
{ {
[Table("Employees")]
public class Employee public class Employee
{ {
[Key] [Key]

View File

@ -4,18 +4,23 @@ namespace DamageAssesment.Api.Employees.Db
{ {
public class EmployeeDbContext: DbContext public class EmployeeDbContext: DbContext
{ {
public DbSet<Db.Employee> Employees { get; set; } private IConfiguration _Configuration { get; set; }
public EmployeeDbContext(DbContextOptions options) : base(options) public EmployeeDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
{ {
_Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("EmployeeConnection"));
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
base.OnModelCreating(modelBuilder); base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Employee>() modelBuilder.Entity<Employee>()
.Property(item => item.Id) .Property(item => item.Id)
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd();
} }
public DbSet<Db.Employee> Employees { get; set; }
} }
} }

View File

@ -1,30 +1,88 @@
using DamageAssesment.Api.Employees.Db; using DamageAssesment.Api.Employees.Db;
using DamageAssesment.Api.Employees.Interfaces; using DamageAssesment.Api.Employees.Interfaces;
using DamageAssesment.Api.Employees.Providers; using DamageAssesment.Api.Employees.Providers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection; using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
// Add services to the container. // Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/Employees-{Date}.txt"); // Specify the file path and format
});
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddScoped<IEmployeesProvider, EmployeesProvider>(); builder.Services.AddScoped<IEmployeesProvider, EmployeesProvider>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
builder.Services.AddDbContext<EmployeeDbContext>(option => builder.Services.AddDbContext<EmployeeDbContext>(option =>
{ {
option.UseInMemoryDatabase("Employees"); option.UseSqlServer("EmployeeConnection");
}); });
var app = builder.Build(); var app = builder.Build();
@ -42,7 +100,8 @@ if (app.Environment.IsDevelopment())
employeesProvider.SeedData(); employeesProvider.SeedData();
} }
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

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

View File

@ -9,9 +9,9 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"settings": { "ConnectionStrings": {
"endpoint1": "xxx", //"EmployeeConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"endpoint2": "xxx", "EmployeeConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
"endpoint3": "xxx"
} }
} }

View File

@ -1,4 +1,5 @@
using DamageAssesment.Api.Locations.Interfaces; using DamageAssesment.Api.Locations.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -15,7 +16,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Get all locations. /// Get all locations.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("locations")] [HttpGet("locations")]
public async Task<ActionResult> GetLocationsAsync() public async Task<ActionResult> GetLocationsAsync()
{ {
@ -31,7 +32,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Get all locations based on locationdId. /// Get all locations based on locationdId.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("locations/{id}")] [HttpGet("locations/{id}")]
public async Task<ActionResult> GetLocationByIdAsync(int id) public async Task<ActionResult> GetLocationByIdAsync(int id)
{ {
@ -47,7 +48,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Update a Location. /// Update a Location.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut("locations/{id}")] [HttpPut("locations/{id}")]
public async Task<IActionResult> UpdateLocation(int id, Models.Location Location) public async Task<IActionResult> UpdateLocation(int id, Models.Location Location)
{ {
@ -65,7 +66,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Save a new location. /// Save a new location.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("locations")] [HttpPost("locations")]
public async Task<IActionResult> CreateLocation(Models.Location Location) public async Task<IActionResult> CreateLocation(Models.Location Location)
{ {
@ -83,7 +84,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Delete an existing location. /// Delete an existing location.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("locations/{id}")] [HttpDelete("locations/{id}")]
public async Task<IActionResult> DeleteLocation(int id) public async Task<IActionResult> DeleteLocation(int id)
{ {

View File

@ -1,4 +1,5 @@
using DamageAssesment.Api.Locations.Interfaces; using DamageAssesment.Api.Locations.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Locations.Controllers namespace DamageAssesment.Api.Locations.Controllers
@ -15,7 +16,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// Get all regions.2 /// Get all regions.2
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("regions")] [HttpGet("regions")]
public async Task<ActionResult> GetRegionsAsync() public async Task<ActionResult> GetRegionsAsync()
{ {
@ -29,7 +30,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// GET request for retrieving a region by its ID. /// GET request for retrieving a region by its ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpGet("regions/{id}")] [HttpGet("regions/{id}")]
public async Task<ActionResult> GetRegionAsync(int id) public async Task<ActionResult> GetRegionAsync(int id)
{ {
@ -43,7 +44,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// POST request for creating a new region. /// POST request for creating a new region.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("regions")] [HttpPost("regions")]
public async Task<ActionResult> PostRegionAsync(Models.Region region) public async Task<ActionResult> PostRegionAsync(Models.Region region)
{ {
@ -57,7 +58,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// <summary> /// <summary>
/// PUT request for updating an existing region. /// PUT request for updating an existing region.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut("regions/{id}")] [HttpPut("regions/{id}")]
public async Task<ActionResult> PutRegionAsync(int id, Models.Region region) public async Task<ActionResult> PutRegionAsync(int id, Models.Region region)
{ {
@ -75,7 +76,7 @@ namespace DamageAssesment.Api.Locations.Controllers
/// DELETE request for deleting a region based on ID. /// DELETE request for deleting a region based on ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("regions/{id}")] [HttpDelete("regions/{id}")]
public async Task<ActionResult> DeleteRegionAsync(int id) public async Task<ActionResult> DeleteRegionAsync(int id)
{ {

View File

@ -11,10 +11,24 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Locations.Db namespace DamageAssesment.Api.Locations.Db
{ {
[Table("Locations")]
public class Location public class Location
{ {
[Key] [Key]
@ -20,10 +21,6 @@ namespace DamageAssesment.Api.Locations.Db
[StringLength(2)] [StringLength(2)]
public string SchoolType { get; set; } public string SchoolType { get; set; }
public int? DataValue { get; set; }
public int? Enrollment { get; set; }
public double? Longitute { get; set; }
public double? Latitude { get; set; }
} }
} }

View File

@ -4,6 +4,16 @@ namespace DamageAssesment.Api.Locations.Db
{ {
public class LocationDbContext : DbContext public class LocationDbContext : DbContext
{ {
private IConfiguration _Configuration { get; set; }
public LocationDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
{
_Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("LocationConnection"));
}
public DbSet<Db.Location> Locations { get; set; } public DbSet<Db.Location> Locations { get; set; }
public DbSet<Db.Region> Regions { get; set; } public DbSet<Db.Region> Regions { get; set; }
public LocationDbContext(DbContextOptions options) : base(options) public LocationDbContext(DbContextOptions options) : base(options)

View File

@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Locations.Db namespace DamageAssesment.Api.Locations.Db
{ {
[Table("Regions")]
public class Region public class Region
{ {
[Key] [Key]

View File

@ -11,9 +11,5 @@ namespace DamageAssesment.Api.Locations.Models
public string Name { get; set; } public string Name { get; set; }
public string MaintenanceCenter { get; set; } public string MaintenanceCenter { get; set; }
public string SchoolType { get; set; } public string SchoolType { get; set; }
public int? DataValue { get; set; }
public int? Enrollment { get; set; }
public double? Longitute { get; set; }
public double? Latitude { get; set; }
} }
} }

View File

@ -1,32 +1,92 @@
using DamageAssesment.Api.Locations.Db; using DamageAssesment.Api.Locations.Db;
using DamageAssesment.Api.Locations.Interfaces; using DamageAssesment.Api.Locations.Interfaces;
using DamageAssesment.Api.Locations.Providers; using DamageAssesment.Api.Locations.Providers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection; using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
// Add services to the container. // Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/Locations-{Date}.txt"); // Specify the file path and format
});
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddScoped<ILocationsProvider, LocationsProvider>(); builder.Services.AddScoped<ILocationsProvider, LocationsProvider>();
builder.Services.AddScoped<IRegionsProvider, RegionsProvider>(); builder.Services.AddScoped<IRegionsProvider, RegionsProvider>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30
builder.Services.AddDbContext<LocationDbContext>(option => builder.Services.AddDbContext<LocationDbContext>(option =>
{ {
option.UseInMemoryDatabase("Locations"); option.UseSqlServer("LocationConnection");
}); });
var app = builder.Build(); var app = builder.Build();
// Add services to the container.
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
@ -43,7 +103,8 @@ if (app.Environment.IsDevelopment())
regionProvider.SeedData(); regionProvider.SeedData();
} }
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@ -17,7 +17,7 @@ namespace DamageAssesment.Api.Locations.Providers
this.locationDbContext = locationDbContext; this.locationDbContext = locationDbContext;
this.logger = logger; this.logger = logger;
this.mapper = mapper; this.mapper = mapper;
// SeedData(); // SeedData();
} }
public async Task<(bool IsSuccess, IEnumerable<Models.Location> Locations, string ErrorMessage)> GetLocationsAsync() public async Task<(bool IsSuccess, IEnumerable<Models.Location> Locations, string ErrorMessage)> GetLocationsAsync()
@ -28,8 +28,6 @@ namespace DamageAssesment.Api.Locations.Providers
var locations = await locationDbContext.Locations.AsNoTracking().ToListAsync(); var locations = await locationDbContext.Locations.AsNoTracking().ToListAsync();
if (locations != null) if (locations != null)
{ {
int maxenrollment = (int)locations.Max(a => a.Enrollment);
foreach (Db.Location item in locations) { item.DataValue = GetHeatmapdata(item.Enrollment, maxenrollment); }
logger?.LogInformation($"{locations.Count} Locations(s) found"); logger?.LogInformation($"{locations.Count} Locations(s) found");
var result = mapper.Map<IEnumerable<Db.Location>, IEnumerable<Models.Location>>(locations); var result = mapper.Map<IEnumerable<Db.Location>, IEnumerable<Models.Location>>(locations);
return (true, result, null); return (true, result, null);
@ -48,12 +46,9 @@ namespace DamageAssesment.Api.Locations.Providers
try try
{ {
logger?.LogInformation("Query Location"); logger?.LogInformation("Query Location");
int maxenrollment = (int)await locationDbContext.Locations.AsNoTracking().MaxAsync(a => a.Enrollment);
var location = await locationDbContext.Locations.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id); var location = await locationDbContext.Locations.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id);
if (location != null) if (location != null)
{if(maxenrollment>0) {
location.DataValue = GetHeatmapdata(location.Enrollment, maxenrollment);
logger?.LogInformation($"{location} found"); logger?.LogInformation($"{location} found");
var result = mapper.Map<Db.Location, Models.Location>(location); var result = mapper.Map<Db.Location, Models.Location>(location);
return (true, result, null); return (true, result, null);
@ -66,10 +61,6 @@ namespace DamageAssesment.Api.Locations.Providers
return (false, null, ex.Message); return (false, null, ex.Message);
} }
} }
private int GetHeatmapdata(int? enrollment,int maxenrollment)
{
return (enrollment != null ? enrollment.Value : 0) * 100 / maxenrollment;
}
public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> PostLocationAsync(Models.Location location) public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> PostLocationAsync(Models.Location location)
{ {
try try
@ -148,9 +139,9 @@ namespace DamageAssesment.Api.Locations.Providers
{ {
if (!locationDbContext.Locations.Any()) if (!locationDbContext.Locations.Any())
{ {
locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0091", RegionId = 5, Name = "BOB GRAHAM EDUCATION CENTER", MaintenanceCenter = "1", SchoolType = "K8", DataValue = 25,Enrollment=780,Latitude= 25.83604,Longitute= -80.21618 }); locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0091", RegionId = 5, Name = "BOB GRAHAM EDUCATION CENTER", MaintenanceCenter = "1", SchoolType = "K8" });
locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0092", RegionId = 1, Name = "NORMAN S. EDELCUP/SUNNY ISLES BEACH K-8", MaintenanceCenter = "1", SchoolType = "K8", DataValue = 46, Enrollment = 650, Latitude = 20.83604, Longitute = -40.21618 }); locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0092", RegionId = 1, Name = "NORMAN S. EDELCUP/SUNNY ISLES BEACH K-8", MaintenanceCenter = "1", SchoolType = "K8" });
locationDbContext.Locations.Add(new Db.Location() { LocationCode = "7511", RegionId = 4, Name = "MIAMI SPRINGS SHS", MaintenanceCenter = "2", SchoolType = "S", DataValue = 12, Enrollment = 500, Latitude = 53.83604, Longitute = -60.21618 }); locationDbContext.Locations.Add(new Db.Location() { LocationCode = "7511", RegionId = 4, Name = "MIAMI SPRINGS SHS", MaintenanceCenter = "2", SchoolType = "S" });
//locationDbContext.Locations.Add(new Db.Location() { Id = 3, LocationCode = "Loc3", RegionId = 3, Name = "BOB GRAHAM EDUCATION CENTER 3", MaintenanceCenter = "1", SchoolType = "US" }); //locationDbContext.Locations.Add(new Db.Location() { Id = 3, LocationCode = "Loc3", RegionId = 3, Name = "BOB GRAHAM EDUCATION CENTER 3", MaintenanceCenter = "1", SchoolType = "US" });
//locationDbContext.Locations.Add(new Db.Location() { Id = 4, LocationCode = "Loc4", RegionId = 1, Name = "BOB GRAHAM EDUCATION CENTER 4", MaintenanceCenter = "1", SchoolType = "US" }); //locationDbContext.Locations.Add(new Db.Location() { Id = 4, LocationCode = "Loc4", RegionId = 1, Name = "BOB GRAHAM EDUCATION CENTER 4", MaintenanceCenter = "1", SchoolType = "US" });
//locationDbContext.Locations.Add(new Db.Location() { Id = 5, LocationCode = "Loc5", RegionId = 2, Name = "BOB GRAHAM EDUCATION CENTER 5", MaintenanceCenter = "1", SchoolType = "US" }); //locationDbContext.Locations.Add(new Db.Location() { Id = 5, LocationCode = "Loc5", RegionId = 2, Name = "BOB GRAHAM EDUCATION CENTER 5", MaintenanceCenter = "1", SchoolType = "US" });

View File

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

View File

@ -8,5 +8,10 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
//"LocationConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"LocationConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
}
} }

View File

@ -1,4 +1,6 @@
using DamageAssesment.Api.Questions.Interfaces; using DamageAssesment.Api.Questions.Interfaces;
using DamageAssesment.Api.Questions.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Questions.Controllers namespace DamageAssesment.Api.Questions.Controllers
@ -10,16 +12,13 @@ namespace DamageAssesment.Api.Questions.Controllers
public QuestionsController(IQuestionsProvider questionsProvider) public QuestionsController(IQuestionsProvider questionsProvider)
{ {
this.questionsProvider = questionsProvider; this.questionsProvider = questionsProvider;
} }
/// <summary> /// <summary>
/// GET request for retrieving questions. /// GET request for retrieving questions.
/// </summary> /// </summary>
//get all questions
// get all questions [Authorize(Roles = "admin,survey,user,report")]
[Route("questions")] [Route("questions")]
[Route("questions/{language:alpha}")] [Route("questions/{language:alpha}")]
[HttpGet] [HttpGet]
@ -37,6 +36,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// <summary> /// <summary>
/// GET request for retrieving a question by ID. /// GET request for retrieving a question by ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("questions/{id}/{language:alpha}")] [Route("questions/{id}/{language:alpha}")]
[Route("questions/{id:int}")] [Route("questions/{id:int}")]
[HttpGet] [HttpGet]
@ -55,6 +55,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// GET request for retrieving survey questions based on a survey ID. /// GET request for retrieving survey questions based on a survey ID.
/// Uri: {Optional language}/GetSurveyQuestions/{surveyId} :Default returns question in all languages /// Uri: {Optional language}/GetSurveyQuestions/{surveyId} :Default returns question in all languages
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("questions/bysurvey/{surveyId:int}")] [Route("questions/bysurvey/{surveyId:int}")]
[Route("questions/bysurvey/{surveyId:int}/{language:alpha}")] [Route("questions/bysurvey/{surveyId:int}/{language:alpha}")]
[HttpGet] [HttpGet]
@ -71,6 +72,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// PUT request for updating a question (multilingual). /// PUT request for updating a question (multilingual).
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPut("questions")] [HttpPut("questions")]
public async Task<IActionResult> UpdateQuestion(Models.Question question) public async Task<IActionResult> UpdateQuestion(Models.Question question)
{ {
@ -91,6 +93,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// <summary> /// <summary>
/// POST request for creating a multiple question (multilingual). /// POST request for creating a multiple question (multilingual).
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("questions/multiple")] [HttpPost("questions/multiple")]
public async Task<IActionResult> CreateQuestions(List<Models.Question> questions) public async Task<IActionResult> CreateQuestions(List<Models.Question> questions)
{ {
@ -106,12 +109,33 @@ namespace DamageAssesment.Api.Questions.Controllers
return BadRequest(result.ErrorMessage); return BadRequest(result.ErrorMessage);
} }
return CreatedAtRoute("DefaultApi",questions); return CreatedAtRoute("DefaultApi", questions);
}
/// <summary>
/// PUT request for update a multiple question (multilingual) for survey.
/// </summary>
[HttpPut("questions/multiple/{surveyid}")]
public async Task<IActionResult> CreateQuestions(int surveyid, List<Models.Question> questions)
{
if (questions != null)
{
var result = await this.questionsProvider.PutQuestionsAsync(surveyid,questions);
if (result.IsSuccess)
{
return Ok(result.Question);
}
if (result.ErrorMessage == "Not Found")
return NotFound(result.ErrorMessage);
return BadRequest(result.ErrorMessage);
}
return CreatedAtRoute("DefaultApi", questions);
} }
/// <summary> /// <summary>
/// POST request for creating a new question (multilingual). /// POST request for creating a new question (multilingual).
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("questions")] [HttpPost("questions")]
public async Task<IActionResult> CreateQuestion(Models.Question question) public async Task<IActionResult> CreateQuestion(Models.Question question)
{ {
@ -130,6 +154,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// DELETE request for deleting a question based on ID. /// DELETE request for deleting a question based on ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("questions/{id}")] [HttpDelete("questions/{id}")]
public async Task<IActionResult> DeleteQuestion(int id) public async Task<IActionResult> DeleteQuestion(int id)
{ {
@ -145,6 +170,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// GET request for retrieving question categories. /// GET request for retrieving question categories.
/// </summary> /// </summary>
[Authorize(Roles = "admin,user,report")]
[HttpGet("questions/categories")] [HttpGet("questions/categories")]
[HttpGet("questions/categories/{language:alpha}")] [HttpGet("questions/categories/{language:alpha}")]
public async Task<IActionResult> GetQuestionCategoriesAsync(string? language) public async Task<IActionResult> GetQuestionCategoriesAsync(string? language)
@ -159,7 +185,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// <summary> /// <summary>
/// GET request for retrieving a question category by ID. /// GET request for retrieving a question category by ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin,report")]
[HttpGet("questions/categories/{id:int}")] [HttpGet("questions/categories/{id:int}")]
[HttpGet("questions/categories/{id:int}/{language:alpha}")] [HttpGet("questions/categories/{id:int}/{language:alpha}")]
public async Task<IActionResult> GetQuestionCategoryAsync(int id,string? language) public async Task<IActionResult> GetQuestionCategoryAsync(int id,string? language)
@ -176,7 +202,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// <summary> /// <summary>
/// PUT request for updating a question category. /// PUT request for updating a question category.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,report")]
[HttpPut("questions/categories")] [HttpPut("questions/categories")]
public async Task<IActionResult> UpdateQuestionCategory(Models.QuestionCategory questionCategory) public async Task<IActionResult> UpdateQuestionCategory(Models.QuestionCategory questionCategory)
{ {
@ -198,6 +224,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// POST request for creating a new question category. /// POST request for creating a new question category.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpPost("questions/categories")] [HttpPost("questions/categories")]
public async Task<IActionResult> CreateQuestionCategory(Models.QuestionCategory questionCategory) public async Task<IActionResult> CreateQuestionCategory(Models.QuestionCategory questionCategory)
{ {
@ -216,6 +243,7 @@ namespace DamageAssesment.Api.Questions.Controllers
/// DELETE request for deleting a question category based on ID. /// DELETE request for deleting a question category based on ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin")]
[HttpDelete("questions/categories/{id}")] [HttpDelete("questions/categories/{id}")]
public async Task<IActionResult> DeleteQuestionCategory(int id) public async Task<IActionResult> DeleteQuestionCategory(int id)
{ {

View File

@ -11,10 +11,24 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace DamageAssesment.Api.Questions.Db namespace DamageAssesment.Api.Questions.Db
{ {
[Table("QuestionCategoryTrans")]
public class CategoryTranslation public class CategoryTranslation
{ {
[Key] [Key]

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Questions.Db namespace DamageAssesment.Api.Questions.Db
{ {
[Table("Questions")]
public class Question public class Question
{ {
[Key] [Key]

View File

@ -1,8 +1,10 @@
using System.Buffers.Text; using System.Buffers.Text;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Questions.Db namespace DamageAssesment.Api.Questions.Db
{ {
[Table("QuestionCategories")]
public class QuestionCategory public class QuestionCategory
{ {
[Key] [Key]

View File

@ -6,6 +6,16 @@ namespace DamageAssesment.Api.Questions.Db
{ {
public class QuestionDbContext : DbContext public class QuestionDbContext : DbContext
{ {
private IConfiguration _Configuration { get; set; }
public QuestionDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
{
_Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("QuestionConnection"));
}
public DbSet<Db.Question> Questions { get; set; } public DbSet<Db.Question> Questions { get; set; }
public DbSet<Db.QuestionType> QuestionTypes { get; set; } public DbSet<Db.QuestionType> QuestionTypes { get; set; }
public DbSet<Db.QuestionsTranslation> QuestionsTranslations { get; set; } public DbSet<Db.QuestionsTranslation> QuestionsTranslations { get; set; }

View File

@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Questions.Db namespace DamageAssesment.Api.Questions.Db
{ {
[Table("QuestionTypes")]
public class QuestionType public class QuestionType
{ {
[Key] [Key]

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Questions.Db namespace DamageAssesment.Api.Questions.Db
{ {
[Table("QuestionTrans")]
public class QuestionsTranslation public class QuestionsTranslation
{ {
[Key] [Key]

View File

@ -9,6 +9,7 @@ namespace DamageAssesment.Api.Questions.Interfaces
Task<(bool IsSuccess, List<SurveyQuestions> SurveyQuestions, string ErrorMessage)> GetSurveyQuestionAsync(int surveyId,string language); Task<(bool IsSuccess, List<SurveyQuestions> SurveyQuestions, string ErrorMessage)> GetSurveyQuestionAsync(int surveyId,string language);
Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> PostQuestionAsync(Models.Question Question); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> PostQuestionAsync(Models.Question Question);
Task<(bool IsSuccess, IEnumerable<Models.MultiLanguage> Question, string ErrorMessage)> PostQuestionsAsync(List<Models.Question> Questions); Task<(bool IsSuccess, IEnumerable<Models.MultiLanguage> Question, string ErrorMessage)> PostQuestionsAsync(List<Models.Question> Questions);
Task<(bool IsSuccess, IEnumerable<Models.MultiLanguage> Question, string ErrorMessage)> PutQuestionsAsync(int surveyId,List<Models.Question> Questions);
Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question);
Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> DeleteQuestionAsync(int id); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> DeleteQuestionAsync(int id);

View File

@ -12,7 +12,7 @@
public bool IsRequired { get; set; } public bool IsRequired { get; set; }
public bool Comment { get; set; } public bool Comment { get; set; }
public bool Key { get; set; } public bool Key { get; set; }
public int? SurveyId { get; set; } public int SurveyId { get; set; }
public int CategoryId { get; set; } public int CategoryId { get; set; }
} }
} }

View File

@ -5,6 +5,7 @@
public int CategoryId { get; set; } public int CategoryId { get; set; }
public string IconName { get; set; } public string IconName { get; set; }
public string IconLibrary { get; set; } public string IconLibrary { get; set; }
public object CategoryNames { get; set; }
public List<MultiLanguage> QuestionsText { get; set; } public List<MultiLanguage> QuestionsText { get; set; }
} }
} }

View File

@ -1,11 +1,41 @@
using DamageAssesment.Api.Questions.Db; using DamageAssesment.Api.Questions.Db;
using DamageAssesment.Api.Questions.Interfaces; using DamageAssesment.Api.Questions.Interfaces;
using DamageAssesment.Api.Questions.Providers; using DamageAssesment.Api.Questions.Providers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection; using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/Questions-{Date}.txt"); // Specify the file path and format
});
// Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
// Add services to the container. // Add services to the container.
builder.Services.AddControllers(); builder.Services.AddControllers();
@ -17,16 +47,44 @@ builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddDbContext<QuestionDbContext>(option => builder.Services.AddDbContext<QuestionDbContext>(option =>
{ {
option.UseInMemoryDatabase("Questions"); option.UseSqlServer("QuestionConnection");
}); });
var app = builder.Build(); var app = builder.Build();
@ -43,7 +101,8 @@ if (app.Environment.IsDevelopment())
questionProvider.SeedData(); questionProvider.SeedData();
} }
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@ -31,8 +31,7 @@ namespace DamageAssesment.Api.Questions.Providers
questionDbContext.QuestionTypes.Add(new Db.QuestionType() { TypeText = "TextBox" }); questionDbContext.QuestionTypes.Add(new Db.QuestionType() { TypeText = "TextBox" });
questionDbContext.SaveChanges(); questionDbContext.SaveChanges();
} }
if (!questionDbContext.QuestionsTranslations.Any())
if (!questionDbContext.QuestionCategories.Any())
{ {
questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { IconName = "Flooding", IconLibrary = "https://example.com/images/img1.png" }); questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { IconName = "Flooding", IconLibrary = "https://example.com/images/img1.png" });
questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { IconName = "Electrical", IconLibrary = "https://example.com/images/img2.png" }); questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { IconName = "Electrical", IconLibrary = "https://example.com/images/img2.png" });
@ -65,14 +64,51 @@ namespace DamageAssesment.Api.Questions.Providers
if (!questionDbContext.Questions.Any()) if (!questionDbContext.Questions.Any())
{ {
var question1 = new Db.Question() { QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 }; var question1 = new Db.Question() { QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 };
var question2 = new Db.Question() { QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 1 }; var question2 = new Db.Question() { QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 2 };
var question3 = new Db.Question() { QuestionTypeId = 1, SurveyId = 2, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 }; var question3 = new Db.Question() { QuestionTypeId = 1, SurveyId = 2, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 };
var question4 = new Db.Question() { QuestionTypeId = 1, SurveyId = 2, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 1 }; var question4 = new Db.Question() { QuestionTypeId = 1, SurveyId = 2, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 2 };
var question5 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 };
var question6 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 2 };
var question7 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 3};
var question8 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 4 };
var question9 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = true, Key = true, CategoryId = 5 };
var question10 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = false, Key = true, CategoryId = 1 };
var question11 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = false, CategoryId = 2 };
var question12 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = true, CategoryId = 3 };
var question13 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 4 };
var question14 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 5 };
var question15 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = false, CategoryId = 1 };
var question16 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = true, CategoryId = 2 };
var question17 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = false, CategoryId = 3 };
var question18 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 4 };
var question19 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 5 };
var question20 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, CategoryId = 1 };
var question21 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 2 };
var question22 = new Db.Question() { QuestionTypeId = 1, SurveyId = 3, QuestionNumber = 2, IsRequired = false, Comment = true, Key = true, CategoryId = 3 };
questionDbContext.Questions.Add(question1); questionDbContext.Questions.Add(question1);
questionDbContext.Questions.Add(question2); questionDbContext.Questions.Add(question2);
questionDbContext.Questions.Add(question3); questionDbContext.Questions.Add(question3);
questionDbContext.Questions.Add(question4); questionDbContext.Questions.Add(question4);
questionDbContext.Questions.Add(question5);
questionDbContext.Questions.Add(question6);
questionDbContext.Questions.Add(question7);
questionDbContext.Questions.Add(question8);
questionDbContext.Questions.Add(question9);
questionDbContext.Questions.Add(question10);
questionDbContext.Questions.Add(question11);
questionDbContext.Questions.Add(question12);
questionDbContext.Questions.Add(question13);
questionDbContext.Questions.Add(question14);
questionDbContext.Questions.Add(question15);
questionDbContext.Questions.Add(question16);
questionDbContext.Questions.Add(question17);
questionDbContext.Questions.Add(question18);
questionDbContext.Questions.Add(question19);
questionDbContext.Questions.Add(question20);
questionDbContext.Questions.Add(question21);
questionDbContext.Questions.Add(question22);
questionDbContext.SaveChanges(); questionDbContext.SaveChanges();
} }
@ -90,6 +126,64 @@ namespace DamageAssesment.Api.Questions.Providers
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "Are the grounds flooded ?", Language = "en" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "Are the grounds flooded ?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "Les terrains sont-ils inondés ?", Language = "fr" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "Les terrains sont-ils inondés ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "¿Están inundados los terrenos?", Language = "es" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 4, QuestionText = "¿Están inundados los terrenos?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 5, QuestionText = "Can you open?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 6, QuestionText = "Is debris blocking access?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 7, QuestionText = "Are the grounds flooded?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 8, QuestionText = "Is the access blocked by flooding?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 9, QuestionText = "Are any utility wires down?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 10, QuestionText = "Do you have damage to windows, doors, or walls?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 11, QuestionText = "Do you have roof damage?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 12, QuestionText = "Do you have major water intrusion?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 13, QuestionText = "Are any portable classrooms damaged and unusable?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 14, QuestionText = "Does your facility need to be secured/boarded?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 15, QuestionText = "Are you without commercial power?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 16, QuestionText = "Are you without water pressure?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 17, QuestionText = "Are you without telephones?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 18, QuestionText = "Are traffic signals damaged/missing?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 19, QuestionText = "Are you without an operable fire alarm?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 20, QuestionText = "Are you without an operable public address?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 21, QuestionText = "Do you have major debris?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 22, QuestionText = "Are there any problems or issues not addressed above that would impede you from opening? If yes, please explain below?", Language = "en" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 5, QuestionText = "Pouvez-vous ouvrir ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 6, QuestionText = "Est-ce que des débris bloquent l'accès ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 7, QuestionText = "Les terrains sont-ils inondés ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 8, QuestionText = "L'accès est-il bloqué par des inondations ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 9, QuestionText = "Des câbles d'utilité sont-ils tombés ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 10, QuestionText = "Avez-vous des dommages aux fenêtres, portes ou murs ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 11, QuestionText = "Avez-vous des dommages au toit ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 12, QuestionText = "Avez-vous une intrusion d'eau majeure ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 13, QuestionText = "Les salles de classe portables sont-elles endommagées et inutilisables ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 14, QuestionText = "Votre établissement a-t-il besoin d'être sécurisé/protégé ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 15, QuestionText = "Êtes-vous sans alimentation électrique commerciale ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 16, QuestionText = "Êtes-vous sans pression d'eau ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 17, QuestionText = "Êtes-vous sans téléphones ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 18, QuestionText = "Les feux de circulation sont-ils endommagés/absents ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 19, QuestionText = "N'avez-vous pas d'alarme incendie fonctionnelle ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 20, QuestionText = "N'avez-vous pas de système de sonorisation opérationnel ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 21, QuestionText = "Avez-vous une grande quantité de débris ?", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 22, QuestionText = "Y a-t-il des problèmes ou des problèmes non abordés ci-dessus qui vous empêcheraient d'ouvrir ? Si oui, veuillez expliquer ci-dessous.", Language = "fr" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 5, QuestionText = "¿Puedes abrir ?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 6, QuestionText = "¿Los escombros bloquean el acceso?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 7, QuestionText = "¿Están inundados los terrenos?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 8, QuestionText = "¿El acceso está bloqueado por inundaciones?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 9, QuestionText = "¿Hay cables de utilidad caídos?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 10, QuestionText = "¿Tienes daños en ventanas, puertas o paredes?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 11, QuestionText = "¿Tienes daños en el techo?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 12, QuestionText = "¿Tienes una gran intrusión de agua?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 13, QuestionText = "¿Hay aulas portátiles dañadas e inutilizables?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 14, QuestionText = "¿Tu instalación necesita ser asegurada/tabicada?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 15, QuestionText = "¿No tienes energía comercial?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 16, QuestionText = "¿No tienes presión de agua?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 17, QuestionText = "¿No tienes teléfonos?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 18, QuestionText = "¿Los semáforos están dañados/faltan?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 19, QuestionText = "¿No tienes una alarma de incendios operativa?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 20, QuestionText = "¿No tienes un sistema de megafonía operativo?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 21, QuestionText = "¿Tienes una gran cantidad de escombros?", Language = "es" });
questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { QuestionId = 22, QuestionText = "¿Hay algún problema o asunto no abordado anteriormente que le impida abrir? Si es así, por favor explíquelo a continuación.", Language = "es" });
questionDbContext.SaveChanges(); questionDbContext.SaveChanges();
} }
} }
@ -219,6 +313,7 @@ namespace DamageAssesment.Api.Questions.Providers
CategoryId = item.Id, CategoryId = item.Id,
IconLibrary = item.IconLibrary, IconLibrary = item.IconLibrary,
IconName = item.IconName, IconName = item.IconName,
CategoryNames= CreateCategoryMultiLanguageObject(GetCategoryTranslations(item.Id, language)),
QuestionsText = GetSurveyQuestion(mapper.Map<List<Db.Question>, List<Models.MultiLanguage>>(questions.Where(a => a.CategoryId == item.Id).ToList()), language) QuestionsText = GetSurveyQuestion(mapper.Map<List<Db.Question>, List<Models.MultiLanguage>>(questions.Where(a => a.CategoryId == item.Id).ToList()), language)
}); });
} }
@ -268,7 +363,7 @@ namespace DamageAssesment.Api.Questions.Providers
try try
{ {
List<Models.MultiLanguage> results = new List<MultiLanguage>(); List<Models.MultiLanguage> results = new List<MultiLanguage>();
logger?.LogInformation("Query Question"); logger?.LogInformation("Query Question");
foreach (Models.Question Question in Questions) foreach (Models.Question Question in Questions)
{ {
results.Add(InsertQuestion(Question)); results.Add(InsertQuestion(Question));
@ -281,6 +376,36 @@ namespace DamageAssesment.Api.Questions.Providers
return (false, null, ex.Message); return (false, null, ex.Message);
} }
} }
public async Task<(bool IsSuccess, IEnumerable<Models.MultiLanguage> Question, string ErrorMessage)> PutQuestionsAsync(int surveyId, List<Models.Question> Questions)
{
try
{
var questions=await questionDbContext.Questions.AsNoTracking().Where(a=>a.SurveyId == surveyId).ToListAsync();
if (questions != null)
{
List<int> questionids=questions.Select(a=>a.Id).ToList();
var questiontrans = await questionDbContext.QuestionsTranslations.AsNoTracking().Where(x => questionids.Contains(x.QuestionId)).ToListAsync();
if (questiontrans != null)
questionDbContext.QuestionsTranslations.RemoveRange(questiontrans);
questionDbContext.Questions.RemoveRange(questions);
questionDbContext.SaveChanges();
}
List<Models.MultiLanguage> results = new List<MultiLanguage>();
logger?.LogInformation("Query Question");
foreach (Models.Question Question in Questions)
{
Question.SurveyId = surveyId;
results.Add(InsertQuestion(Question));
}
return (true, results, null);
}
catch (Exception ex)
{
logger?.LogError(ex.ToString());
return (false, null, ex.Message);
}
}
public async Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question) public async Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question)
{ {
try try
@ -314,8 +439,11 @@ namespace DamageAssesment.Api.Questions.Providers
if (question != null) if (question != null)
{ {
var questiontrans=await questionDbContext.QuestionsTranslations.AsNoTracking().Where(x=>x.QuestionId== id).ToListAsync();
var result = mapper.Map<Db.Question, Models.MultiLanguage>(question); var result = mapper.Map<Db.Question, Models.MultiLanguage>(question);
result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id, "")); result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id, ""));
if(questiontrans!=null)
questionDbContext.QuestionsTranslations.RemoveRange(questiontrans);
questionDbContext.Questions.Remove(question); questionDbContext.Questions.Remove(question);
questionDbContext.SaveChanges(); questionDbContext.SaveChanges();
return (true, result, $"QuestionID {id} deleted Successfuly"); return (true, result, $"QuestionID {id} deleted Successfuly");

View File

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

View File

@ -8,5 +8,10 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
//"QuestionConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"QuestionConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
}
} }

View File

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Moq" Version="4.18.4" /> <PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" /> <PackageReference Include="xunit" Version="2.4.2" />

View File

@ -86,8 +86,9 @@ namespace DamageAssesment.Api.Questions.Test
List<Models.Question> Questions = new List<Models.Question>(); List<Models.Question> Questions = new List<Models.Question>();
QuestionsTranslations.Add(QuestionsTranslation); QuestionsTranslations.Add(QuestionsTranslation);
Questions.Models.Question question = new Questions.Models.Question() { Id = 1, Questions = QuestionsTranslations, TypeText = "Text 1", SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 }; Questions.Models.Question question = new Questions.Models.Question() { Id = 1, Questions = QuestionsTranslations, TypeText = "Text 1", SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 };
Questions.Add(question); Questions.Add(question);
return Questions; return Questions;
} }
} }
} }

View File

@ -356,6 +356,5 @@ namespace DamageAssesment.Api.Questions.Test
Assert.Equal(404, result.StatusCode); Assert.Equal(404, result.StatusCode);
} }
} }
} }

View File

@ -25,17 +25,16 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(mockRequestObject); var mockResponse = await MockData.getOkResponse(mockRequestObject);
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
[Fact(DisplayName = "Get Responses - BadRequest case")] [Fact(DisplayName = "Get Responses - BadRequest case")]
public async Task GetSurveyResponsesAsync_ShouldReturnStatusCode204() public async Task GetSurveyResponsesAsync_ShouldReturnStatusCode204()
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }
@ -46,7 +45,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -56,7 +55,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -70,7 +69,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -80,7 +79,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -91,7 +90,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -101,7 +100,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -113,7 +112,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -123,7 +122,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -134,7 +133,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -144,7 +143,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -155,7 +154,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(); var mockResponse = await MockData.getOkResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -165,7 +164,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse);
var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1);
Assert.Equal(204, result.StatusCode); Assert.Equal(204, result.StatusCode);
} }
@ -177,7 +176,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(mockRequestObject); var mockResponse = await MockData.getOkResponse(mockRequestObject);
mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse);
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); var result = (OkObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -188,7 +187,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse);
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (BadRequestObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); var result = (BadRequestObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }
@ -199,7 +198,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(mockRequestObject); var mockResponse = await MockData.getOkResponse(mockRequestObject);
mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse);
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); var result = (OkObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -210,7 +209,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); ; mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); ;
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (BadRequestObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); var result = (BadRequestObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject);
Assert.Equal(400, result.StatusCode); Assert.Equal(400, result.StatusCode);
} }
@ -221,7 +220,7 @@ namespace DamageAssesment.SurveyResponses.Test
SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject();
var mockResponse = await MockData.getOkResponse(mockRequestObject); var mockResponse = await MockData.getOkResponse(mockRequestObject);
mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse);
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (OkObjectResult)await surveyResponseController.DeleteSurveyResponseAsync(1); var result = (OkObjectResult)await surveyResponseController.DeleteSurveyResponseAsync(1);
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -231,7 +230,7 @@ namespace DamageAssesment.SurveyResponses.Test
{ {
var mockResponse = await MockData.getResponse(); var mockResponse = await MockData.getResponse();
mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); ; mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); ;
var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object);
var result = (NotFoundResult)await surveyResponseController.DeleteSurveyResponseAsync(1); var result = (NotFoundResult)await surveyResponseController.DeleteSurveyResponseAsync(1);
Assert.Equal(404, result.StatusCode); Assert.Equal(404, result.StatusCode);
} }

View File

@ -1,16 +1,17 @@
using DamageAssesment.Api.Responses.Interfaces; using DamageAssesment.Api.Responses.Interfaces;
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace DamageAssesment.Api.Responses.Controllers namespace DamageAssesment.Api.Responses.Controllers
{ {
[ApiController] [ApiController]
public class SurveyResponsesController : ControllerBase public class ResponsesController : ControllerBase
{ {
private readonly ISurveysResponse surveyResponseProvider; private readonly ISurveysResponse surveyResponseProvider;
private readonly IExcelExportService excelExportService; private readonly IExcelExportService excelExportService;
public SurveyResponsesController(ISurveysResponse surveyResponseProvider, IExcelExportService excelExportService) public ResponsesController(ISurveysResponse surveyResponseProvider, IExcelExportService excelExportService)
{ {
this.surveyResponseProvider = surveyResponseProvider; this.surveyResponseProvider = surveyResponseProvider;
this.excelExportService = excelExportService; this.excelExportService = excelExportService;
@ -19,6 +20,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// GET request for retrieving survey responses. /// GET request for retrieving survey responses.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/{employeeid:int}")] [Route("responses/{employeeid:int}")]
[Route("responses")] [Route("responses")]
[HttpGet] [HttpGet]
@ -38,6 +40,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <summary> /// <summary>
/// GET request for retrieving survey responses by survey ID. /// GET request for retrieving survey responses by survey ID.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/bysurvey/{surveyid:int}/{employeeid:int}")] [Route("responses/bysurvey/{surveyid:int}/{employeeid:int}")]
[Route("responses/bysurvey/{surveyid:int}")] [Route("responses/bysurvey/{surveyid:int}")]
[HttpGet] [HttpGet]
@ -56,6 +59,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <param name="surveyid">The ID of the survey for which responses are to be retrieved.</param> /// <param name="surveyid">The ID of the survey for which responses are to be retrieved.</param>
/// <param name="locationid">The ID of the location for which responses are to be retrieved.</param> /// <param name="locationid">The ID of the location for which responses are to be retrieved.</param>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/{surveyid:int}/{locationid:int}/{employeeid:int}")] [Route("responses/{surveyid:int}/{locationid:int}/{employeeid:int}")]
[Route("responses/{surveyid:int}/{locationid:int}")] [Route("responses/{surveyid:int}/{locationid:int}")]
[HttpGet] [HttpGet]
@ -75,6 +79,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <param name="questionId">The ID of the question for which responses are to be retrieved.</param> /// <param name="questionId">The ID of the question for which responses are to be retrieved.</param>
/// <param name="answer">The answer for which responses are to be retrieved.</param> /// <param name="answer">The answer for which responses are to be retrieved.</param>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/byanswer/{surveyid:int}/{questionid:int}/{answer:alpha}/{employeeid:int}")] [Route("responses/byanswer/{surveyid:int}/{questionid:int}/{answer:alpha}/{employeeid:int}")]
[Route("responses/byanswer/{surveyid:int}/{questionid:int}/{answer:alpha}")] [Route("responses/byanswer/{surveyid:int}/{questionid:int}/{answer:alpha}")]
[HttpGet] [HttpGet]
@ -93,6 +98,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// </summary> /// </summary>
/// <param name="surveyId">The ID of the survey for which answers are to be retrieved.</param> /// <param name="surveyId">The ID of the survey for which answers are to be retrieved.</param>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/byregion/{surveyid:int}")] [Route("responses/byregion/{surveyid:int}")]
[Route("responses/byregion/{surveyid:int}/{employeeid}")] [Route("responses/byregion/{surveyid:int}/{employeeid}")]
[HttpGet] [HttpGet]
@ -109,6 +115,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// GET request for retrieving survey responses by survey ID and maintenance center. /// GET request for retrieving survey responses by survey ID and maintenance center.
/// </summary> /// </summary>
/// <param name="surveyId">The ID of the survey for which responses are to be retrieved.</param> /// <param name="surveyId">The ID of the survey for which responses are to be retrieved.</param>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/bymaintenancecenter/{surveyid:int}/{employeeid:int}")] [Route("responses/bymaintenancecenter/{surveyid:int}/{employeeid:int}")]
[Route("responses/bymaintenancecenter/{surveyid:int}")] [Route("responses/bymaintenancecenter/{surveyid:int}")]
[HttpGet] [HttpGet]
@ -126,6 +133,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// </summary> /// </summary>
/// <param name="responseId">The ID of the survey response to be retrieved.</param> /// <param name="responseId">The ID of the survey response to be retrieved.</param>
[Authorize(Roles = "admin,survey,user,report")]
[HttpGet("responses/{id}")] [HttpGet("responses/{id}")]
public async Task<ActionResult> GetSurveyResponseByIdAsync(int id) public async Task<ActionResult> GetSurveyResponseByIdAsync(int id)
{ {
@ -142,6 +150,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// </summary> /// </summary>
/// <param name="surveyResponse">The survey response object to be created.</param> /// <param name="surveyResponse">The survey response object to be created.</param>
[Authorize(Roles = "admin,survey,user,report")]
[HttpPost("responses")] [HttpPost("responses")]
public async Task<ActionResult> PostSurveysAsync(Models.SurveyResponse surveyResponse) public async Task<ActionResult> PostSurveysAsync(Models.SurveyResponse surveyResponse)
{ {
@ -158,6 +167,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <param name="Id">The ID of the survey response to be updated.</param> /// <param name="Id">The ID of the survey response to be updated.</param>
/// <param name="surveyResponse">The updated survey response object.</param> /// <param name="surveyResponse">The updated survey response object.</param>
[Authorize(Roles = "admin,survey,user,report")]
[HttpPut("responses/{id}")] [HttpPut("responses/{id}")]
public async Task<ActionResult> PutSurveyResponseAsync(int id, Models.SurveyResponse surveyResponse) public async Task<ActionResult> PutSurveyResponseAsync(int id, Models.SurveyResponse surveyResponse)
{ {
@ -175,6 +185,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// DELETE request for deleting an existing survey response. /// DELETE request for deleting an existing survey response.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[HttpDelete("responses/{id}")] [HttpDelete("responses/{id}")]
public async Task<ActionResult> DeleteSurveyResponseAsync(int id) public async Task<ActionResult> DeleteSurveyResponseAsync(int id)
{ {
@ -190,6 +201,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// </summary> /// </summary>
/// <param name="request">The answers to be submitted for the survey.</param> /// <param name="request">The answers to be submitted for the survey.</param>
[Authorize(Roles = "admin,survey,user,report")]
[HttpPost("responses/answers")] [HttpPost("responses/answers")]
public async Task<ActionResult> PostSurveyAnswersAsync(Request request) public async Task<ActionResult> PostSurveyAnswersAsync(Request request)
{ {
@ -203,6 +215,8 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <summary> /// <summary>
/// Get All active surveys . /// Get All active surveys .
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/surveys/active")] [Route("responses/surveys/active")]
[Route("responses/surveys/active/{language:alpha}")] [Route("responses/surveys/active/{language:alpha}")]
[Route("responses/surveys/active/{employeeid:int}")] [Route("responses/surveys/active/{employeeid:int}")]
@ -220,6 +234,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <summary> /// <summary>
/// Export all survey response data based on survey id. /// Export all survey response data based on survey id.
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[HttpGet] [HttpGet]
[Route("responses/surveys/export/{surveyid}")] [Route("responses/surveys/export/{surveyid}")]
public async Task<ActionResult> GetExcelSurveysAsync(int surveyid, string language, bool IsAdmin = false) public async Task<ActionResult> GetExcelSurveysAsync(int surveyid, string language, bool IsAdmin = false)
@ -250,6 +265,7 @@ namespace DamageAssesment.Api.Responses.Controllers
/// <summary> /// <summary>
/// Get all historical surveys . /// Get all historical surveys .
/// </summary> /// </summary>
[Authorize(Roles = "admin,survey,user,report")]
[Route("responses/surveys/historic")] [Route("responses/surveys/historic")]
[Route("responses/surveys/historic/{language:alpha}")] [Route("responses/surveys/historic/{language:alpha}")]
[Route("responses/surveys/historic/{employeeid:int}")] [Route("responses/surveys/historic/{employeeid:int}")]

View File

@ -11,13 +11,30 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="EPPlus" Version="7.0.0" /> <PackageReference Include="ClosedXML" Version="0.102.1" />
<PackageReference Include="EPPlus" Version="6.2.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.5" /> <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace DamageAssesment.Api.Responses.Db namespace DamageAssesment.Api.Responses.Db
{ {
[Table("SurveyResponses")]
public class SurveyResponse public class SurveyResponse
{ {
[Key] [Key]

View File

@ -4,12 +4,17 @@ namespace DamageAssesment.Api.Responses.Db
{ {
public class SurveyResponseDbContext:DbContext public class SurveyResponseDbContext:DbContext
{ {
public DbSet<Db.SurveyResponse> SurveyResponses { get; set; } private IConfiguration _Configuration { get; set; }
public SurveyResponseDbContext(DbContextOptions options, IConfiguration configuration) : base(options)
public SurveyResponseDbContext(DbContextOptions options) : base(options)
{ {
_Configuration = configuration;
} }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server with connection string from app settings
options.UseSqlServer(_Configuration.GetConnectionString("ResponsesConnection"));
}
public DbSet<Db.SurveyResponse> SurveyResponses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {

View File

@ -4,9 +4,9 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IAnswerServiceProvider public interface IAnswerServiceProvider
{ {
Task<List<Answer>> getAnswersAsync(); Task<List<Answer>> getAnswersAsync(string token);
Task<List<Models.Answer>> GetAnswersByResponseIdAsync(int responseId); Task<List<Models.Answer>> GetAnswersByResponseIdAsync(int responseId, string token);
Task<Models.Answer> PostAnswersAsync(Models.Answer answer); Task<Models.Answer> PostAnswersAsync(Models.Answer answer, string token);
} }
} }

View File

@ -4,7 +4,7 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IAttachmentServiceProvider public interface IAttachmentServiceProvider
{ {
Task<List<Attachment>> getAttachmentsAsync(); Task<List<Attachment>> getAttachmentsAsync(string token);
Task<IEnumerable<Attachment>> PostAttachmentsAsync(Models.AttachmentInfo attachmentInfo); Task<IEnumerable<Attachment>> PostAttachmentsAsync(Models.AttachmentInfo attachmentInfo, string token);
} }
} }

View File

@ -1,10 +1,10 @@
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
namespace DamageAssesment.Api.Responses.Interfaces namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IEmployeeServiceProvider public interface IEmployeeServiceProvider
{ {
Task<List<Employee>> getEmployeesAsync(); Task<List<Employee>> getEmployeesAsync(string token);
Task<Employee> getEmployeeAsync(int employeeId); Task<Employee> getEmployeeAsync(int employeeId, string token);
} }
} }

View File

@ -1,9 +1,9 @@
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
namespace DamageAssesment.Api.Responses.Interfaces namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IHttpUtil public interface IHttpUtil
{ {
Task<string> SendAsync(HttpMethod method, string url, string JsonInput); Task<string> SendAsync(HttpMethod method, string url, string JsonInput, string token);
} }
} }

View File

@ -4,6 +4,6 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface ILocationServiceProvider public interface ILocationServiceProvider
{ {
Task<List<Location>> getLocationsAsync(); Task<List<Location>> getLocationsAsync(string token);
} }
} }

View File

@ -4,9 +4,9 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IQuestionServiceProvider public interface IQuestionServiceProvider
{ {
Task<List<Question>> getQuestionsAsync(string language); Task<List<Question>> getQuestionsAsync(string language, string token);
Task<List<SurveyQuestions>> getSurveyQuestionsAsync(int surveyId); Task<List<SurveyQuestions>> getSurveyQuestionsAsync(int surveyId, string token);
Task<Question> getQuestionsAsync(int questionId); Task<Question> getQuestionsAsync(int questionId, string token);
Task<List<QuestionCategory>> GetQuestionCategoriesAsync(string? language); Task<List<QuestionCategory>> GetQuestionCategoriesAsync(string? language, string token);
} }
} }

View File

@ -4,6 +4,6 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface IRegionServiceProvider public interface IRegionServiceProvider
{ {
Task<List<Region>> getRegionsAsync(); Task<List<Region>> getRegionsAsync(string token);
} }
} }

View File

@ -4,7 +4,7 @@ namespace DamageAssesment.Api.Responses.Interfaces
{ {
public interface ISurveyServiceProvider public interface ISurveyServiceProvider
{ {
Task<List<Survey>> getSurveysAsync(string language); Task<List<Survey>> getSurveysAsync(string language,string token);
Task<Survey> getSurveyAsync(int surveyId); Task<Survey> getSurveyAsync(int surveyId,string token);
} }
} }

View File

@ -11,6 +11,6 @@ namespace DamageAssesment.Api.Responses.Models
public string OfficePhoneNumber { get; set; } public string OfficePhoneNumber { get; set; }
public string Email { get; set; } public string Email { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public string? PreferredLanguage { get; set; } public string PreferredLanguage { get; set; }
} }
} }

View File

@ -8,9 +8,5 @@
public string Name { get; set; } public string Name { get; set; }
public string MaintenanceCenter { get; set; } public string MaintenanceCenter { get; set; }
public string SchoolType { get; set; } public string SchoolType { get; set; }
public int? DataValue { get; set; }
public int? Enrollment { get; set; }
public double? Longitute { get; set; }
public double? Latitude { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@
public class SurveyExport public class SurveyExport
{ {
public int Id { get; set; } public int Id { get; set; }
public string SurveyQuestion { get; set; } public string SurveyQuestion { get; set; }
public string Answer { get; set; } public string Answer { get; set; }
public string Category { get; set; } public string Category { get; set; }

View File

@ -5,6 +5,10 @@ using DamageAssesment.Api.Responses.Providers;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Polly; using Polly;
using System.Reflection; using System.Reflection;
using Microsoft.OpenApi.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
const int maxApiCallRetries = 3; const int maxApiCallRetries = 3;
@ -12,8 +16,33 @@ const int intervalToRetry = 2; //2 seconds
const int maxRetryForCircuitBraker = 5; const int maxRetryForCircuitBraker = 5;
const int intervalForCircuitBraker = 5; //5 seconds const int intervalForCircuitBraker = 5; //5 seconds
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => {
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
}));
builder.Services.AddLogging(builder =>
{
//builder.AddConsole(); // Optional: Add other providers if needed
builder.AddFile("logs/Responses-{Date}.txt"); // Specify the file path and format
});
// Add services to the container. // Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
builder.Services.AddAuthentication(item =>
{
item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
item.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(item =>
{
item.RequireHttpsMetadata = true;
item.SaveToken = true;
item.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authkey)),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@ -27,6 +56,7 @@ builder.Services.AddScoped<IEmployeeServiceProvider, EmployeeServiceProvider>();
builder.Services.AddScoped<IAttachmentServiceProvider, AttachmentServiceProvider>(); builder.Services.AddScoped<IAttachmentServiceProvider, AttachmentServiceProvider>();
builder.Services.AddScoped<ISurveyServiceProvider, SurveyServiceProvider>(); builder.Services.AddScoped<ISurveyServiceProvider, SurveyServiceProvider>();
builder.Services.AddScoped<IExcelExportService, ExcelExportService>(); builder.Services.AddScoped<IExcelExportService, ExcelExportService>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient<IHttpUtil, HttpUtil>(). builder.Services.AddHttpClient<IHttpUtil, HttpUtil>().
AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))). AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))).
@ -36,16 +66,44 @@ builder.Services.AddHttpClient<IHttpUtil, HttpUtil>().
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen(); //builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(c =>
builder.Services.AddSwaggerGen(options =>
{ {
// Include XML comments from your assembly // Include XML comments from your assembly
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath); options.IncludeXmlComments(xmlPath);
OpenApiSecurityScheme securityDefinition = new OpenApiSecurityScheme()
{
Name = "Bearer",
BearerFormat = "JWT",
Scheme = "bearer",
Description = "Specify the authorization token.",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
};
options.AddSecurityDefinition("jwt_auth", securityDefinition);
// Make sure swagger UI requires a Bearer token specified
OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "jwt_auth",
Type = ReferenceType.SecurityScheme
}
};
OpenApiSecurityRequirement securityRequirements = new OpenApiSecurityRequirement()
{
{securityScheme, new string[] { }},
};
options.AddSecurityRequirement(securityRequirements);
}); });
builder.Services.AddDbContext<SurveyResponseDbContext>(option => builder.Services.AddDbContext<SurveyResponseDbContext>(option =>
{ {
option.UseInMemoryDatabase("Responses"); option.UseSqlServer("ResponsesConnection");
}); });
var app = builder.Build(); var app = builder.Build();
@ -55,7 +113,8 @@ if (app.Environment.IsDevelopment())
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
app.UseCors("DamageAppCorsPolicy");
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@ -1,6 +1,6 @@
{ {
"profiles": { "profiles": {
"DamageAssesment.Api.SurveyResponses": { "DamageAssesment.Api.Responses": {
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "swagger", "launchUrl": "swagger",

View File

@ -1,16 +1,16 @@
using DamageAssesment.Api.Responses.Interfaces; using ClosedXML.Excel;
using DamageAssesment.Api.Responses.Interfaces;
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
using OfficeOpenXml; using OfficeOpenXml;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
namespace DamageAssesment.Api.Responses.Providers namespace DamageAssesment.Api.Responses.Providers
{ {
public class ExcelExportService : IExcelExportService public class ExcelExportService: IExcelExportService
{ {
public byte[] ExportToExcel<T1>(List<object> responses) public byte[] ExportToExcel<T1>(List<object> responses)
{ {
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (var package = new ExcelPackage()) using (var package = new ExcelPackage())
{ {
// Create the first worksheet and populate it with responses // Create the first worksheet and populate it with responses
@ -29,7 +29,7 @@ namespace DamageAssesment.Api.Responses.Providers
for (int col = 1; col <= properties.Length; col++) for (int col = 1; col <= properties.Length; col++)
{ {
worksheet.Cells[1, col].Value = properties[col - 1].Name; worksheet.Cells[1, col].Value = properties[col - 1].Name;
if (properties[col - 1].Name.ToLower().Contains("attachment")) if(properties[col - 1].Name.ToLower().Contains("attachment"))
IsAttchments.Add(col); IsAttchments.Add(col);
} }
@ -38,8 +38,8 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
for (int col = 1; col <= properties.Length; col++) for (int col = 1; col <= properties.Length; col++)
{ {
string value = Convert.ToString(properties[col - 1].GetValue(data[row - 2])); string value = Convert.ToString(properties[col - 1].GetValue(data[row - 2]));
if (IsAttchments.Where(a => a == col).Count() > 0 && !string.IsNullOrEmpty(value)) if (IsAttchments.Where(a => a == col).Count() > 0 && !string.IsNullOrEmpty(value))
{ {
List<string> attachments = value.Split("##").ToList(); List<string> attachments = value.Split("##").ToList();
@ -53,7 +53,7 @@ namespace DamageAssesment.Api.Responses.Providers
} }
else else
worksheet.Cells[row, col].Value = value; worksheet.Cells[row, col].Value = value;
} }
} }
} }

View File

@ -2,6 +2,7 @@
using DamageAssesment.Api.Responses.Db; using DamageAssesment.Api.Responses.Db;
using DamageAssesment.Api.Responses.Interfaces; using DamageAssesment.Api.Responses.Interfaces;
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
using DamageAssesment.Api.Responses.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Reflection; using System.Reflection;
@ -21,8 +22,10 @@ namespace DamageAssesment.Api.Responses.Providers
private readonly IQuestionServiceProvider questionServiceProvider; private readonly IQuestionServiceProvider questionServiceProvider;
private readonly ISurveyServiceProvider surveyServiceProvider; private readonly ISurveyServiceProvider surveyServiceProvider;
private readonly IMapper mapper; private readonly IMapper mapper;
private readonly IHttpContextAccessor httpContextAccessor;
private string token;
public SurveyResponsesProvider(SurveyResponseDbContext surveyResponseDbContext, ILogger<SurveyResponsesProvider> logger, IAnswerServiceProvider answerServiceProvider, IRegionServiceProvider regionServiceProvider, ILocationServiceProvider locationServiceProvider, IEmployeeServiceProvider employeeServiceProvider, IAttachmentServiceProvider attachmentServiceProvider, IQuestionServiceProvider questionServiceProvider, ISurveyServiceProvider surveyServiceProvider, IMapper mapper) public SurveyResponsesProvider(SurveyResponseDbContext surveyResponseDbContext, ILogger<SurveyResponsesProvider> logger, IAnswerServiceProvider answerServiceProvider, IRegionServiceProvider regionServiceProvider, ILocationServiceProvider locationServiceProvider, IEmployeeServiceProvider employeeServiceProvider, IAttachmentServiceProvider attachmentServiceProvider, IQuestionServiceProvider questionServiceProvider, ISurveyServiceProvider surveyServiceProvider, IMapper mapper, IHttpContextAccessor httpContextAccessor)
{ {
this.surveyResponseDbContext = surveyResponseDbContext; this.surveyResponseDbContext = surveyResponseDbContext;
this.logger = logger; this.logger = logger;
@ -33,8 +36,20 @@ namespace DamageAssesment.Api.Responses.Providers
this.attachmentServiceProvider = attachmentServiceProvider; this.attachmentServiceProvider = attachmentServiceProvider;
this.questionServiceProvider = questionServiceProvider; this.questionServiceProvider = questionServiceProvider;
this.surveyServiceProvider = surveyServiceProvider; this.surveyServiceProvider = surveyServiceProvider;
this.httpContextAccessor = httpContextAccessor;
this.mapper = mapper; this.mapper = mapper;
SeedData(); SeedData();
token = httpContextAccessor.HttpContext.Request.Headers.Authorization;
if (token != null)
{
token = token.Replace("Bearer ", string.Empty);
}
else
{
token = "";
}
// seedData();
} }
public void SeedData() public void SeedData()
@ -56,16 +71,20 @@ namespace DamageAssesment.Api.Responses.Providers
try try
{ {
logger?.LogInformation("Querying to get SurveyResponse object from DB"); logger?.LogInformation("Querying to get SurveyResponse object from DB");
IQueryable<Db.SurveyResponse> listSurveyResponse = null; List<Db.SurveyResponse> listSurveyResponse = null;
if (employeeid == 0) if (employeeid == 0)
{ {
listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId); listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId).ToList();
} }
else else
{ {
listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId && s.EmployeeId == employeeid); listSurveyResponse = surveyResponseDbContext.SurveyResponses.Where(s => s.SurveyId == surveyId && s.EmployeeId == employeeid).ToList();
} }
listSurveyResponse = listSurveyResponse
.OrderByDescending(obj => obj.Id)
.GroupBy(obj => new { obj.SurveyId, obj.LocationId })//obj.EmployeeId,
.Select(group => group.FirstOrDefault()) // or .FirstOrDefault() if you want to handle empty groups
.ToList();
if (listSurveyResponse.Any()) if (listSurveyResponse.Any())
{ {
var answers = await getAnswersByRegionAndSurveyIdAsync(listSurveyResponse); var answers = await getAnswersByRegionAndSurveyIdAsync(listSurveyResponse);
@ -120,7 +139,7 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
logger?.LogInformation("Querying to get SurveyResponse object from DB"); logger?.LogInformation("Querying to get SurveyResponse object from DB");
//get all the survey that already taken by the employee //get all the survey that already taken by the employee
var surveys = await surveyServiceProvider.getSurveysAsync(language); var surveys = await surveyServiceProvider.getSurveysAsync(language, token);
surveys = surveys.Where(s => s.IsEnabled == true && s.Status == SurveyStatus.ACTIVE.ToString()).ToList(); surveys = surveys.Where(s => s.IsEnabled == true && s.Status == SurveyStatus.ACTIVE.ToString()).ToList();
if (employeeid == null || employeeid == 0) if (employeeid == null || employeeid == 0)
return (true, surveys, null); return (true, surveys, null);
@ -141,7 +160,7 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
logger?.LogInformation("Querying to get SurveyResponse object from DB"); logger?.LogInformation("Querying to get SurveyResponse object from DB");
var surveys = await surveyServiceProvider.getSurveysAsync(language); var surveys = await surveyServiceProvider.getSurveysAsync(language, token);
// returning only historic data: end date is less than current date. // returning only historic data: end date is less than current date.
surveys = surveys.Where(s => s.Status == SurveyStatus.INACTIVE.ToString()).ToList(); surveys = surveys.Where(s => s.Status == SurveyStatus.INACTIVE.ToString()).ToList();
if (employeeid == null || employeeid == 0) if (employeeid == null || employeeid == 0)
@ -166,7 +185,7 @@ namespace DamageAssesment.Api.Responses.Providers
try try
{ {
logger?.LogInformation("Querying to get Survey object from microservice"); logger?.LogInformation("Querying to get Survey object from microservice");
var survey = await surveyServiceProvider.getSurveyAsync(surveyId); var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token);
if (survey != null) if (survey != null)
{ {
@ -197,7 +216,7 @@ namespace DamageAssesment.Api.Responses.Providers
try try
{ {
logger?.LogInformation("Querying to get Survey object from microservice"); logger?.LogInformation("Querying to get Survey object from microservice");
var survey = await surveyServiceProvider.getSurveyAsync(surveyId); var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token);
if (survey != null) if (survey != null)
{ {
@ -228,7 +247,7 @@ namespace DamageAssesment.Api.Responses.Providers
try try
{ {
logger?.LogInformation("Querying to get Survey object from microservice"); logger?.LogInformation("Querying to get Survey object from microservice");
var survey = await surveyServiceProvider.getSurveyAsync(surveyId); var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token);
if (survey != null) if (survey != null)
{ {
@ -259,8 +278,8 @@ namespace DamageAssesment.Api.Responses.Providers
try try
{ {
logger?.LogInformation("Querying to get Survey object from microservice"); logger?.LogInformation("Querying to get Survey object from microservice");
var survey = await surveyServiceProvider.getSurveyAsync(surveyId); var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token);
var question = await questionServiceProvider.getQuestionsAsync(questionId); var question = await questionServiceProvider.getQuestionsAsync(questionId, token);
bool IsCorrectAnswer = answer.ToLower().Equals("yes") || answer.ToLower().Equals("no") ? true : false; bool IsCorrectAnswer = answer.ToLower().Equals("yes") || answer.ToLower().Equals("no") ? true : false;
@ -417,14 +436,13 @@ namespace DamageAssesment.Api.Responses.Providers
} }
//Method to get Answers by region with surveyId as input parameter //Method to get Answers by region with surveyId as input parameter
private async Task<dynamic> getAnswersByRegionAndSurveyIdAsync(IQueryable<Db.SurveyResponse> surveyResponses) private async Task<dynamic> getAnswersByRegionAndSurveyIdAsync(List<Db.SurveyResponse> surveyResponses)
{ {
try try
{ {
var answersList = await answerServiceProvider.getAnswersAsync(); var answersList = await answerServiceProvider.getAnswersAsync(token);
if (answersList == null || !answersList.Any()) if (answersList == null || !answersList.Any())
return null; return null;
//get all the answers for the particular survey //get all the answers for the particular survey
var surveyAnswers = answersList.Join( var surveyAnswers = answersList.Join(
surveyResponses, surveyResponses,
@ -444,8 +462,8 @@ namespace DamageAssesment.Api.Responses.Providers
if (surveyAnswers == null || !surveyAnswers.Any()) if (surveyAnswers == null || !surveyAnswers.Any())
return null; return null;
var regions = await regionServiceProvider.getRegionsAsync(); var regions = await regionServiceProvider.getRegionsAsync(token);
var locations = await locationServiceProvider.getLocationsAsync(); var locations = await locationServiceProvider.getLocationsAsync(token);
if (regions == null || !regions.Any() || locations == null || !locations.Any()) if (regions == null || !regions.Any() || locations == null || !locations.Any())
return null; return null;
@ -507,29 +525,27 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
try try
{ {
var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId); var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId, token);
var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id); var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id, token);
var allQuestions = await questionServiceProvider.getQuestionsAsync(null); var allQuestions = await questionServiceProvider.getQuestionsAsync(null, token);
var questions = allQuestions.Where(s => s.SurveyId == surveyResponse.SurveyId); var questions = allQuestions.Where(s => s.SurveyId == surveyResponse.SurveyId);
var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
var Locations = await locationServiceProvider.getLocationsAsync();
var location = Locations.Where(a => a.Id == surveyResponse.LocationId).FirstOrDefault(); var result = new
var result = new{ {
surveyResponse.Id, surveyResponse.Id,
surveyResponse.SurveyId, surveyResponse.SurveyId,
surveyResponse.LocationId, surveyResponse.LocationId,
surveyResponse.EmployeeId, surveyResponse.EmployeeId,
surveyResponse.ClientDevice, surveyResponse.ClientDevice,
surveyResponse.KeyAnswerResult, // surveyResponse.KeyAnswerResult,
DataValue=(location!=null?location.DataValue:0), surveyResponse.Longitute,
Enrollment= (location != null ? location.Enrollment : 0), surveyResponse.Latitude,
Longitute = (location != null ? location.Longitute : surveyResponse.Longitute),
Latitude=(location != null ? location.Latitude : surveyResponse.Latitude),
Employee = employee, Employee = employee,
answers = from ans in answers answers = from ans in answers
select new select new
{ {
ans.QuestionId, // ans.QuestionId,
ans.Id, ans.Id,
ans.AnswerText, ans.AnswerText,
ans.Comment, ans.Comment,
@ -558,92 +574,52 @@ namespace DamageAssesment.Api.Responses.Providers
if (employeeid == 0) if (employeeid == 0)
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync();
employees = await employeeServiceProvider.getEmployeesAsync(); employees = await employeeServiceProvider.getEmployeesAsync(token);
} }
else else
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync();
employee = await employeeServiceProvider.getEmployeeAsync(employeeid); employee = await employeeServiceProvider.getEmployeeAsync(employeeid, token);
} }
surveyResonses = surveyResonses
.OrderByDescending(obj => obj.Id)
.GroupBy(obj => new { obj.SurveyId, obj.LocationId })//obj.EmployeeId,
.Select(group => group.FirstOrDefault()) // or .FirstOrDefault() if you want to handle empty groups
.ToList();
var answers = await answerServiceProvider.getAnswersAsync(); var answers = await answerServiceProvider.getAnswersAsync(token);
var questions = await questionServiceProvider.getQuestionsAsync(null); var questions = await questionServiceProvider.getQuestionsAsync(null, token);
var Locations = await locationServiceProvider.getLocationsAsync();
var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; var surveyQuestions = from q in questions where q.SurveyId == surveyId select q;
//var surveyQuestions = await questionServiceProvider.getSurveyQuestionsAsync(surveyId); //var surveyQuestions = await questionServiceProvider.getSurveyQuestionsAsync(surveyId);
var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
var result = from r in surveyResonses
select new
{
r.Id,
r.SurveyId,
r.LocationId,
r.EmployeeId,
r.ClientDevice,
// r.KeyAnswerResult,
r.Longitute,
r.Latitude,
// Employee = (from e in employees where e.Id == r.EmployeeId select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
answers = from ans in answers
where ans.SurveyResponseId == r.Id
select new
{
ans.Id,
// ans.QuestionId,
ans.AnswerText,
ans.Comment,
Questions = (from q in surveyQuestions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(),
Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI }
if (employeeid == 0) }
{ };
var result = from r in surveyResonses return result;
join loc in Locations on r.LocationId equals loc.Id
select new
{
r.Id,
r.SurveyId,
r.LocationId,
r.EmployeeId,
r.ClientDevice,
r.KeyAnswerResult,
loc.DataValue,
loc.Enrollment,
loc.Longitute,
loc.Latitude,
Employee = (from e in employees where e.Id == r.EmployeeId select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
answers = from ans in answers
where ans.SurveyResponseId == r.Id
select new
{
ans.Id,
ans.QuestionId,
ans.AnswerText,
ans.Comment,
Questions = (from q in surveyQuestions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(),
Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI }
}
};
return result;
}
else
{
object _employee = new { };
if (employee != null)
{
_employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber };
}
var result = from r in surveyResonses
join loc in Locations on r.LocationId equals loc.Id
select new
{
r.Id,
r.SurveyId,
r.LocationId,
r.EmployeeId,
r.ClientDevice,
r.KeyAnswerResult,
loc.DataValue,
loc.Enrollment,
loc.Longitute,
loc.Latitude,
Employee = _employee,
answers = from ans in answers
where ans.SurveyResponseId == r.Id
select new
{
ans.Id,
ans.QuestionId,
ans.AnswerText,
ans.Comment,
Questions = (from q in questions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(),
Attachments = from att in attachments where att.AnswerId == ans.Id select new { att.Id, att.URI }
}
};
return result;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -665,12 +641,12 @@ namespace DamageAssesment.Api.Responses.Providers
if (employeeid == 0) if (employeeid == 0)
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.ToListAsync();
employees = await employeeServiceProvider.getEmployeesAsync(); employees = await employeeServiceProvider.getEmployeesAsync(token);
} }
else else
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync();
employee = await employeeServiceProvider.getEmployeeAsync(employeeid); employee = await employeeServiceProvider.getEmployeeAsync(employeeid, token);
if (employee != null) if (employee != null)
{ {
@ -678,14 +654,16 @@ namespace DamageAssesment.Api.Responses.Providers
} }
} }
surveyResonses = surveyResonses
.OrderByDescending(obj => obj.Id)
.GroupBy(obj => new { obj.SurveyId, obj.EmployeeId, obj.LocationId })
.Select(group => group.FirstOrDefault()) // or .FirstOrDefault() if you want to handle empty groups
.ToList();
var answers = await answerServiceProvider.getAnswersAsync(token);
var questions = await questionServiceProvider.getQuestionsAsync(null, token);
var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
var answers = await answerServiceProvider.getAnswersAsync();
var questions = await questionServiceProvider.getQuestionsAsync(null);
var attachments = await attachmentServiceProvider.getAttachmentsAsync();
var Locations = await locationServiceProvider.getLocationsAsync();
var result = from r in surveyResonses var result = from r in surveyResonses
join loc in Locations on r.LocationId equals loc.Id
select new select new
{ {
r.Id, r.Id,
@ -693,18 +671,16 @@ namespace DamageAssesment.Api.Responses.Providers
r.LocationId, r.LocationId,
r.EmployeeId, r.EmployeeId,
r.ClientDevice, r.ClientDevice,
r.KeyAnswerResult, // r.KeyAnswerResult,
loc.DataValue, r.Longitute,
loc.Enrollment, r.Latitude,
loc.Longitute, // Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
loc.Latitude,
Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
answers = from ans in answers answers = from ans in answers
where ans.SurveyResponseId == r.Id where ans.SurveyResponseId == r.Id
select new select new
{ {
ans.Id, ans.Id,
ans.QuestionId, // ans.QuestionId,
ans.AnswerText, ans.AnswerText,
ans.Comment, ans.Comment,
Questions = (from q in questions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(), Questions = (from q in questions where q.Id == ans.QuestionId select new { q.Id, q.QuestionNumber, q.CategoryId, q.Text }).SingleOrDefault(),
@ -712,8 +688,6 @@ namespace DamageAssesment.Api.Responses.Providers
} }
}; };
return result; return result;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -729,12 +703,12 @@ namespace DamageAssesment.Api.Responses.Providers
if (string.IsNullOrEmpty(language)) language = "en"; if (string.IsNullOrEmpty(language)) language = "en";
List<Db.SurveyResponse> surveyResonses; List<Db.SurveyResponse> surveyResonses;
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(a => a.SurveyId == surveyId).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(a => a.SurveyId == surveyId).ToListAsync();
var answers = await answerServiceProvider.getAnswersAsync(); var answers = await answerServiceProvider.getAnswersAsync(token);
var Locations = await locationServiceProvider.getLocationsAsync(); var Locations = await locationServiceProvider.getLocationsAsync(token);
var regions = await regionServiceProvider.getRegionsAsync(); var regions = await regionServiceProvider.getRegionsAsync(token);
var questions = await questionServiceProvider.getQuestionsAsync(language); var questions = await questionServiceProvider.getQuestionsAsync(language, token);
var categories = await questionServiceProvider.GetQuestionCategoriesAsync(language); var categories = await questionServiceProvider.GetQuestionCategoriesAsync(language, token);
var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
List<object> questionLists = new List<object>(); List<object> questionLists = new List<object>();
var allques = from res in surveyResonses var allques = from res in surveyResonses
join loc in Locations on res.LocationId equals loc.Id join loc in Locations on res.LocationId equals loc.Id
@ -866,8 +840,8 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync(); surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync();
} }
var answers = await answerServiceProvider.getAnswersAsync(); var answers = await answerServiceProvider.getAnswersAsync(token);
var locations = await locationServiceProvider.getLocationsAsync(); var locations = await locationServiceProvider.getLocationsAsync(token);
var maintenanceCenters = locations.DistinctBy(m => m.MaintenanceCenter); var maintenanceCenters = locations.DistinctBy(m => m.MaintenanceCenter);
//get all the answers for the particular survey //get all the answers for the particular survey
@ -933,27 +907,29 @@ namespace DamageAssesment.Api.Responses.Providers
if (employeeid == 0) if (employeeid == 0)
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.LocationId == locationId).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.LocationId == locationId).ToListAsync();
employees = await employeeServiceProvider.getEmployeesAsync(); employees = await employeeServiceProvider.getEmployeesAsync(token);
} }
else else
{ {
surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid && x.LocationId == locationId).ToListAsync(); surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid && x.LocationId == locationId).ToListAsync();
employee = await employeeServiceProvider.getEmployeeAsync(employeeid); employee = await employeeServiceProvider.getEmployeeAsync(employeeid, token);
if (employee != null) if (employee != null)
{ {
_employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber };
} }
} }
surveyResonses = surveyResonses
var answers = await answerServiceProvider.getAnswersAsync(); .OrderByDescending(obj => obj.Id)
var questions = await questionServiceProvider.getQuestionsAsync(null); .GroupBy(obj => new { obj.SurveyId, obj.LocationId }) //obj.EmployeeId,
.Select(group => group.FirstOrDefault()) // or .FirstOrDefault() if you want to handle empty groups
.ToList();
var answers = await answerServiceProvider.getAnswersAsync(token);
var questions = await questionServiceProvider.getQuestionsAsync(null, token);
var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; var surveyQuestions = from q in questions where q.SurveyId == surveyId select q;
var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
var Locations = await locationServiceProvider.getLocationsAsync();
var result = from r in surveyResonses var result = from r in surveyResonses
join loc in Locations on r.LocationId equals loc.Id
select new select new
{ {
r.Id, r.Id,
@ -961,18 +937,16 @@ namespace DamageAssesment.Api.Responses.Providers
r.LocationId, r.LocationId,
r.EmployeeId, r.EmployeeId,
r.ClientDevice, r.ClientDevice,
r.KeyAnswerResult, // r.KeyAnswerResult,
loc.DataValue, r.Longitute,
loc.Enrollment, r.Latitude,
loc.Longitute, // Employee = (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
loc.Latitude,
Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
answers = from ans in answers answers = from ans in answers
where ans.SurveyResponseId == r.Id where ans.SurveyResponseId == r.Id
select new select new
{ {
ans.QuestionId, // ans.QuestionId,
ans.Id, ans.Id,
ans.AnswerText, ans.AnswerText,
ans.Comment, ans.Comment,
@ -981,7 +955,6 @@ namespace DamageAssesment.Api.Responses.Providers
} }
}; };
return result; return result;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1004,26 +977,29 @@ namespace DamageAssesment.Api.Responses.Providers
if (employeeid == 0) if (employeeid == 0)
{ {
surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id).ToListAsync(); surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id).ToListAsync();
employees = await employeeServiceProvider.getEmployeesAsync(); employees = await employeeServiceProvider.getEmployeesAsync(token);
} }
else else
{ {
surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id && x.EmployeeId == employeeid).ToListAsync(); surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == survey.Id && x.EmployeeId == employeeid).ToListAsync();
employee = await employeeServiceProvider.getEmployeeAsync(employeeid); employee = await employeeServiceProvider.getEmployeeAsync(employeeid, token);
if (employee != null) if (employee != null)
{ {
_employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber }; _employee = new { employee.Id, employee.Name, employee.BirthDate, employee.Email, employee.OfficePhoneNumber };
} }
} }
surveyResponses = surveyResponses
.OrderByDescending(obj => obj.Id)
.GroupBy(obj => new { obj.SurveyId, obj.LocationId })//, obj.EmployeeId
.Select(group => group.FirstOrDefault()) // or .FirstOrDefault() if you want to handle empty groups
.ToList();
//var surveyResponses = await surveyResponseDbContext.Responses.Where(x => x.SurveyId == survey.Id).ToListAsync(); //var surveyResponses = await surveyResponseDbContext.Responses.Where(x => x.SurveyId == survey.Id).ToListAsync();
// var employees = await employeeServiceProvider.getEmployeesAsync(); // var employees = await employeeServiceProvider.getEmployeesAsync();
var answers = await answerServiceProvider.getAnswersAsync(); var answers = await answerServiceProvider.getAnswersAsync(token);
var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token);
var Locations = await locationServiceProvider.getLocationsAsync();
var result = from r in surveyResponses var result = from r in surveyResponses
join loc in Locations on r.LocationId equals loc.Id
select new select new
{ {
r.Id, r.Id,
@ -1031,12 +1007,10 @@ namespace DamageAssesment.Api.Responses.Providers
r.LocationId, r.LocationId,
r.EmployeeId, r.EmployeeId,
r.ClientDevice, r.ClientDevice,
r.KeyAnswerResult, // r.KeyAnswerResult,
loc.DataValue, r.Longitute,
loc.Enrollment, r.Latitude,
loc.Longitute, // Employee = (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
loc.Latitude,
Employee = employeeid != 0 ? _employee : (from e in employees where r.EmployeeId == e.Id select new { e.Id, e.Name, e.BirthDate, e.Email, e.OfficePhoneNumber }).SingleOrDefault(),
answers = from ans in answers answers = from ans in answers
where ans.SurveyResponseId == r.Id where ans.SurveyResponseId == r.Id
&& ans.QuestionId == question.Id && ans.QuestionId == question.Id
@ -1044,7 +1018,7 @@ namespace DamageAssesment.Api.Responses.Providers
select new select new
{ {
ans.QuestionId, // ans.QuestionId,
AnswerId = ans.Id, AnswerId = ans.Id,
ans.AnswerText, ans.AnswerText,
ans.Comment, ans.Comment,
@ -1066,12 +1040,12 @@ namespace DamageAssesment.Api.Responses.Providers
{ {
if (answerRequest != null) if (answerRequest != null)
{ {
var answer = await answerServiceProvider.PostAnswersAsync(new Models.Answer { QuestionId = answerRequest.QuestionId, AnswerText = answerRequest.AnswerText, Comment = answerRequest.Comment, SurveyResponseId = surveyResponseId }); var answer = await answerServiceProvider.PostAnswersAsync(new Models.Answer { QuestionId = answerRequest.QuestionId, AnswerText = answerRequest.AnswerText, Comment = answerRequest.Comment, SurveyResponseId = surveyResponseId }, token);
if (answer != null) if (answer != null)
{ {
List<AnswerInfo> listAnswerInfo = new List<AnswerInfo>(); List<AnswerInfo> listAnswerInfo = new List<AnswerInfo>();
listAnswerInfo.Add(new AnswerInfo { AnswerId = answer.Id, postedFiles = answerRequest.PostedFiles }); listAnswerInfo.Add(new AnswerInfo { AnswerId = answer.Id, postedFiles = answerRequest.PostedFiles });
var attachments = attachmentServiceProvider.PostAttachmentsAsync(new AttachmentInfo { ResponseId = surveyResponseId, Answers = listAnswerInfo }); var attachments = attachmentServiceProvider.PostAttachmentsAsync(new AttachmentInfo { ResponseId = surveyResponseId, Answers = listAnswerInfo }, token);
string message = $"Answer for question {answerRequest.QuestionId} saved to the database"; string message = $"Answer for question {answerRequest.QuestionId} saved to the database";
logger?.LogInformation(message); logger?.LogInformation(message);
@ -1092,7 +1066,6 @@ namespace DamageAssesment.Api.Responses.Providers
} }
} }
public async Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyAnswersAsync(Models.Request request) public async Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyAnswersAsync(Models.Request request)
{ {
try try

View File

@ -1,5 +1,6 @@
using DamageAssesment.Api.Responses.Interfaces; using DamageAssesment.Api.Responses.Interfaces;
using DamageAssesment.Api.Responses.Models; using DamageAssesment.Api.Responses.Models;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -10,11 +11,11 @@ namespace DamageAssesment.Api.Responses.Services
public AnswerServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger<AnswerServiceProvider> logger) : base(configuration, httpUtil, logger, configuration.GetValue<string>("RessourceSettings:Answer"), configuration.GetValue<string>("EndPointSettings:AnswerUrlBase")) public AnswerServiceProvider(IConfiguration configuration, IHttpUtil httpUtil, ILogger<AnswerServiceProvider> logger) : base(configuration, httpUtil, logger, configuration.GetValue<string>("RessourceSettings:Answer"), configuration.GetValue<string>("EndPointSettings:AnswerUrlBase"))
{ {
} }
public async Task<List<Answer>> getAnswersAsync() public async Task<List<Answer>> getAnswersAsync(string token)
{ {
try try
{ {
var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token);
var answers = JsonConvert.DeserializeObject<List<Answer>>(responseJsonString); var answers = JsonConvert.DeserializeObject<List<Answer>>(responseJsonString);
if (answers == null || !answers.Any()) if (answers == null || !answers.Any())
@ -28,12 +29,12 @@ namespace DamageAssesment.Api.Responses.Services
} }
} }
public async Task<List<Answer>> GetAnswersByResponseIdAsync(int responseId) public async Task<List<Answer>> GetAnswersByResponseIdAsync(int responseId, string token)
{ {
try try
{ {
url = urlBase + string.Format(configuration.GetValue<string>("RessourceSettings:AnswerByResponse"), responseId); url = urlBase + string.Format(configuration.GetValue<string>("RessourceSettings:AnswerByResponse"), responseId);
var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token);
var answers = JsonConvert.DeserializeObject<List<Answer>>(responseJsonString); var answers = JsonConvert.DeserializeObject<List<Answer>>(responseJsonString);
if (answers == null || !answers.Any()) if (answers == null || !answers.Any())
@ -47,12 +48,12 @@ namespace DamageAssesment.Api.Responses.Services
} }
} }
public async Task<Answer> PostAnswersAsync(Answer answer) public async Task<Answer> PostAnswersAsync(Answer answer, string token )
{ {
try try
{ {
var requestJsonString = JsonConvert.SerializeObject(answer); var requestJsonString = JsonConvert.SerializeObject(answer);
var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString); var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString, token);
var answers = JsonConvert.DeserializeObject<Answer>(responseJsonString); var answers = JsonConvert.DeserializeObject<Answer>(responseJsonString);
if (answers == null) if (answers == null)

View File

@ -10,11 +10,11 @@ namespace DamageAssesment.Api.Responses.Services
{ {
} }
public async Task<List<Attachment>> getAttachmentsAsync() public async Task<List<Attachment>> getAttachmentsAsync(string token)
{ {
try try
{ {
var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token);
var attachments = JsonConvert.DeserializeObject<List<Attachment>>(responseJsonString); var attachments = JsonConvert.DeserializeObject<List<Attachment>>(responseJsonString);
if (attachments == null || !attachments.Any()) if (attachments == null || !attachments.Any())
@ -28,12 +28,12 @@ namespace DamageAssesment.Api.Responses.Services
} }
} }
public async Task<IEnumerable<Attachment>> PostAttachmentsAsync(AttachmentInfo attachmentInfo) public async Task<IEnumerable<Attachment>> PostAttachmentsAsync(AttachmentInfo attachmentInfo, string token)
{ {
try try
{ {
var requestJsonString = JsonConvert.SerializeObject(attachmentInfo); var requestJsonString = JsonConvert.SerializeObject(attachmentInfo);
var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString); var responseJsonString = await httpUtil.SendAsync(HttpMethod.Post, url, requestJsonString, token);
var attachments = JsonConvert.DeserializeObject<IEnumerable<Attachment>>(responseJsonString); var attachments = JsonConvert.DeserializeObject<IEnumerable<Attachment>>(responseJsonString);
if (attachments == null) if (attachments == null)

Some files were not shown because too many files have changed in this diff Show More