4 Commitit d023282c01 ... 6d5ea727d6

Tekijä SHA1 Viesti Päivämäärä
  zinab_elgendy 6d5ea727d6 taskAttachments 2 kuukautta sitten
  zinab_elgendy 89ad831904 Fix team update 2 kuukautta sitten
  zinab_elgendy 56098cea7f Fix Register file issue by using IFormFile 2 kuukautta sitten
  zinab_elgendy e76f399536 update user without multipart formFiles 2 kuukautta sitten
32 muutettua tiedostoa jossa 15282 lisäystä ja 139 poistoa
  1. 6 6
      MTWorkHR.API/Controllers/CompanyController.cs
  2. 5 5
      MTWorkHR.API/Controllers/UserController.cs
  3. 3 3
      MTWorkHR.API/appsettings.Development.json
  4. 3 3
      MTWorkHR.API/appsettings.json
  5. 5 0
      MTWorkHR.Application/Dtos/Identity/AttachmentDto.cs
  6. 3 0
      MTWorkHR.Application/Dtos/Identity/AttachmentResponseDto.cs
  7. 14 14
      MTWorkHR.Application/Dtos/Identity/UserDto.cs
  8. 9 0
      MTWorkHR.Application/Dtos/Identity/UserUpdateDto.cs
  9. 6 6
      MTWorkHR.Application/Dtos/User/CompanyDto.cs
  10. 1 0
      MTWorkHR.Application/Dtos/User/TeamUserDto.cs
  11. 39 0
      MTWorkHR.Application/Dtos/User/UpdateCompanyDto.cs
  12. 25 2
      MTWorkHR.Application/Mapper/MappingProfile.cs
  13. 51 1
      MTWorkHR.Application/Services/Base/BlobFileService.cs
  14. 3 1
      MTWorkHR.Application/Services/Interfaces/ICompanyService.cs
  15. 4 2
      MTWorkHR.Application/Services/Interfaces/IUserService.cs
  16. 57 9
      MTWorkHR.Application/Services/Task/UserTaskAttachmentService.cs
  17. 7 0
      MTWorkHR.Application/Services/Task/UserTaskService.cs
  18. 57 13
      MTWorkHR.Application/Services/User/CompanyService.cs
  19. 24 19
      MTWorkHR.Application/Services/User/TeamService.cs
  20. 120 33
      MTWorkHR.Application/Services/User/UserService.cs
  21. 1 0
      MTWorkHR.Core/Entities/User/TeamUser.cs
  22. 1 1
      MTWorkHR.Core/Entities/User/UserTaskAttachment.cs
  23. 1 0
      MTWorkHR.Core/IRepositories/Task/IUserTaskAttachmentRepository.cs
  24. 27 18
      MTWorkHR.Infrastructure/EmailService/MailSender.cs
  25. 1 1
      MTWorkHR.Infrastructure/Entities/UserAttachment.cs
  26. 1 1
      MTWorkHR.Infrastructure/InfrastructureServiceRegistration.cs
  27. 7354 0
      MTWorkHR.Infrastructure/Migrations/20250526104756_altrAttachmentOriginal.Designer.cs
  28. 40 0
      MTWorkHR.Infrastructure/Migrations/20250526104756_altrAttachmentOriginal.cs
  29. 7360 0
      MTWorkHR.Infrastructure/Migrations/20250529131711_altrTaskAttachment.Designer.cs
  30. 38 0
      MTWorkHR.Infrastructure/Migrations/20250529131711_altrTaskAttachment.cs
  31. 6 1
      MTWorkHR.Infrastructure/Migrations/HRDataContextModelSnapshot.cs
  32. 10 0
      MTWorkHR.Infrastructure/Repositories/Task/TaskAttachmentRepository.cs

+ 6 - 6
MTWorkHR.API/Controllers/CompanyController.cs

@@ -29,23 +29,23 @@ namespace MTWorkHR.API.Controllers
         }
         [HttpGet("Get")]
         [AppAuthorize(Permissions = "Company")]
-        public async Task<ActionResult<CompanyDto>> Get()
+        public async Task<ActionResult<UpdateCompanyDto>> Get()
         {
             return Ok(await _companyService.GetById());
         }
         [HttpGet("GetById")]
         [AppAuthorize(Permissions = "Company")]
-        public async Task<ActionResult<CompanyDto>> GetById(long companyId)
+        public async Task<ActionResult<UpdateCompanyDto>> GetById(long companyId)
         {
-            return Ok(await _companyService.GetById(companyId));
+            return Ok(await _companyService.GetByIdForUpdate(companyId));
         }
 
         [HttpPost("Create")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-       // [Consumes("multipart/form-data")]
+        [Consumes("multipart/form-data")]
         [AllowAnonymous]
         [AppAuthorize(Permissions = "Company.Create")]
-        public async Task<ActionResult<CompanyDto>> Create([FromBody] CompanyDto input)
+        public async Task<ActionResult<CompanyDto>> Create([FromForm] CompanyDto input)
         {
             return await _companyService.Create(input);
         }
@@ -54,7 +54,7 @@ namespace MTWorkHR.API.Controllers
         [ProducesResponseType(StatusCodes.Status200OK)]
        // [Consumes("multipart/form-data")]
         [AppAuthorize(Permissions = "Company.Update")]
-        public async Task<ActionResult<CompanyDto>> Update([FromBody] CompanyDto input)
+        public async Task<ActionResult<UpdateCompanyDto>> Update([FromBody] UpdateCompanyDto input)
         {
             return await _companyService.Update(input);
         }

+ 5 - 5
MTWorkHR.API/Controllers/UserController.cs

@@ -35,15 +35,15 @@ namespace MTWorkHR.API.Controllers
         }
         [HttpGet("Get")]
         [AppAuthorize(Permissions = "User")]
-        public async Task<ActionResult<UserDto>> Get()
+        public async Task<ActionResult<UserUpdateDto>> Get()
         {
             return Ok(await _userService.GetById());
         }
         [HttpGet("GetById")]
         [AppAuthorize(Permissions = "User")]
-        public async Task<ActionResult<UserDto>> GetById([FromQuery] string userId)
+        public async Task<ActionResult<UserUpdateDto>> GetById([FromQuery] string userId)
         {
-            return Ok(await _userService.GetById(userId));
+            return Ok(await _userService.GetByIdForUpdate(userId));
         }
 
         [HttpGet("GetEmployeeById")]
