Bladeren bron

BlobFile service

zinab_elgendy 7 maanden geleden
bovenliggende
commit
6d5ddc811f

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

@@ -48,7 +48,7 @@ namespace MTWorkHR.API.Controllers
         [HttpPost("Update")]
         [Consumes("multipart/form-data")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        public async Task Update([FromForm] UserDto input)
+        public async Task Update([FromForm] UserUpdateDto input)
         {
             await _userService.Update(input);
         }

+ 9 - 2
MTWorkHR.API/Program.cs

@@ -12,14 +12,19 @@ using MTWorkHR.Infrastructure.DBContext;
 using Microsoft.AspNetCore.Mvc.Controllers;
 using Microsoft.OpenApi.Models;
 using MTWorkHR.API.Swagger;
+using Azure.Storage.Blobs;
+using Microsoft.Extensions.DependencyInjection;
 
 var builder = WebApplication.CreateBuilder(args);
+var config = new AppSettingsConfiguration();
 // Add services to the container.
 builder.Services.AddDbContext<HRDataContext>(options =>
 {   
-    options.UseSqlServer(builder.Configuration.GetSection("ConnectionStrings:MTWorkHRConnectionString").Value);
+    options.UseSqlServer(config.ConnectionStrings.MTWorkHRConnectionString);
+  //  options.UseSqlServer(builder.Configuration.GetSection("ConnectionStrings:MTWorkHRConnectionString").Value);
 });
-var config = new AppSettingsConfiguration();
+
+
 builder.Configuration.Bind(config);
 builder.Services.AddApplicationServices(config);
 builder.Services.AddInfrastructureIdentityServices(config);
@@ -27,6 +32,8 @@ builder.Services.AddInfrastructureIdentityServices(config);
 //builder.Services.AddIdentityServices(config);
 builder.Services.AddHostedService<DbMigrationService>();
 
+builder.Services.AddSingleton(x => new BlobServiceClient(config.ConnectionStrings.BlobConnectionString));
+
 //builder.Services.AddControllers();
 builder.Services.AddControllers(options =>
 {

+ 2 - 1
MTWorkHR.Application/ApplicationServiceRegistration.cs

@@ -22,7 +22,8 @@ namespace MTWorkHR.Application
 
             services.AddTransient<IAuthService, AuthService>();
             services.AddTransient<IUserService, UserService>();
-            services.AddTransient<IFileService, FileService>();
+            //services.AddTransient<IFileService, FileService>();
+            services.AddTransient<IFileService, BlobFileService>();
             services.AddScoped<IProjectService, ProjectService>();
             services.AddScoped<IUserTaskService, UserTaskService>();
             services.AddScoped<IUserTaskAttachmentService, UserTaskAttachmentService>();

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

@@ -16,6 +16,7 @@ namespace MTWorkHR.Application.Models
         public string? FileName { get; set; }
 
         public string? OriginalName { get; set; }
+        public string? FilePath { get; set; }
 
     }
 }

+ 1 - 0
MTWorkHR.Application/Dtos/Identity/UserDto.cs

@@ -50,6 +50,7 @@ namespace MTWorkHR.Application.Models
         public decimal IncomeTaxValue { get; set; }
         public long? CompanyId { get; set; }
 
+        public IFormFile? ProfileImage { get; set; }
         public IFormFile? CVAttach { get; set; }
         public IFormFile? PassportAttach { get; set; }
         public IFormFile? EduCertificateAttach { get; set; }

+ 46 - 10
MTWorkHR.Application/Dtos/Identity/UserUpdateDto.cs

@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using Microsoft.AspNetCore.Http;
+using MTWorkHR.Core.Global;
+using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 
 namespace MTWorkHR.Application.Models
@@ -6,18 +8,52 @@ namespace MTWorkHR.Application.Models
     public class UserUpdateDto
     {
         public string? Id { get; set; }
-        public string? ManagerId { get; set; }
-        public long? DepartmentId { get; set; }
-        public long? BranchId { get; set; }
+        [Required]
+        public string FirstName { get; set; }
+        public DateTime DateOfBirth { get; set; }
 
-        [Required(ErrorMessage = "User Name is required")]
-        public string UserName { get; set; }
-
-        [Required(ErrorMessage = "Email is required")]
+        public string IdNumber { get; set; }
+        public string LastName { get; set; }
+        [Required]
+        [EmailAddress]
         public string Email { get; set; }
-        public string FullName { get; set; }
+
+        public string PassportNumber { get; set; }
+        public string? FavoriteName { get; set; }
+
         public string PhoneNumber { get; set; }
-        public bool IsSalesman { get; set; }
+        public string? LinkedInLink { get; set; }
+        [Required]
+        public UserTypeEnum UserType { get; set; }
+        [Required]
+        [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; }
+        public int? IndustryId { get; set; }
+        public int? CountryId { get; set; }
+        public string? QualificationName { get; set; }
+        public string? UniversityName { get; set; }
+        public string? JobTitleName { get; set; }
+        public string? IndustryName { get; set; }
+        public string? CountryName { get; set; }
+
+        public decimal TaxNumber { get; set; }
+        public decimal IncomeTaxValue { get; set; }
+        public long? CompanyId { 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; }
+
         public IList<UserRoleDto>? UserRoles { get; set; }
+        public IList<AttachmentDto>? UserAttachments { get; set; }
+        public UserAddressDto? UserAddress { get; set; }
     }
 }

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

