From fd65417a7b114bfc5f23900bf83b90c41fd83450 Mon Sep 17 00:00:00 2001 From: uppuv Date: Thu, 31 Aug 2023 19:00:51 -0400 Subject: [PATCH 1/2] Added Document api solution --- .../DamageAssesment.Api.Documents.Test.csproj | 27 ++ .../DocumentsServiceTest.cs | 331 ++++++++++++++++ .../LinkTypeMockData.cs | 61 +++ .../MockData.cs | 117 ++++++ .../Controllers/DocumentsController.cs | 222 +++++++++++ .../DASA_Documents/Active/Document_1.txt | 1 + .../DamageAssesment.Api.Documents.csproj | 31 ++ .../Db/Document.cs | 22 ++ .../Db/DocumentDbContext.cs | 37 ++ .../Db/DocumentsTranslation.cs | 16 + .../Db/LinkType.cs | 13 + .../Interfaces/IAzureBlobService.cs | 10 + .../Interfaces/IDocumentTypeProvider.cs | 11 + .../Interfaces/IDocumentsProvider.cs | 17 + .../Interfaces/IUploadService.cs | 12 + ...28165655_InitialDocumentCreate.Designer.cs | 95 +++++ .../20230828165655_InitialDocumentCreate.cs | 60 +++ ...0830200432_DocumentTranslation.Designer.cs | 118 ++++++ .../20230830200432_DocumentTranslation.cs | 70 ++++ .../DocumentDbContextModelSnapshot.cs | 115 ++++++ .../Models/Document.cs | 19 + .../Models/DocumentInfo.cs | 19 + .../Models/DocumentsTranslation.cs | 12 + .../Models/LinkType.cs | 12 + .../Profiles/DocumentProfile.cs | 17 + .../DamageAssesment.Api.Documents/Program.cs | 35 ++ .../Properties/launchSettings.json | 31 ++ .../Providers/AzureBlobService.cs | 44 +++ .../Providers/DocumentsProvider.cs | 363 ++++++++++++++++++ .../Providers/UploadService.cs | 123 ++++++ .../appsettings.Development.json | 8 + .../appsettings.json | 16 + DamageAssesmentApi/DamageAssesment.sln | 12 + 33 files changed, 2097 insertions(+) create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DamageAssesment.Api.Documents.Test.csproj create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DocumentsServiceTest.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents.Test/LinkTypeMockData.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents.Test/MockData.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Controllers/DocumentsController.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/DASA_Documents/Active/Document_1.txt create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/DamageAssesment.Api.Documents.csproj create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Db/Document.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentsTranslation.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Db/LinkType.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IAzureBlobService.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentTypeProvider.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentsProvider.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IUploadService.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.Designer.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.Designer.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/DocumentDbContextModelSnapshot.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Models/Document.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentInfo.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentsTranslation.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Models/LinkType.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Profiles/DocumentProfile.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Properties/launchSettings.json create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/AzureBlobService.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/UploadService.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.Development.json create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DamageAssesment.Api.Documents.Test.csproj b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DamageAssesment.Api.Documents.Test.csproj new file mode 100644 index 0000000..725bea6 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DamageAssesment.Api.Documents.Test.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DocumentsServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DocumentsServiceTest.cs new file mode 100644 index 0000000..9d63289 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/DocumentsServiceTest.cs @@ -0,0 +1,331 @@ +using DamageAssesment.Api.Documents.Controllers; +using DamageAssesment.Api.Documents.Interfaces; +using DamageAssesment.Api.Documents.Models; +using Microsoft.AspNetCore.Mvc; +using Moq; +using Xunit; + +namespace DamageAssesment.Api.Documents.Test +{ + + public class DocumentServiceTest + { + + [Fact(DisplayName = "Get Documents - NoContent Case")] + public async Task GetDocumentsLanguageAsync_ShouldReturnStatusCode204() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNoContentResponse(); + mockDocumentService.Setup(service => service.GetDocumnetsAsync()).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.GetDocumentsbyFormsandLanguageAsync("", ""); + + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "Get Documents - NoContent Case")] + public async Task GetDocumentsLinkTypeAsync_ShouldReturnStatusCode204() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNoContentResponse(); + mockDocumentService.Setup(service => service.GetDocumnetsAsync()).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.GetDocumentsbyFormsandLanguageAsync("", ""); + + Assert.Equal(204, result.StatusCode); + } + [Fact(DisplayName = "Get Documents - Ok case")] + public async Task GetDocumentsAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(); + mockDocumentService.Setup(service => service.GetDocumnetsAsync()).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.GetDocumentsAsync(); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Get Documents - NoContent Case")] + public async Task GetDocumentsAsync_ShouldReturnStatusCode204() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNoContentResponse(); + mockDocumentService.Setup(service => service.GetDocumnetsAsync()).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.GetDocumentsAsync(); + + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "Get Document by Id - Ok case")] + public async Task GetDocumentAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(1); + mockDocumentService.Setup(service => service.GetDocumentAsync(1)).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.GetDocumentAsync(1); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Get Document by Id - NotFound case")] + public async Task GetDocumentAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNotFoundResponse(); + mockDocumentService.Setup(service => service.GetDocumentAsync(99)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundResult)await DocumentProvider.GetDocumentAsync(99); + Assert.Equal(404, result.StatusCode); + } + [Fact(DisplayName = "Post Document - Ok case")] + public async Task PostDocumentAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(1); + var mockInputDocument = await MockData.getInputDocumentData(); + var DocumentResponse = await MockData.GetDocumentsInfo(0); + mockDocumentService.Setup(service => service.PostDocumentAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.CreateDocument(DocumentResponse); + + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "Post Document - BadRequest case")] + public async Task PostDocumentAsync_ShouldReturnStatusCode400() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockInputDocument = await MockData.getInputDocumentData(); + var mockResponse = await MockData.getBadRequestResponse(); + DocumentInfo documentInfo = null; + mockDocumentService.Setup(service => service.PostDocumentAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (BadRequestObjectResult)await DocumentProvider.CreateDocument(documentInfo); + + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "Put Document - Ok case")] + public async Task PutDocumentAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(1); + var mockInputDocument = await MockData.getInputDocumentData(); + var DocumentResponse = await MockData.GetDocumentsInfo(1); + mockDocumentService.Setup(service => service.UpdateDocumentAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.UpdateDocument(DocumentResponse); + + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "Put Document - BadRequest case")] + public async Task PutDocumentAsync_ShouldReturnStatusCode400() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getBadRequestResponse(); + var mockInputDocument = await MockData.getInputDocumentData(); + mockDocumentService.Setup(service => service.UpdateDocumentAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (BadRequestObjectResult)await DocumentProvider.UpdateDocument(null); + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "Delete Document - Ok case")] + public async Task DeleteDocumentAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getOkResponse(1); + mockDocumentService.Setup(service => service.DeleteDocumentAsync(1)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.DeleteDocument(1); + + Assert.Equal(200, result.StatusCode); + } + [Fact(DisplayName = "Delete Document - NotFound case")] + public async Task DeleteDocumentAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await MockData.getNotFoundResponse(); + mockDocumentService.Setup(service => service.DeleteDocumentAsync(1)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundResult)await DocumentProvider.DeleteDocument(1); + Assert.Equal(404, result.StatusCode); + } + + + // Link Type Test cases + + + [Fact(DisplayName = "Get Link types - Ok case")] + public async Task GetDocumentCategoriesAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getOkResponse(); + mockDocumentService.Setup(service => service.GetLinkTypesAsync()).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.GetLinkTypesAsync(); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Get Link types - NoContent Case")] + public async Task GetDocumentCategoriesAsync_ShouldReturnStatusCode204() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getNoContentResponse(); + mockDocumentService.Setup(service => service.GetLinkTypesAsync()).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NoContentResult)await DocumentProvider.GetLinkTypesAsync(); + + Assert.Equal(204, result.StatusCode); + } + + [Fact(DisplayName = "Get Link Type by Id - Ok case")] + public async Task GetDocumentcategoryAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getOkResponse(1); + mockDocumentService.Setup(service => service.GetLinkTypeAsync(1)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.GetLinkTypeAsync(1); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Get Link Type by Id - NotFound case")] + public async Task GetDocumentcategoryAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getNotFoundResponse(); + mockDocumentService.Setup(service => service.GetLinkTypeAsync(99)).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundResult)await DocumentProvider.GetLinkTypeAsync(99); + Assert.Equal(404, result.StatusCode); + } + + [Fact(DisplayName = "Post Link Type - Ok case")] + public async Task PostDocumentcategoryAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getOkResponse(1); + var mockInputDocument = await LinkTypeMockData.getInputLinkData(0); + mockDocumentService.Setup(service => service.PostLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.CreateLinkType(mockInputDocument); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Post Link Type - BadRequest case")] + public async Task PostDocumentcategoryAsync_ShouldReturnStatusCode400() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockInputDocument = await LinkTypeMockData.getInputLinkData(99); + var mockResponse = await LinkTypeMockData.getBadRequestResponse(); + mockDocumentService.Setup(service => service.PostLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (BadRequestObjectResult)await DocumentProvider.CreateLinkType(mockInputDocument); + + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "Put Document - Ok case")] + public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getOkResponse(1); + var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); + mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.UpdateLinkType(mockInputDocument); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Put Document - NotFound case")] + public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getNotFoundResponse(); + var mockInputDocument = await LinkTypeMockData.getInputLinkData(99); + mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundObjectResult)await DocumentProvider.UpdateLinkType(mockInputDocument); + + Assert.Equal(404, result.StatusCode); + } + + [Fact(DisplayName = "Put Document - BadRequest case")] + public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode400() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getBadRequestResponse(); + var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); + mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (BadRequestObjectResult)await DocumentProvider.UpdateLinkType(mockInputDocument); + + Assert.Equal(400, result.StatusCode); + } + + [Fact(DisplayName = "Delete Document - Ok case")] + public async Task DeleteDocumentcategoryAsync_ShouldReturnStatusCode200() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getOkResponse(1); + + mockDocumentService.Setup(service => service.DeleteLinkTypeAsync(1)).ReturnsAsync(mockResponse); + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (OkObjectResult)await DocumentProvider.DeleteLinkType(1); + + Assert.Equal(200, result.StatusCode); + } + [Fact(DisplayName = "Delete Document - NotFound case")] + public async Task DeleteDocumentcategoryAsync_ShouldReturnStatusCode404() + { + var mockDocumentService = new Mock(); + var mockUploadService = new Mock(); + var mockResponse = await LinkTypeMockData.getNotFoundResponse(); + mockDocumentService.Setup(service => service.DeleteLinkTypeAsync(1)).ReturnsAsync(mockResponse); + + var DocumentProvider = new DocumentsController(mockDocumentService.Object, mockUploadService.Object); + var result = (NotFoundResult)await DocumentProvider.DeleteLinkType(99); + + Assert.Equal(404, result.StatusCode); + } + + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/LinkTypeMockData.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/LinkTypeMockData.cs new file mode 100644 index 0000000..644b7d5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/LinkTypeMockData.cs @@ -0,0 +1,61 @@ +using DamageAssesment.Api.Documents.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; + +namespace DamageAssesment.Api.Documents.Test +{ + public class LinkTypeMockData + { + + public static async Task<(bool, List, string)> getOkResponse() + { + List list = new List(); + + for (int i = 1; i < 4; i++) + { + list.Add(new Documents.Models.LinkType() + { + Id = i, + TypeText = "sample"+i, + IsActive = true + }); + } + return (true, list, null); + } + public static async Task<(bool, Documents.Models.LinkType, string)> getOkResponse(int Id) + { + var Documents = await getOkResponse(); + var Document = Documents.Item2.FirstOrDefault(s => s.Id == Id); + return (true, Document, null); + } + public static async Task<(bool, Documents.Models.LinkType, string)> getBadRequestResponse() + { + return (false, null, "Bad Request"); + } + + public static async Task<(bool, Documents.Models.LinkType, string)> getNotFoundResponse() + { + return (false, null, "Not Found"); + } + public static async Task<(bool, IEnumerable, string)> getNoContentResponse() + { + IEnumerable list = new List(); + return (false, list, null); + } + + public static async Task getInputLinkData(int id) + { + return new Models.LinkType + { + Id = id, + TypeText = "sample", + IsActive = true + }; + } + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/MockData.cs new file mode 100644 index 0000000..374a929 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents.Test/MockData.cs @@ -0,0 +1,117 @@ +using DamageAssesment.Api.Documents.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; + +namespace DamageAssesment.Api.Documents.Test +{ + public class MockData + { + + public static async Task<(bool, List, string)> getOkResponse() + { + List list = new List(); + + for (int i = 1; i < 4; i++) + { + List documentsTranslations = new List(); + documentsTranslations.Add(new DocumentsTranslation() + { + Language = "en", + title = "tel"+i, + description = "Sample"+i + }); + list.Add(new Documents.Models.Document() + { + + Id = i, + linkTypeId = i, + docName = "sample"+i, + url = "testurl" + i, + Path = "testpath" + i, + IsActive = true, + documentsTranslations= documentsTranslations, + dateCreated = DateTime.Now, + dateUpdated = DateTime.Now + }); + } + return (true, list, null); + } + public static async Task<(bool, Documents.Models.Document, string)> getOkResponse(int Id) + { + var Documents = await getOkResponse(); + var Document = Documents.Item2.FirstOrDefault(s => s.Id == Id); + return (true, Document, null); + } + + public static async Task<(bool, Documents.Models.Document, string)> getBadRequestResponse() + { + return (false, null, "Bad Request"); + } + + public static async Task<(bool, Documents.Models.Document, string)> getNotFoundResponse() + { + return (false, null, "Not Found"); + } + public static async Task<(bool, IEnumerable, string)> getNoContentResponse() + { + IEnumerable list = new List(); + return (false, list, null); + } + public static async Task GetDocumentsInfo(int id) + { + FileModel fileModel = new FileModel() { FileName = "Sample", FileContent = "c2FtcGxl", FileExtension = ".txt" }; + return new DocumentInfo() { Id=id, linkTypeId = 1, url = "Sample", File = fileModel }; + } + public static async Task getInputDocumentData() + { + List documentsTranslations = new List(); + documentsTranslations.Add(new DocumentsTranslation() + { + Language = "en", + title = "tel", + description = "Sample" + }); + return new Models.Document + { + Id = 1, + linkTypeId = 1, + docName = "sample", + url = "testurl", + Path = "testpath", + IsActive = true, + documentsTranslations= documentsTranslations, + dateCreated = DateTime.Now, + dateUpdated = DateTime.Now + }; + } + public static async Task> getInputDocumentsData() + { + List documentsTranslations = new List(); + documentsTranslations.Add(new DocumentsTranslation() + { + Language = "en", + title = "tel", + description="Sample" + }); + List Documents = new List(); + Documents.Add(new Models.Document + { + Id = 1, + linkTypeId = 1, + docName = "sample", + url = "testurl", + Path = "testpath", + IsActive = true, + documentsTranslations= documentsTranslations, + dateCreated = DateTime.Now, + dateUpdated = DateTime.Now + }); + return Documents; + } + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Controllers/DocumentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Controllers/DocumentsController.cs new file mode 100644 index 0000000..38d8ee5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Controllers/DocumentsController.cs @@ -0,0 +1,222 @@ +using DamageAssesment.Api.Documents.Db; +using DamageAssesment.Api.Documents.Interfaces; +using DamageAssesment.Api.Documents.Models; +using DamageAssesment.Api.Documents.Providers; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace DamageAssesment.Api.Documents.Controllers +{ + [Route("api")] + [ApiController] + public class DocumentsController : ControllerBase + { + private readonly IDocumentsProvider documentsProvider; + private readonly IUploadService uploadService; + + public DocumentsController(IDocumentsProvider documentsProvider,IUploadService uploadService) + { + + this.documentsProvider = documentsProvider; + this.uploadService = uploadService; + + } + + /// + /// Get all documnets. + /// + [HttpGet("{language}/{LinkType}/documents")] + public async Task GetDocumentsbyFormsandLanguageAsync(string language,string LinkType) + { + var result = await this.documentsProvider.GetDocumnetsByLinkAsync(language, LinkType); + if (result.IsSuccess) + { + return Ok(result.documents); + } + return NoContent(); + } + /// + /// Get all documnets. + /// + [HttpGet("{LinkType}/documents")] + public async Task GetDocumentsbyFormAsync(string LinkType) + { + var result = await this.documentsProvider.GetDocumnetsByLinkAsync(null, LinkType); + if (result.IsSuccess) + { + return Ok(result.documents); + } + return NoContent(); + } + /// + /// Get all documnets. + /// + [HttpGet("documents")] + public async Task GetDocumentsAsync() + { + var result = await this.documentsProvider.GetDocumnetsAsync(); + if (result.IsSuccess) + { + return Ok(result.documents); + } + return NoContent(); + } + + /// + /// Get a documnet by id. + /// + [HttpGet("documents/{id}")] + public async Task GetDocumentAsync(int id) + { + var result = await this.documentsProvider.GetDocumentAsync(id); + if (result.IsSuccess) + { + return Ok(result.Document); + } + return NotFound(); + } + /// + /// Upload new document. + /// + [HttpPut("documents")] + public async Task UpdateDocument(DocumentInfo documentInfo) + { + if (documentInfo != null) + { + var dbdoc = await this.documentsProvider.GetDocumentAsync(documentInfo.Id); + if (dbdoc.IsSuccess) + { + Models.Document document = uploadService.UpdateDocuments(dbdoc.Document, documentInfo); + var result = await this.documentsProvider.UpdateDocumentAsync(document); + if (result.IsSuccess) + { + return Ok(result.Document); + } + return NoContent(); + } + return NoContent(); + } + return BadRequest(documentInfo); + } + /// + /// update existing document. + /// + [HttpPost("documents")] + public async Task CreateDocument(DocumentInfo documentInfo) + { + try + { + if (documentInfo != null) + { + var documents = await this.documentsProvider.GetDocumentCounter(); + Models.Document document = uploadService.UploadDocument(documents.counter, documentInfo); + var result = await this.documentsProvider.PostDocumentAsync(document); + if (result.IsSuccess) + { + return Ok(result.Document); + } + return NoContent(); + } + return BadRequest(documentInfo); + } + catch (Exception ex) + { + return BadRequest($"Internal server error: {ex}"); + } + } + /// + /// Delete documnet by id. + /// + [HttpDelete("documents/{id}")] + public async Task DeleteDocument(int id) + { + // database soft delete + var result = await this.documentsProvider.DeleteDocumentAsync(id); + if (result.IsSuccess) + { + // deleting file from folder + uploadService.Movefile(result.Document.Path); + return Ok(result.Document); + } + return NotFound(); + } + /// + /// Get all document link type. + /// + [HttpGet("LinkTypes")] + public async Task GetLinkTypesAsync() + { + var result = await this.documentsProvider.GetLinkTypesAsync(); + if (result.IsSuccess) + { + return Ok(result.LinkTypes); + } + return NoContent(); + } + /// + /// Get a document link type by id. + /// + [HttpGet("LinkTypes/{id}")] + public async Task GetLinkTypeAsync(int id) + { + var result = await this.documentsProvider.GetLinkTypeAsync(id); + if (result.IsSuccess) + { + return Ok(result.LinkType); + } + return NotFound(); + } + /// + /// Update a existing document link type. + /// + [HttpPut("LinkTypes")] + public async Task UpdateLinkType(Models.LinkType linkType) + { + if (linkType != null) + { + var result = await this.documentsProvider.UpdateLinkTypeAsync(linkType); + if (result.IsSuccess) + { + return Ok(result.LinkType); + } + if (result.ErrorMessage == "Not Found") + return NotFound(result.ErrorMessage); + + return BadRequest(result.ErrorMessage); + } + return CreatedAtRoute("DefaultApi", new { id = linkType.Id }, linkType); + } + /// + /// Create a new document link type. + /// + [HttpPost("LinkTypes")] + public async Task CreateLinkType(Models.LinkType linkType) + { + if (linkType != null) + { + var result = await this.documentsProvider.PostLinkTypeAsync(linkType); + if (result.IsSuccess) + { + return Ok(result.LinkType); + } + return BadRequest(result.ErrorMessage); + } + return CreatedAtRoute("DefaultApi", new { id = linkType.Id }, linkType); + } + /// + /// Delete a existing document link type by id. + /// + [HttpDelete("LinkTypes/{id}")] + public async Task DeleteLinkType(int id) + { + var result = await this.documentsProvider.DeleteLinkTypeAsync(id); + if (result.IsSuccess) + { + return Ok(result.LinkType); + } + return NotFound(); + } + + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/DASA_Documents/Active/Document_1.txt b/DamageAssesmentApi/DamageAssesment.Api.Documents/DASA_Documents/Active/Document_1.txt new file mode 100644 index 0000000..eed7e79 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/DASA_Documents/Active/Document_1.txt @@ -0,0 +1 @@ +sample \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/DamageAssesment.Api.Documents.csproj b/DamageAssesmentApi/DamageAssesment.Api.Documents/DamageAssesment.Api.Documents.csproj new file mode 100644 index 0000000..03eeae8 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/DamageAssesment.Api.Documents.csproj @@ -0,0 +1,31 @@ + + + + net6.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/Document.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/Document.cs new file mode 100644 index 0000000..d5c7280 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/Document.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DamageAssesment.Api.Documents.Db +{ + public class Document + { + [Key] + public int Id { get; set; } + [ForeignKey("LinkType")] + public int linkTypeId { get; set; } + public string docName { get; set; } + + public string url { get; set; } + public string Path { get; set; } + public bool IsActive { get; set; } + public DateTime dateCreated { get; set; } + public DateTime dateUpdated { get; set; } + + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs new file mode 100644 index 0000000..f0ddc60 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using System.ComponentModel.DataAnnotations; + +namespace DamageAssesment.Api.Documents.Db +{ + public class DocumentDbContext : DbContext + { + private IConfiguration _Configuration { get; set; } + public DocumentDbContext(DbContextOptions options, IConfiguration configuration) : base(options) + { + _Configuration = configuration; + } + public DbSet Documents { get; set; } + public DbSet LinkTypes { get; set; } + public DbSet DocumentsTranslations { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + // connect to sql server with connection string from app settings + options.UseSqlServer(_Configuration.GetConnectionString("DocumentConnection")); + } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + modelBuilder.Entity() + .Property(item => item.Id) + .ValueGeneratedOnAdd(); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentsTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentsTranslation.cs new file mode 100644 index 0000000..b3a31fc --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentsTranslation.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DamageAssesment.Api.Documents.Db +{ + public class DocumentsTranslation + { + [Key] + public int Id { get; set; } + [ForeignKey("Document")] + public int DocumentId { get; set; } + public string title { get; set; } + public string description { get; set; } + public string Language { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/LinkType.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/LinkType.cs new file mode 100644 index 0000000..f5e1e86 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/LinkType.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace DamageAssesment.Api.Documents.Db +{ + public class LinkType + { + [Key] + public int Id { get; set; } + public string TypeText { get; set; } + public bool IsActive { get; set; } + public bool IsAttachment { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IAzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IAzureBlobService.cs new file mode 100644 index 0000000..d88c827 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IAzureBlobService.cs @@ -0,0 +1,10 @@ +using Azure.Storage.Blobs.Models; + +namespace DamageAssesment.Api.Documents.Interfaces +{ + public interface IAzureBlobService + { + Task>> UploadFiles(List files); + void DeleteFile(string path); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentTypeProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentTypeProvider.cs new file mode 100644 index 0000000..a4f0f97 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentTypeProvider.cs @@ -0,0 +1,11 @@ +namespace DamageAssesment.Api.Documents.Interfaces +{ + public interface ILinkTypesProvider + { + Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> GetLinkTypeAsync(int Id); + Task<(bool IsSuccess, IEnumerable LinkTypes, string ErrorMessage)> GetLinkTypesAsync(); + Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> PostLinkTypeAsync(Models.LinkType LinkType); + Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> UpdateLinkTypeAsync(Models.LinkType LinkType); + Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> DeleteLinkTypeAsync(int Id); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentsProvider.cs new file mode 100644 index 0000000..845a51f --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IDocumentsProvider.cs @@ -0,0 +1,17 @@ +using DamageAssesment.Api.Documents.Models; + +namespace DamageAssesment.Api.Documents.Interfaces +{ + public interface IDocumentsProvider : ILinkTypesProvider + { + Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> GetDocumentAsync(int Id); + Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsAsync(); + Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsByLinkAsync(string Language,string LinkType); + Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> PostDocumentAsync(Models.Document Document); + Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> UpdateDocumentAsync(Models.Document Document); + Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> DeleteDocumentAsync(int Id); + Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter(); + + + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IUploadService.cs new file mode 100644 index 0000000..2b79efe --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Interfaces/IUploadService.cs @@ -0,0 +1,12 @@ +using DamageAssesment.Api.Documents.Models; + +namespace DamageAssesment.Api.Documents.Interfaces +{ + public interface IUploadService + { + Models.Document UploadDocument( int counter, DocumentInfo documentInfo); + public Models.Document UpdateDocuments( Models.Document document, DocumentInfo documentInfo); + void Deletefile(string path); + void Movefile(string path); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.Designer.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.Designer.cs new file mode 100644 index 0000000..ba5ecae --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.Designer.cs @@ -0,0 +1,95 @@ +// +using System; +using DamageAssesment.Api.Documents.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DamageAssesment.Api.Documents.Migrations +{ + [DbContext(typeof(DocumentDbContext))] + [Migration("20230828165655_InitialDocumentCreate")] + partial class InitialDocumentCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("dateCreated") + .HasColumnType("datetime2"); + + b.Property("dateUpdated") + .HasColumnType("datetime2"); + + b.Property("description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("docName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("linkTypeId") + .HasColumnType("int"); + + b.Property("title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.LinkType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("TypeText") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LinkTypes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.cs new file mode 100644 index 0000000..3d55b84 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230828165655_InitialDocumentCreate.cs @@ -0,0 +1,60 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DamageAssesment.Api.Documents.Migrations +{ + /// + public partial class InitialDocumentCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Documents", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + title = table.Column(type: "nvarchar(max)", nullable: false), + linkTypeId = table.Column(type: "int", nullable: false), + description = table.Column(type: "nvarchar(max)", nullable: false), + docName = table.Column(type: "nvarchar(max)", nullable: false), + url = table.Column(type: "nvarchar(max)", nullable: false), + Path = table.Column(type: "nvarchar(max)", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + dateCreated = table.Column(type: "datetime2", nullable: false), + dateUpdated = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Documents", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "LinkTypes", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + TypeText = table.Column(type: "nvarchar(max)", nullable: false), + IsActive = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LinkTypes", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Documents"); + + migrationBuilder.DropTable( + name: "LinkTypes"); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.Designer.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.Designer.cs new file mode 100644 index 0000000..9fcc43d --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.Designer.cs @@ -0,0 +1,118 @@ +// +using System; +using DamageAssesment.Api.Documents.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DamageAssesment.Api.Documents.Migrations +{ + [DbContext(typeof(DocumentDbContext))] + [Migration("20230830200432_DocumentTranslation")] + partial class DocumentTranslation + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("dateCreated") + .HasColumnType("datetime2"); + + b.Property("dateUpdated") + .HasColumnType("datetime2"); + + b.Property("docName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("linkTypeId") + .HasColumnType("int"); + + b.Property("url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.DocumentsTranslation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DocumentId") + .HasColumnType("int"); + + b.Property("Language") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DocumentsTranslations"); + }); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.LinkType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsAttachment") + .HasColumnType("bit"); + + b.Property("TypeText") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LinkTypes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.cs new file mode 100644 index 0000000..90f26be --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/20230830200432_DocumentTranslation.cs @@ -0,0 +1,70 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DamageAssesment.Api.Documents.Migrations +{ + /// + public partial class DocumentTranslation : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "description", + table: "Documents"); + + migrationBuilder.DropColumn( + name: "title", + table: "Documents"); + + migrationBuilder.AddColumn( + name: "IsAttachment", + table: "LinkTypes", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateTable( + name: "DocumentsTranslations", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DocumentId = table.Column(type: "int", nullable: false), + title = table.Column(type: "nvarchar(max)", nullable: false), + description = table.Column(type: "nvarchar(max)", nullable: false), + Language = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DocumentsTranslations", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DocumentsTranslations"); + + migrationBuilder.DropColumn( + name: "IsAttachment", + table: "LinkTypes"); + + migrationBuilder.AddColumn( + name: "description", + table: "Documents", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "title", + table: "Documents", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/DocumentDbContextModelSnapshot.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/DocumentDbContextModelSnapshot.cs new file mode 100644 index 0000000..24681f1 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Migrations/DocumentDbContextModelSnapshot.cs @@ -0,0 +1,115 @@ +// +using System; +using DamageAssesment.Api.Documents.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DamageAssesment.Api.Documents.Migrations +{ + [DbContext(typeof(DocumentDbContext))] + partial class DocumentDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("dateCreated") + .HasColumnType("datetime2"); + + b.Property("dateUpdated") + .HasColumnType("datetime2"); + + b.Property("docName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("linkTypeId") + .HasColumnType("int"); + + b.Property("url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.DocumentsTranslation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DocumentId") + .HasColumnType("int"); + + b.Property("Language") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DocumentsTranslations"); + }); + + modelBuilder.Entity("DamageAssesment.Api.Documents.Db.LinkType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsAttachment") + .HasColumnType("bit"); + + b.Property("TypeText") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LinkTypes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/Document.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/Document.cs new file mode 100644 index 0000000..1652dca --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/Document.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; + +namespace DamageAssesment.Api.Documents.Models +{ + public class Document + { + public int Id { get; set; } + + public int linkTypeId { get; set; } + public string docName { get; set; } + + public string url { get; set; } + public string Path { get; set; } + public bool IsActive { get; set; } + public DateTime dateCreated { get; set; } + public DateTime dateUpdated { get; set; } + public List documentsTranslations { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentInfo.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentInfo.cs new file mode 100644 index 0000000..3a5dc3b --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentInfo.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace DamageAssesment.Api.Documents.Models +{ + public class DocumentInfo + { + public int Id { get; set; } + public int linkTypeId { get; set; } + public string url { get; set; } + public List documentsTranslations { get; set; } + public FileModel? File { get; set; } + } + public class FileModel + { + public string? FileName { get; set; } + public string? FileContent { get; set; } + public string? FileExtension { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentsTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentsTranslation.cs new file mode 100644 index 0000000..f2ca5af --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/DocumentsTranslation.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DamageAssesment.Api.Documents.Models +{ + public class DocumentsTranslation + { + public string title { get; set; } + public string description { get; set; } + public string Language { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/LinkType.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/LinkType.cs new file mode 100644 index 0000000..9bbcdbc --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Models/LinkType.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace DamageAssesment.Api.Documents.Models +{ + public class LinkType + { + public int Id { get; set; } + public string TypeText { get; set; } + public bool IsActive { get; set; } + public bool IsAttachment { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Profiles/DocumentProfile.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Profiles/DocumentProfile.cs new file mode 100644 index 0000000..f9a2570 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Profiles/DocumentProfile.cs @@ -0,0 +1,17 @@ +using AutoMapper; + +namespace DamageAssesment.Api.Documents.Profiles +{ + public class DocumentProfile : AutoMapper.Profile + { + public DocumentProfile() + { + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs new file mode 100644 index 0000000..a1e9361 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs @@ -0,0 +1,35 @@ +using DamageAssesment.Api.Documents.Db; +using DamageAssesment.Api.Documents.Interfaces; +using DamageAssesment.Api.Documents.Providers; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +// 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(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 +builder.Services.AddDbContext(option => +{ + option.UseSqlServer("DocumentConnection"); +}); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Properties/launchSettings.json b/DamageAssesmentApi/DamageAssesment.Api.Documents/Properties/launchSettings.json new file mode 100644 index 0000000..e4e08ae --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:60754", + "sslPort": 0 + } + }, + "profiles": { + "DamageAssesment.Api.Questions": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5133", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/AzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/AzureBlobService.cs new file mode 100644 index 0000000..bc456f5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/AzureBlobService.cs @@ -0,0 +1,44 @@ + +using Azure.Storage.Blobs; +using Azure.Storage.Blobs.Models; +using Azure.Storage.Blobs.Specialized; +using DamageAssesment.Api.Documents.Interfaces; + +namespace DamageAssesment.Api.Documents.Providers +{ + public class AzureBlobService: IAzureBlobService + { + BlobServiceClient _blobClient; + BlobContainerClient _containerClient; + string azureConnectionString = ""; + public AzureBlobService() + { + _blobClient = new BlobServiceClient(azureConnectionString); + _containerClient = _blobClient.GetBlobContainerClient("apiimages"); + } + + public async Task>> UploadFiles(List files) + { + + var azureResponse = new List>(); + foreach (var file in files) + { + string fileName = file.FileName; + using (var memoryStream = new MemoryStream()) + { + file.CopyTo(memoryStream); + memoryStream.Position = 0; + var client = await _containerClient.UploadBlobAsync(fileName, memoryStream, default); + azureResponse.Add(client); + } + }; + + return azureResponse; + } + public void DeleteFile(string url) + { + var blob = _containerClient.GetBlockBlobClient(url); + blob.DeleteIfExists(); + } + } +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs new file mode 100644 index 0000000..8b6c1ee --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs @@ -0,0 +1,363 @@ +using AutoMapper; +using DamageAssesment.Api.Documents.Db; +using DamageAssesment.Api.Documents.Interfaces; +using DamageAssesment.Api.Documents.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System; +using System.Diagnostics.Eventing.Reader; + +namespace DamageAssesment.Api.Documents.Providers +{ + + + public class documentsProvider : IDocumentsProvider + { + private DocumentDbContext DocumentDbContext; + private ILogger logger; + private IUploadService uploadservice; + private IMapper mapper; + + public documentsProvider(DocumentDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice) + { + this.DocumentDbContext = DocumentDbContext; + this.logger = logger; + this.mapper = mapper; + this.uploadservice = uploadservice; + SeedData(); + } + + + + private void SeedData() + { + if (!DocumentDbContext.LinkTypes.Any()) + { + DocumentDbContext.LinkTypes.Add(new Db.LinkType() {TypeText = "Forms",IsActive=true, IsAttachment=true }); + DocumentDbContext.LinkTypes.Add(new Db.LinkType() {TypeText = "Communiques",IsActive = true,IsAttachment=false }); + DocumentDbContext.LinkTypes.Add(new Db.LinkType() {TypeText = "Memos",IsActive = true,IsAttachment=true }); + DocumentDbContext.SaveChanges(); + } + if (!DocumentDbContext.Documents.Any()) + { + FileModel fileModel = new FileModel() { FileName = "Sample", FileContent = "c2FtcGxl", FileExtension = ".txt" }; + DocumentInfo documentInfo = new DocumentInfo() { linkTypeId = 1, url = "Sample", File = fileModel }; + Models.Document document = uploadservice.UploadDocument(0, documentInfo); + DocumentDbContext.Documents.Add(mapper.Map(document)); + DocumentDbContext.SaveChanges(); + } + if (!DocumentDbContext.DocumentsTranslations.Any()) + { + Db.DocumentsTranslation documents = new Db.DocumentsTranslation { Id = 0, DocumentId = 1, title = "Test", description = "ss", Language = "en" }; + DocumentDbContext.DocumentsTranslations.Add(documents); + DocumentDbContext.SaveChanges(); + } + } + public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsByLinkAsync(string Language, string LinkType) + { + + try + { + logger?.LogInformation("Query Question"); + var documents=new List(); + if(String.IsNullOrEmpty(LinkType)) + documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => q.IsActive).ToListAsync(); + else + documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => q.IsActive && + q.linkTypeId == (DocumentDbContext.LinkTypes.AsNoTracking().Where(a => a.TypeText.ToLower() == LinkType.ToLower()).Select(a => a.Id).FirstOrDefault())).ToListAsync(); + if (documents != null) + { + var result = mapper.Map, IEnumerable>(documents); + foreach (var item in result) + { + if(!String.IsNullOrEmpty(Language)) + item.documentsTranslations = mapper.Map, List>( + DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == item.Id && (a.Language.ToLower() == Language.ToLower())).ToList()); + else + item.documentsTranslations = mapper.Map, List>( + DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == item.Id).ToList()); + } + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + + } + public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsAsync() + { + + try + { + logger?.LogInformation("Query Question"); + var documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => q.IsActive).ToListAsync(); + if (documents != null) + { + logger?.LogInformation($"{documents.Count} Document(s) found"); + var result = mapper.Map, IEnumerable>(documents); + foreach (var item in result) + { + item.documentsTranslations = mapper.Map, List>( + DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == item.Id).ToList()); + } + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + + } + public async Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> GetDocumentAsync(int Id) + { + try + { + logger?.LogInformation("Query LinkType"); + var Document = await DocumentDbContext.Documents.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id && q.IsActive); + if (Document != null) + { + logger?.LogInformation($"{Document} customer(s) found"); + var result = mapper.Map(Document); + result.documentsTranslations = mapper.Map, List>( + DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == result.Id).ToList()); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + public async Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> PostDocumentAsync(Models.Document Document) + { + try + { + var document = mapper.Map(Document); + DocumentDbContext.Documents.Add(document); + DocumentDbContext.SaveChanges(); + var dbtranslation = mapper.Map, List>(Document.documentsTranslations); + dbtranslation.ForEach(i => i.DocumentId = document.Id); + DocumentDbContext.DocumentsTranslations.AddRange(dbtranslation); + DocumentDbContext.SaveChanges(); + Document.Id = document.Id; + return (true, Document, null); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> UpdateDocumentAsync(Models.Document Document) + { + try + { + if (Document != null) + { + var existing = DocumentDbContext.Documents.AsNoTracking().FirstOrDefault(x => x.Id == Document.Id); + if (existing != null) + { + var document = mapper.Map(Document); + DocumentDbContext.Documents.Update(document); + DocumentDbContext.SaveChanges(); + var oldtranslations = DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == Document.Id).ToList(); + if (oldtranslations != null) + DocumentDbContext.DocumentsTranslations.RemoveRange(oldtranslations); + var dbtranslation = mapper.Map, List>(Document.documentsTranslations); + dbtranslation.ForEach(i => i.DocumentId = Document.Id); + return (true, Document, "Successful"); + } + else + { + logger?.LogInformation($"{Document} Not found"); + return (false, null, "Not Found"); + } + } + else + { + logger?.LogInformation($"{Document} Bad Request"); + return (false, null, "Bad request"); + } + + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + public async Task<(bool IsSuccess, Models.Document Document, string ErrorMessage)> DeleteDocumentAsync(int Id) + { + + try + { + Db.Document Document = DocumentDbContext.Documents.AsNoTracking().Where(a => a.Id == Id).FirstOrDefault(); + if (Document == null) + { + return (false, null, "Not Found"); + } + Document.IsActive = false; + DocumentDbContext.Documents.Update(Document); + DocumentDbContext.SaveChanges(); + return (true, mapper.Map(Document), $"DocumentId {Id} deleted Successfuly"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + + public async Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter() + { + try + { + int AttachmentId = DocumentDbContext.Documents.Max(a => a.Id); + return (true, AttachmentId, ""); + } + catch (Exception ex) + { + return (false, 0, ex.Message); + } + } + + //Link Type methods + public async Task<(bool IsSuccess, IEnumerable LinkTypes, string ErrorMessage)> GetLinkTypesAsync() + { + + try + { + logger?.LogInformation("Query Question"); + var LinkType = await DocumentDbContext.LinkTypes.AsNoTracking().Where(q=>q.IsActive).ToListAsync(); + if (LinkType != null) + { + logger?.LogInformation($"{LinkType.Count} LinkTypes(s) found"); + var result = mapper.Map, IEnumerable>(LinkType); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + + } + + public async Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> GetLinkTypeAsync(int Id) + { + try + { + logger?.LogInformation("Query LinkType"); + var LinkType = await DocumentDbContext.LinkTypes.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id&&q.IsActive); + if (LinkType != null) + { + logger?.LogInformation($"{LinkType} customer(s) found"); + var result = mapper.Map(LinkType); + return (true, result, null); + } + return (false, null, "Not found"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + public async Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> PostLinkTypeAsync(Models.LinkType LinkType) + { + try + { + logger?.LogInformation("Query LinkType"); + if (!LinkTypeExists(LinkType.Id)) + { + var dbLink = mapper.Map(LinkType); + DocumentDbContext.LinkTypes.Add(dbLink); + DocumentDbContext.SaveChanges(); + var result = mapper.Map(dbLink); + return (true, result, null); + } + return (false, null, "LinkType is already exits"); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + public async Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> UpdateLinkTypeAsync(Models.LinkType LinkType) + { + try + { + if (LinkType != null) + { + var existing = DocumentDbContext.LinkTypes.AsNoTracking().FirstOrDefault(x => x.Id == LinkType.Id); + if (existing != null) + { + var dbLink = mapper.Map(LinkType); + DocumentDbContext.LinkTypes.Update(dbLink); + DocumentDbContext.SaveChanges(); + return (true, mapper.Map(dbLink), "Successful"); + } + else + { + logger?.LogInformation($"{LinkType} Not found"); + return (false, null, "Not Found"); + } + } + else + { + logger?.LogInformation($"{LinkType} Bad Request"); + return (false, null, "Bad request"); + } + + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + public async Task<(bool IsSuccess, Models.LinkType LinkType, string ErrorMessage)> DeleteLinkTypeAsync(int Id) + { + + try + { + Db.LinkType LinkType = DocumentDbContext.LinkTypes.AsNoTracking().Where(a => a.Id == Id).FirstOrDefault(); + if (LinkType == null) + { + return (false, null, "Not Found"); + } + LinkType.IsActive = false; + DocumentDbContext.LinkTypes.Update(LinkType); + DocumentDbContext.SaveChanges(); + return (true, mapper.Map(LinkType), $"LinkTypeId {Id} deleted Successfuly"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } + private bool LinkTypeExists(int id) + { + return DocumentDbContext.LinkTypes.AsNoTracking().Count(e => e.Id == id) > 0; + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/UploadService.cs new file mode 100644 index 0000000..4493274 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/UploadService.cs @@ -0,0 +1,123 @@ +using AutoMapper; +using Azure; +using DamageAssesment.Api.Documents.Db; +using DamageAssesment.Api.Documents.Interfaces; +using DamageAssesment.Api.Documents.Models; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.Diagnostics.Metrics; +using System.Net.Http; +using System.Security.AccessControl; +using System.Security.Principal; + +namespace DamageAssesment.Api.Documents.Providers +{ + public class UploadService : IUploadService + { + private ILogger logger; + private IMapper mapper; + private string uploadpath = ""; + private string Deletepath = ""; + public UploadService(IConfiguration configuration, ILogger logger, IMapper mapper) + { + this.logger = logger; + this.mapper = mapper; + uploadpath = configuration.GetValue("Fileupload:folderpath"); + Deletepath = configuration.GetValue("Fileupload:Deletepath"); + } + + public Models.Document UploadDocument(int counter, DocumentInfo documentInfo) + { + Models.Document Documents = new Models.Document(); + try + { + string path = "", UserfileName=""; + if (documentInfo.File != null) + { + counter++; + var fullDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), uploadpath); + if (!Directory.Exists(fullDirectoryPath)) //Create deirectory if does not exist + Directory.CreateDirectory(fullDirectoryPath); + UserfileName = Path.GetFileName(documentInfo.File.FileName); + var fileName = String.Format("Document_{0}{1}", counter, documentInfo.File.FileExtension); + path = Path.Combine(fullDirectoryPath, fileName); + File.WriteAllBytes(path, Convert.FromBase64String(documentInfo.File.FileContent)); + } + Documents=new Models.Document (){ linkTypeId = documentInfo.linkTypeId, + documentsTranslations = documentInfo.documentsTranslations, + docName = UserfileName, + url = documentInfo.url, Path = path,IsActive =true,dateCreated=DateTime.Now,dateUpdated=DateTime.Now}; + + return Documents; + } + catch (Exception ex) { + return new Models.Document(); + } + + + } + public Models.Document UpdateDocuments(Models.Document document, DocumentInfo documentInfo) + { + try + { + Deletefile(document.Path); + var fullDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), uploadpath); + if (!Directory.Exists(fullDirectoryPath)) //Create deirectory if does not exist + Directory.CreateDirectory(fullDirectoryPath); + + string path = "", UserfileName = ""; + if (documentInfo.File != null) + { + UserfileName = Path.GetFileName(documentInfo.File.FileName); + var fileName = String.Format("Document_{0}{1}", documentInfo.Id, documentInfo.File.FileExtension); + path = Path.Combine(fullDirectoryPath, fileName); + File.WriteAllBytes(path, Convert.FromBase64String(documentInfo.File.FileContent)); + } + Models.Document Documents = new Models.Document() + { + Id = documentInfo.Id, + linkTypeId = documentInfo.linkTypeId, + documentsTranslations=documentInfo.documentsTranslations, + docName = UserfileName, + url = documentInfo.url, + Path = path, + IsActive = true, + dateCreated = document.dateCreated, + dateUpdated = DateTime.Now + }; + + return Documents; + } + + catch (Exception ex) { + return new Models.Document(); + } + } + public void Deletefile(string path) + { + if (path != "") + { + FileInfo file = new FileInfo(path); + if (file?.Exists??false)//check file exsit or not + { + file.Delete(); + } + } + } + public void Movefile(string path) + { + if (path != "") + { + var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), Deletepath); + if (!Directory.Exists(pathToSave)) //Create deirectory if does not exist + Directory.CreateDirectory(pathToSave); + FileInfo file = new FileInfo(path); + if (file?.Exists ?? false)//check file exsit or not + { + string filename = file.Name.Replace(file.Extension, " ") + DateTime.Now.ToShortDateString().Replace("/","_") + file.Extension; + file.MoveTo(pathToSave+"\\"+ filename); + } + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.Development.json b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json new file mode 100644 index 0000000..5006fa8 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Fileupload": { + "folderpath": "DASA_Documents/Active", + "Deletepath": "DASA_Documents/Deleted" + }, + "ConnectionStrings": { + "DocumentConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" + } +} diff --git a/DamageAssesmentApi/DamageAssesment.sln b/DamageAssesmentApi/DamageAssesment.sln index a8b1fcc..2871442 100644 --- a/DamageAssesmentApi/DamageAssesment.sln +++ b/DamageAssesmentApi/DamageAssesment.sln @@ -37,6 +37,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Employe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Employees.Test", "DamageAssesment.Api.Employees.Test\DamageAssesment.Api.Employees.Test.csproj", "{D6BF9AE9-72FA-4726-A326-35A35D27FFB8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DamageAssesment.Api.Documents", "DamageAssesment.Api.Documents\DamageAssesment.Api.Documents.csproj", "{977C1053-9D63-4153-B61B-C3D2F1010F9F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DamageAssesment.Api.Documents.Test", "DamageAssesment.Api.Documents.Test\DamageAssesment.Api.Documents.Test.csproj", "{884BA4AC-9170-49B1-BD6B-850B350C95C0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -98,6 +102,14 @@ Global {D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Debug|Any CPU.Build.0 = Debug|Any CPU {D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6BF9AE9-72FA-4726-A326-35A35D27FFB8}.Release|Any CPU.Build.0 = Release|Any CPU + {977C1053-9D63-4153-B61B-C3D2F1010F9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {977C1053-9D63-4153-B61B-C3D2F1010F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {977C1053-9D63-4153-B61B-C3D2F1010F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {977C1053-9D63-4153-B61B-C3D2F1010F9F}.Release|Any CPU.Build.0 = Release|Any CPU + {884BA4AC-9170-49B1-BD6B-850B350C95C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {884BA4AC-9170-49B1-BD6B-850B350C95C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {884BA4AC-9170-49B1-BD6B-850B350C95C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {884BA4AC-9170-49B1-BD6B-850B350C95C0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From d78d5e0ba444615f924b3cba521462b92f090c9d Mon Sep 17 00:00:00 2001 From: uppuv Date: Thu, 31 Aug 2023 19:12:47 -0400 Subject: [PATCH 2/2] Modified Documents api for InMemory Logic --- .../Db/DocumentDbContext.cs | 9 +-------- .../DamageAssesment.Api.Documents/Program.cs | 2 +- .../Providers/DocumentsProvider.cs | 2 +- .../DamageAssesment.Api.Documents/appsettings.json | 3 --- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs index f0ddc60..4df2f77 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Db/DocumentDbContext.cs @@ -7,19 +7,12 @@ namespace DamageAssesment.Api.Documents.Db { public class DocumentDbContext : DbContext { - private IConfiguration _Configuration { get; set; } - public DocumentDbContext(DbContextOptions options, IConfiguration configuration) : base(options) + public DocumentDbContext(DbContextOptions options) : base(options) { - _Configuration = configuration; } public DbSet Documents { get; set; } public DbSet LinkTypes { get; set; } public DbSet DocumentsTranslations { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder options) - { - // connect to sql server with connection string from app settings - options.UseSqlServer(_Configuration.GetConnectionString("DocumentConnection")); - } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs index a1e9361..af38287 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Program.cs @@ -17,7 +17,7 @@ builder.Services.AddScoped(); builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //4/30 builder.Services.AddDbContext(option => { - option.UseSqlServer("DocumentConnection"); + option.UseInMemoryDatabase("DocumentConnection"); }); var app = builder.Build(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs index 8b6c1ee..4af3174 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/Providers/DocumentsProvider.cs @@ -49,7 +49,7 @@ namespace DamageAssesment.Api.Documents.Providers } if (!DocumentDbContext.DocumentsTranslations.Any()) { - Db.DocumentsTranslation documents = new Db.DocumentsTranslation { Id = 0, DocumentId = 1, title = "Test", description = "ss", Language = "en" }; + Db.DocumentsTranslation documents = new Db.DocumentsTranslation { DocumentId = 1, title = "Test", description = "ss", Language = "en" }; DocumentDbContext.DocumentsTranslations.Add(documents); DocumentDbContext.SaveChanges(); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json index 5006fa8..e38d9fb 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Documents/appsettings.json @@ -9,8 +9,5 @@ "Fileupload": { "folderpath": "DASA_Documents/Active", "Deletepath": "DASA_Documents/Deleted" - }, - "ConnectionStrings": { - "DocumentConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" } }