@@ -62,9 +62,9 @@ namespace MTWorkHR.API.Controllers
 
         [HttpPost("Create")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-       // [Consumes("multipart/form-data")]
+        [Consumes("multipart/form-data")]
         [AppAuthorize(Permissions = "User.Create")]
-        public async Task<ActionResult<UserDto>> Create([FromBody] UserDto input)
+        public async Task<ActionResult<UserDto>> Create([FromForm] UserDto input)
         {
             return await _userService.Create(input);
         }

+ 3 - 3
MTWorkHR.API/appsettings.Development.json

@@ -32,10 +32,10 @@
   },
   "MailSettings": {
     "ApiKey": "SendGrid-Key",
-    "FromAddress": "DoNotReply@bc3ee9f1-57df-4a29-b566-a84d72074975.azurecomm.net",
+    "FromAddress": "noreply@mtwork.com",
     "FromName": "MTWork Hr Management System",
-    "Password": "1qU8Q~gt4nex-gO3gWrc3FO~fpv8uGoTGqjyFbHx",
-    "Host": "smtp.azurecomm.net",
+    "Password": "Noreply@1111",
+    "Host": "smtp.gmail.com",
     "SmtpUsername": "SMTP_username", // "MTCommunicationServiceResource.57fe2efd-9859-488f-8313-0acd27450cf0.2ff48a6f-9604-49d0-b338-28e96f91ec99", //"EmailSMTPApp",
     "Port": 587,
     "TemplatePath": "C:\\Attachment\\MailTemp\\EmailTemplate.html"

+ 3 - 3
MTWorkHR.API/appsettings.json

@@ -31,10 +31,10 @@
   },
   "MailSettings": {
     "ApiKey": "SendGrid-Key",
-    "FromAddress": "DoNotReply@bc3ee9f1-57df-4a29-b566-a84d72074975.azurecomm.net",
+    "FromAddress": "noreply@mtwork.com",
     "FromName": "MTWork Hr Management System",
-    "Password": "1qU8Q~gt4nex-gO3gWrc3FO~fpv8uGoTGqjyFbHx",
-    "Host": "smtp.azurecomm.net",
+    "Password": "Noreply@1111",
+    "Host": "smtp.gmail.com",
     "Port": 587,
     "SmtpUsername": "SMTP_username", // "MTCommunicationServiceResource.57fe2efd-9859-488f-8313-0acd27450cf0.2ff48a6f-9604-49d0-b338-28e96f91ec99", //"EmailSMTPApp",
     "TemplatePath": "C:\\Attachment\\MailTemp\\EmailTemplate.html"

+ 5 - 0
MTWorkHR.Application/Dtos/Identity/AttachmentDto.cs

@@ -14,8 +14,13 @@ namespace MTWorkHR.Application.Models
 
         public IFormFile? FileData { get; set; }
         public string? FileName { get; set; }
+        public long? FileSize { get; set; }
 
         public string? CreateDate { get; set; }
+        public string? CreateUser { get; set; }
+        
+        public string? CreatedUserName { get; set; }
+        public string? ProfileImage { get; set; }
         public string? OriginalName { get; set; }
         public string? FilePath { get; set; }
         public byte[]? Content { get; set; }

+ 3 - 0
MTWorkHR.Application/Dtos/Identity/AttachmentResponseDto.cs

@@ -11,6 +11,9 @@ namespace MTWorkHR.Application.Models
         public string? FileName { get; set; }
 
         public string? FilePath { get; set; }
+        public long? FileSize { get; set; }
+        public string? ContentType { get; set; }
+        
 
     }
 }

+ 14 - 14
MTWorkHR.Application/Dtos/Identity/UserDto.cs

@@ -12,11 +12,11 @@ namespace MTWorkHR.Application.Models
     public class UserDto
     {
         public string? Id { get; set; }
-       
+
         [Required]
         public string FirstName { get; set; }
         public DateTime DateOfBirth { get; set; }
-       
+
         public string IdNumber { get; set; }
         public string LastName { get; set; }
         [Required]
@@ -36,7 +36,7 @@ namespace MTWorkHR.Application.Models
         [MinLength(6)]
         public string UserName { get; set; }
         public string? Password { get; set; }
-      
+
         public int? QualificationId { get; set; }
         public int? UniversityId { get; set; }
         public int? JobTitleId { get; set; }
@@ -56,19 +56,19 @@ namespace MTWorkHR.Application.Models
         public bool IsCheckedIn { get; set; }
         public bool IsCheckedOut { get; set; }
         public string? ProfileImagePath { get; set; }
-        public AttachmentDto? ProfileImage { get; set; }
-        public AttachmentDto? CVAttach { get; set; }
-        public AttachmentDto? PassportAttach { get; set; }
-        public AttachmentDto? EduCertificateAttach { get; set; }
-        public AttachmentDto? ExperienceCertificateAttach { get; set; }
-        public AttachmentDto? ProfCertificateAttach { get; set; }
+        public IFormFile? ProfileImage { get; set; }
+        public IFormFile? CVAttach { get; set; }
+        public IFormFile? PassportAttach { get; set; }
+        public IFormFile? EduCertificateAttach { get; set; }
+        public IFormFile? ExperienceCertificateAttach { get; set; }
+        public IFormFile? ProfCertificateAttach { get; set; }
         //Company attach
-        public AttachmentDto? CommercialRegAttach { get; set; }
-        public AttachmentDto? TaxDeclarationAttach { get; set; }
-        public AttachmentDto? IdAttach { get; set; }
+        public IFormFile? CommercialRegAttach { get; set; }
+        public IFormFile? TaxDeclarationAttach { get; set; }
+        public IFormFile? IdAttach { get; set; }
 
         public IList<UserRoleDto>? UserRoles { get; set; }
-        public IList<AttachmentDto>? UserAttachments{ get; set; }
-        public UserAddressDto? UserAddress{ get; set; }
+        public IList<AttachmentDto>? UserAttachments { get; set; }
+        public UserAddressDto? UserAddress { get; set; }
     }
 }

+ 9 - 0
MTWorkHR.Application/Dtos/Identity/UserUpdateDto.cs

@@ -47,6 +47,9 @@ namespace MTWorkHR.Application.Models
         public decimal IncomeTaxValue { get; set; }
         public string? Position { get; set; }
         public long? CompanyId { get; set; }
+        public string? ProfileImagePath { get; set; }
+        public bool IsCheckedIn { get; set; }
+        public bool IsCheckedOut { get; set; }
         public AttachmentDto? ProfileImage { get; set; }
 
         public AttachmentDto? CVAttach { get; set; }
@@ -55,6 +58,12 @@ namespace MTWorkHR.Application.Models
         public AttachmentDto? ExperienceCertificateAttach { get; set; }
         public AttachmentDto? ProfCertificateAttach { get; set; }
 
+
+        public AttachmentDto? CommercialRegAttach { get; set; }
+        public AttachmentDto? TaxDeclarationAttach { get; set; }
+        public AttachmentDto? IdAttach { get; set; }
+
+
         public IList<UserRoleDto>? UserRoles { get; set; }
         public IList<AttachmentDto>? UserAttachments { get; set; }
         public UserAddressDto? UserAddress { get; set; }

+ 6 - 6
MTWorkHR.Application/Dtos/User/CompanyDto.cs

@@ -25,12 +25,12 @@ namespace MTWorkHR.Application.Models
         public string? CountryName { get; set; }
         public UserTypeEnum? UserType { get; set; }
         public CompanyUserDto? CompanyUser { get; set; }
-        public AttachmentDto? ProfileImage { get; set; }
-        public AttachmentDto? CommercialRegAttach { get; set; }
-        public AttachmentDto? TaxDeclarationAttach { get; set; }
-        public AttachmentDto? PassportAttach { get; set; }
-        public AttachmentDto? ExperienceCertificateAttach { get; set; }
-        public AttachmentDto? IdAttach { get; set; }
+        public IFormFile? ProfileImage { get; set; }
+        public IFormFile? CommercialRegAttach { get; set; }
+        public IFormFile? TaxDeclarationAttach { get; set; }
+        public IFormFile? PassportAttach { get; set; }
+        public IFormFile? ExperienceCertificateAttach { get; set; }
+        public IFormFile? IdAttach { get; set; }
         public string? CreateUser { get; set; }
         public bool IsSuspended { get; set; }
 

+ 1 - 0
MTWorkHR.Application/Dtos/User/TeamUserDto.cs

@@ -14,6 +14,7 @@ namespace MTWorkHR.Application.Models
         public string AssignedUserId { get; set; }
         public string? AssignedUserName { get; set; }
         public string? AssignedUserEmail { get; set; }
+        public string? ProfileImage { get; set; }
 
     }
 }

+ 39 - 0
MTWorkHR.Application/Dtos/User/UpdateCompanyDto.cs

