zinab_elgendy 1 napja
szülő
commit
7b62a7d24a

+ 9 - 0
MTWorkHR.API/Controllers/UserController.cs

@@ -106,6 +106,15 @@ namespace MTWorkHR.API.Controllers
             return await _userService.ResetPassword(input);
         }
 
+        [HttpPost("SetUpJobInterview")]
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [AppAuthorize(Permissions = "User")]
+        public async Task<ActionResult<JobInterviewDto>> SetUpJobInterview([FromBody] JobInterviewDto interview)
+        {
+            var result = await _userService.SetUpInterview(interview);
+            return result;
+        }
+
         [HttpGet("GetBlobFile")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         public async Task<ActionResult> GetBlobFile([FromQuery] string filePath)

+ 1 - 1
MTWorkHR.API/Program.cs

@@ -41,7 +41,7 @@ var config = new AppSettingsConfiguration();
 // Add services to the container.
 builder.Services.AddDbContext<HRDataContext>(options =>
 {
-    options.UseSqlServer(config.ConnectionStrings.MTWorkHRConnectionString);
+    options.UseSqlServer(config.ConnectionStrings.LocalConnectionString);
     //  options.UseSqlServer(builder.Configuration.GetSection("ConnectionStrings:MTWorkHRConnectionString").Value);
 });
 

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

@@ -32,9 +32,9 @@
   },
   "MailSettings": {
     "ApiKey": "SendGrid-Key",
-    "FromAddress": "Aamuarzaa@gmail.com",
+    "FromAddress": "noreply@mtwork.com",
     "FromName": "Hr Management System",
-    "Password": "Muath&111",
+    "Password": "Noreply&111",
     "Host": "smtp.gmail.com",
     "Port": 587,
     "TemplatePath": "C:\\Attachment\\MailTemp\\EmailTemplate.html"

+ 2 - 2
MTWorkHR.API/appsettings.json

@@ -31,9 +31,9 @@
   },
   "MailSettings": {
     "ApiKey": "SendGrid-Key",
-    "FromAddress": "Aamuarzaa@gmail.com",
+    "FromAddress": "noreply@mtwork.com",
     "FromName": "Hr Management System",
-    "Password": "Muath&111",
+    "Password": "Noreply&111",
     "Host": "smtp.gmail.com",
     "Port": 587,
     "TemplatePath": "C:\\Attachment\\MailTemp\\EmailTemplate.html"

+ 23 - 0
MTWorkHR.Application/Dtos/User/JobInterviewDto.cs

@@ -0,0 +1,23 @@
+using Microsoft.AspNetCore.Http;
+using MTWorkHR.Core.Entities;
+using MTWorkHR.Core.Entities.Base;
+using MTWorkHR.Core.Global;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace MTWorkHR.Application.Models
+{
+    public class JobInterviewDto : EntityDto
+    {
+        [Required]
+        public string Email { get; set; }
+        public string UserId { get; set; }
+        public DateTime InterviewDate { get; set; }
+        public string? InterviewTime { get; set; }
+       
+        [MaxLength(250)]
+        public string? InterviewLink { get; set; }
+        public bool? SendByMail { get; set; }
+        
+    }
+}

+ 3 - 0
MTWorkHR.Application/Mapper/MappingProfile.cs

@@ -187,6 +187,9 @@ namespace MTWorkHR.Application.Mapper
 
             CreateMap<ContractDetail, Contract>();
             CreateMap<Contract, ContractDetail>();
+            
+            
+            CreateMap<JobInterview, JobInterviewDto>().ReverseMap();
             //.ForMember(s => s.ContractDuration, o => o.MapFrom(s => s.ContractDurationId == null ? "" : ((ContractDurationEnum)s.ContractDurationId).ToString()));
             //.ForMember(s => s.WorkCountry, o => o.MapFrom(s => s.WorkCountryId == null ? "" : s.WorkCountryId));
         }

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

@@ -22,7 +22,8 @@ namespace MTWorkHR.Application.Identity
         Task Delete(string id);
         Task<UserDto> Create(UserDto input);
         Task<UserUpdateDto> Update(UserUpdateDto input);
-        Task<ForgetPasswordResponseDto> ForgetPasswordMail(string input);
+        Task<ForgetPasswordResponseDto> ForgetPasswordMail(string email);
+        Task<JobInterviewDto> SetUpInterview(JobInterviewDto interview);
         Task<bool> ResetPassword(ResetPasswordDto input);
 
         Task<bool> ForgetPassword(ForgetPasswordDto model);