@@ -18,6 +18,7 @@ namespace MTWorkHR.Application.Models
 
 
         public CompanyUserDto? CompanyUser { get; set; }
+        public IFormFile? ProfileImage { get; set; }
         public IFormFile? CommercialRegAttach { get; set; }
         public IFormFile? TaxDeclarationAttach { get; set; }
         public IFormFile? PassportAttach { get; set; }

+ 1 - 0
MTWorkHR.Application/MTWorkHR.Application.csproj

@@ -9,6 +9,7 @@
   <ItemGroup>
     <PackageReference Include="AutoMapper" Version="12.0.1" />
     <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
+    <PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
     <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" />
     <PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />

+ 6 - 6
MTWorkHR.Application/Mapper/MappingProfile.cs

@@ -22,9 +22,10 @@ namespace MTWorkHR.Application.Mapper
 
             CreateMap<UserDto, ApplicationUser>()
                 .ForMember(m => m.UserRoles, op => op.Ignore())
-                .ForMember(m => m.UserAttachments, op => op.Ignore())
-                .ForMember(m => m.UserAddress, op => op.Ignore())
-                .ForMember(m => m.Id, op => op.Ignore());
+               // .ForMember(m => m.UserAttachments, op => op.Ignore())
+               // .ForMember(m => m.UserAddress, op => op.Ignore())
+                .ForMember(m => m.Id, op => op.Ignore()
+                );
 
             CreateMap<ApplicationUser, UserDto>().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))
@@ -43,9 +44,8 @@ namespace MTWorkHR.Application.Mapper
             
             CreateMap<UserUpdateDto, ApplicationUser>()
                 .ForMember(m => m.UserRoles, op => op.Ignore())
-               // .ForMember(m => m.UserBranchs, op => op.Ignore())
-               // .ForMember(m => m.UserCycleApprovals, op => op.Ignore())
-                //.ForMember(m => m.Hierarchies, op => op.Ignore())
+                .ForMember(m => m.UserAttachments, op => op.Ignore())
+                .ForMember(m => m.UserAddress, op => op.Ignore())
                 .ForMember(m => m.Id, op => op.Ignore());
 
             CreateMap<ApplicationUser, UserUpdateDto>();

+ 138 - 0
MTWorkHR.Application/Services/Base/BlobFileService.cs