@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.Http;
+using MTWorkHR.Core.Global;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MTWorkHR.Application.Models
+{
+    public class UpdateCompanyDto : EntityDto
+    {
+        public string CompanyName { get; set; }
+
+        public string CRNumber { get; set; } //Commercial Registration
+        public string? UserId { get; set; }
+        public string? PhoneNumber { get; set; }
+        public string? Address { get; set; }
+        public string? Email { get; set; }
+        public long? CountryId { get; set; }
+        public long? CityId { get; set; }
+        public string? CityName { get; set; }
+        public string? PostalCode { get; set; }
+        public string? CountryName { get; set; }
+        public UserTypeEnum? UserType { get; set; }
+        public CompanyUserDto? CompanyUser { get; set; }
+        public AttachmentDto? ProfileImage { get; set; }
+        public AttachmentDto? CommercialRegAttach { get; set; }
+        public AttachmentDto? TaxDeclarationAttach { get; set; }
+        public AttachmentDto? PassportAttach { get; set; }
+        public AttachmentDto? ExperienceCertificateAttach { get; set; }
+        public AttachmentDto? IdAttach { get; set; }
+        public string? CreateUser { get; set; }
+        public bool IsSuspended { get; set; }
+
+
+    }
+}

+ 25 - 2
MTWorkHR.Application/Mapper/MappingProfile.cs

@@ -1,6 +1,7 @@
 using AutoMapper;
 using Azure;
 using Countries.NET;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Identity;
 using MTWorkHR.Application.Models;
 using MTWorkHR.Core.Entities;
@@ -49,10 +50,30 @@ namespace MTWorkHR.Application.Mapper
               //  .ForMember(m => m.UserAddress, op => op.Ignore())
                 .ForMember(m => m.Id, op => op.Ignore());
 
-            CreateMap<ApplicationUser, UserUpdateDto>().ForMember(m => m.Password, op => op.Ignore());
-            CreateMap<UserDto, UserUpdateDto>().ReverseMap();
+            CreateMap<ApplicationUser, UserUpdateDto>().ForMember(m => m.Password, op => op.Ignore())
+                .ForMember(s => s.QualificationName, o => o.MapFrom(s => s.Qualification == null ? "" : GlobalInfo.lang == "ar" ? s.Qualification.NameAr : s.Qualification.NameEn))
+                .ForMember(s => s.JobTitleName, o => o.MapFrom(s => s.JobTitle == null ? "" : GlobalInfo.lang == "ar" ? s.JobTitle.NameAr : s.JobTitle.NameEn))
+                .ForMember(s => s.IndustryName, o => o.MapFrom(s => s.Industry == null ? "" : GlobalInfo.lang == "ar" ? s.Industry.NameAr : s.Industry.NameEn))
+                .ForMember(s => s.CountryName, o => o.MapFrom(s => s.Country == null ? "" : GlobalInfo.lang == "ar" ? s.Country.NameAr : s.Country.NameEn))
+                .ForMember(s => s.UniversityName, o => o.MapFrom(s => s.University == null ? "" : GlobalInfo.lang == "ar" ? s.University.NameAr : s.University.NameEn));
+            CreateMap<UserDto, UserUpdateDto>()
+                //.ForMember(m => m.CVAttach, op => op.Ignore())
+                //.ForMember(m => m.EduCertificateAttach, op => op.Ignore())
+                //.ForMember(m => m.ExperienceCertificateAttach, op => op.Ignore())
+                //.ForMember(m => m.PassportAttach, op => op.Ignore())
+                //.ForMember(m => m.ProfCertificateAttach, op => op.Ignore())
+                //.ForMember(m => m.ProfileImage, op => op.Ignore())
+                .ReverseMap();
             CreateMap<UserBasicInfoDto, ApplicationUser>().ReverseMap();
             CreateMap<UserBasicInfoDto, UserDto>().ReverseMap();
+
+
+
+            CreateMap<IFormFile, AttachmentDto>()
+            .ForMember(dest => dest.FileData, opt => opt.MapFrom(src => src))
+            .ForMember(dest => dest.FileName, opt => opt.MapFrom(src => src.FileName))
+            .ForMember(dest => dest.OriginalName, opt => opt.MapFrom(src => src.FileName)) // Adjust if OriginalName differs
+            .ForMember(dest => dest.FilePath, opt => opt.Ignore()); // Ignore FilePath or map if you have logic
             // -------------------view Employee info
             CreateMap<ApplicationUser, EmployeeInfoDto>()
               .ForMember(s => s.QualificationName, o => o.MapFrom(s => s.Qualification == null ? "" : GlobalInfo.lang == "ar" ? s.Qualification.NameAr : s.Qualification.NameEn))
@@ -144,6 +165,8 @@ namespace MTWorkHR.Application.Mapper
 
             CreateMap<OrderType, OrderTypeDto>().ReverseMap();
             CreateMap<LeaveType, LeaveTypeDto>().ReverseMap();
+            CreateMap<Company, UpdateCompanyDto>();
+            CreateMap<UpdateCompanyDto, Company>().ForMember(d => d.CreateDate, o => o.Ignore()).ForMember(d => d.CreateUser, o => o.Ignore());
             CreateMap<CompanyDto, Company>().ForMember(d => d.CreateDate, o => o.Ignore()).ForMember(d => d.CreateUser, o => o.Ignore());
             CreateMap<Company, CompanyDto>()
                 .ForMember(s => s.CityName, o => o.MapFrom(s => s.City == null ? "" : GlobalInfo.lang == "ar" ? s.City.NameAr : s.City.NameEn))

+ 51 - 1
MTWorkHR.Application/Services/Base/BlobFileService.cs

@@ -31,7 +31,7 @@ namespace MTWorkHR.Application.Services
             _logger = logger;
         }
 
-        public async Task<AttachmentResponseDto> UploadFile(IFormFile file)
+        public async Task<AttachmentResponseDto> UploadFile2(IFormFile file)
         {
             AttachmentResponseDto result = new AttachmentResponseDto();
             try
@@ -46,6 +46,8 @@ namespace MTWorkHR.Application.Services
                         uniqueFileName = GenerateUniqueFileName(file.FileName);
                     }
                     var status = await blobClient.UploadAsync(file.OpenReadStream(), true);
+                    result.ContentType = file.ContentType;
+                    result.FileSize = file.Length;
                     result.OriginalName = file.FileName;
                     result.FileName = uniqueFileName;
                     result.FilePath = blobClient.Uri.AbsoluteUri;
@@ -60,6 +62,51 @@ namespace MTWorkHR.Application.Services
                 return result;
             }
         }