+ 35 - 1
MTWorkHR.Application/Services/User/UserService.cs

@@ -811,6 +811,40 @@ namespace MTWorkHR.Application.Services
                 await _unitOfWork.CompleteAsync();
             }
         }
-      
+        public async Task<JobInterviewDto> SetUpInterview(JobInterviewDto input) 
+        {
+            var foundUser = await _userManager.FindByEmailAsync(input.Email);
+            if (foundUser != null)
+            {
+                if (input.SendByMail.HasValue && input.SendByMail.Value)
+                {
+                    var sendMailResult = await _emailSender.SendEmail(new EmailMessage
+                    {
+                        Subject = "Interview meeting link",
+                        To = input.Email,
+                        Body = "Please attend the job interview by using the following link"
+                        ,
+                        url = input.InterviewLink,
+                        userId = foundUser.Id
+                    });
+
+                    if (!sendMailResult)
+                    {
+                        throw new AppException("could not send the email!");
+                    }
+                }
+                input.UserId = foundUser.Id;
+                var jobInterview = MapperObject.Mapper.Map<JobInterview>(input);
+                var result = await _unitOfWork.JobInterview.AddAsync(jobInterview);
+                await _unitOfWork.CompleteAsync();
+
+                var res = MapperObject.Mapper.Map<JobInterviewDto>(result);
+                return res;
+            }
+            else
+            {
+                throw new AppException(ExceptionEnum.UserNotExist);
+            }
+        }
     }
 }

+ 24 - 0
MTWorkHR.Core/Entities/User/JobInterview.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MTWorkHR.Core.Entities.Base;
+using MTWorkHR.Core.Global;
+
+namespace MTWorkHR.Core.Entities
+{
+    public class JobInterview : FullAuditEntity, IHaveCompany
+    {
+        public long CompanyId { get; set; }
+        public string UserId { get; set; }
+        public string Email { get; set; }
+        public DateTime InterviewDate { get; set; }
+        public string? InterviewTime { get; set; }
+
+        [MaxLength(250)]
+        public string? InterviewLink { get; set; }
+        public bool? SendByMail { get; set; }
+    }
+}

+ 15 - 0
MTWorkHR.Core/IRepositories/User/IJobInterviewRepository.cs

@@ -0,0 +1,15 @@
+using MTWorkHR.Core.Entities;
+using MTWorkHR.Core.IRepositories.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MTWorkHR.Core.IRepositories
+{
+    public interface IJobInterviewRepository : IRepository<JobInterview>
+    {
+      
+    }
+}

+ 1 - 0
MTWorkHR.Core/IUnitOfWork/IUnitOfWork.cs

@@ -43,6 +43,7 @@ namespace MTWorkHR.Core.UnitOfWork
         IHubConnectionRepository HubConnection { get; }
         ISubscriptionConfigurationRepository SubscriptionConfiguration { get; }
         IInvoiceRepository Invoice { get; }
+        IJobInterviewRepository JobInterview { get; }
         Task<int> CompleteAsync();
 
         void BeginTran();

+ 2 - 1
MTWorkHR.Infrastructure/DBContext/HRDataContext.cs

@@ -55,7 +55,8 @@ namespace MTWorkHR.Infrastructure.DBContext
         public DbSet<Contract> Contracts { get; set; }
         public DbSet<Nationality> Nationalities{ get; set; }
         public DbSet<SubscriptionConfiguration> SubscriptionConfiguration { get; set; }
-        public DbSet<Invoice> Invoice { get; set; }
+        public DbSet<Invoice> Invoices { get; set; }
+        public DbSet<JobInterview> JobInterviews { get; set; }
 
         //------------------------Logs------------------------
         public DbSet<UserLog> UserLogs { get; set; }

+ 24 - 5
MTWorkHR.Infrastructure/EmailService/MailSender.cs

@@ -1,4 +1,5 @@
-using MailKit.Net.Smtp;
+using MailKit;
+using MailKit.Net.Smtp;
 using Microsoft.Extensions.Options;
 using MimeKit;
 using MTWorkHR.Core.Email;
@@ -52,24 +53,42 @@ namespace MTWorkHR.Infrastructure.EmailService
             //MailText = MailText.Replace("[NotificationType]", email.Subject).Replace("[Info]", email.Body).Replace("[Link]", email.url );
 
             var emailObj = new MimeMessage();