@@ -0,0 +1,138 @@
+using AutoMapper;
+using Azure.Storage.Blobs;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
+using MTWorkHR.Application.Models;
+using MTWorkHR.Application.Services.Interfaces;
+using MTWorkHR.Core.Global;
+using System.Net.Http.Headers;
+
+namespace MTWorkHR.Application.Services
+{
+    public class BlobFileService : IFileService
+    {
+       // private readonly AppSettingsConfiguration settings;
+        private const string ContainerName = "blobcontainer";
+        public const string SuccessMessageKey = "SuccessMessage";
+        public const string ErrorMessageKey = "ErrorMessage";
+        private readonly BlobServiceClient _blobServiceClient;
+        private readonly BlobContainerClient _containerClient;
+
+        public BlobFileService(BlobServiceClient blobServiceClient)
+        {
+            _blobServiceClient = blobServiceClient;
+            _containerClient = _blobServiceClient.GetBlobContainerClient(ContainerName);
+            _containerClient.CreateIfNotExists();
+        }
+        public async Task<string> UploadFile(IFormFile file)
+        {
+            try
+            {
+                var blobClient = _containerClient.GetBlobClient(file.FileName);
+                var status = await blobClient.UploadAsync(file.OpenReadStream(), true);
+                //if(status.Value == "201")
+                return blobClient.Uri.AbsoluteUri;
+            }
+            catch (Exception ex)
+            {
+                return "";
+            }
+        }
+       
+        public async Task<List<string>> UploadFiles(List<IFormFile> files)
+        {
+            List<string> msgs = new List<string>();
+            foreach (var formFile in files)
+            {
+                msgs.Add(await UploadFile(formFile));
+            }
+            return msgs;
+        }
+        public async Task<Tuple<bool, string>> UploadFile2(IFormFile file)
+        {
+            try
+            {
+                var blobClient = _containerClient.GetBlobClient(file.FileName);
+                var status = await blobClient.UploadAsync(file.OpenReadStream(), true);
+                return new Tuple<bool, string>(true, "");// = "File uploaded successfully.";
+            }
+            catch (Exception ex)
+            {
+                return new Tuple<bool, string>(false, ex.Message);
+            }
+        }
+        public async Task<List<Tuple<bool, string>>> UploadFiles2(List<IFormFile> files)
+        {
+            List<Tuple<bool, string>> msgs = new List<Tuple<bool, string>>();
+            foreach (var formFile in files)
+            {
+                msgs.Add( await UploadFile2(formFile));
+            }
+            return msgs;
+        }
+
+       
+
+
+
+        
+        public async Task<bool> Delete(string fileName)
+        {
+            try
+            {
+                var blobClient = _containerClient.GetBlobClient(fileName);
+                await blobClient.DeleteIfExistsAsync();
+                return true;
+            }
+            catch (Exception ex)
+            {
+                return false;
+            }
+        }
+
+        public void CopyFileToCloud(ref List<AttachmentDto> attachments)
+        {
+            foreach(var attach in attachments)
+            {
+                if (attach.FileData != null)
+                {
+                    var resPath = UploadFile(attach.FileData).Result;
+                    if (resPath != "")
+                        attach.FilePath = resPath;
+                }
+                
+            }
+        }
+
+        public bool CopyFileToActualFolder(string FileName)
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool DeleteFileFromTempFolder(string FileName)
+        {
+            throw new NotImplementedException();
+        }
+
+        public string GetTempAttachmentPath()
+        {
+            throw new NotImplementedException();
+        }
+
+        public string GetActualAttachmentPath()
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task<Tuple<MemoryStream, string, string>> GetFileDownloadInfo(string fileUrl)
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task<bool> CopyFileToActualFolder(List<AttachmentDto> attachments)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 4 - 1
MTWorkHR.Application/Services/Base/FileService.cs

@@ -206,6 +206,9 @@ namespace MTWorkHR.Application.Services
             return true;
         }
 
- 
+        public void CopyFileToCloud(ref List<AttachmentDto> attachments)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 1 - 1
MTWorkHR.Application/Services/Interfaces/IFileService.cs

@@ -15,7 +15,7 @@ namespace MTWorkHR.Application.Services.Interfaces
         Task<bool> CopyFileToActualFolder(List<AttachmentDto> attachments);
         bool CopyFileToActualFolder(string FileName);
         bool DeleteFileFromTempFolder(string FileName);
-
+        void CopyFileToCloud(ref List<AttachmentDto> attachments);
         string GetTempAttachmentPath();
         string GetActualAttachmentPath();
         Task<Tuple<MemoryStream, string, string>> GetFileDownloadInfo(string fileUrl);

+ 1 - 1
MTWorkHR.Application/Services/Interfaces/IUserService.cs

@@ -17,7 +17,7 @@ namespace MTWorkHR.Application.Identity
         Task<UserDto> GetUserById(string id);
         Task Delete(string id);
         Task<UserDto> Create(UserDto input);
-        Task<UserDto> Update(UserDto input);
+        Task<UserUpdateDto> Update(UserUpdateDto input);
         Task<ForgetPasswordResponseDto> ForgetPasswordMail(string input);
         Task<bool> ResetPassword(ResetPasswordDto input);
 

+ 8 - 4
MTWorkHR.Application/Services/User/CompanyService.cs

@@ -87,6 +87,10 @@ namespace MTWorkHR.Application.Services
             //    UserAddress = input.Address,
             //};
             var  UserAttachments = new List<AttachmentDto>();
+            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 });
@@ -107,10 +111,10 @@ namespace MTWorkHR.Application.Services
             {
                 UserAttachments.Add(new AttachmentDto { FileData = input.IdAttach, OriginalName = input.IdAttach?.Name, FileName = input.IdAttach?.FileName, AttachmentTypeId = 8 });
             }