+
+        public async Task<AttachmentResponseDto> UploadFile(IFormFile file)
+        {
+            AttachmentResponseDto result = new AttachmentResponseDto();
+            try
+            {
+                if (file == null || file.Length == 0)
+                {
+                    _logger.LogWarning("No file uploaded or file is empty.");
+                    throw new AppException(ExceptionEnum.InCorrectFileLength);
+                }
+
+                _logger.LogInformation("Received file: Name={FileName}, ContentType={ContentType}, Length={Length}",
+                    file.FileName, file.ContentType, file.Length);
+
+                string uniqueFileName = GenerateUniqueFileName(file.FileName);
+                var blobClient = _containerClient.GetBlobClient(uniqueFileName);
+
+                if (await blobClient.ExistsAsync())
+                {
+                    uniqueFileName = GenerateUniqueFileName(file.FileName);
+                    blobClient = _containerClient.GetBlobClient(uniqueFileName);
+                }
+
+                using var stream = file.OpenReadStream();
+                if (stream.Length == 0)
+                {
+                    _logger.LogWarning("File stream is empty for file: {FileName}", file.FileName);
+                    throw new AppException(ExceptionEnum.InCorrectFileLength);
+                }
+
+                var status = await blobClient.UploadAsync(stream, true);
+                result.ContentType = file.ContentType;
+                result.FileSize = file.Length; // Should now reflect the correct size
+                result.OriginalName = file.FileName;
+                result.FileName = uniqueFileName;
+                result.FilePath = blobClient.Uri.AbsoluteUri;
+                return result;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Failed to upload file: {Message}", ex.Message);
+                throw new AppException(ExceptionEnum.CouldNotMoveFiles);
+            }
+        }
         public async Task<string> UploadFileCloud(AttachmentDto file)
         {
             try
@@ -67,6 +114,7 @@ namespace MTWorkHR.Application.Services
                 // Generate a unique file name to avoid overwriting
                 string uniqueFileName = GenerateUniqueFileName(file.FileName);
                 var blobClient = _containerClient.GetBlobClient(uniqueFileName);
+                _logger.LogInformation("0########## File upload start uniqueFileName={0}", uniqueFileName);
 
                 if (blobClient != null)
                 {
@@ -91,6 +139,8 @@ namespace MTWorkHR.Application.Services
                             file.FileName = uniqueFileName;
                         }
                     }
+                    _logger.LogInformation("1########## File upload finish path={0}", blobClient.Uri.AbsoluteUri);
+
                     return blobClient.Uri.AbsoluteUri;
                 }
                 else

+ 3 - 1
MTWorkHR.Application/Services/Interfaces/ICompanyService.cs

@@ -13,9 +13,11 @@ namespace MTWorkHR.Application.Services.Interfaces
     {
       
         Task<List<CompanyDto>> GetAllCompanies();
-        Task<CompanyDto> GetById();
+        Task<UpdateCompanyDto> GetById();
         Task<CompanyDto> GetById(long companyId);
+        Task<UpdateCompanyDto> GetByIdForUpdate(long companyId);
         Task Suspend(long companyId);
+        Task<UpdateCompanyDto> Update(UpdateCompanyDto input);
 
     }
 }

+ 4 - 2
MTWorkHR.Application/Services/Interfaces/IUserService.cs

@@ -12,8 +12,10 @@ namespace MTWorkHR.Application.Identity
     {
         Task<PagingResultDto<UserAllDto>> GetAll(UserPagingInputDto PagingInputDto);
         Task<UserDto> GetById(string userId);
+        Task<UserUpdateDto> GetByIdForUpdate(string userId);
+
         Task<UserDto> GetByEmail(string email);
-        Task<UserDto> GetById();
+        Task<UserUpdateDto> GetById();
         Task<List<UserDto>> GetAllEmployees();
 
         Task<UserDto> GetUserById(string id);
@@ -40,7 +42,7 @@ namespace MTWorkHR.Application.Identity
         Task<bool> Update(string userId, long companyId);
         Task Suspend(string id);
         Task<bool> UnAssignCompanyEmployees(long companyId);
-        Task<(string FullName, string Email)> GetUserNameEmail(string userId);
+        Task<(string FullName, string Email, string ProfileImage)> GetUserNameEmail(string userId);
 
     }
 }

+ 57 - 9
MTWorkHR.Application/Services/Task/UserTaskAttachmentService.cs

@@ -12,20 +12,26 @@ using MTWorkHR.Infrastructure.UnitOfWorks;
 using MTWorkHR.Core.IRepositories.Base;
 using Microsoft.AspNetCore.Http;
 using System.IO;
+using System.Linq.Dynamic.Core;
+using Microsoft.EntityFrameworkCore;
+using MTWorkHR.Application.Identity;
+
 
 namespace MTWorkHR.Application.Services
 {
     public class UserTaskAttachmentService : BaseService<UserTaskAttachment, AttachmentDto, AttachmentDto>, IUserTaskAttachmentService
     {
         private readonly IUnitOfWork _unitOfWork;
-        //private readonly AppSettingsConfiguration _configuration;
-        //private readonly GlobalInfo _globalInfo;
+        private readonly IUserService _userService;
         private readonly IFileService _fileService;
+        private readonly GlobalInfo _globalInfo;
 
-        public UserTaskAttachmentService(IUnitOfWork unitOfWork, IFileService fileService) : base(unitOfWork)
+        public UserTaskAttachmentService(IUnitOfWork unitOfWork, IFileService fileService, GlobalInfo globalInfo, IUserService userService) : base(unitOfWork)
         {
             _unitOfWork = unitOfWork;
             _fileService = fileService;
+            _globalInfo = globalInfo;
+            _userService = userService;
         }
 
 
@@ -36,6 +42,41 @@ namespace MTWorkHR.Application.Services
             return response;
         }
 
+        public override async Task<PagingResultDto<AttachmentDto>> GetAll(PagingInputDto PagingInputDto)
+        {
+            var res = await _unitOfWork.UserTaskAttachment.GetAllWithChildrenAsync();
+            var query = res.Item1;
+          
+            if (PagingInputDto.Filter != null)
+            {
+                var filter = PagingInputDto.Filter;
+                query = query.Where(u => u.FileName.Contains(filter));
+            }
+
+            var order = query.OrderBy(PagingInputDto.OrderByField + " " + PagingInputDto.OrderType);
+
+            var page = order.Skip((PagingInputDto.PageNumber * PagingInputDto.PageSize) - PagingInputDto.PageSize).Take(PagingInputDto.PageSize);
+
+            var total = await query.CountAsync();
+
+            var list = MapperObject.Mapper
+                .Map<IList<AttachmentDto>>(await page.ToListAsync());
+            // Fetch user data for all employees
+            foreach (var attach in list)
+            {
+                var user = await _userService.GetUserNameEmail(attach.CreateUser);
+                attach.ProfileImage = user.ProfileImage;
+                attach.CreatedUserName = user.FullName;
+            }
+            var response = new PagingResultDto<AttachmentDto>
+            {
+                Result = list,
+                Total = total
+            };
+
+            return response;
+        }
+
         public override async Task<AttachmentDto> Create(AttachmentDto input)
         {
             //if (input.FileData != null)
@@ -54,26 +95,33 @@ namespace MTWorkHR.Application.Services
                 throw new AppException(ExceptionEnum.MapperIssue);
             }
 
-            var task = await _unitOfWork.UserTaskAttachment.AddAsync(entity);
+            var attach = await _unitOfWork.UserTaskAttachment.AddAsync(entity);
             await _unitOfWork.CompleteAsync();
 
-            var response = MapperObject.Mapper.Map<AttachmentDto>(task);
-           
+            var response = MapperObject.Mapper.Map<AttachmentDto>(attach);
+            var user = await _userService.GetUserNameEmail(attach.CreateUser);
+            response.ProfileImage = user.ProfileImage;
+            response.CreatedUserName = user.FullName;
             return response;
         }
 
 
         public override async Task<AttachmentDto> Update(AttachmentDto input)
         {
-            var entitiy = await _unitOfWork.UserTaskAttachment.GetByIdAsync(input.Id);
+            var attach = await _unitOfWork.UserTaskAttachment.GetByIdAsync(input.Id);
 
-            if (entitiy == null)
+            if (attach == null)
                 throw new AppException(ExceptionEnum.RecordNotExist);
 
-            MapperObject.Mapper.Map(input, entitiy, typeof(AttachmentDto), typeof(UserTaskAttachment));
+            MapperObject.Mapper.Map(input, attach, typeof(AttachmentDto), typeof(UserTaskAttachment));
 
             await _unitOfWork.CompleteAsync();
 
+            var response = MapperObject.Mapper.Map<AttachmentDto>(attach);
+
+            var user = await _userService.GetUserNameEmail(attach.CreateUser);
+            response.ProfileImage = user.ProfileImage;
+            response.CreatedUserName = user.FullName;
             return input;
         }
     }