+            emailObj.From.Add(new MailboxAddress("Zinab Elgendy", _configuration.MailSettings.FromAddress)); // Ensure From matches authenticated email
             emailObj.Sender = MailboxAddress.Parse(_configuration.MailSettings.FromAddress);
             emailObj.To.Add(MailboxAddress.Parse(mailTo));
             emailObj.Subject = email.Subject;
 
             var builder = new BodyBuilder();
             email.Body = email.Body +
-                 ( string.IsNullOrEmpty( email.url ) ?"":  "Please click on <a href =\"" + email.url + "\">this link</a> to confirm your email address is correct. ");
+                 ( string.IsNullOrEmpty( email.url ) ?"":  "Please click on <a href =\"" + email.url + "\">this link</a> or copy the following url and open it : \' " + email.url+"\'");
 
             builder.HtmlBody = email.Body;
             emailObj.Body = builder.ToMessageBody();
+            using var logger = new ProtocolLogger("smtp.log", append: false);
+            using var smtp = new SmtpClient(logger);
             try
             {
-                using var smtp = new SmtpClient();
+               
+
                 smtp.Connect(_configuration.MailSettings.Host, _configuration.MailSettings.Port, MailKit.Security.SecureSocketOptions.StartTls);
                 smtp.Authenticate(_configuration.MailSettings.FromAddress, _configuration.MailSettings.Password);
                 await smtp.SendAsync(emailObj);
-                smtp.Disconnect(true);
-            }catch (Exception ex) { var ms = ex.Message; }
+                //smtp.Disconnect(true);
+            }
+            catch (MailKit.Security.AuthenticationException ex)
+            {
+                Console.WriteLine($"Authentication failed: {ex.Message}");
+                throw;
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"Error sending email: {ex.Message}");
+                throw;
+            }
+            finally
+            {
+                await smtp.DisconnectAsync(true);
+            }
             return true;
         }
     }

+ 2 - 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();
@@ -108,6 +108,7 @@ namespace MTWorkHR.Infrastructure
             services.AddScoped(typeof(IProjectStageAttachmentRepository), typeof(ProjectStageAttachmentRepository));
             services.AddScoped(typeof(ISubscriptionConfigurationRepository), typeof(SubscriptionConfigurationRepository));
             services.AddScoped(typeof(IInvoiceRepository), typeof(InvoiceRepository));
+            services.AddScoped(typeof(IJobInterviewRepository), typeof(JobInterviewRepository));
 
             services.AddScoped(typeof(IHubConnectionRepository), typeof(HubConnectionRepository));
             

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 7351 - 0
MTWorkHR.Infrastructure/Migrations/20250506101722_jobInterview.Designer.cs


+ 78 - 0
MTWorkHR.Infrastructure/Migrations/20250506101722_jobInterview.cs

@@ -0,0 +1,78 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace MTWorkHR.Infrastructure.Migrations
+{
+    /// <inheritdoc />
+    public partial class jobInterview : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropPrimaryKey(
+                name: "PK_Invoice",
+                table: "Invoice");
+
+            migrationBuilder.RenameTable(
+                name: "Invoice",
+                newName: "Invoices");
+
+            migrationBuilder.AddPrimaryKey(
+                name: "PK_Invoices",
+                table: "Invoices",
+                column: "Id");
+
+            migrationBuilder.CreateTable(
+                name: "JobInterviews",
+                columns: table => new
+                {
+                    Id = table.Column<long>(type: "bigint", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    CreateUser = table.Column<string>(type: "nvarchar(450)", maxLength: 450, nullable: true),
+                    UpdateUser = table.Column<string>(type: "nvarchar(450)", maxLength: 450, nullable: true),
+                    CreateDate = table.Column<DateTime>(type: "datetime2", nullable: false),
+                    UpdateDate = table.Column<DateTime>(type: "datetime2", nullable: true),
+                    IsDeleted = table.Column<bool>(type: "bit", nullable: false),
+                    DeleteUserId = table.Column<string>(type: "nvarchar(450)", maxLength: 450, nullable: true),
+                    CompanyId = table.Column<long>(type: "bigint", nullable: false),
+                    UserId = table.Column<string>(type: "nvarchar(max)", nullable: false),
+                    Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
+                    InterviewDate = table.Column<DateTime>(type: "datetime2", nullable: false),
+                    InterviewTime = table.Column<string>(type: "nvarchar(max)", nullable: true),
+                    InterviewLink = table.Column<string>(type: "nvarchar(250)", maxLength: 250, nullable: true),
+                    SendByMail = table.Column<bool>(type: "bit", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_JobInterviews", x => x.Id);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_JobInterviews_CompanyId",
+                table: "JobInterviews",
+                column: "CompanyId");
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "JobInterviews");
+
+            migrationBuilder.DropPrimaryKey(
+                name: "PK_Invoices",
+                table: "Invoices");
+
+            migrationBuilder.RenameTable(
+                name: "Invoices",
+                newName: "Invoice");
+
+            migrationBuilder.AddPrimaryKey(
+                name: "PK_Invoice",
+                table: "Invoice",
+                column: "Id");
+        }
+    }
+}

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

