From 43eb29c2e834b3bd8fd9b6532dfb8903a35bf2b1 Mon Sep 17 00:00:00 2001 From: Santhosh S <913341@dadeschools.net> Date: Fri, 10 Nov 2023 14:09:43 -0500 Subject: [PATCH 01/12] Updat for CORS Resolution --- .../DamageAssesment.Api.Answers/Program.cs | 12 ++++++++-- .../Program.cs | 8 +++++++ .../DamageAssesment.Api.DocuLinks/Program.cs | 8 +++++++ .../DamageAssesment.Api.Employees/Program.cs | 13 +++++++++-- .../DamageAssesment.Api.Locations/Program.cs | 12 ++++++++-- .../DamageAssesment.Api.Questions/Program.cs | 10 ++++++++- .../DamageAssesment.Api.Responses/Program.cs | 7 ++++++ .../DamageAssesment.Api.Surveys/Program.cs | 22 +++++++++++++++---- 8 files changed, 81 insertions(+), 11 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs index 0a38399..417195c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Answers/Program.cs @@ -8,10 +8,16 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -28,7 +34,6 @@ builder.Services.AddDbContext(option => var app = builder.Build(); - // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { @@ -36,8 +41,11 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } -app.UseAuthorization(); +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); +app.UseAuthorization(); +// Map controllers to their respective routes. app.MapControllers(); app.Run(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs index 4fd2e59..6aa5ed1 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs @@ -8,12 +8,18 @@ using System.Reflection; var builder = WebApplication.CreateBuilder(args); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -45,6 +51,8 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); app.UseAuthorization(); app.UseHttpsRedirection(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs index f28dd76..a2ec7ef 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs @@ -6,6 +6,11 @@ using System.Reflection; var builder = WebApplication.CreateBuilder(args); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + // Add services to the container. builder.Services.AddControllers(); @@ -36,6 +41,9 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } + +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs index 7d61871..b8548ff 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Employees/Program.cs @@ -6,12 +6,18 @@ using System.Reflection; var builder = WebApplication.CreateBuilder(args); -// Add services to the container. +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + + +// Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); -//builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -43,6 +49,9 @@ if (app.Environment.IsDevelopment()) } } +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); + app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs index f8136bd..a96e13f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Locations/Program.cs @@ -5,13 +5,18 @@ using Microsoft.EntityFrameworkCore; using System.Reflection; var builder = WebApplication.CreateBuilder(args); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + // Add services to the container. - +// Add controller services and API Explorer for endpoint discovery. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); -//builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -44,6 +49,9 @@ if (app.Environment.IsDevelopment()) } } +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); + app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs index c47a38d..2eedaff 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Program.cs @@ -15,8 +15,14 @@ builder.Services.AddControllers(); builder.Services.AddScoped(); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); + +// Add controller services and API Explorer for endpoint discovery. builder.Services.AddEndpointsApiExplorer(); -//builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -44,6 +50,8 @@ if (app.Environment.IsDevelopment()) } } +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs index 8b25674..972ccce 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs @@ -16,6 +16,10 @@ const int intervalForCircuitBraker = 5; //5 seconds // Add services to the container. builder.Services.AddControllers(); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddScoped(); @@ -36,6 +40,7 @@ builder.Services.AddHttpClient(). builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -56,6 +61,8 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); app.UseAuthorization(); app.MapControllers(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs index 178b5fd..c6a58a3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs @@ -10,7 +10,11 @@ using System.Reflection; var builder = WebApplication.CreateBuilder(args); // Add services to the container. + +// Retrieve the security key for JWT token validation. var authkey = builder.Configuration.GetValue("JwtSettings:securitykey"); + +// Configure JWT authentication and validation. builder.Services.AddAuthentication(item => { item.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; @@ -29,12 +33,18 @@ builder.Services.AddAuthentication(item => }; }); +// CORS setup to allow requests from any origin. +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); +// Add controller services and API Explorer for endpoint discovery. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddScoped(); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddEndpointsApiExplorer(); -//builder.Services.AddSwaggerGen(); + +// Add Swagger/OpenAPI documentation support. builder.Services.AddSwaggerGen(c => { // Include XML comments from your assembly @@ -42,10 +52,13 @@ builder.Services.AddSwaggerGen(c => var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); + +// Configure the database context for SurveysDbContext using SQL Server. builder.Services.AddDbContext(option => { option.UseSqlServer("SurveyConnection"); }); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -53,7 +66,7 @@ if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); - + // Seed initial data in the database when in development mode using (var serviceScope = app.Services.CreateScope()) { var services = serviceScope.ServiceProvider; @@ -61,10 +74,11 @@ if (app.Environment.IsDevelopment()) surveyProvider.seedData(); } } - +// Enable CORS, authentication, and authorization middleware. +app.UseCors("DamageAppCorsPolicy"); app.UseAuthentication(); app.UseAuthorization(); - +// Map controllers to their respective routes. app.MapControllers(); app.Run(); From b7e5e7d7fe5cfa2adda3271fe86543cbadd5e0f6 Mon Sep 17 00:00:00 2001 From: Santhosh S <913341@dadeschools.net> Date: Sat, 11 Nov 2023 22:00:06 -0500 Subject: [PATCH 02/12] Updated CORS with POST specific with Surveys --- .../DamageAssesment.Api.Surveys/Program.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs index c6a58a3..93545ae 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs @@ -34,9 +34,23 @@ builder.Services.AddAuthentication(item => }); // CORS setup to allow requests from any origin. -builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { - build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); -})); +//builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { +// build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +//})); + + + +builder.Services.AddCors(options => +{ + options.AddPolicy("DamageAppCorsPolicy", builder => + { + builder.WithOrigins("*") + .AllowAnyHeader() + .WithMethods("POST") // Allowing only the POST method + .AllowAnyOrigin(); + }); +}); + // Add controller services and API Explorer for endpoint discovery. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle From f00c7dd99c4c55580fcd4031bb4742fdbe8e8f52 Mon Sep 17 00:00:00 2001 From: Santhosh S <913341@dadeschools.net> Date: Sun, 12 Nov 2023 14:28:58 -0500 Subject: [PATCH 03/12] Updated WithOrigins(http://localhost:3000) test fix CORS --- .../DamageAssesment.Api.Surveys/Program.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs index 93545ae..eca1be6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs @@ -40,16 +40,20 @@ builder.Services.AddAuthentication(item => -builder.Services.AddCors(options => -{ - options.AddPolicy("DamageAppCorsPolicy", builder => - { - builder.WithOrigins("*") - .AllowAnyHeader() - .WithMethods("POST") // Allowing only the POST method - .AllowAnyOrigin(); - }); -}); +//builder.Services.AddCors(options => +//{ +// options.AddPolicy("DamageAppCorsPolicy", builder => +// { +// builder.WithOrigins("*") +// .AllowAnyHeader() +// .WithMethods("POST") // Allowing only the POST method +// .AllowAnyOrigin(); +// }); + +//}); +builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { + build.WithOrigins("http://localhost:3000").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); +})); // Add controller services and API Explorer for endpoint discovery. builder.Services.AddControllers(); From 1fba3e81f1745ea01fed76f24ef1b5c17c3d8a03 Mon Sep 17 00:00:00 2001 From: Santhosh S <913341@dadeschools.net> Date: Mon, 13 Nov 2023 21:24:16 -0500 Subject: [PATCH 04/12] Reverted Surveys CORS changes WithOrigins('*') --- .../DamageAssesment.Api.Surveys/Program.cs | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs index eca1be6..8c774f6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Program.cs @@ -33,28 +33,13 @@ builder.Services.AddAuthentication(item => }; }); -// CORS setup to allow requests from any origin. -//builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { -// build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); -//})); - - - -//builder.Services.AddCors(options => -//{ -// options.AddPolicy("DamageAppCorsPolicy", builder => -// { -// builder.WithOrigins("*") -// .AllowAnyHeader() -// .WithMethods("POST") // Allowing only the POST method -// .AllowAnyOrigin(); -// }); - -//}); +//CORS setup to allow requests from any origin. builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { - build.WithOrigins("http://localhost:3000").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); + build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); })); + + // Add controller services and API Explorer for endpoint discovery. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle From fc154274a0ba1b026e95e525a9ee243671d6a260 Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Tue, 14 Nov 2023 15:16:15 -0500 Subject: [PATCH 05/12] Added new endpoint for creating multiple questions --- .../Controllers/QuestionsController.cs | 20 +++++++++ .../Interfaces/IQuestionsProvider.cs | 1 + .../Providers/QuestionsProvider.cs | 43 ++++++++++++++----- .../MockData.cs | 17 ++++++-- .../QuestionsServiceTest.cs | 27 ++++++++++++ 5 files changed, 95 insertions(+), 13 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs index 7dec941..c73ff8a 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs @@ -89,6 +89,26 @@ namespace DamageAssesment.Api.Questions.Controllers return CreatedAtRoute("DefaultApi", new { id = question.Id }, question); } /// + /// POST request for creating a multiple question (multilingual). + /// + [HttpPost("questions/multiple")] + public async Task CreateQuestions(List questions) + { + if (questions != null) + { + var result = await this.questionsProvider.PostQuestionsAsync(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); + } + /// /// POST request for creating a new question (multilingual). /// diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs index f8e13c8..4fcea32 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs @@ -8,6 +8,7 @@ namespace DamageAssesment.Api.Questions.Interfaces Task<(bool IsSuccess, IEnumerable Questions, string ErrorMessage)> GetQuestionsAsync(string language); Task<(bool IsSuccess, List SurveyQuestions, string ErrorMessage)> GetSurveyQuestionAsync(int surveyId,string language); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> PostQuestionAsync(Models.Question Question); + Task<(bool IsSuccess, IEnumerable Question, string ErrorMessage)> PostQuestionsAsync(List Questions); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> DeleteQuestionAsync(int id); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs index 0122af7..e39d62c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs @@ -334,16 +334,7 @@ namespace DamageAssesment.Api.Questions.Providers try { logger?.LogInformation("Query Question"); - var dbquestion = mapper.Map(Question); - var dbquestiontranslation = mapper.Map, List>(Question.Questions); - dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); - questionDbContext.Questions.Add(dbquestion); - dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); - questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); - questionDbContext.SaveChanges(); - Question.Id = dbquestion.Id; - var result = mapper.Map(dbquestion); - result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id,"")); + var result = InsertQuestion(Question); return (true, result, null); } catch (Exception ex) @@ -352,6 +343,38 @@ namespace DamageAssesment.Api.Questions.Providers return (false, null, ex.Message); } } + private Models.MultiLanguage InsertQuestion(Models.Question Question) + { + var dbquestion = mapper.Map(Question); + var dbquestiontranslation = mapper.Map, List>(Question.Questions); + dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); + questionDbContext.Questions.Add(dbquestion); + dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); + questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); + questionDbContext.SaveChanges(); + Question.Id = dbquestion.Id; + var result = mapper.Map(dbquestion); + result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id, "")); + return result; + } + public async Task<(bool IsSuccess, IEnumerable Question, string ErrorMessage)> PostQuestionsAsync(List Questions) + { + try + { + List results = new List(); + logger?.LogInformation("Query Question"); + foreach (Models.Question Question in Questions) + { + 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) { try diff --git a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs index 8b13b70..df621f5 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs @@ -75,8 +75,19 @@ namespace DamageAssesment.Api.Questions.Test return new Questions.Models.Question { Id = 1, Questions=QuestionsTranslations, TypeText = "Text 1", SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId=1}; } - - - + public static async Task> getInputQuestionsData() + { + Models.QuestionsTranslation QuestionsTranslation = new Models.QuestionsTranslation() + { + Language = "en", + QuestionText = "Sample question" + }; + List QuestionsTranslations = new List(); + List Questions = new List(); + 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.Add(question); + return Questions; + } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs index bda9db2..b44e479 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs @@ -110,6 +110,33 @@ namespace DamageAssesment.Api.Questions.Test Assert.Equal(400, result.StatusCode); } + [Fact(DisplayName = "Post Questions - Ok case")] + public async Task PostQuestionsAsync_ShouldReturnStatusCode200() + { + var mockQuestionService = new Mock(); + var mockResponse = await MockData.getOkResponse(); + var mockInputQuestion = await MockData.getInputQuestionsData(); + mockQuestionService.Setup(service => service.PostQuestionsAsync(mockInputQuestion)).ReturnsAsync(mockResponse); + + var QuestionProvider = new QuestionsController(mockQuestionService.Object); + var result = (OkObjectResult)await QuestionProvider.CreateQuestions(mockInputQuestion); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Post Questions - BadRequest case")] + public async Task PostQuestionsAsync_ShouldReturnStatusCode400() + { + var mockQuestionService = new Mock(); + var mockInputQuestion = await MockData.getInputQuestionData(); + var mockResponse = await MockData.getBadRequestResponse(); + mockQuestionService.Setup(service => service.UpdateQuestionAsync(mockInputQuestion)).ReturnsAsync(mockResponse); + + var QuestionProvider = new QuestionsController(mockQuestionService.Object); + var result = (BadRequestObjectResult)await QuestionProvider.UpdateQuestion(mockInputQuestion); + + Assert.Equal(400, result.StatusCode); + } [Fact(DisplayName = "Put Question - Ok case")] public async Task PutQuestionAsync_ShouldReturnStatusCode200() From 281a789deb595bb95ee314adeb7cfa5be48814d7 Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Wed, 15 Nov 2023 09:05:20 -0500 Subject: [PATCH 06/12] fixed question transation issue --- .../DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs index e39d62c..d6bfebc 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs @@ -349,6 +349,7 @@ namespace DamageAssesment.Api.Questions.Providers var dbquestiontranslation = mapper.Map, List>(Question.Questions); dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); questionDbContext.Questions.Add(dbquestion); + questionDbContext.SaveChanges(); dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); questionDbContext.SaveChanges(); From 1df15e9a6d1409d55b0e84c58115890e71666b27 Mon Sep 17 00:00:00 2001 From: Santhosh S <913341@dadeschools.net> Date: Mon, 27 Nov 2023 14:49:14 -0500 Subject: [PATCH 07/12] Return Employee ID for POST --- .../Providers/EmployeesProvider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Employees/Providers/EmployeesProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Employees/Providers/EmployeesProvider.cs index b1741be..a071ab9 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Employees/Providers/EmployeesProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Employees/Providers/EmployeesProvider.cs @@ -77,7 +77,8 @@ namespace DamageAssesment.Api.Employees.Providers EmployeeDbContext.Employees.Add(_employee); Employee.Id = _employee.Id; EmployeeDbContext.SaveChanges(); - return (true, Employee, null); + //return (true, Employee, null); + return (true, mapper.Map(_employee), null); } return (false, null, "Employee code is already exits"); } From db5e14bde46d6d2cee874877becd0b8f945c3083 Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Thu, 30 Nov 2023 19:04:14 -0500 Subject: [PATCH 08/12] added multi language support for doculink attachments --- .../MockData.cs | 6 +++- .../Db/DoculinkAttachments.cs | 1 + .../Models/DoculinkAttachments.cs | 1 + .../Models/ReqDoculink.cs | 1 + .../Providers/DoculinkProvider.cs | 34 ++++++++++++------- .../Providers/UploadService.cs | 4 +-- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs index 843b4d3..0466fa8 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs @@ -32,7 +32,8 @@ namespace DamageAssesment.Api.DocuLinks.Test doclinksAttachments.Add(new DoculinkAttachments() { docName = "",Path="www.google.com", - IsAttachments=false,CustomOrder=1 + Language = "en", + IsAttachments =false,CustomOrder=1 }); list.Add(new DocuLinks.Models.ResDoculink() { @@ -74,6 +75,7 @@ namespace DamageAssesment.Api.DocuLinks.Test docName = "", Path = "www.google.com", IsAttachments = false, + Language = "en", CustomOrder = 1 }); list.Add(new DocuLinks.Models.ResDoculink() @@ -138,6 +140,7 @@ namespace DamageAssesment.Api.DocuLinks.Test docName = "", Path = "www.google.com", IsAttachments = false, + Language = "en", CustomOrder = 1 }); return new Models.Doculink @@ -165,6 +168,7 @@ namespace DamageAssesment.Api.DocuLinks.Test docName = "", Path = "www.google.com", IsAttachments = false, + Language = "en", CustomOrder = 1 }); List DocuLinks = new List(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Db/DoculinkAttachments.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Db/DoculinkAttachments.cs index b6eac5c..f277570 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Db/DoculinkAttachments.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Db/DoculinkAttachments.cs @@ -15,5 +15,6 @@ namespace DamageAssesment.Api.DocuLinks.Db public string Path { get; set; } public bool IsAttachments { get; set; } public int CustomOrder { get; set; } + public string Language { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/DoculinkAttachments.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/DoculinkAttachments.cs index ce87857..04a6970 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/DoculinkAttachments.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/DoculinkAttachments.cs @@ -8,6 +8,7 @@ namespace DamageAssesment.Api.DocuLinks.Models public string docName { get; set; } public string Path { get; set; } public bool IsAttachments { get; set; } + public string Language { get; set; } public int CustomOrder { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs index 0f2ea17..270a5f3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs @@ -18,5 +18,6 @@ namespace DamageAssesment.Api.DocuLinks.Models public int CustomOrder { get; set; } public string url { get;set; } public bool IsAttachments { get; set; } + public string Language { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 01ec9cf..749f200 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Immutable; using System.Diagnostics.Eventing.Reader; using System.Reflection.Metadata; +using System.Runtime.CompilerServices; using System.Xml; using System.Xml.Linq; @@ -71,10 +72,10 @@ namespace DamageAssesment.Api.DocuLinks.Providers { linkTypeId = 1; - fileModel = new FileModel() { FileName = "Sample" + i, FileExtension = ".txt", FileContent = "c2FtcGxl", IsAttachments = true, CustomOrder = 1 }; + fileModel = new FileModel() { FileName = "Sample" + i, FileExtension = ".txt", FileContent = "c2FtcGxl", IsAttachments = true, CustomOrder = 1, Language = "en" }; } else - fileModel = new FileModel() { url = "www.google" + i + ".com", IsAttachments = false, CustomOrder = 1 }; + fileModel = new FileModel() { url = "www.google" + i + ".com", IsAttachments = false, CustomOrder = 1,Language="en" }; ReqDoculink documentInfo = new ReqDoculink() { linkTypeId = i, CustomOrder = i, Files = new List() { fileModel } }; Models.Doculink document = uploadservice.UploadDocument(counter, documentInfo); DocumentDbContext.Documents.Add(mapper.Map(document)); @@ -170,7 +171,19 @@ namespace DamageAssesment.Api.DocuLinks.Providers MultiLanguage = dicttitle; return MultiLanguage; } - + private List GetDocumentAttachment(int id,string? language) + { + if (string.IsNullOrEmpty(language)) + { + return mapper.Map, List>( + DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + } + else + { + return mapper.Map, List>( + DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList()); + } + } public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive) { @@ -192,8 +205,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers item.titles = multilan.titles; item.description = multilan.description; item.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(item.linkTypeId, language)); - item.doclinksAttachments = mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == item.Id).ToList()); + item.doclinksAttachments = GetDocumentAttachment(item.Id,language); } // List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); return (true, result, null); @@ -228,8 +240,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers item.titles = multilan.titles; item.description = multilan.description; item.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(item.linkTypeId, language)); - item.doclinksAttachments = mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == item.Id).ToList()); + item.doclinksAttachments = GetDocumentAttachment(item.Id, language); } //List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); return (true, result, null); @@ -284,8 +295,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.documentsTranslations = mapper.Map, List>( DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == result.Id).ToList()); - result.doclinksAttachments = mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + result.doclinksAttachments = GetDocumentAttachment(id, ""); return (true, result, null); } return (false, null, "Not found"); @@ -317,8 +327,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, language)); result.titles = multilan.titles; result.description = multilan.description; - result.doclinksAttachments = mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + result.doclinksAttachments = GetDocumentAttachment(id, language); return (true, result, null); } return (false, null, "Not found"); @@ -429,8 +438,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.titles = multilan.titles; result.description = multilan.description; result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, "")); - result.doclinksAttachments = mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + result.doclinksAttachments = GetDocumentAttachment(id, ""); Document.IsActive = false; DocumentDbContext.Documents.Update(Document); DocumentDbContext.SaveChanges(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index 807a2e0..b4c5b52 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -51,7 +51,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers } else path = item.url; - attachments.Add(new Models.DoculinkAttachments { docName=UserfileName,Path=path,IsAttachments=item.IsAttachments,CustomOrder=item.CustomOrder }); + attachments.Add(new Models.DoculinkAttachments { docName=UserfileName,Path=path,IsAttachments=item.IsAttachments,CustomOrder=item.CustomOrder,Language=item.Language }); } } Documents=new Models.Doculink (){ linkTypeId = documentInfo.linkTypeId, @@ -92,7 +92,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers } else path = item.url; - attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path,IsAttachments=item.IsAttachments,CustomOrder=item.CustomOrder }); + attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path,IsAttachments=item.IsAttachments,CustomOrder=item.CustomOrder,Language=item.Language }); } Models.Doculink Documents = new Models.Doculink() { From 99a7802cf60f394cd309b39d1916c002fd91631d Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Fri, 1 Dec 2023 17:22:49 -0500 Subject: [PATCH 09/12] attachment and doculinks url changes --- .../Controllers/AttachmentsController.cs | 23 +++++++++ .../Interfaces/IAttachmentsProvider.cs | 1 + .../Interfaces/IUploadService.cs | 1 + .../Program.cs | 1 + .../Providers/AttachmentsProvider.cs | 45 ++++++++++++++++-- .../Providers/UploadService.cs | 21 ++++++++- .../Controllers/DoculinkController.cs | 23 +++++++++ .../Interfaces/IDoculinkProvider.cs | 1 + .../Interfaces/IUploadService.cs | 1 + .../DamageAssesment.Api.DocuLinks/Program.cs | 1 + .../Providers/DoculinkProvider.cs | 47 +++++++++++++++---- .../Providers/UploadService.cs | 21 ++++++++- 12 files changed, 169 insertions(+), 17 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs index 16c223c..b7cd328 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs @@ -136,6 +136,29 @@ namespace DamageAssesment.Api.Attachments.Controllers } } /// + /// download an existing attachment. + /// + [HttpGet("attachments/download/{id}")] + public async Task downloadfile1(int id) + { + try + { + var result = await this.AttachmentProvider.GetDownloadAttachmentAsync(id); + if(!result.IsSuccess) + return NotFound(); + byte[] fileContent = await UploadService.DownloadFile(result.Attachment.URI); + if (fileContent == null || fileContent.Length == 0) + return NotFound(); + var contentType = "application/octet-stream"; + return File(fileContent, contentType, result.Attachment.FileName); + } + catch (Exception ex) + { + // Handle the exception here or log it + return StatusCode(500, "An error occurred: " + ex.Message); + } + } + /// /// Delete an existing attachment. /// [HttpDelete("attachments/{id}")] diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs index 5e56dbb..06c4ead 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs @@ -9,6 +9,7 @@ namespace DamageAssesment.Api.Attachments.Interfaces Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> PostAttachmentAsync(List Attachments); Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> PutAttachmentAsync(List Attachments); Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> DeleteAttachmentAsync(int Id); + Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> GetDownloadAttachmentAsync(int Id); Task<(bool IsSuccess, int counter, string Path)> DeleteAttachmentsAsync(int responseId, int answerId); Task<(bool IsSuccess, int counter, string Path)> DeleteBulkAttachmentsAsync(int responseId, List answerIds); Task<(bool IsSuccess, int counter, string message)> GetAttachmentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs index f645593..f89653f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs @@ -7,6 +7,7 @@ namespace DamageAssesment.Api.Attachments.Interfaces List UploadAttachment(int responseId,int answerId, int counter, List postedFile); List UploadAttachment(int responseId, int counter, List answers); public List UpdateAttachments(int responseId, List answers, IEnumerable attachments); + Task DownloadFile(string path); void Deletefile(string path); void Movefile(string path); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs index 6aa5ed1..018740c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs @@ -27,6 +27,7 @@ builder.Services.AddSwaggerGen(c => var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs index 92c20e5..3489e28 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs @@ -13,25 +13,33 @@ namespace DamageAssesment.Api.Attachments.Providers private AttachmentsDbContext AttachmentDbContext; private ILogger logger; private IUploadService uploadservice; - private IMapper mapper; - - public AttachmentsProvider(AttachmentsDbContext AttachmentDbContext, ILogger logger, IMapper mapper,IUploadService uploadservice) + private IMapper mapper; + private readonly IHttpContextAccessor httpContextAccessor; + private string baseUrl; + public AttachmentsProvider(AttachmentsDbContext AttachmentDbContext, ILogger logger, IMapper mapper,IUploadService uploadservice, IHttpContextAccessor httpContextAccessor) { this.AttachmentDbContext = AttachmentDbContext; this.logger = logger; this.mapper = mapper; this.uploadservice = uploadservice; - //SeedData(); + this.httpContextAccessor = httpContextAccessor; + baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; + baseUrl = baseUrl + "/attachments/download"; + SeedData(); } public async Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> GetAttachmentsAsync() { - + try { logger?.LogInformation("Query Question"); var Attachment = await AttachmentDbContext.Attachments.AsNoTracking().Where(a => !a.IsDeleted).ToListAsync(); if (Attachment != null) { + foreach (var attachment in Attachment) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } logger?.LogInformation($"{Attachment.Count} Attachments(s) found"); var result = mapper.Map, IEnumerable>(Attachment); return (true, result, null); @@ -54,6 +62,7 @@ namespace DamageAssesment.Api.Attachments.Providers if (Attachment != null) { logger?.LogInformation($"{Attachment} customer(s) found"); + Attachment.URI = $"{baseUrl}/{Attachment.Id}"; var result = mapper.Map(Attachment); return (true, result, null); } @@ -73,6 +82,10 @@ namespace DamageAssesment.Api.Attachments.Providers List attachments = mapper.Map, List>(Attachments); AttachmentDbContext.Attachments.AddRange(attachments); await AttachmentDbContext.SaveChangesAsync(); + foreach (var attachment in attachments) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } var result = mapper.Map, IEnumerable>(attachments); return (true, result, null); } @@ -91,6 +104,10 @@ namespace DamageAssesment.Api.Attachments.Providers List attachments = mapper.Map, List>(Attachments); AttachmentDbContext.Attachments.UpdateRange(attachments); await AttachmentDbContext.SaveChangesAsync(); + foreach (var attachment in attachments) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } var result = mapper.Map, IEnumerable>(attachments); return (true, result, null); } @@ -197,6 +214,24 @@ namespace DamageAssesment.Api.Attachments.Providers { return AttachmentDbContext.Attachments.AsNoTracking().Count(e => e.Id == id && !e.IsDeleted) > 0; } + public async Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> GetDownloadAttachmentAsync(int Id) + { + try + { + Db.Attachment Attachment = AttachmentDbContext.Attachments.Where(a => a.Id == Id).AsNoTracking().FirstOrDefault(); + if (Attachment == null) + { + return (false, null, "Not Found"); + } + return (true, mapper.Map(Attachment), $"Attachment {Id}"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } private void SeedData() { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs index 8c9045c..6e03fd0 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs @@ -24,6 +24,23 @@ namespace DamageAssesment.Api.Attachments.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task DownloadFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return await System.IO.File.ReadAllBytesAsync(path); + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + } public List UploadAttachment(int responseId,int answerId,int counter, List postedFile) { var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), uploadpath); @@ -89,7 +106,7 @@ namespace DamageAssesment.Api.Attachments.Providers { counter++; - var UserfileName = Path.GetFileName(file.FileName); + var UserfileName = Path.GetFileName(file.FileName+ file.FileExtension); var fileName = String.Format("Attachment_{0}{1}", counter, file.FileExtension); var dbPath = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(dbPath, Convert.FromBase64String(file.FileContent)); @@ -126,7 +143,7 @@ namespace DamageAssesment.Api.Attachments.Providers foreach (var file in item.postedFiles) { Models.Attachment attachment= attachments.Where(a=>a.Id == file.AttachmentId).FirstOrDefault(); - var UserfileName = Path.GetFileName(file.FileName); + var UserfileName = Path.GetFileName(file.FileName + file.FileExtension); var fileName = String.Format("Attachment_{0}{1}", attachment?.Id, file.FileExtension); var dbPath = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(dbPath, Convert.FromBase64String(file.FileContent)); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs index 99d00a8..1d2e3de 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs @@ -104,6 +104,29 @@ namespace DamageAssesment.Api.DocuLinks.Controllers return NotFound(); } /// + /// download an existing attachment. + /// + [HttpGet("doculinks/download/{id}")] + public async Task downloadfile1(int id) + { + try + { + var result = await this.documentsProvider.GetDownloadAttachmentAsync(id); + if (!result.IsSuccess) + return NotFound(); + byte[] fileContent = await uploadService.DownloadFile(result.DoculinkAttachments.Path); + if (fileContent == null || fileContent.Length == 0) + return NotFound(); + var contentType = "application/octet-stream"; + return File(fileContent, contentType, result.DoculinkAttachments.docName); + } + catch (Exception ex) + { + // Handle the exception here or log it + return StatusCode(500, "An error occurred: " + ex.Message); + } + } + /// /// Get all Doculink. /// /// diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs index e9717ee..22f0fe6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs @@ -12,6 +12,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> PostDocumentAsync(Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id); + Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id); Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs index 4219fd6..4fbc5ee 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs @@ -7,6 +7,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces Models.Doculink UploadDocument( int counter, ReqDoculink documentInfo); public Models.Doculink UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo); void Deletefile(string path); + Task DownloadFile(string path); void Movefile(string path); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs index a2ec7ef..ec3acea 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs @@ -24,6 +24,7 @@ builder.Services.AddSwaggerGen(c => // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 749f200..30d3103 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -2,10 +2,12 @@ using DamageAssesment.Api.DocuLinks.Db; using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Models; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.Eventing.Reader; using System.Reflection.Metadata; @@ -23,13 +25,18 @@ namespace DamageAssesment.Api.DocuLinks.Providers private ILogger logger; private IUploadService uploadservice; private IMapper mapper; + private readonly IHttpContextAccessor httpContextAccessor; + private string baseUrl; - public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice) + public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice, IHttpContextAccessor httpContextAccessor) { this.DocumentDbContext = DocumentDbContext; this.logger = logger; this.mapper = mapper; this.uploadservice = uploadservice; + this.httpContextAccessor = httpContextAccessor; + baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; + baseUrl = baseUrl + "/doculinks/download"; SeedData(); } @@ -173,15 +180,38 @@ namespace DamageAssesment.Api.DocuLinks.Providers } private List GetDocumentAttachment(int id,string? language) { + List doculinkAttachments = null; if (string.IsNullOrEmpty(language)) { - return mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList(); } else { - return mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList()); + doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList(); + } + foreach (var attachment in doculinkAttachments) + { + if (attachment.IsAttachments) + attachment.Path = $"{baseUrl}/{attachment.Id}"; + } + return mapper.Map, List>(doculinkAttachments); + } + public async Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id) + { + try + { + Db.DoculinkAttachments Attachment = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.Id == id).AsNoTracking().FirstOrDefault(); + if (Attachment == null) + { + return (false, null, "Not Found"); + } + return (true, mapper.Map(Attachment), $"Attachment {id}"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); } } public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive) @@ -358,7 +388,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(Document.linkTypeId, "")); result.titles = multilan.titles; result.description = multilan.description; - result.doclinksAttachments = Document.doclinksAttachments; + result.doclinksAttachments = GetDocumentAttachment(document.Id,""); return (true, result, null); } catch (Exception ex) @@ -400,7 +430,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(document.linkTypeId, "")); result.titles = multilan.titles; result.description = multilan.description; - result.doclinksAttachments = Document.doclinksAttachments; + result.doclinksAttachments = GetDocumentAttachment(document.Id, ""); return (true, result, "Successful"); } else @@ -438,7 +468,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.titles = multilan.titles; result.description = multilan.description; result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, "")); - result.doclinksAttachments = GetDocumentAttachment(id, ""); + result.doclinksAttachments = mapper.Map, List>( + DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); Document.IsActive = false; DocumentDbContext.Documents.Update(Document); DocumentDbContext.SaveChanges(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index b4c5b52..12e29c3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -25,6 +25,23 @@ namespace DamageAssesment.Api.DocuLinks.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task DownloadFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return await System.IO.File.ReadAllBytesAsync(path); + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + } public Models.Doculink UploadDocument(int counter, ReqDoculink documentInfo) { @@ -44,7 +61,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers counter++; if (item.IsAttachments) { - UserfileName = Path.GetFileName(item.FileName); + UserfileName = Path.GetFileName(item.FileName + item.FileExtension); var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); path = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent)); @@ -85,7 +102,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers counter++; if (item.IsAttachments) { - UserfileName = Path.GetFileName(item.FileName); + UserfileName = Path.GetFileName(item.FileName+item.FileExtension); var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); path = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent)); From 9aa3f230c5d254bb7b2a4c31b6d275be534004dc Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Fri, 1 Dec 2023 17:23:19 -0500 Subject: [PATCH 10/12] attachment and doculinks url changes --- .../Providers/AttachmentsProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs index 3489e28..f409654 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs @@ -25,7 +25,7 @@ namespace DamageAssesment.Api.Attachments.Providers this.httpContextAccessor = httpContextAccessor; baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; baseUrl = baseUrl + "/attachments/download"; - SeedData(); + //SeedData(); } public async Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> GetAttachmentsAsync() { From fcc020517566ab00649d5914324055a4600cca6a Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Mon, 4 Dec 2023 09:52:05 -0500 Subject: [PATCH 11/12] added IsActive flag in doculinks request --- .../DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs | 1 + .../DamageAssesment.Api.DocuLinks/Providers/UploadService.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs index 0f2ea17..3691be2 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Models/ReqDoculink.cs @@ -7,6 +7,7 @@ namespace DamageAssesment.Api.DocuLinks.Models public int Id { get; set; } public int linkTypeId { get; set; } public List documentsTranslations { get; set; } + public bool IsActive { get; set; } public int CustomOrder { get; set; } public List? Files { get; set; } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index 807a2e0..e4900dc 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -56,7 +56,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers } Documents=new Models.Doculink (){ linkTypeId = documentInfo.linkTypeId, documentsTranslations = documentInfo.documentsTranslations,doclinksAttachments=attachments, - IsDeleted=false,CustomOrder=documentInfo.CustomOrder, IsActive =true}; + IsDeleted=false,CustomOrder=documentInfo.CustomOrder, IsActive =documentInfo.IsActive + }; return Documents; } @@ -99,7 +100,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers Id = documentInfo.Id, linkTypeId = documentInfo.linkTypeId, documentsTranslations=documentInfo.documentsTranslations, - IsActive = true, + IsActive = documentInfo.IsActive, IsDeleted=false, CustomOrder = documentInfo.CustomOrder, doclinksAttachments = attachments From e58782243c36f94171077675a0763bd6a939de1f Mon Sep 17 00:00:00 2001 From: Vijay Uppu <913468@dadeschools.net> Date: Mon, 4 Dec 2023 14:56:13 -0500 Subject: [PATCH 12/12] changed download url format and added new endpoint for doculink isactive update --- .../Controllers/AttachmentsController.cs | 63 ++++++++++-- .../Interfaces/IUploadService.cs | 1 + .../Providers/UploadService.cs | 18 ++++ .../DoculinkServiceTest.cs | 22 +++++ .../Controllers/DoculinkController.cs | 99 +++++++++++++++---- .../Interfaces/IDoculinkProvider.cs | 1 + .../Interfaces/IUploadService.cs | 1 + .../Providers/DoculinkProvider.cs | 29 ++++++ .../Providers/UploadService.cs | 18 ++++ 9 files changed, 229 insertions(+), 23 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs index b7cd328..e2fbe25 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs @@ -139,24 +139,75 @@ namespace DamageAssesment.Api.Attachments.Controllers /// download an existing attachment. /// [HttpGet("attachments/download/{id}")] - public async Task downloadfile1(int id) + public async Task downloadfile(int id) { try { var result = await this.AttachmentProvider.GetDownloadAttachmentAsync(id); - if(!result.IsSuccess) + if (!result.IsSuccess) return NotFound(); - byte[] fileContent = await UploadService.DownloadFile(result.Attachment.URI); - if (fileContent == null || fileContent.Length == 0) + string path = await UploadService.GetFile(result.Attachment.URI); + if (path == null) return NotFound(); - var contentType = "application/octet-stream"; - return File(fileContent, contentType, result.Attachment.FileName); + var contentType = GetContentType(result.Attachment.FileName); + if (contentType == "application/octet-stream") + return PhysicalFile(path, contentType, result.Attachment.FileName); + return PhysicalFile(path, contentType, enableRangeProcessing: true);// result.Attachment.FileName); } catch (Exception ex) { // Handle the exception here or log it return StatusCode(500, "An error occurred: " + ex.Message); } + //try + //{ + // var result = await this.AttachmentProvider.GetDownloadAttachmentAsync(id); + // if(!result.IsSuccess) + // return NotFound(); + // byte[] fileContent = await UploadService.DownloadFile(result.Attachment.URI); + // if (fileContent == null || fileContent.Length == 0) + // return NotFound(); + // var contentType = "application/octet-stream"; + // return File(fileContent, contentType, result.Attachment.FileName); + //} + //catch (Exception ex) + //{ + // // Handle the exception here or log it + // return StatusCode(500, "An error occurred: " + ex.Message); + //} + } + private string GetContentType(string fileName) + { + // You can add more content types based on the file extensions + switch (Path.GetExtension(fileName).ToLower()) + { + //case ".txt": + // return "text/plain"; + case ".jpg": + case ".jpeg": + return "image/jpeg"; + case ".png": + return "image/png"; + case ".gif": + return "image/gif"; + case ".bmp": + return "image/bmp"; + case ".webp": + return "image/webp"; + case ".csv": + return "text/csv"; + case ".pdf": + return "application/pdf"; + case ".docx": + case ".doc": + return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + case ".xlsx": + case ".xls": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + // Add more cases as needed + default: + return "application/octet-stream"; + } } /// /// Delete an existing attachment. diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs index f89653f..1d2d0e0 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs @@ -8,6 +8,7 @@ namespace DamageAssesment.Api.Attachments.Interfaces List UploadAttachment(int responseId, int counter, List answers); public List UpdateAttachments(int responseId, List answers, IEnumerable attachments); Task DownloadFile(string path); + Task GetFile(string path); void Deletefile(string path); void Movefile(string path); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs index 6e03fd0..09711b5 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs @@ -24,6 +24,24 @@ namespace DamageAssesment.Api.Attachments.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task GetFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return path; + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + + } public async Task DownloadFile(string path) { try diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs index a8f45d1..e30925f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs @@ -197,7 +197,29 @@ namespace DamageAssesment.Api.DocuLinks.Test var result = (NotFoundResult)await DocumentProvider.DeleteDocument(1); Assert.Equal(404, result.StatusCode); } + [Fact(DisplayName = "Update Document IsActive- Ok case")] + public async Task UpdateDocumentAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(1); + mockDocumentService.Setup(service => service.UpdateDocumentAsync(1,true)).ReturnsAsync(mockResponse); + var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.UpdateIsActiveDocument(1,true); + Assert.Equal(200, result.StatusCode); + } + [Fact(DisplayName = "Update Document IsActive - NotFound case")] + public async Task UpdateDocumentAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNotFoundResponse(); + mockDocumentService.Setup(service => service.UpdateDocumentAsync(1,true)).ReturnsAsync(mockResponse); + var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundResult)await DocumentProvider.UpdateIsActiveDocument(1,true); + Assert.Equal(404, result.StatusCode); + } // Link Type Test cases diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs index 1d2e3de..4cee929 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs @@ -13,11 +13,11 @@ namespace DamageAssesment.Api.DocuLinks.Controllers private readonly IDoculinkProvider documentsProvider; private readonly IUploadService uploadService; - public DoculinkController(IDoculinkProvider documentsProvider,IUploadService uploadService) + public DoculinkController(IDoculinkProvider documentsProvider, IUploadService uploadService) { this.documentsProvider = documentsProvider; - this.uploadService = uploadService; + this.uploadService = uploadService; } /// @@ -41,7 +41,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers [HttpGet] [Route("doculinks/types/{id}")] [Route("doculinks/types/{id}/{language:alpha}")] - public async Task GetLinkTypeAsync(int id,string? language) + public async Task GetLinkTypeAsync(int id, string? language) { var result = await this.documentsProvider.GetLinkTypeAsync(id, language); if (result.IsSuccess) @@ -55,11 +55,11 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// [HttpPut] [Route("doculinks/types/{id}")] - public async Task UpdateLinkType(int id,Models.LinkType linkType) + public async Task UpdateLinkType(int id, Models.LinkType linkType) { if (linkType != null) { - var result = await this.documentsProvider.UpdateLinkTypeAsync(id,linkType); + var result = await this.documentsProvider.UpdateLinkTypeAsync(id, linkType); if (result.IsSuccess) { return Ok(result.LinkType); @@ -107,24 +107,75 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// download an existing attachment. /// [HttpGet("doculinks/download/{id}")] - public async Task downloadfile1(int id) + public async Task downloadfile(int id) { try { var result = await this.documentsProvider.GetDownloadAttachmentAsync(id); if (!result.IsSuccess) return NotFound(); - byte[] fileContent = await uploadService.DownloadFile(result.DoculinkAttachments.Path); - if (fileContent == null || fileContent.Length == 0) + string path = await uploadService.GetFile(result.DoculinkAttachments.Path); + if (path == null) return NotFound(); - var contentType = "application/octet-stream"; - return File(fileContent, contentType, result.DoculinkAttachments.docName); + var contentType = GetContentType(result.DoculinkAttachments.docName); + if (contentType == "application/octet-stream") + return PhysicalFile(path, contentType, result.DoculinkAttachments.docName); + return PhysicalFile(path, contentType, enableRangeProcessing: true); } catch (Exception ex) { // Handle the exception here or log it return StatusCode(500, "An error occurred: " + ex.Message); } + //try + //{ + // var result = await this.documentsProvider.GetDownloadAttachmentAsync(id); + // if (!result.IsSuccess) + // return NotFound(); + // byte[] fileContent = await uploadService.DownloadFile(result.DoculinkAttachments.Path); + // if (fileContent == null || fileContent.Length == 0) + // return NotFound(); + // var contentType = "application/octet-stream"; + // return File(fileContent, contentType, result.DoculinkAttachments.docName); + //} + //catch (Exception ex) + //{ + // // Handle the exception here or log it + // return StatusCode(500, "An error occurred: " + ex.Message); + //} + } + private string GetContentType(string fileName) + { + // You can add more content types based on the file extensions + switch (Path.GetExtension(fileName).ToLower()) + { + //case ".txt": + // return "text/plain"; + case ".jpg": + case ".jpeg": + return "image/jpeg"; + case ".png": + return "image/png"; + case ".gif": + return "image/gif"; + case ".bmp": + return "image/bmp"; + case ".webp": + return "image/webp"; + case ".csv": + return "text/csv"; + case ".pdf": + return "application/pdf"; + case ".docx": + case ".doc": + return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + case ".xlsx": + case ".xls": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + // Add more cases as needed + default: + return "application/octet-stream"; + } } /// /// Get all Doculink. @@ -134,7 +185,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers [Route("doculinks/{linktype:alpha}")] [Route("doculinks/{linktype:alpha}/{language:alpha}")] [HttpGet] - public async Task GetDocumentsAsync(string? linktype, string? language,bool? isactive) + public async Task GetDocumentsAsync(string? linktype, string? language, bool? isactive) { var result = await this.documentsProvider.GetdocumentsByLinkAsync(linktype, language, isactive); if (result.IsSuccess) @@ -152,7 +203,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers [HttpGet] public async Task GetDocumentsByActiveAsync(string? linktype, string? language) { - var result = await this.documentsProvider.GetdocumentsByLinkAsync(linktype, language,true); + var result = await this.documentsProvider.GetdocumentsByLinkAsync(linktype, language, true); if (result.IsSuccess) { return Ok(result.documents); @@ -181,7 +232,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers [Route("doculinks/{id}")] [Route("doculinks/{id}/{linktype:alpha}")] [Route("doculinks/{id}/{linktype:alpha}/{language:alpha}")] - public async Task GetDocumentAsync(int id,string? linktype, string? language) + public async Task GetDocumentAsync(int id, string? linktype, string? language) { var result = await this.documentsProvider.GetDocumentAsync(id, linktype, language); if (result.IsSuccess) @@ -195,7 +246,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// [HttpPut] [Route("doculinks/{id}")] - public async Task UpdateDocument(int id,ReqDoculink documentInfo) + public async Task UpdateDocument(int id, ReqDoculink documentInfo) { if (documentInfo != null) { @@ -203,7 +254,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers if (dbdoc.IsSuccess) { var documents = await this.documentsProvider.GetDocumentCounter(); - Models.Doculink DocuLink= uploadService.UpdateDocuments(documents.counter,dbdoc.Document, documentInfo); + Models.Doculink DocuLink = uploadService.UpdateDocuments(documents.counter, dbdoc.Document, documentInfo); var result = await this.documentsProvider.UpdateDocumentAsync(id, DocuLink); if (result.IsSuccess) { @@ -216,6 +267,20 @@ namespace DamageAssesment.Api.DocuLinks.Controllers return BadRequest(documentInfo); } /// + /// update existing doclink isactive field. + /// + [HttpPut] + [Route("doculinks/{id}/{isactive}")] + public async Task UpdateIsActiveDocument(int id, bool isactive) + { + var result = await this.documentsProvider.UpdateDocumentAsync(id, isactive); + if (result.IsSuccess) + { + return Ok(result.Document); + } + return NotFound(); + } + /// /// Create new doclink. /// [HttpPost] @@ -227,7 +292,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers if (documentInfo != null) { var documents = await this.documentsProvider.GetDocumentCounter(); - Models.Doculink DocuLink= uploadService.UploadDocument(documents.counter, documentInfo); + Models.Doculink DocuLink = uploadService.UploadDocument(documents.counter, documentInfo); var result = await this.documentsProvider.PostDocumentAsync(DocuLink); if (result.IsSuccess) { @@ -262,6 +327,6 @@ namespace DamageAssesment.Api.DocuLinks.Controllers } return NotFound(); } - + } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs index 22f0fe6..d873bbe 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs @@ -11,6 +11,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> PostDocumentAsync(Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, Models.Doculink Document); + Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, bool isactive); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id); Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id); Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs index 4fbc5ee..63c00aa 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs @@ -8,6 +8,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces public Models.Doculink UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo); void Deletefile(string path); Task DownloadFile(string path); + Task GetFile(string path); void Movefile(string path); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 30d3103..b7c119d 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -453,6 +453,35 @@ namespace DamageAssesment.Api.DocuLinks.Providers return (false, null, ex.Message); } } + public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id,bool isactive) + { + + try + { + Db.Doculink Document = DocumentDbContext.Documents.AsNoTracking().Where(a => a.Id == id).FirstOrDefault(); + if (Document == null) + { + return (false, null, "Not Found"); + } + Document.IsActive = isactive; + DocumentDbContext.Documents.Update(Document); + DocumentDbContext.SaveChanges(); + var result = mapper.Map(Document); + var multilan = CreateMultiLanguageObject(GetDocumentTranslations(Document.Id, "")); + result.titles = multilan.titles; + result.description = multilan.description; + result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, "")); + result.doclinksAttachments = mapper.Map, List>( + DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + return (true, result, $"DocumentId {id} deleted Successfuly"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index 12e29c3..5d670b7 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -25,6 +25,24 @@ namespace DamageAssesment.Api.DocuLinks.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task GetFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return path; + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + + } public async Task DownloadFile(string path) { try