+ 7 - 0
MTWorkHR.Application/Services/Task/UserTaskService.cs

@@ -33,6 +33,13 @@ namespace MTWorkHR.Application.Services
         {
             var entity = await _unitOfWork.UserTask.GetByIdWithAllChildren(id);
             var response = MapperObject.Mapper.Map<UserTaskDto>(entity);
+
+            foreach (var attach in response.TaskAttachments)
+            {
+                var user = await _userService.GetUserNameEmail(attach.CreateUser);
+                attach.ProfileImage = user.ProfileImage;
+                attach.CreatedUserName = user.FullName;
+            }
             await GetUserData(response);
             return response;
         }

+ 57 - 13
MTWorkHR.Application/Services/User/CompanyService.cs

@@ -45,12 +45,12 @@ namespace MTWorkHR.Application.Services
 
        
 
-        public async Task<CompanyDto> GetById()
+        public async Task<UpdateCompanyDto> GetById()
         {
             if (_globalInfo.CompanyId.HasValue)
-                return await GetById(_globalInfo.CompanyId.Value);
+                return await GetByIdForUpdate(_globalInfo.CompanyId.Value);
             else 
-                return new CompanyDto();
+                return new UpdateCompanyDto();
         }
         public override async Task<CompanyDto> GetById(long companyId)
         {
@@ -77,6 +77,32 @@ namespace MTWorkHR.Application.Services
             return companyResponse;
         }
 
+
+        public async Task<UpdateCompanyDto> GetByIdForUpdate(long companyId)
+        {
+            var companyResponse = new UpdateCompanyDto();
+            if (companyId > 0)
+            {
+                var entity = await _unitOfWork.Company.GetByIdWithAllChildren(companyId);
+                if (entity == null)
+                    throw new AppException(ExceptionEnum.RecordAlreadyExist);
+
+                companyResponse = MapperObject.Mapper.Map<UpdateCompanyDto>(entity);
+                var userDto = await _userService.GetByIdForUpdate(entity.UserId);
+                companyResponse.CommercialRegAttach = userDto.CommercialRegAttach;
+                if (userDto != null)
+                {
+                    companyResponse.PassportAttach = userDto.PassportAttach;
+                    companyResponse.IdAttach = userDto.IdAttach;
+                    companyResponse.ExperienceCertificateAttach = userDto.ExperienceCertificateAttach;
+                    companyResponse.TaxDeclarationAttach = userDto.TaxDeclarationAttach;
+                    companyResponse.CompanyUser = MapperObject.Mapper.Map<CompanyUserDto>(userDto);
+                    companyResponse.UserType = companyResponse.CompanyUser.UserType;
+                }
+            }
+            return companyResponse;
+        }
+
         public async  Task<List<CompanyDto>> GetAllCompanies()
         {
             var Companys = await _unitOfWork.Company.GetAllAsync();
@@ -136,13 +162,31 @@ namespace MTWorkHR.Application.Services
             //};
             var  UserAttachments = new List<AttachmentDto>();
 
-            AddAttachment(input.ProfileImage, 9, UserAttachments);
-            AddAttachment(input.CommercialRegAttach, 6, UserAttachments);
-            AddAttachment(input.PassportAttach, 2, UserAttachments);
-            AddAttachment(input.TaxDeclarationAttach, 7, UserAttachments);
-            AddAttachment(input.ExperienceCertificateAttach, 4, UserAttachments);
-            AddAttachment(input.IdAttach, 8, UserAttachments);
-          
+            if (input.ProfileImage != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.ProfileImage, OriginalName = input.ProfileImage?.Name, FileName = input.ProfileImage?.FileName, AttachmentTypeId = 9 });
+            }
+            if (input.CommercialRegAttach != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.CommercialRegAttach, OriginalName = input.CommercialRegAttach?.Name, FileName = input.CommercialRegAttach?.FileName, AttachmentTypeId = 6 });
+            }
+            if (input.PassportAttach != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.PassportAttach, OriginalName = input.PassportAttach?.Name, FileName = input.PassportAttach?.FileName, AttachmentTypeId = 2 });
+            }
+            if (input.TaxDeclarationAttach != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.TaxDeclarationAttach, OriginalName = input.TaxDeclarationAttach?.Name, FileName = input.TaxDeclarationAttach?.FileName, AttachmentTypeId = 7 });
+            }
+            if (input.ExperienceCertificateAttach != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.ExperienceCertificateAttach, OriginalName = input.ExperienceCertificateAttach?.Name, FileName = input.ExperienceCertificateAttach?.FileName, AttachmentTypeId = 4 });
+            }
+            if (input.IdAttach != null)
+            {
+                UserAttachments.Add(new AttachmentDto { FileData = input.IdAttach, OriginalName = input.IdAttach?.Name, FileName = input.IdAttach?.FileName, AttachmentTypeId = 8 });
+            }
+
             _fileService.CopyFileToCloud(ref UserAttachments);
             companyUser.UserAttachments = UserAttachments;
 
@@ -184,7 +228,7 @@ namespace MTWorkHR.Application.Services
             }
         }
 
-        public override async Task<CompanyDto> Update(CompanyDto input)
+        public async Task<UpdateCompanyDto> Update(UpdateCompanyDto input)
         {
             //var companyUser = MapperObject.Mapper.Map<UserUpdateDto>(input.CompanyUser);
             _unitOfWork.BeginTran();
@@ -196,14 +240,14 @@ namespace MTWorkHR.Application.Services
             if (entity == null)
                 throw new AppException(ExceptionEnum.RecordNotExist);
 
-            MapperObject.Mapper.Map(input, entity, typeof(CompanyDto), typeof(Company));
+            MapperObject.Mapper.Map(input, entity, typeof(UpdateCompanyDto), typeof(Company));
 
             await _unitOfWork.CompleteAsync();
             _unitOfWork.CommitTran();
 
             return input;
         }
-        public async Task<UserUpdateDto> UpdateCompanyUser(CompanyDto input)
+        public async Task<UserUpdateDto> UpdateCompanyUser(UpdateCompanyDto input)
         {
             try
             {

+ 24 - 19
MTWorkHR.Application/Services/User/TeamService.cs

@@ -82,18 +82,20 @@ namespace MTWorkHR.Application.Services
             }
             //entity.TeamUsers = input.TeamUserIds?.Select(s => new TeamUser { AssignedUserId = s,AssignedUserName = _userService.GetUserFullName(s).Result, IsAdmin = false }).ToList();
 
-
-            entity.TeamUsers = (await Task.WhenAll(input.TeamUserIds?.Select(async s =>
+            foreach(var teamUserId in input.TeamUserIds)
             {
-                var userInfo = await _userService.GetUserNameEmail(s);
-                return new TeamUser
+                var userInfo = await _userService.GetUserNameEmail(teamUserId);
+                if (entity.TeamUsers == null)
+                    entity.TeamUsers = new List<TeamUser>();
+                entity.TeamUsers.Add( new TeamUser
                 {
-                    AssignedUserId = s,
+                    AssignedUserId = teamUserId,
                     AssignedUserName = userInfo.FullName,
                     AssignedUserEmail = userInfo.Email,
+                    ProfileImage = userInfo.ProfileImage,
                     IsAdmin = false
-                };
-            }) ?? Enumerable.Empty<Task<TeamUser>>())).ToList();
+                });
+            }         
 
             var team = await _unitOfWork.Team.AddAsync(entity);
             await _unitOfWork.CompleteAsync();