@@ -1476,7 +1476,74 @@ namespace MTWorkHR.Infrastructure.Migrations
 
                     b.HasKey("Id");
 
-                    b.ToTable("Invoice");
+                    b.ToTable("Invoices");
+                });
+
+            modelBuilder.Entity("MTWorkHR.Core.Entities.JobInterview", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasColumnOrder(0);
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("CompanyId")
+                        .HasColumnType("bigint");
+
+                    b.Property<DateTime>("CreateDate")
+                        .HasColumnType("datetime2")
+                        .HasColumnOrder(3);
+
+                    b.Property<string>("CreateUser")
+                        .HasMaxLength(450)
+                        .HasColumnType("nvarchar(450)")
+                        .HasColumnOrder(1);
+
+                    b.Property<string>("DeleteUserId")
+                        .HasMaxLength(450)
+                        .HasColumnType("nvarchar(450)")
+                        .HasColumnOrder(8);
+
+                    b.Property<string>("Email")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<DateTime>("InterviewDate")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("InterviewLink")
+                        .HasMaxLength(250)
+                        .HasColumnType("nvarchar(250)");
+
+                    b.Property<string>("InterviewTime")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<bool>("IsDeleted")
+                        .HasColumnType("bit")
+                        .HasColumnOrder(7);
+
+                    b.Property<bool?>("SendByMail")
+                        .HasColumnType("bit");
+
+                    b.Property<DateTime?>("UpdateDate")
+                        .HasColumnType("datetime2")
+                        .HasColumnOrder(4);
+
+                    b.Property<string>("UpdateUser")
+                        .HasMaxLength(450)
+                        .HasColumnType("nvarchar(450)")
+                        .HasColumnOrder(2);
+
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CompanyId");
+
+                    b.ToTable("JobInterviews");
                 });
 
             modelBuilder.Entity("MTWorkHR.Core.Entities.JobTitle", b =>

+ 19 - 0
MTWorkHR.Infrastructure/Repositories/User/JobInterviewRepository.cs

@@ -0,0 +1,19 @@
+using Microsoft.EntityFrameworkCore;
+using MTWorkHR.Core.Entities;
+using MTWorkHR.Core.IDto;
+using MTWorkHR.Core.IRepositories;
+using MTWorkHR.Infrastructure.Entities;
+using MTWorkHR.Infrastructure.DBContext;
+
+namespace MTWorkHR.Infrastructure.Repositories
+{
+    public class JobInterviewRepository : Repository<JobInterview>, IJobInterviewRepository
+    {
+        private readonly DbSet<JobInterview> dbSet;
+        public JobInterviewRepository(HRDataContext context) : base(context)
+        {
+            dbSet = context.Set<JobInterview>();
+        }
+       
+    }
+}

+ 4 - 2
MTWorkHR.Infrastructure/UnitOfWork/UnitOfWork.cs

@@ -45,7 +45,8 @@ namespace MTWorkHR.Infrastructure.UnitOfWorks
         public IProjectStageAttachmentRepository ProjectStageAttachment { get; }
         public ISubscriptionConfigurationRepository SubscriptionConfiguration { get; }
         public IInvoiceRepository Invoice { get; }
-
+        public IJobInterviewRepository JobInterview { get; }
+        
         public UnitOfWork(HRDataContext _context
             , IPermissionRepository permission
             , ICompanyRepository company
@@ -78,7 +79,7 @@ namespace MTWorkHR.Infrastructure.UnitOfWorks
             , IHubConnectionRepository connection
             , ISubscriptionConfigurationRepository subscriptionConfiguration
             , IInvoiceRepository invoice
-
+            , IJobInterviewRepository jobInterview
             )
         {
             context = _context;
@@ -113,6 +114,7 @@ namespace MTWorkHR.Infrastructure.UnitOfWorks
             ProjectStageAttachment = projectStageAttachment;
             SubscriptionConfiguration = subscriptionConfiguration;
             Invoice = invoice;
+            JobInterview = jobInterview;
         }
 
         public async Task<int> CompleteAsync()