-            if (!await _fileService.CopyFileToActualFolder(UserAttachments.ToList()))
-                throw new AppException(ExceptionEnum.CouldNotMoveFiles);
+            _fileService.CopyFileToCloud(ref UserAttachments);
+            companyUser.UserAttachments = UserAttachments;
 
-           // var userResp = await _userService.Create(companyUser);
+            // var userResp = await _userService.Create(companyUser);
             var user = MapperObject.Mapper.Map<ApplicationUser>(companyUser);
             if (user.UserType == 0)
             {
@@ -132,7 +136,7 @@ namespace MTWorkHR.Application.Services
 
         public override async Task<CompanyDto> Update(CompanyDto input)
         {
-            var companyUser = MapperObject.Mapper.Map<UserDto>(input.CompanyUser);
+            var companyUser = MapperObject.Mapper.Map<UserUpdateDto>(input.CompanyUser);
 
             await _userService.Update(companyUser);
             var entity = await _unitOfWork.Company.GetByIdAsync(input.Id);

+ 22 - 6
MTWorkHR.Application/Services/User/UserService.cs

@@ -195,7 +195,11 @@ namespace MTWorkHR.Application.Services
             //  _fileService.UploadFiles(files);
             if (input.UserAttachments == null )
                 input.UserAttachments = new List<AttachmentDto>();
-            if(input.CVAttach != null)
+            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 });
             }
@@ -215,8 +219,12 @@ namespace MTWorkHR.Application.Services
             {
                 input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfCertificateAttach, OriginalName = input.ProfCertificateAttach?.Name, FileName = input.ProfCertificateAttach?.FileName, AttachmentTypeId = 5 });
             }
-            if (!await _fileService.CopyFileToActualFolder(input.UserAttachments.ToList()))
-                throw new AppException(ExceptionEnum.CouldNotMoveFiles);
+            var files = input.UserAttachments.Select(a=> a.FileData).ToList();
+            List<AttachmentDto> attachs = input.UserAttachments.ToList();
+             _fileService.CopyFileToCloud(ref attachs);
+            //if (!res)
+            //    throw new AppException(ExceptionEnum.CouldNotMoveFiles);
+            input.UserAttachments = attachs;
             var user = MapperObject.Mapper.Map<ApplicationUser>(input);
             if(user.UserType == 0)
             {
@@ -330,7 +338,7 @@ namespace MTWorkHR.Application.Services
             return new Tuple<string, string>(confirmEmailUrl, user.Email);
         }
 
-        public async Task<UserDto> Update(UserDto input)
+        public async Task<UserUpdateDto> Update(UserUpdateDto input)
         {
             try
             {
@@ -340,6 +348,10 @@ namespace MTWorkHR.Application.Services
                     throw new AppException(ExceptionEnum.RecordNotExist);
                 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 });