@@ -120,18 +122,22 @@ namespace MTWorkHR.Application.Services
             var NewItems = input.TeamUserIds?.Where(u => !oldUsers.Contains(u));
           //  var newTeamUsers = NewItems?.Select(s => new TeamUser {TeamId = input.Id, AssignedUserId = s, AssignedUserName = _userService.GetUserFullName(s).Result, IsAdmin = false }).ToList();
 
-            var newTeamUsers = (await Task.WhenAll(NewItems?.Select(async s =>
+            var newTeamUsers = new List<TeamUser>();
+            foreach (var teamUserId in NewItems)
             {
-                var (fullName, email) = await _userService.GetUserNameEmail(s);
-                return new TeamUser
+                var userInfo = await _userService.GetUserNameEmail(teamUserId);
+                if (entity.TeamUsers == null)
+                    entity.TeamUsers = new List<TeamUser>();
+                entity.TeamUsers.Add(new TeamUser
                 {
                     TeamId = input.Id,
-                    AssignedUserId = s,
-                    AssignedUserName = fullName,
-                    AssignedUserEmail = email,
+                    AssignedUserId = teamUserId,
+                    AssignedUserName = userInfo.FullName,
+                    AssignedUserEmail = userInfo.Email,
+                    ProfileImage = userInfo.ProfileImage,
                     IsAdmin = false
-                };
-            }) ?? Enumerable.Empty<Task<TeamUser>>())).ToList();
+                });
+            }
 
             var DeletedItems = oldUsers?.Where(u => !input.TeamUserIds.Contains(u));
             _unitOfWork.BeginTran();
@@ -140,15 +146,14 @@ namespace MTWorkHR.Application.Services
                 var removeItem = entity.TeamUsers?.FirstOrDefault(u => u.AssignedUserId == delUser);
                 if(removeItem != null) await _unitOfWork.TeamUser.DeleteAsync(removeItem);
             }
-            foreach (var newUsr in newTeamUsers)
-            {
-                await _unitOfWork.TeamUser.AddAsync(newUsr);
-            }
+          
 
             await _unitOfWork.CompleteAsync();
             _unitOfWork.CommitTran();
 
             var response = Mapper.MapperObject.Mapper.Map<TeamDto>(entity);
+            response.TeamUserIds = input.TeamUserIds;
+
             return response;
         }
 

+ 120 - 33
MTWorkHR.Application/Services/User/UserService.cs

@@ -28,6 +28,7 @@ using System.ComponentModel.Design;
 using static iText.StyledXmlParser.Jsoup.Select.Evaluator;
 using static iText.IO.Util.IntHashtable;
 using Microsoft.Extensions.Logging;
+using iText.IO.Image;
 
 namespace MTWorkHR.Application.Services
 {
@@ -60,9 +61,9 @@ namespace MTWorkHR.Application.Services
             _logger = logger;
         }
 
-        public async Task<UserDto> GetById()
+        public async Task<UserUpdateDto> GetById()
         {
-            return await GetById(_globalInfo.UserId);
+            return await GetByIdForUpdate(_globalInfo.UserId);
         }
         public async Task<UserDto> GetByEmail(string email)
         {
@@ -89,6 +90,81 @@ namespace MTWorkHR.Application.Services
             if (response.UserAttachments != null)
                 foreach (var attach in response.UserAttachments.Where(a => a.Content != null))
                 {
+                    //var stream = new MemoryStream(attach.Content);
+                    //IFormFile file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName);
+
+                    using (var stream = new MemoryStream(attach.Content))
+                    {
+                        var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FilePath)
+                        {
+                            Headers = new HeaderDictionary(),
+                            ContentType = attach.ContentType,
+
+                        };
+
+                        System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
+                        {
+                            FileName = file.FileName
+                        };
+                        file.ContentDisposition = cd.ToString();
+                        switch (attach.AttachmentTypeId)
+                        {
+                            case 1:
+                                response.CVAttach = file;
+                                break;
+                            case 2:
+                                response.PassportAttach = file;
+                                break;
+                            case 3:
+                                response.EduCertificateAttach = file;
+                                break;
+                            case 4:
+                                response.ExperienceCertificateAttach = file;
+                                break;
+                            case 5:
+                                response.ProfCertificateAttach = file;
+                                break;
+                            case 6:
+                                response.CommercialRegAttach = file;
+                                break;
+                            case 7:
+                                response.TaxDeclarationAttach = file;
+                                break;
+                            case 8:
+                                response.IdAttach = file;
+                                break;
+                            case 9:
+                                response.ProfileImage = file;
+                                response.ProfileImagePath = attach.FilePath;
+                                break;
+                        }
+                        attach.Content = new byte[0];
+                    }
+
+                }
+
+            var attendance = await _unitOfWork.Attendance.GetAttendanceByUserId(id, DateTime.UtcNow.Date);
+            response.IsCheckedIn = attendance != null && attendance.CheckInTime.HasValue;
+            response.IsCheckedOut = attendance != null && attendance.CheckOutTime.HasValue;
+            return response;
+        }
+        public async Task<UserUpdateDto> GetByIdForUpdate(string id)
+        {
+            var entity = await _userManager.Users
+                .Include(x => x.UserRoles)
+                .Include(x => x.UserAddress).ThenInclude(x => x.City)
+                .Include(x => x.UserAddress).ThenInclude(x => x.Country)
+                .Include(x => x.UserAttachments)
+                .Include(x => x.JobTitle)
+                .Include(x => x.Industry)
+                .Include(x => x.University)
+                .Include(x => x.Country)
+                .Include(x => x.Qualification)
+                .FirstOrDefaultAsync(x => x.Id == id);
+            var response = MapperObject.Mapper.Map<UserUpdateDto>(entity);
+            if (response.UserAttachments != null)
+                foreach (var attach in response.UserAttachments)
+                {
                     switch (attach.AttachmentTypeId)
                     {
                         case 1:
@@ -101,7 +177,7 @@ namespace MTWorkHR.Application.Services
                             response.EduCertificateAttach = attach;
                             break;
                         case 4:
-                            response.ExperienceCertificateAttach= attach;
+                            response.ExperienceCertificateAttach = attach;
                             break;
                         case 5:
                             response.ProfCertificateAttach = attach;
@@ -122,7 +198,6 @@ namespace MTWorkHR.Application.Services
                     }
                     attach.Content = new byte[0];
                 }
-            
             var attendance = await _unitOfWork.Attendance.GetAttendanceByUserId(id, DateTime.UtcNow.Date);
             response.IsCheckedIn = attendance != null && attendance.CheckInTime.HasValue;
             response.IsCheckedOut = attendance != null && attendance.CheckOutTime.HasValue;
@@ -190,7 +265,7 @@ namespace MTWorkHR.Application.Services
         }
         public async Task<UserDto> GetUserById(string id)
         {
-            var entity = await _userManager.Users
+            var entity = await _userManager.Users.Include(u=> u.UserAttachments)
                 .FirstOrDefaultAsync(x => x.Id == id);
             var response = MapperObject.Mapper.Map<UserDto>(entity);
 
@@ -203,17 +278,23 @@ namespace MTWorkHR.Application.Services
             return name;
         }
 
-        public async Task<(string FullName, string Email)> GetUserNameEmail(string userId)
+        public async Task<(string FullName, string Email, string ProfileImage)> GetUserNameEmail(string userId)
         {
             var entity = await GetUserById(userId);
+            var imagePath = "";
 
             if (entity == null)
-                return (string.Empty, string.Empty);
+                return (string.Empty, string.Empty, string.Empty);
 
+            if (entity != null)
+            {
+                var imageAtt = entity.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9);
+                imagePath = imageAtt != null ? imageAtt.FilePath : "";
+            }
             var name = $"{entity.FirstName} {entity.LastName}".Trim();
             var email = entity.Email ?? string.Empty;
 
-            return (name, email);
+            return (name, email, imagePath);
         }
 
         public async Task<UserDto> GetUserWithAttachmentById(string id)
@@ -446,18 +527,36 @@ namespace MTWorkHR.Application.Services
             //loop for given list of attachment, and move each file from Temp path to Actual path
             //  _fileService.UploadFiles(files);
             input.CountryId = input.CountryId == null || input.CountryId == 0 ? input.UserAddress?.CountryId : input.CountryId;
-           // if (input.UserAttachments == null )
-            input.UserAttachments = new List<AttachmentDto>();
-            AddAttachment(input.ProfileImage, 9,  input.UserAttachments);
-            AddAttachment(input.CVAttach, 1,  input.UserAttachments);
-            AddAttachment(input.PassportAttach, 2,  input.UserAttachments);
-            AddAttachment(input.EduCertificateAttach, 3,  input.UserAttachments);
-            AddAttachment(input.ExperienceCertificateAttach, 4,  input.UserAttachments);
-            AddAttachment(input.ProfCertificateAttach, 5,  input.UserAttachments);
-
+            if (input.UserAttachments == null)
+                input.UserAttachments = new List<AttachmentDto>();
+            if (input.ProfileImage != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfileImage, OriginalName = input.ProfileImage?.Name, FileName = input.ProfileImage?.FileName, AttachmentTypeId = 9 });
+            }
+            if (input.CVAttach != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.CVAttach, OriginalName = input.CVAttach?.Name, FileName = input.CVAttach?.FileName, AttachmentTypeId = 1 });
+            }
+            if (input.PassportAttach != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.PassportAttach, OriginalName = input.PassportAttach?.Name, FileName = input.PassportAttach?.FileName, AttachmentTypeId = 2 });
+            }
+            if (input.EduCertificateAttach != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.EduCertificateAttach, OriginalName = input.EduCertificateAttach?.Name, FileName = input.EduCertificateAttach?.FileName, AttachmentTypeId = 3 });
+            }
+            if (input.ExperienceCertificateAttach != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.ExperienceCertificateAttach, OriginalName = input.ExperienceCertificateAttach?.Name, FileName = input.ExperienceCertificateAttach?.FileName, AttachmentTypeId = 4 });
+            }
+            if (input.ProfCertificateAttach != null)
+            {
+                input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfCertificateAttach, OriginalName = input.ProfCertificateAttach?.Name, FileName = input.ProfCertificateAttach?.FileName, AttachmentTypeId = 5 });
+            }
 
             var files = input.UserAttachments.Select(a=> a.FileData).ToList();
             List<AttachmentDto> attachs = input.UserAttachments.ToList();
+            if(attachs != null && attachs.Count > 0)
              _fileService.CopyFileToCloud(ref attachs);
             //if (!res)
             //    throw new AppException(ExceptionEnum.CouldNotMoveFiles);
@@ -550,19 +649,7 @@ namespace MTWorkHR.Application.Services
 
 
 
-        private void AddAttachment(AttachmentDto attachment, int attachmentTypeId, IList<AttachmentDto> attachList)
-        {
-            if (attachment != null)
-            {
-                attachList.Add(new AttachmentDto
-                {
-                    FilePath = attachment.FilePath,
-                    OriginalName = attachment.OriginalName,
-                    FileName = attachment.FileName,
-                    AttachmentTypeId = attachmentTypeId
-                });
-            }
-        }
+     
         public async Task<BlobObject> Download(string filePath)
         {
             var file = await _fileService.Download(filePath);
@@ -652,8 +739,8 @@ namespace MTWorkHR.Application.Services
                 throw e;
             }
             // Return updated user
-            var userResponse = await GetById(input.Id);
-            return MapperObject.Mapper.Map<UserUpdateDto>(userResponse);
+            var userResponse = await GetByIdForUpdate(input.Id);
+            return userResponse;
         }
 
         private void ProcessAttachment(ICollection<UserAttachment> oldAttachments, IList<AttachmentDto> newAttachments, AttachmentDto attachment,int attachmentTypeId)
@@ -670,7 +757,7 @@ namespace MTWorkHR.Application.Services
             newAttachments.Add(new AttachmentDto
             {
                 FilePath = attachment.FilePath,
-                OriginalName = attachment.OriginalName,
+                OriginalName = string.IsNullOrEmpty( attachment.OriginalName) ? attachment.FileName : attachment.OriginalName,
                 FileName = attachment.FileName,
                 AttachmentTypeId = attachmentTypeId
             });

+ 1 - 0
MTWorkHR.Core/Entities/User/TeamUser.cs

@@ -19,6 +19,7 @@ namespace MTWorkHR.Core.Entities
         public string AssignedUserId { get; set; }
         public string AssignedUserName { get; set; }
         public string AssignedUserEmail { get; set; }
+        public string? ProfileImage { get; set; }
         public bool IsAdmin { get; set; }
 
     }

+ 1 - 1
MTWorkHR.Core/Entities/User/UserTaskAttachment.cs

@@ -21,7 +21,7 @@ namespace MTWorkHR.Core.Entities
 
         [MaxLength(250)]
         public string? OriginalName { get; set; }
-
+        public long? FileSize { get; set; }
         public byte[] Content { get; set; }
         public string? FilePath { get; set; }
         public string? ContentType { get; set; }

+ 1 - 0
MTWorkHR.Core/IRepositories/Task/IUserTaskAttachmentRepository.cs

@@ -11,5 +11,6 @@ namespace MTWorkHR.Core.IRepositories
 {
     public interface IUserTaskAttachmentRepository : IRepository<UserTaskAttachment>
     {
+        Task<Tuple<IQueryable<UserTaskAttachment>, int>> GetAllWithChildrenAsync();
     }
 }

+ 27 - 18
MTWorkHR.Infrastructure/EmailService/MailSender.cs

@@ -42,7 +42,13 @@ namespace MTWorkHR.Infrastructure.EmailService
 
         //    return response.IsSuccessStatusCode;
         //}
-        public async Task<bool> SendEmail(EmailMessage email)
+
+        /// <summary>
+        /// Send Email using an azure email address, smtpUserName and password
+        /// </summary>
+        /// <param name="email"></param>
+        /// <returns></returns>
+        public async Task<bool> SendEmailAzure(EmailMessage email)
         {
             var mailTo = email.To;
             var settings = _configuration.MailSettings;
@@ -99,22 +105,16 @@ namespace MTWorkHR.Infrastructure.EmailService
                 _logger.LogError(ex, "Authentication failed for username {SmtpUsername}: {Message}",
                 settings.SmtpUsername, ex.Message);
                 throw ex;
-                Console.WriteLine($"Authentication failed: {ex.Message}, Inner Exception: {ex.InnerException?.Message}");
-                return false;
             }
             catch (SmtpCommandException ex)
             {
                 _logger.LogError(ex, "SMTP error: {Message}, Status: {StatusCode}", ex.Message, ex.StatusCode);
                 throw ex;
-                Console.WriteLine($"SMTP error: {ex.Message}, Status: {ex.StatusCode}, Inner Exception: {ex.InnerException?.Message}");
-                return false;
             }
             catch (Exception ex)
             {
                 _logger.LogError(ex, "Error sending email to {To}: {Message}", mailTo, ex.Message);
                 throw ex;
-                Console.WriteLine($"Error sending email: {ex.Message}, Inner Exception: {ex.InnerException?.Message}");
-                return false;
             }
             finally
             {
@@ -128,7 +128,9 @@ namespace MTWorkHR.Infrastructure.EmailService
 
             return true;
         }