@@ -360,8 +372,12 @@ namespace MTWorkHR.Application.Services
                 {
                     input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfCertificateAttach, OriginalName = input.ProfCertificateAttach?.Name, FileName = input.ProfCertificateAttach?.FileName, AttachmentTypeId = 5 });
                 }
-                if (!await _fileService.CopyFileToActualFolder(input.UserAttachments.ToList()))
-                    throw new AppException(ExceptionEnum.CouldNotMoveFiles);
+                List<AttachmentDto> attachs = input.UserAttachments.ToList();
+                _fileService.CopyFileToCloud(ref attachs);
+                input.UserAttachments = attachs;
+
+                //if (!await _fileService.CopyFileToActualFolder(input.UserAttachments.ToList()))
+                //    throw new AppException(ExceptionEnum.CouldNotMoveFiles);
 
 
                 MapperObject.Mapper.Map(input, entity);

+ 6 - 0
MTWorkHR.Infrastructure/Configurations/AttachmentTypeConfiguration.cs

@@ -69,6 +69,12 @@ namespace MTWorkHR.Infrastructure.Configurations
                     Id = 8,
                     NameEn = "Identification",
                     NameAr = "الهوية"
+                },
+                new AttachmentType
+                {
+                    Id = 9,
+                    NameEn = "Image",
+                    NameAr = "الصورة"
                 }
                ) ;
         }

+ 2 - 0
MTWorkHR.Infrastructure/Entities/UserAttachment.cs

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

File diff suppressed because it is too large
+ 3333 - 0
MTWorkHR.Infrastructure/Migrations/20240624143650_altrAttachpath.Designer.cs


+ 56 - 0
MTWorkHR.Infrastructure/Migrations/20240624143650_altrAttachpath.cs

@@ -0,0 +1,56 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace MTWorkHR.Infrastructure.Migrations
+{
+    /// <inheritdoc />
+    public partial class altrAttachpath : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<string>(
+                name: "FilePath",
+                table: "UserAttachments",
+                type: "nvarchar(max)",
+                nullable: true);
+
+            migrationBuilder.UpdateData(
+                table: "AspNetUsers",
+                keyColumn: "Id",
+                keyValue: "ADMB3B92-2311-48F8-9DEC-F9FAEF1F21UA",
+                columns: new[] { "CompanyId", "NormalizedUserName", "UserName" },
+                values: new object[] { 1L, "A@B.COM", "A@b.com" });
+
+            migrationBuilder.UpdateData(
+                table: "AspNetUsers",
+                keyColumn: "Id",
+                keyValue: "AL5B3B92-2311-48F8-9DEC-F9FAEF1F21UB",
+                columns: new[] { "CompanyId", "NormalizedUserName", "UserName" },
+                values: new object[] { 1L, "ALI@B.COM", "Ali@b.com" });
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "FilePath",
+                table: "UserAttachments");
+
+            migrationBuilder.UpdateData(
+                table: "AspNetUsers",
+                keyColumn: "Id",
+                keyValue: "ADMB3B92-2311-48F8-9DEC-F9FAEF1F21UA",
+                columns: new[] { "CompanyId", "NormalizedUserName", "UserName" },
+                values: new object[] { null, "ADMIN", "Admin" });
+
+            migrationBuilder.UpdateData(
+                table: "AspNetUsers",
+                keyColumn: "Id",
+                keyValue: "AL5B3B92-2311-48F8-9DEC-F9FAEF1F21UB",
+                columns: new[] { "CompanyId", "NormalizedUserName", "UserName" },
+                values: new object[] { null, "ALI", "ali" });
+        }
+    }
+}

File diff suppressed because it is too large
+ 3340 - 0
MTWorkHR.Infrastructure/Migrations/20240625073053_addAttachmentType.Designer.cs


+ 28 - 0
MTWorkHR.Infrastructure/Migrations/20240625073053_addAttachmentType.cs

@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace MTWorkHR.Infrastructure.Migrations
+{
+    /// <inheritdoc />
+    public partial class addAttachmentType : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.InsertData(
+                table: "AttachmentTypes",
+                columns: new[] { "Id", "IsRequired", "NameAr", "NameEn" },
+                values: new object[] { 9L, false, "الصورة", "Image" });
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DeleteData(
+                table: "AttachmentTypes",
+                keyColumn: "Id",
+                keyValue: 9L);
+        }
+    }
+}

+ 16 - 4
MTWorkHR.Infrastructure/Migrations/HRDataContextModelSnapshot.cs

@@ -304,6 +304,13 @@ namespace MTWorkHR.Infrastructure.Migrations
                             IsRequired = false,
                             NameAr = "الهوية",
                             NameEn = "Identification"
+                        },
+                        new
+                        {
+                            Id = 9L,
+                            IsRequired = false,
+                            NameAr = "الصورة",
+                            NameEn = "Image"
                         });
                 });
 
@@ -2699,6 +2706,7 @@ namespace MTWorkHR.Infrastructure.Migrations
                         {
                             Id = "ADMB3B92-2311-48F8-9DEC-F9FAEF1F21UA",
                             AccessFailedCount = 0,
+                            CompanyId = 1L,
                             ConcurrencyStamp = "7cc87689-9eab-4280-b8e3-1834080783a5",
                             DateOfBirth = new DateTime(2000, 2, 10, 0, 0, 0, 0, DateTimeKind.Unspecified),
                             Email = "a@b.com",
@@ -2711,7 +2719,7 @@ namespace MTWorkHR.Infrastructure.Migrations
                             LastName = "Elgendy",
                             LockoutEnabled = false,
                             NormalizedEmail = "A@B.COM",
-                            NormalizedUserName = "ADMIN",
+                            NormalizedUserName = "A@B.COM",
                             PassportNumber = "1234567",
                             PasswordHash = "AQAAAAIAAYagAAAAEPg+ASbciPFxtyxQq8Wx5ilBUQ0RbAoITXXkOQm1PzC5BzySX0sn/wUmOjBKPDGV9w==",
                             PhoneNumber = "1234567890",
@@ -2719,13 +2727,14 @@ namespace MTWorkHR.Infrastructure.Migrations
                             SecurityStamp = "49bb16c3-4704-4c60-908d-dc8506950acc",
                             TaxNumber = 111m,
                             TwoFactorEnabled = false,
-                            UserName = "Admin",
+                            UserName = "A@b.com",
                             UserType = 1
                         },
                         new
                         {
                             Id = "AL5B3B92-2311-48F8-9DEC-F9FAEF1F21UB",
                             AccessFailedCount = 0,
+                            CompanyId = 1L,
                             ConcurrencyStamp = "4af7b4cf-802a-455b-b598-997e167745b3",
                             DateOfBirth = new DateTime(2001, 5, 13, 0, 0, 0, 0, DateTimeKind.Unspecified),
                             Email = "ali@b.com",
@@ -2738,7 +2747,7 @@ namespace MTWorkHR.Infrastructure.Migrations
                             LastName = "Farok",
                             LockoutEnabled = false,
                             NormalizedEmail = "ALI@B.COM",
-                            NormalizedUserName = "ALI",
+                            NormalizedUserName = "ALI@B.COM",
                             PassportNumber = "7654321001010",
                             PasswordHash = "AQAAAAIAAYagAAAAEI3QJkcZjCH4Y8Db4rEgL8Mmll5oCvYcWiXZjQSN9bGW4SMcjHe3ZPMnkN/l9DmJeQ==",
                             PhoneNumber = "1234567888",
@@ -2746,7 +2755,7 @@ namespace MTWorkHR.Infrastructure.Migrations
                             SecurityStamp = "62549056-1b9d-46d4-84f8-adea3e4d8b68",
                             TaxNumber = 222m,
                             TwoFactorEnabled = false,
-                            UserName = "ali",
+                            UserName = "Ali@b.com",
                             UserType = 1
                         });
                 });
@@ -2861,6 +2870,9 @@ namespace MTWorkHR.Infrastructure.Migrations
                         .HasMaxLength(250)
                         .HasColumnType("nvarchar(250)");
 
+                    b.Property<string>("FilePath")
+                        .HasColumnType("nvarchar(max)");
+
                     b.Property<string>("OriginalName")
                         .IsRequired()
                         .HasMaxLength(250)