-        public async Task<bool> SendEmailSMTP(EmailMessage email)
+
+        //Send Email using an email address and password
+        public async Task<bool> SendEmail(EmailMessage email)
         {
             var mailTo = email.To;
             var settings = _configuration.MailSettings;
@@ -158,25 +160,32 @@ namespace MTWorkHR.Infrastructure.EmailService
             using var smtp = new SmtpClient(logger);
             try
             {
-               
-
-                smtp.Connect(_configuration.MailSettings.Host, _configuration.MailSettings.Port, MailKit.Security.SecureSocketOptions.StartTls);
-                smtp.Authenticate(_configuration.MailSettings.FromAddress, _configuration.MailSettings.Password);
+                await smtp.ConnectAsync(_configuration.MailSettings.Host, _configuration.MailSettings.Port, MailKit.Security.SecureSocketOptions.StartTls);
+                await smtp.AuthenticateAsync(_configuration.MailSettings.FromAddress, _configuration.MailSettings.Password);
+                _logger.LogInformation("Sending email to {To} with subject {Subject}", mailTo, email.Subject);
                 await smtp.SendAsync(emailObj);
-                //smtp.Disconnect(true);
+                _logger.LogInformation("Email sent successfully to {To}", mailTo);
+
             }
-            catch (MailKit.Security.AuthenticationException ex)
+            catch (AuthenticationException ex)
             {
-                Console.WriteLine($"Authentication failed: {ex.Message}");
-                throw;
+                _logger.LogError(ex, "Authentication failed for username {SmtpUsername}: {Message}",
+                settings.SmtpUsername, ex.Message);
+                throw ex;
+            }
+            catch (SmtpCommandException ex)
+            {
+                _logger.LogError(ex, "SMTP error: {Message}, Status: {StatusCode}", ex.Message, ex.StatusCode);
+                throw ex;
             }
             catch (Exception ex)
             {
-                Console.WriteLine($"Error sending email: {ex.Message}");
-                throw;
+                _logger.LogError(ex, "Error sending email to {To}: {Message}", mailTo, ex.Message);
+                throw ex;
             }
             finally
             {
+                _logger.LogInformation("Disconnected from SMTP server");
                 await smtp.DisconnectAsync(true);
             }
             return true;

+ 1 - 1
MTWorkHR.Infrastructure/Entities/UserAttachment.cs

@@ -20,7 +20,7 @@ namespace MTWorkHR.Infrastructure.Entities
         public byte[] Content { get; set; }
 
         [MaxLength(250)]
-        public string OriginalName { get; set; }
+        public string? OriginalName { get; set; }
         public string? FilePath { get; set; }
         public string? ContentType { get; set; }
 

+ 1 - 1
MTWorkHR.Infrastructure/InfrastructureServiceRegistration.cs

@@ -32,7 +32,7 @@ namespace MTWorkHR.Infrastructure
             
             services.AddDbContext<HRDataContext>(options =>
                 options.UseSqlServer(
-                    config.ConnectionStrings.MTWorkHRConnectionString  //configuration.GetSection("ConnectionString:MTWorkHRConnectionString").Value
+                    config.ConnectionStrings.LocalConnectionString  //configuration.GetSection("ConnectionString:MTWorkHRConnectionString").Value
                     ));
            
             services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<HRDataContext>().AddDefaultTokenProviders();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 7354 - 0
MTWorkHR.Infrastructure/Migrations/20250526104756_altrAttachmentOriginal.Designer.cs


+ 40 - 0
MTWorkHR.Infrastructure/Migrations/20250526104756_altrAttachmentOriginal.cs

@@ -0,0 +1,40 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace MTWorkHR.Infrastructure.Migrations
+{
+    /// <inheritdoc />
+    public partial class altrAttachmentOriginal : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AlterColumn<string>(
+                name: "OriginalName",
+                table: "UserAttachments",
+                type: "nvarchar(250)",
+                maxLength: 250,
+                nullable: true,
+                oldClrType: typeof(string),
+                oldType: "nvarchar(250)",
+                oldMaxLength: 250);
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AlterColumn<string>(
+                name: "OriginalName",
+                table: "UserAttachments",
+                type: "nvarchar(250)",
+                maxLength: 250,
+                nullable: false,
+                defaultValue: "",
+                oldClrType: typeof(string),
+                oldType: "nvarchar(250)",
+                oldMaxLength: 250,
+                oldNullable: true);
+        }
+    }
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 7360 - 0
MTWorkHR.Infrastructure/Migrations/20250529131711_altrTaskAttachment.Designer.cs


+ 38 - 0
MTWorkHR.Infrastructure/Migrations/20250529131711_altrTaskAttachment.cs

@@ -0,0 +1,38 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace MTWorkHR.Infrastructure.Migrations
+{
+    /// <inheritdoc />
+    public partial class altrTaskAttachment : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<long>(
+                name: "FileSize",
+                table: "UserTaskAttachments",
+                type: "bigint",
+                nullable: true);
+
+            migrationBuilder.AddColumn<string>(
+                name: "ProfileImage",
+                table: "TeamUser",
+                type: "nvarchar(max)",
+                nullable: true);
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "FileSize",
+                table: "UserTaskAttachments");
+
+            migrationBuilder.DropColumn(
+                name: "ProfileImage",
+                table: "TeamUser");
+        }
+    }
+}

+ 6 - 1
MTWorkHR.Infrastructure/Migrations/HRDataContextModelSnapshot.cs

@@ -4845,6 +4845,9 @@ namespace MTWorkHR.Infrastructure.Migrations
                     b.Property<bool>("IsAdmin")
                         .HasColumnType("bit");
 
+                    b.Property<string>("ProfileImage")
+                        .HasColumnType("nvarchar(max)");
+
                     b.Property<long>("TeamId")
                         .HasColumnType("bigint");
 
@@ -5162,6 +5165,9 @@ namespace MTWorkHR.Infrastructure.Migrations
                     b.Property<string>("FilePath")
                         .HasColumnType("nvarchar(max)");
 
+                    b.Property<long?>("FileSize")
+                        .HasColumnType("bigint");
+
                     b.Property<string>("OriginalName")
                         .HasMaxLength(250)
                         .HasColumnType("nvarchar(250)");
@@ -6662,7 +6668,6 @@ namespace MTWorkHR.Infrastructure.Migrations
                         .HasColumnType("nvarchar(max)");
 
                     b.Property<string>("OriginalName")
-                        .IsRequired()
                         .HasMaxLength(250)
                         .HasColumnType("nvarchar(250)");
 

+ 10 - 0
MTWorkHR.Infrastructure/Repositories/Task/TaskAttachmentRepository.cs

@@ -9,9 +9,19 @@ namespace MTWorkHR.Infrastructure.Repositories
 {
     public class UserTaskAttachmentRepository : Repository<UserTaskAttachment>, IUserTaskAttachmentRepository
     {
+        private readonly DbSet<UserTaskAttachment> dbSet;
+
         public UserTaskAttachmentRepository(HRDataContext context) : base(context)
         {
+            dbSet = context.Set<UserTaskAttachment>();
+
         }
+        public async Task<Tuple<IQueryable<UserTaskAttachment>, int>> GetAllWithChildrenAsync()
+        {
+            var query = dbSet.AsQueryable();
+            var total = await query.CountAsync();
 
+            return new Tuple<IQueryable<UserTaskAttachment>, int>(query, total);
+        }
     }
 }