From 0b439d02681e5d2330fe6f312c1bd8625d2e5986 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 11 Nov 2025 18:52:35 +0330 Subject: [PATCH] Refactor and integrate face embedding API support Refactored `EmployeeUploadPicture.cshtml.cs` to improve readability, maintainability, and modularity. Introduced `_httpClientFactory` for HTTP requests and added `SendEmbeddingsToApi` for Python API integration. Enhanced employee-related operations, including activation, image handling, and settings management. Added `IFaceEmbeddingService` interface and implemented it in `FaceEmbeddingService` to manage face embeddings. Integrated with a Python API for generating, refining, deleting, and retrieving embeddings. Included robust error handling and detailed logging. Improved code structure, reduced duplication, and added comments for better debugging and future development. Add face embedding integration for employee management Introduced `IFaceEmbeddingService` and its implementation to manage face embeddings via a Python API. Integrated embedding generation into `EmployeeApplication` and `EmployeeUploadPictureModel`, enabling image uploads, embedding creation, and validation. Refactored `EmployeeUploadPictureModel` for clarity, adding methods to handle image processing, API interactions, and employee activation/deactivation with embedding checks. Enhanced error handling, logging, and user feedback. Removed legacy code and updated dependencies to include `IHttpClientFactory` and `IFaceEmbeddingService`. Added localized error messages and improved maintainability by streamlining code. --- .../FaceEmbedding/IFaceEmbeddingService.cs | 24 + .../InfraStructure/FaceEmbeddingService.cs | 316 ++++ .../EmployeeAplication.cs | 51 +- .../RollCall/EmployeeUploadPicture.cshtml.cs | 1366 +++++++++-------- 4 files changed, 1083 insertions(+), 674 deletions(-) create mode 100644 0_Framework/Application/FaceEmbedding/IFaceEmbeddingService.cs create mode 100644 0_Framework/InfraStructure/FaceEmbeddingService.cs diff --git a/0_Framework/Application/FaceEmbedding/IFaceEmbeddingService.cs b/0_Framework/Application/FaceEmbedding/IFaceEmbeddingService.cs new file mode 100644 index 00000000..b5aab83b --- /dev/null +++ b/0_Framework/Application/FaceEmbedding/IFaceEmbeddingService.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace _0_Framework.Application.FaceEmbedding; + +public interface IFaceEmbeddingService +{ + Task GenerateEmbeddingsAsync(long employeeId, long workshopId, string employeeFullName, string picture1Path, string picture2Path); + Task GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, string employeeFullName, Stream picture1Stream, Stream picture2Stream); + Task RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, float confidence, Dictionary metadata = null); + Task DeleteEmbeddingAsync(long employeeId, long workshopId); + Task> GetEmbeddingAsync(long employeeId, long workshopId); +} + +public class FaceEmbeddingResponse +{ + public long EmployeeId { get; set; } + public long WorkshopId { get; set; } + public string EmployeeFullName { get; set; } + public float[] Embedding { get; set; } + public float Confidence { get; set; } + public Dictionary Metadata { get; set; } +} diff --git a/0_Framework/InfraStructure/FaceEmbeddingService.cs b/0_Framework/InfraStructure/FaceEmbeddingService.cs new file mode 100644 index 00000000..402e4cc7 --- /dev/null +++ b/0_Framework/InfraStructure/FaceEmbeddingService.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Text.Json; +using _0_Framework.Application; +using _0_Framework.Application.FaceEmbedding; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Http; +using System.Threading.Tasks; + +namespace _0_Framework.Infrastructure; + +/// +/// پیاده‌سازی سرویس ارتباط با API پایتون برای مدیریت Embeddings چهره +/// +public class FaceEmbeddingService : IFaceEmbeddingService +{ + private readonly IHttpClientFactory _httpClientFactory; + private readonly ILogger _logger; + private readonly string _apiBaseUrl; + + public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger logger) + { + _httpClientFactory = httpClientFactory; + _logger = logger; + _apiBaseUrl = "http://localhost:8000"; + } + + public async Task GenerateEmbeddingsAsync(long employeeId, long workshopId, + string employeeFullName, string picture1Path, string picture2Path) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.BaseAddress = new Uri(_apiBaseUrl); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + using var content = new MultipartFormDataContent(); + + // Add form fields + content.Add(new StringContent(employeeId.ToString()), "employee_id"); + content.Add(new StringContent(workshopId.ToString()), "workshop_id"); + content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name"); + + // Add picture files + if (File.Exists(picture1Path)) + { + var picture1Bytes = await File.ReadAllBytesAsync(picture1Path); + var picture1Content = new ByteArrayContent(picture1Bytes); + picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); + content.Add(picture1Content, "picture1", "1.jpg"); + } + else + { + _logger.LogWarning("Picture1 not found at path: {Path}", picture1Path); + return new OperationResult { IsSuccedded = false, Message = "تصویر اول یافت نشد" }; + } + + if (File.Exists(picture2Path)) + { + var picture2Bytes = await File.ReadAllBytesAsync(picture2Path); + var picture2Content = new ByteArrayContent(picture2Bytes); + picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); + content.Add(picture2Content, "picture2", "2.jpg"); + } + else + { + _logger.LogWarning("Picture2 not found at path: {Path}", picture2Path); + return new OperationResult { IsSuccedded = false, Message = "تصویر دوم یافت نشد" }; + } + + // Send request to Python API + var response = await httpClient.PostAsync("embeddings", content); + + if (response.IsSuccessStatusCode) + { + var responseContent = await response.Content.ReadAsStringAsync(); + _logger.LogInformation("Embeddings generated successfully for Employee {EmployeeId}, Workshop {WorkshopId}", + employeeId, workshopId); + + return new OperationResult + { + IsSuccedded = true, + Message = "Embedding با موفقیت ایجاد شد" + }; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("Failed to generate embeddings. Status: {StatusCode}, Error: {Error}", + response.StatusCode, errorContent); + + return new OperationResult + { + IsSuccedded = false, + Message = $"خطا در تولید Embedding: {response.StatusCode}" + }; + } + } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "HTTP error while calling embeddings API for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطا در ارتباط با سرور Embedding" + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while calling embeddings API for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطای غیرمنتظره در تولید Embedding" + }; + } + } + + public async Task GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, + string employeeFullName, Stream picture1Stream, Stream picture2Stream) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.BaseAddress = new Uri(_apiBaseUrl); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + using var content = new MultipartFormDataContent(); + + // Add form fields + content.Add(new StringContent(employeeId.ToString()), "employee_id"); + content.Add(new StringContent(workshopId.ToString()), "workshop_id"); + content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name"); + + // Add picture streams + var picture1Content = new StreamContent(picture1Stream); + picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); + content.Add(picture1Content, "picture1", "1.jpg"); + + var picture2Content = new StreamContent(picture2Stream); + picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); + content.Add(picture2Content, "picture2", "2.jpg"); + + // Send request to Python API + var response = await httpClient.PostAsync("embeddings", content); + + if (response.IsSuccessStatusCode) + { + _logger.LogInformation("Embeddings generated successfully from streams for Employee {EmployeeId}", employeeId); + return new OperationResult { IsSuccedded = true, Message = "Embedding با موفقیت ایجاد شد" }; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("Failed to generate embeddings from streams. Status: {StatusCode}, Error: {Error}", + response.StatusCode, errorContent); + + return new OperationResult + { + IsSuccedded = false, + Message = $"خطا در تولید Embedding: {response.StatusCode}" + }; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while generating embeddings from streams for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطا در تولید Embedding" + }; + } + } + + public async Task RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, + float confidence, Dictionary metadata = null) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.BaseAddress = new Uri(_apiBaseUrl); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + var requestBody = new + { + employeeId, + workshopId, + embedding, + confidence, + metadata = metadata ?? new Dictionary() + }; + + var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody); + + if (response.IsSuccessStatusCode) + { + _logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId); + return new OperationResult { IsSuccedded = true, Message = "Embedding بهبود یافت" }; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("Failed to refine embedding. Status: {StatusCode}, Error: {Error}", + response.StatusCode, errorContent); + + return new OperationResult + { + IsSuccedded = false, + Message = $"خطا در بهبود Embedding: {response.StatusCode}" + }; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while refining embedding for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطا در بهبود Embedding" + }; + } + } + + public async Task DeleteEmbeddingAsync(long employeeId, long workshopId) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.BaseAddress = new Uri(_apiBaseUrl); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + var response = await httpClient.DeleteAsync($"embeddings/{workshopId}/{employeeId}"); + + if (response.IsSuccessStatusCode) + { + _logger.LogInformation("Embedding deleted successfully for Employee {EmployeeId}", employeeId); + return new OperationResult { IsSuccedded = true, Message = "Embedding حذف شد" }; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("Failed to delete embedding. Status: {StatusCode}, Error: {Error}", + response.StatusCode, errorContent); + + return new OperationResult + { + IsSuccedded = false, + Message = $"خطا در حذف Embedding: {response.StatusCode}" + }; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while deleting embedding for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطا در حذف Embedding" + }; + } + } + + public async Task> GetEmbeddingAsync(long employeeId, long workshopId) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.BaseAddress = new Uri(_apiBaseUrl); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + var response = await httpClient.GetAsync($"embeddings/{workshopId}/{employeeId}"); + + if (response.IsSuccessStatusCode) + { + var content = await response.Content.ReadAsStringAsync(); + var embeddingData = JsonSerializer.Deserialize(content, + new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + _logger.LogInformation("Embedding retrieved successfully for Employee {EmployeeId}", employeeId); + + return new OperationResult + { + IsSuccedded = true, + Message = "Embedding دریافت شد", + Data = embeddingData + }; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + _logger.LogError("Failed to get embedding. Status: {StatusCode}, Error: {Error}", + response.StatusCode, errorContent); + + return new OperationResult + { + IsSuccedded = false, + Message = $"خطا در دریافت Embedding: {response.StatusCode}" + }; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while getting embedding for Employee {EmployeeId}", employeeId); + return new OperationResult + { + IsSuccedded = false, + Message = "خطا در دریافت Embedding" + }; + } + } +} diff --git a/CompanyManagment.Application/EmployeeAplication.cs b/CompanyManagment.Application/EmployeeAplication.cs index 47624e1f..34fae070 100644 --- a/CompanyManagment.Application/EmployeeAplication.cs +++ b/CompanyManagment.Application/EmployeeAplication.cs @@ -31,6 +31,7 @@ using Company.Domain.LeftWorkAgg; using CompanyManagment.App.Contracts.Employee.DTO; using Company.Domain.EmployeeAuthorizeTempAgg; using Company.Domain.LeftWorkInsuranceAgg; +using _0_Framework.Application.FaceEmbedding; namespace CompanyManagment.Application; @@ -61,29 +62,31 @@ public class EmployeeAplication : RepositoryBase, IEmployeeAppli private readonly ICustomizeWorkshopGroupSettingsRepository _customizeWorkshopGroupSettingsRepository; private readonly IEmployeeAuthorizeTempRepository _employeeAuthorizeTempRepository; private readonly ILeftWorkInsuranceRepository _leftWorkInsuranceRepository; + private readonly IFaceEmbeddingService _faceEmbeddingService; - public EmployeeAplication(IEmployeeRepository employeeRepository, CompanyContext context, IWorkshopRepository workShopRepository, IWebHostEnvironment webHostEnvironment, IRollCallEmployeeStatusApplication rollCallEmployeeStatusApplication, IRollCallEmployeeRepository rollCallEmployeeRepository, ICustomizeWorkshopSettingsApplication customizeWorkshopSettingsApplication, IEmployeeDocumentsApplication employeeDocumentsApplication, IEmployeeDocumentsRepository employeeDocumentsRepository, IEmployeeBankInformationApplication employeeBankInformationApplication, ILeftWorkTempRepository leftWorkTempRepository, IUidService uidService, ICustomizeWorkshopEmployeeSettingsRepository customizeWorkshopEmployeeSettingsRepository, IPersonnelCodeRepository personnelCodeRepository, IEmployeeClientTempRepository employeeClientTempRepository, ICustomizeWorkshopGroupSettingsRepository customizeWorkshopGroupSettingsRepository, ILeftWorkRepository leftWorkRepository, IEmployeeAuthorizeTempRepository employeeAuthorizeTempRepository, ILeftWorkInsuranceRepository leftWorkInsuranceRepository) : base(context) - { - _context = context; - _WorkShopRepository = workShopRepository; - _webHostEnvironment = webHostEnvironment; - _rollCallEmployeeStatusApplication = rollCallEmployeeStatusApplication; - _rollCallEmployeeRepository = rollCallEmployeeRepository; - _customizeWorkshopSettingsApplication = customizeWorkshopSettingsApplication; - _employeeDocumentsApplication = employeeDocumentsApplication; - _employeeBankInformationApplication = employeeBankInformationApplication; - _leftWorkTempRepository = leftWorkTempRepository; - _uidService = uidService; - _customizeWorkshopEmployeeSettingsRepository = customizeWorkshopEmployeeSettingsRepository; - _personnelCodeRepository = personnelCodeRepository; - _employeeClientTempRepository = employeeClientTempRepository; - _leftWorkRepository = leftWorkRepository; - _employeeAuthorizeTempRepository = employeeAuthorizeTempRepository; - _leftWorkInsuranceRepository = leftWorkInsuranceRepository; - _EmployeeRepository = employeeRepository; - } + public EmployeeAplication(IEmployeeRepository employeeRepository, CompanyContext context, IWorkshopRepository workShopRepository, IWebHostEnvironment webHostEnvironment, IRollCallEmployeeStatusApplication rollCallEmployeeStatusApplication, IRollCallEmployeeRepository rollCallEmployeeRepository, ICustomizeWorkshopSettingsApplication customizeWorkshopSettingsApplication, IEmployeeDocumentsApplication employeeDocumentsApplication, IEmployeeDocumentsRepository employeeDocumentsRepository, IEmployeeBankInformationApplication employeeBankInformationApplication, ILeftWorkTempRepository leftWorkTempRepository, IUidService uidService, ICustomizeWorkshopEmployeeSettingsRepository customizeWorkshopEmployeeSettingsRepository, IPersonnelCodeRepository personnelCodeRepository, IEmployeeClientTempRepository employeeClientTempRepository, ICustomizeWorkshopGroupSettingsRepository customizeWorkshopGroupSettingsRepository, ILeftWorkRepository leftWorkRepository, IEmployeeAuthorizeTempRepository employeeAuthorizeTempRepository, ILeftWorkInsuranceRepository leftWorkInsuranceRepository, IFaceEmbeddingService faceEmbeddingService) : base(context) + { + _context = context; + _WorkShopRepository = workShopRepository; + _webHostEnvironment = webHostEnvironment; + _rollCallEmployeeStatusApplication = rollCallEmployeeStatusApplication; + _rollCallEmployeeRepository = rollCallEmployeeRepository; + _customizeWorkshopSettingsApplication = customizeWorkshopSettingsApplication; + _employeeDocumentsApplication = employeeDocumentsApplication; + _employeeBankInformationApplication = employeeBankInformationApplication; + _leftWorkTempRepository = leftWorkTempRepository; + _uidService = uidService; + _customizeWorkshopEmployeeSettingsRepository = customizeWorkshopEmployeeSettingsRepository; + _personnelCodeRepository = personnelCodeRepository; + _employeeClientTempRepository = employeeClientTempRepository; + _leftWorkRepository = leftWorkRepository; + _employeeAuthorizeTempRepository = employeeAuthorizeTempRepository; + _leftWorkInsuranceRepository = leftWorkInsuranceRepository; + _EmployeeRepository = employeeRepository; + _faceEmbeddingService = faceEmbeddingService; + } - public OperationResult Create(CreateEmployee command) + public OperationResult Create(CreateEmployee command) { var opration = new OperationResult(); if (_EmployeeRepository.Exists(x => @@ -1122,6 +1125,12 @@ public class EmployeeAplication : RepositoryBase, IEmployeeAppli rollCallEmployee.HasImage(); _rollCallEmployeeRepository.Create(rollCallEmployee); _rollCallEmployeeRepository.SaveChanges(); + string employeeFullName = employee.FName + " " + employee.LName; + var res = _faceEmbeddingService.GenerateEmbeddingsAsync(employee.id,command.WorkshopId,employeeFullName, filePath1,filePath2).GetAwaiter().GetResult(); + if (!res.IsSuccedded) + { + return op.Failed(res.Message); + } } diff --git a/ServiceHost/Areas/Client/Pages/Company/RollCall/EmployeeUploadPicture.cshtml.cs b/ServiceHost/Areas/Client/Pages/Company/RollCall/EmployeeUploadPicture.cshtml.cs index f451487c..7e21d5ee 100644 --- a/ServiceHost/Areas/Client/Pages/Company/RollCall/EmployeeUploadPicture.cshtml.cs +++ b/ServiceHost/Areas/Client/Pages/Company/RollCall/EmployeeUploadPicture.cshtml.cs @@ -24,47 +24,48 @@ using Microsoft.AspNetCore.Builder; namespace ServiceHost.Areas.Client.Pages.Company.RollCall { - [Authorize] - [NeedsPermission(SubAccountPermissionHelper.UploadEmployeePicturePermissionCode)] - public class EmployeeUploadPictureModel : PageModel - { - public string WorkshopFullName; - public RollCallEmployeeViewModel Employees; - public RollCallServiceViewModel RollCallService; - public bool HasEmployees; + [Authorize] + [NeedsPermission(SubAccountPermissionHelper.UploadEmployeePicturePermissionCode)] + public class EmployeeUploadPictureModel : PageModel + { + public string WorkshopFullName; + public RollCallEmployeeViewModel Employees; + public RollCallServiceViewModel RollCallService; + public bool HasEmployees; - //[BindProperty] - public int MaxPersonValid { get; set; } - public long WorkshopId; - public int PageIndex; + //[BindProperty] + public int MaxPersonValid { get; set; } + public long WorkshopId; + public int PageIndex; - private readonly IWorkshopApplication _workshopApplication; - private readonly IEmployeeApplication _employeeApplication; - private readonly IRollCallEmployeeApplication _rollCallEmployeeApplication; - private readonly IRollCallServiceApplication _rollCallServiceApplication; - private readonly IWebHostEnvironment _webHostEnvironment; - private readonly IPasswordHasher _passwordHasher; - private readonly IRollCallEmployeeStatusApplication _rollCallEmployeeStatusApplication; - private readonly ICustomizeWorkshopSettingsApplication _customizeWorkshopSettingsApplication; - private readonly IHttpContextAccessor _contextAccessor; - private readonly IPersonnelCodeApplication _personnelCodeApplication; - private readonly IEmployeeClientTempApplication _employeeClientTemp; - private readonly IEmployeeDocumentsApplication _employeeDocumentsApplication; - private readonly IJobApplication _jobApplication; + private readonly IWorkshopApplication _workshopApplication; + private readonly IEmployeeApplication _employeeApplication; + private readonly IRollCallEmployeeApplication _rollCallEmployeeApplication; + private readonly IRollCallServiceApplication _rollCallServiceApplication; + private readonly IWebHostEnvironment _webHostEnvironment; + private readonly IPasswordHasher _passwordHasher; + private readonly IRollCallEmployeeStatusApplication _rollCallEmployeeStatusApplication; + private readonly ICustomizeWorkshopSettingsApplication _customizeWorkshopSettingsApplication; + private readonly IHttpContextAccessor _contextAccessor; + private readonly IPersonnelCodeApplication _personnelCodeApplication; + private readonly IEmployeeClientTempApplication _employeeClientTemp; + private readonly IEmployeeDocumentsApplication _employeeDocumentsApplication; + private readonly IJobApplication _jobApplication; + private readonly IHttpClientFactory _httpClientFactory; - - - - private readonly long _workshopId; + private readonly long _workshopId; public EmployeeUploadPictureModel(IWorkshopApplication workshopApplication, IPasswordHasher passwordHasher, IRollCallEmployeeApplication rollCallEmployeeApplication, - IJobApplication jobApplication, + IJobApplication jobApplication, IRollCallServiceApplication rollCallServiceApplication, IWebHostEnvironment webHostEnvironment, IEmployeeApplication employeeApplication, IRollCallEmployeeStatusApplication rollCallEmployeeStatusApplication, ICustomizeWorkshopSettingsApplication customizeWorkshopSettingsApplication, - IHttpContextAccessor contextAccessor, IPersonnelCodeApplication personnelCodeApplication, IEmployeeClientTempApplication employeeClientTempApplication, IEmployeeDocumentsApplication employeeDocumentsApplication) + IHttpContextAccessor contextAccessor, IPersonnelCodeApplication personnelCodeApplication, + IEmployeeClientTempApplication employeeClientTempApplication, + IEmployeeDocumentsApplication employeeDocumentsApplication, + IHttpClientFactory httpClientFactory) { _workshopApplication = workshopApplication; _passwordHasher = passwordHasher; @@ -76,699 +77,758 @@ namespace ServiceHost.Areas.Client.Pages.Company.RollCall _customizeWorkshopSettingsApplication = customizeWorkshopSettingsApplication; _contextAccessor = contextAccessor; _personnelCodeApplication = personnelCodeApplication; - _employeeClientTemp = employeeClientTempApplication; - _employeeDocumentsApplication = employeeDocumentsApplication; - _jobApplication = jobApplication; + _employeeClientTemp = employeeClientTempApplication; + _employeeDocumentsApplication = employeeDocumentsApplication; + _jobApplication = jobApplication; + _httpClientFactory = httpClientFactory; + + var workshopHash = _contextAccessor.HttpContext?.User.FindFirstValue("WorkshopSlug"); + _workshopId = _passwordHasher.SlugDecrypt(workshopHash); + + if (_workshopId < 1) + throw new InvalidDataException("اختلال در کارگاه"); + } + + public IActionResult OnGet() + { + RollCallService = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); + if (RollCallService == null) + return Redirect("/Client/Company/RollCall"); + + var workshop = _workshopApplication.GetWorkshopInfo(_workshopId); + + WorkshopFullName = workshop.WorkshopFullName; + + // if (string.IsNullOrEmpty(HttpContext.Session.GetString("MaxPersonValid"))) + // { + // MaxPersonValid = RollCallService.MaxPersonValid; + //HttpContext.Session.SetString("MaxPersonValid", MaxPersonValid.ToString()); + // } + // else + // { + // MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); + // } + + MaxPersonValid = RollCallService.MaxPersonValid; + //var distinctEmployees = _rollCallEmployeeApplication.GetPersonnelRollCallListPaginate(new RollCallEmployeeSearchModel() + //{ + + //}); + WorkshopId = _workshopId; + PageIndex = 0; + + HasEmployees = _rollCallEmployeeApplication.HasEmployees(_workshopId); + + return Page(); + } + + public IActionResult OnGetEmployeeUploadDataAjax(int pageIndex, string searchName) + { + //MaxPersonValid = _rollCallServiceApplication.GetActiveServiceByWorkshopId(workshopId).MaxPersonValid; + var distinctEmployees = _rollCallEmployeeApplication.GetPersonnelRollCallListPaginate( + new RollCallEmployeeSearchModel() + { + WorkshopId = _workshopId, + PageIndex = pageIndex, + Name = searchName + }); + + Employees = new RollCallEmployeeViewModel + { + PersonnelInfoViewModels = distinctEmployees + }; + return new JsonResult(new + { + isSuccedded = true, + data = Employees, + pageIndex = Employees.PersonnelInfoViewModels.Count() + }); + } + + public IActionResult OnGetLoadInfoCount() + { + //MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); + var activeService = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); + MaxPersonValid = activeService.MaxPersonValid; - - var workshopHash = _contextAccessor.HttpContext?.User.FindFirstValue("WorkshopSlug"); - _workshopId = _passwordHasher.SlugDecrypt(workshopHash); - - if (_workshopId < 1) - throw new InvalidDataException("اختلال در کارگاه"); - } - - public IActionResult OnGet() - { - RollCallService = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); - if (RollCallService == null) - return Redirect("/Client/Company/RollCall"); - - var workshop = _workshopApplication.GetWorkshopInfo(_workshopId); - - WorkshopFullName = workshop.WorkshopFullName; - - // if (string.IsNullOrEmpty(HttpContext.Session.GetString("MaxPersonValid"))) - // { - // MaxPersonValid = RollCallService.MaxPersonValid; - //HttpContext.Session.SetString("MaxPersonValid", MaxPersonValid.ToString()); - // } - // else - // { - // MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); - // } - - MaxPersonValid = RollCallService.MaxPersonValid; - //var distinctEmployees = _rollCallEmployeeApplication.GetPersonnelRollCallListPaginate(new RollCallEmployeeSearchModel() - //{ - - //}); - WorkshopId = _workshopId; - PageIndex = 0; - - HasEmployees = _rollCallEmployeeApplication.HasEmployees(_workshopId); - - return Page(); - } - - public IActionResult OnGetEmployeeUploadDataAjax(int pageIndex, string searchName) - { - //MaxPersonValid = _rollCallServiceApplication.GetActiveServiceByWorkshopId(workshopId).MaxPersonValid; - var distinctEmployees = _rollCallEmployeeApplication.GetPersonnelRollCallListPaginate( - new RollCallEmployeeSearchModel() - { - WorkshopId = _workshopId, - PageIndex = pageIndex, - Name = searchName - }); - - Employees = new RollCallEmployeeViewModel - { - PersonnelInfoViewModels = distinctEmployees - }; - return new JsonResult(new - { - isSuccedded = true, - data = Employees, - pageIndex = Employees.PersonnelInfoViewModels.Count() - }); - } - - public IActionResult OnGetLoadInfoCount() - { - //MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); - var activeService = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); - MaxPersonValid = activeService.MaxPersonValid; + var employeesCount = _rollCallEmployeeApplication.GetActiveAndDeActiveRollCallEmployees(_workshopId); - var employeesCount = _rollCallEmployeeApplication.GetActiveAndDeActiveRollCallEmployees(_workshopId); + return new JsonResult(new + { + isSuccedded = true, + maxPersonValid = MaxPersonValid == -1 ? "نامحدود" : MaxPersonValid.ToString(), + isTrueActiveCount = employeesCount.activeEmployees, + isFalseActiveCount = employeesCount.deActiveEmployees, + message = "موفق" + }); + } + + public IActionResult OnGetCheckModalTakeImage() + { + //MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); + + var plan = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); + + if (plan == null) + { + return new JsonResult(new + { + isSuccedded = false, + message = "شما سرویس خریداری شده ندارید" + }); + } + + if (plan.IsActiveString != "true") + { + return new JsonResult(new + { + isSuccedded = false, + message = "سرویس شما فعال نیست" + }); + } + + //var maxValid = RollCallService.MaxPersonValid; + + if (plan.MaxPersonValid == -1 || + _rollCallEmployeeApplication.activedPerson(_workshopId) < plan.MaxPersonValid) + { + return new JsonResult(new + { + isSuccedded = true, + message = "موفق" + }); + } + + return new JsonResult(new + { + isSuccedded = false, + message = "محدودیت افزودن پرسنل" + }); + } + + public IActionResult OnGetWorkshopSettingList() + { + var resultData = _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); + resultData.GroupSettings = resultData.GroupSettings.Where(x => !x.MainGroup).ToList(); + + return new JsonResult(new + { + success = true, + data = resultData, + }); + } + + public IActionResult OnGetModalTakeImages(long employeeId) + { + var employeeWorkshopInfo = + _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); + + bool hasPicture = false; + if (employeeWorkshopInfo != null && !string.IsNullOrEmpty(employeeWorkshopInfo.HasUploadedImage)) + hasPicture = bool.Parse(employeeWorkshopInfo.HasUploadedImage); + + var employeeDetails = _employeeApplication.GetDetails(employeeId); + + string employeeName = string.Empty; + if (employeeDetails != null) + employeeName = employeeDetails.EmployeeFullName; + + string pic1 = ""; + string pic2 = ""; + if (hasPicture) + { + string path1 = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{_workshopId}\\{employeeId}\\{1}.jpg"; + string path2 = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{_workshopId}\\{employeeId}\\{2}.jpg"; + + if (System.IO.File.Exists(path1)) + { + byte[] fileContent1 = System.IO.File.ReadAllBytes(path1); + pic1 = Convert.ToBase64String(fileContent1); + } + + if (System.IO.File.Exists(path2)) + { + byte[] fileContent2 = System.IO.File.ReadAllBytes(path2); + pic2 = Convert.ToBase64String(fileContent2); + } + + //byte[] fileContent1 = System.IO.File.ReadAllBytes($"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}\\{1}.jpg"); + //pic1 = Convert.ToBase64String(fileContent1); + //byte[] fileContent2 = System.IO.File.ReadAllBytes($"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}\\{2}.jpg"); + //pic2 = Convert.ToBase64String(fileContent2); + } - return new JsonResult(new - { - isSuccedded = true, - maxPersonValid = MaxPersonValid == -1 ? "نامحدود" : MaxPersonValid.ToString(), - isTrueActiveCount = employeesCount.activeEmployees, - isFalseActiveCount = employeesCount.deActiveEmployees, - message = "موفق" - }); - } + var workshopGroupSettings = + _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); - public IActionResult OnGetCheckModalTakeImage() - { - //MaxPersonValid = Convert.ToInt32(HttpContext.Session.GetString("MaxPersonValid")); - - var plan = _rollCallServiceApplication.GetActiveServiceByWorkshopId(_workshopId); - - if (plan == null) - { - return new JsonResult(new - { - isSuccedded = false, - message = "شما سرویس خریداری شده ندارید" - }); - } - - if (plan.IsActiveString != "true") - { - return new JsonResult(new - { - isSuccedded = false, - message = "سرویس شما فعال نیست" - }); - } - - //var maxValid = RollCallService.MaxPersonValid; - - if (plan.MaxPersonValid == -1 || - _rollCallEmployeeApplication.activedPerson(_workshopId) < plan.MaxPersonValid) - { - return new JsonResult(new - { - isSuccedded = true, - message = "موفق" - }); - } - - return new JsonResult(new - { - isSuccedded = false, - message = "محدودیت افزودن پرسنل" - }); - } - - public IActionResult OnGetWorkshopSettingList() - { - var resultData = _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); - resultData.GroupSettings = resultData.GroupSettings.Where(x => !x.MainGroup).ToList(); - - return new JsonResult(new - { - success = true, - data = resultData, - }); - } - - public IActionResult OnGetModalTakeImages(long employeeId) - { - var employeeWorkshopInfo = - _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); - - bool hasPicture = false; - if (employeeWorkshopInfo != null && !string.IsNullOrEmpty(employeeWorkshopInfo.HasUploadedImage)) - hasPicture = bool.Parse(employeeWorkshopInfo.HasUploadedImage); - - var employeeDetails = _employeeApplication.GetDetails(employeeId); - - string employeeName = string.Empty; - if (employeeDetails != null) - employeeName = employeeDetails.EmployeeFullName; - - string pic1 = ""; - string pic2 = ""; - if (hasPicture) - { - string path1 = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{_workshopId}\\{employeeId}\\{1}.jpg"; - string path2 = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{_workshopId}\\{employeeId}\\{2}.jpg"; - - if (System.IO.File.Exists(path1)) - { - byte[] fileContent1 = System.IO.File.ReadAllBytes(path1); - pic1 = Convert.ToBase64String(fileContent1); - } - - if (System.IO.File.Exists(path2)) - { - byte[] fileContent2 = System.IO.File.ReadAllBytes(path2); - pic2 = Convert.ToBase64String(fileContent2); - } - - //byte[] fileContent1 = System.IO.File.ReadAllBytes($"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}\\{1}.jpg"); - //pic1 = Convert.ToBase64String(fileContent1); - //byte[] fileContent2 = System.IO.File.ReadAllBytes($"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}\\{2}.jpg"); - //pic2 = Convert.ToBase64String(fileContent2); - } + var employeeSettings = + _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings(_workshopId, + employeeId); - var workshopGroupSettings = - _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); + var employeeClientTemp = _employeeClientTemp.GetDetails(employeeId, _workshopId); + if (employeeClientTemp != null) + { + employeeDetails.FName = employeeClientTemp.FName; + employeeDetails.LName = employeeClientTemp.LName; - var employeeSettings = - _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings(_workshopId, - employeeId); - + } - var employeeClientTemp = _employeeClientTemp.GetDetails(employeeId, _workshopId); - if (employeeClientTemp != null) - { - employeeDetails.FName = employeeClientTemp.FName; - employeeDetails.LName = employeeClientTemp.LName; - - } - - var rollCallEmployee = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); + var rollCallEmployee = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); - var res = new TakePictureModel() - { - HasPicture = hasPicture, - EmployeeId = employeeId, - WorkshopId = _workshopId, - Name = employeeName, - FirstNickName = rollCallEmployee?.EmployeeFName ?? employeeDetails.FName, - LastNickName = rollCallEmployee?.EmployeeLName ?? employeeDetails.LName, - Pic1 = pic1, - Pic2 = pic2, - GroupSettings = workshopGroupSettings, - EmployeeSettings = employeeSettings, - HasUploadedImage = rollCallEmployee?.HasUploadedImage == "true" - }; + var res = new TakePictureModel() + { + HasPicture = hasPicture, + EmployeeId = employeeId, + WorkshopId = _workshopId, + Name = employeeName, + FirstNickName = rollCallEmployee?.EmployeeFName ?? employeeDetails.FName, + LastNickName = rollCallEmployee?.EmployeeLName ?? employeeDetails.LName, + Pic1 = pic1, + Pic2 = pic2, + GroupSettings = workshopGroupSettings, + EmployeeSettings = employeeSettings, + HasUploadedImage = rollCallEmployee?.HasUploadedImage == "true" + }; - if (res.HasUploadedImage && res.EmployeeSettings != null) - { - return Partial("ModalTakeImagesEdit", res); - } - else - { - return Partial("ModalTakeImages", res); - } - } + if (res.HasUploadedImage && res.EmployeeSettings != null) + { + return Partial("ModalTakeImagesEdit", res); + } + else + { + return Partial("ModalTakeImages", res); + } + } - public IActionResult OnPostTakePicture(string base64pic1, string base64pic2, long workshopId, long employeeId, EditCustomizeEmployeeSettings command) - { + public async Task OnPostTakePicture(string base64pic1, string base64pic2, + long workshopId, long employeeId, EditCustomizeEmployeeSettings command) + { - try - { - using var transactionScope = new TransactionScope(); + try + { + using var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); - var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; - if (!Directory.Exists(directoryPath)) - Directory.CreateDirectory(directoryPath); + var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; + if (!Directory.Exists(directoryPath)) + Directory.CreateDirectory(directoryPath); - var filePath1 = Path.Combine(directoryPath) + $@"\1.jpg"; - CreateImageFromBase64(base64pic1, filePath1); - var filePath2 = Path.Combine(directoryPath) + $@"\2.jpg"; - CreateImageFromBase64(base64pic2, filePath2); + var filePath1 = Path.Combine(directoryPath) + $@"\1.jpg"; + CreateImageFromBase64(base64pic1, filePath1); + var filePath2 = Path.Combine(directoryPath) + $@"\2.jpg"; + CreateImageFromBase64(base64pic2, filePath2); - var employee = _employeeApplication.GetDetailsForClient(employeeId, workshopId); - var rollCallEmployee = - _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, workshopId); + // Call Python API to generate embeddings + await SendEmbeddingsToApi(employeeId, workshopId, filePath1, filePath2); - var result = new OperationResult() - { - IsSuccedded = false, - Message = "هنوز عملیاتی انجام نشده است" - }; - if (rollCallEmployee == null) - { - var createCommand = new CreateRollCallEmployee() - { - EmployeeId = employeeId, - WorkshopId = workshopId, - EmployeeFullName = employee.EmployeeFullName, - HasUploadedImage = "true", - }; - result = _rollCallEmployeeApplication.Create(createCommand); - var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() - { - RollCallEmployeeId = result.SendId - }); - if (result.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - if (createRollCallEmployeeStatus.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = createRollCallEmployeeStatus.IsSuccedded, - message = createRollCallEmployeeStatus.Message, - }); - } - _rollCallEmployeeStatusApplication.SyncRollCallEmployeeWithLeftWork(result.SendId); + var employee = _employeeApplication.GetDetailsForClient(employeeId, workshopId); + var rollCallEmployee = + _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, workshopId); + + var result = new OperationResult() + { + IsSuccedded = false, + Message = "هنوز عملیاتی انجام نشده است" + }; + if (rollCallEmployee == null) + { + var createCommand = new CreateRollCallEmployee() + { + EmployeeId = employeeId, + WorkshopId = workshopId, + EmployeeFullName = employee.EmployeeFullName, + HasUploadedImage = "true", + }; + result = _rollCallEmployeeApplication.Create(createCommand); + var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() + { + RollCallEmployeeId = result.SendId + }); + if (result.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + if (createRollCallEmployeeStatus.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = createRollCallEmployeeStatus.IsSuccedded, + message = createRollCallEmployeeStatus.Message, + }); + } + _rollCallEmployeeStatusApplication.SyncRollCallEmployeeWithLeftWork(result.SendId); } else - { - if ( rollCallEmployee.Statuses == null || rollCallEmployee.Statuses?.Any(x => x.StartDateGr <= DateTime.Now.Date && x.EndDateGr >= DateTime.Now.Date)== false) - { - var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() - { - RollCallEmployeeId = rollCallEmployee.Id - }); - if (createRollCallEmployeeStatus.IsSuccedded ==false) - { - return new JsonResult(new - { - isSuccedded = createRollCallEmployeeStatus.IsSuccedded, - message = createRollCallEmployeeStatus.Message, - }); - } - } + { + if (rollCallEmployee.Statuses == null || rollCallEmployee.Statuses?.Any(x => x.StartDateGr <= DateTime.Now.Date && x.EndDateGr >= DateTime.Now.Date) == false) + { + var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() + { + RollCallEmployeeId = rollCallEmployee.Id + }); + if (createRollCallEmployeeStatus.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = createRollCallEmployeeStatus.IsSuccedded, + message = createRollCallEmployeeStatus.Message, + }); + } + } - result = _rollCallEmployeeApplication.UploadedImage(employeeId, workshopId); - if (result.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - } + result = _rollCallEmployeeApplication.UploadedImage(employeeId, workshopId); + if (result.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + } - if (command.GroupId != 0) - { - command.EmployeeIds = [employeeId]; - command.WorkshopId = workshopId; - var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeesSettingsAndSetChanges(command); - if (employeeSettingsResult.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = employeeSettingsResult.IsSuccedded, - message = employeeSettingsResult.Message, - }); - } - } - - transactionScope.Complete(); - return new JsonResult(new - { - IsSuccedded = result.IsSuccedded, - Message = result.Message, - src = Tools.ResizeImage( - Path.Combine(_webHostEnvironment.ContentRootPath, "Faces", workshopId.ToString(), - employeeId.ToString(), "1.jpg"), 150, 150), - Id = result.SendId - }); - } - catch (Exception e) - { - Console.WriteLine(e); - return new JsonResult(new - { - IsSuccedded = false, - Message = e.Message, - }); - } - } + if (command.GroupId != 0) + { + command.EmployeeIds = [employeeId]; + command.WorkshopId = workshopId; + var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeesSettingsAndSetChanges(command); + if (employeeSettingsResult.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = employeeSettingsResult.IsSuccedded, + message = employeeSettingsResult.Message, + }); + } + } - public void CreateImageFromBase64(string base64, string imagePathWithExtension) - { - var subBase64 = base64.Substring(base64.LastIndexOf(',') + 1); - byte[] bytes = Convert.FromBase64String(subBase64); - System.IO.File.WriteAllBytes(imagePathWithExtension, bytes); - } - - public IActionResult OnPostActivePersonnel(long id) - { - var hasRollCallEmployee = _rollCallEmployeeApplication.GetDetails(id); - - if (hasRollCallEmployee == null) - { - return new JsonResult(new - { - isSuccedded = false, - message = - "برای این پرسنل، هنوز هیچ عکسی آپلود نشده است. بعد از آپلود عکس بطور خودکار فعال خواهد شد", - }); - } - else - { - if (hasRollCallEmployee.HasUploadedImage == "false") - return new JsonResult(new - { - isSuccedded = false, - message = - "برای این پرسنل، هنوز هیچ عکسی آپلود نشده است. بعد از آپلود عکس بطور خودکار فعال خواهد شد", - }); - else - { - var employeeSettings = - _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings( - _workshopId, hasRollCallEmployee.EmployeeId); - if (employeeSettings == null || employeeSettings.Id == 0) - { - return new JsonResult(new - { - isSuccedded = false, - HasEmployeeSetting = false, - message = "برای فعال سازی پرسنل می بایست حتما گروهبندی پرسنل را مشخص کنید" - - }); - } - - } - - var result = _rollCallEmployeeApplication.Active(hasRollCallEmployee.Id); - if (result.IsSuccedded) - { - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - else - { - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - } - - return new JsonResult(new - { - isSuccedded = false, - message = "خطایی رخ آمده است", - }); - } - - public IActionResult OnPostDeActivePersonnel(long id) - { - var result = _rollCallEmployeeApplication.DeActive(id); - if (result.IsSuccedded) - { - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } - - public IActionResult OnGetLoadFirstImage(long employeeId, long workshopId) - { - var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; - var imageDir = Path.Combine(directoryPath, "1.jpg"); - return PhysicalFile(imageDir, "image/jpeg"); - } - - public IActionResult OnGetLoadSecondImage(long employeeId, long workshopId) - { - var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; - var imageDir = Path.Combine(directoryPath, "2.jpg"); - return PhysicalFile(imageDir, "image/jpeg"); - } - - public IActionResult OnGetModalChangeName(long employeeId) - { - var command = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); - - return Partial("ModalChangeName", command); - } - - public IActionResult OnPostChangeName(long rollCallEmployeeId, string fName, string lName) - { - var result = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployeeId, fName, lName); - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } + transactionScope.Complete(); + return new JsonResult(new + { + IsSuccedded = result.IsSuccedded, + Message = result.Message, + src = Tools.ResizeImage( + Path.Combine(_webHostEnvironment.ContentRootPath, "Faces", workshopId.ToString(), + employeeId.ToString(), "1.jpg"), 150, 150), + Id = result.SendId + }); - public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatus(EditCustomizeEmployeeSettings command, string fName, string lName) - { - using var transactionScope = new TransactionScope(); + } + catch (Exception e) + { + Console.WriteLine(e); + return new JsonResult(new + { + IsSuccedded = false, + Message = e.Message, + }); + } + } - if (command.GroupId != 0) - { - var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeeSettings(command); - if (employeeSettingsResult.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = employeeSettingsResult.IsSuccedded, - message = employeeSettingsResult.Message, - }); - } - } - var rollCallEmployee = - _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(command.EmployeeIds.First(), _workshopId); + public void CreateImageFromBase64(string base64, string imagePathWithExtension) + { + var subBase64 = base64.Substring(base64.LastIndexOf(',') + 1); + byte[] bytes = Convert.FromBase64String(subBase64); + System.IO.File.WriteAllBytes(imagePathWithExtension, bytes); + } - if (rollCallEmployee == null) - { - return new JsonResult(new - { - isSuccedded = false, - message = "لطفا بخش آپلود عکس خودرا تکمیل نمایید", - }); - } + public IActionResult OnPostActivePersonnel(long id) + { + var hasRollCallEmployee = _rollCallEmployeeApplication.GetDetails(id); + + if (hasRollCallEmployee == null) + { + return new JsonResult(new + { + isSuccedded = false, + message = + "برای این پرسنل، هنوز هیچ عکسی آپلود نشده است. بعد از آپلود عکس بطور خودکار فعال خواهد شد", + }); + } + else + { + if (hasRollCallEmployee.HasUploadedImage == "false") + return new JsonResult(new + { + isSuccedded = false, + message = + "برای این پرسنل، هنوز هیچ عکسی آپلود نشده است. بعد از آپلود عکس بطور خودکار فعال خواهد شد", + }); + else + { + var employeeSettings = + _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings( + _workshopId, hasRollCallEmployee.EmployeeId); + if (employeeSettings == null || employeeSettings.Id == 0) + { + return new JsonResult(new + { + isSuccedded = false, + HasEmployeeSetting = false, + message = "برای فعال سازی پرسنل می بایست حتما گروهبندی پرسنل را مشخص کنید" + + }); + } + + } + + var result = _rollCallEmployeeApplication.Active(hasRollCallEmployee.Id); + if (result.IsSuccedded) + { + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + else + { + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + } + + return new JsonResult(new + { + isSuccedded = false, + message = "خطایی رخ آمده است", + }); + } + + public IActionResult OnPostDeActivePersonnel(long id) + { + var result = _rollCallEmployeeApplication.DeActive(id); + if (result.IsSuccedded) + { + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + + public IActionResult OnGetLoadFirstImage(long employeeId, long workshopId) + { + var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; + var imageDir = Path.Combine(directoryPath, "1.jpg"); + return PhysicalFile(imageDir, "image/jpeg"); + } + + public IActionResult OnGetLoadSecondImage(long employeeId, long workshopId) + { + var directoryPath = $"{_webHostEnvironment.ContentRootPath}\\Faces\\{workshopId}\\{employeeId}"; + var imageDir = Path.Combine(directoryPath, "2.jpg"); + return PhysicalFile(imageDir, "image/jpeg"); + } + + public IActionResult OnGetModalChangeName(long employeeId) + { + var command = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); + + return Partial("ModalChangeName", command); + } + + public IActionResult OnPostChangeName(long rollCallEmployeeId, string fName, string lName) + { + var result = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployeeId, fName, lName); + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } + + + public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatus(EditCustomizeEmployeeSettings command, string fName, string lName) + { + using var transactionScope = new TransactionScope(); + + if (command.GroupId != 0) + { + var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeeSettings(command); + if (employeeSettingsResult.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = employeeSettingsResult.IsSuccedded, + message = employeeSettingsResult.Message, + }); + } + } + var rollCallEmployee = + _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(command.EmployeeIds.First(), _workshopId); + + if (rollCallEmployee == null) + { + return new JsonResult(new + { + isSuccedded = false, + message = "لطفا بخش آپلود عکس خودرا تکمیل نمایید", + }); + } - var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() - { - RollCallEmployeeId = rollCallEmployee.Id - }); + var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() + { + RollCallEmployeeId = rollCallEmployee.Id + }); - if (createRollCallEmployeeStatus.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = createRollCallEmployeeStatus.IsSuccedded, - message = createRollCallEmployeeStatus.Message, - }); - } + if (createRollCallEmployeeStatus.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = createRollCallEmployeeStatus.IsSuccedded, + message = createRollCallEmployeeStatus.Message, + }); + } - var changeNameResult = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployee.Id, fName, lName); - if (changeNameResult.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = changeNameResult.IsSuccedded, - message = changeNameResult.Message, - }); - } + var changeNameResult = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployee.Id, fName, lName); + if (changeNameResult.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = changeNameResult.IsSuccedded, + message = changeNameResult.Message, + }); + } - transactionScope.Complete(); + transactionScope.Complete(); - return new JsonResult(new - { - isSuccedded = true, - message = createRollCallEmployeeStatus.Message, - }); - } + return new JsonResult(new + { + isSuccedded = true, + message = createRollCallEmployeeStatus.Message, + }); + } - public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatusModalStatus(long employeeId) - { - var employeeWorkshopInfo = - _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); + public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatusModalStatus(long employeeId) + { + var employeeWorkshopInfo = + _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); - bool hasPicture = false; - if (employeeWorkshopInfo != null && !string.IsNullOrEmpty(employeeWorkshopInfo.HasUploadedImage)) - hasPicture = bool.Parse(employeeWorkshopInfo.HasUploadedImage); + bool hasPicture = false; + if (employeeWorkshopInfo != null && !string.IsNullOrEmpty(employeeWorkshopInfo.HasUploadedImage)) + hasPicture = bool.Parse(employeeWorkshopInfo.HasUploadedImage); - var employeeDetails = _employeeApplication.GetDetails(employeeId); + var employeeDetails = _employeeApplication.GetDetails(employeeId); - string employeeName = string.Empty; - if (employeeDetails != null) - employeeName = employeeDetails.EmployeeFullName; + string employeeName = string.Empty; + if (employeeDetails != null) + employeeName = employeeDetails.EmployeeFullName; - var workshopGroupSettings = - _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); + var workshopGroupSettings = + _customizeWorkshopSettingsApplication.GetWorkshopIncludeGroupsByWorkshopId(_workshopId); - var employeeSettings = - _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings(_workshopId, - employeeId); + var employeeSettings = + _customizeWorkshopSettingsApplication.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings(_workshopId, + employeeId); - var rollCallEmployee = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); + var rollCallEmployee = _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(employeeId, _workshopId); - var res = new TakePictureModel() - { - EmployeeId = employeeId, - WorkshopId = _workshopId, - Name = employeeName, - FirstNickName = rollCallEmployee?.EmployeeFName ?? employeeDetails.FName, - LastNickName = rollCallEmployee?.EmployeeLName ?? employeeDetails.LName, + var res = new TakePictureModel() + { + EmployeeId = employeeId, + WorkshopId = _workshopId, + Name = employeeName, + FirstNickName = rollCallEmployee?.EmployeeFName ?? employeeDetails.FName, + LastNickName = rollCallEmployee?.EmployeeLName ?? employeeDetails.LName, - GroupSettings = workshopGroupSettings, - EmployeeSettings = employeeSettings, - HasUploadedImage = rollCallEmployee?.HasUploadedImage == "true" - }; + GroupSettings = workshopGroupSettings, + EmployeeSettings = employeeSettings, + HasUploadedImage = rollCallEmployee?.HasUploadedImage == "true" + }; - return Partial("ModalTakeImages", res); - } + return Partial("ModalTakeImages", res); + } - public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatusModalStatusSave(EditCustomizeEmployeeSettings command, string fName, string lName) - { - using var transactionScope = new TransactionScope(); + public IActionResult OnPostCreateEmployeeSettingsAndChangeNameAndCreateRollCallEmployeeStatusModalStatusSave(EditCustomizeEmployeeSettings command, string fName, string lName) + { + using var transactionScope = new TransactionScope(); - if (command.GroupId != 0) - { - var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeeSettings(command); - if (employeeSettingsResult.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = employeeSettingsResult.IsSuccedded, - message = employeeSettingsResult.Message, - }); - } - } - var rollCallEmployee = - _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(command.EmployeeIds.First(), _workshopId); + if (command.GroupId != 0) + { + var employeeSettingsResult = _customizeWorkshopSettingsApplication.CreateEmployeeSettings(command); + if (employeeSettingsResult.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = employeeSettingsResult.IsSuccedded, + message = employeeSettingsResult.Message, + }); + } + } + var rollCallEmployee = + _rollCallEmployeeApplication.GetByEmployeeIdAndWorkshopId(command.EmployeeIds.First(), _workshopId); - if (rollCallEmployee == null) - { - return new JsonResult(new - { - isSuccedded = false, - message = "لطفا بخش آپلود عکس خودرا تکمیل نمایید", - }); - } + if (rollCallEmployee == null) + { + return new JsonResult(new + { + isSuccedded = false, + message = "لطفا بخش آپلود عکس خودرا تکمیل نمایید", + }); + } - var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() - { - RollCallEmployeeId = rollCallEmployee.Id - }); + var createRollCallEmployeeStatus = _rollCallEmployeeStatusApplication.Create(new CreateRollCallEmployeeStatus() + { + RollCallEmployeeId = rollCallEmployee.Id + }); - if (createRollCallEmployeeStatus.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = createRollCallEmployeeStatus.IsSuccedded, - message = createRollCallEmployeeStatus.Message, - }); - } + if (createRollCallEmployeeStatus.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = createRollCallEmployeeStatus.IsSuccedded, + message = createRollCallEmployeeStatus.Message, + }); + } - var changeNameResult = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployee.Id, fName, lName); - if (changeNameResult.IsSuccedded == false) - { - return new JsonResult(new - { - isSuccedded = changeNameResult.IsSuccedded, - message = changeNameResult.Message, - }); - } + var changeNameResult = _rollCallEmployeeApplication.ChangeEmployeeRollCallName(rollCallEmployee.Id, fName, lName); + if (changeNameResult.IsSuccedded == false) + { + return new JsonResult(new + { + isSuccedded = changeNameResult.IsSuccedded, + message = changeNameResult.Message, + }); + } - transactionScope.Complete(); + transactionScope.Complete(); - return new JsonResult(new - { - isSuccedded = true, - message = createRollCallEmployeeStatus.Message, - }); - } + return new JsonResult(new + { + isSuccedded = true, + message = createRollCallEmployeeStatus.Message, + }); + } - public IActionResult OnGetCreateEmployee() - { - var command = new CreateEmployeeByClient(); - command.PersonnelCode = (_personnelCodeApplication.GetLastPersonnelCodeByWorkshop(_workshopId) + 1).ToString(); - command.HasRollCallService = _rollCallServiceApplication.IsExistActiveServiceByWorkshopId(_workshopId); - return Partial("../Employees/CreateEmployeeModal", command); - } + public IActionResult OnGetCreateEmployee() + { + var command = new CreateEmployeeByClient(); + command.PersonnelCode = (_personnelCodeApplication.GetLastPersonnelCodeByWorkshop(_workshopId) + 1).ToString(); + command.HasRollCallService = _rollCallServiceApplication.IsExistActiveServiceByWorkshopId(_workshopId); + return Partial("../Employees/CreateEmployeeModal", command); + } - public IActionResult OnPostSaveSubmit(SubmitEmployeeDocuments cmd) - { - var result = _employeeDocumentsApplication.SubmitDocumentItemsByClient(cmd); + public IActionResult OnPostSaveSubmit(SubmitEmployeeDocuments cmd) + { + var result = _employeeDocumentsApplication.SubmitDocumentItemsByClient(cmd); - return new JsonResult(new - { - isSuccedded = result.IsSuccedded, - message = result.Message, - }); - } + return new JsonResult(new + { + isSuccedded = result.IsSuccedded, + message = result.Message, + }); + } - public IActionResult OnPostCreateEmployee(CreateEmployeeByClient command) - { - command.WorkshopId = _workshopId; - var result = _employeeApplication.CreateEmployeeByClient(command); - return new JsonResult(new - { - success = result.IsSuccedded, - message = result.Message, - }); - } + public IActionResult OnPostCreateEmployee(CreateEmployeeByClient command) + { + command.WorkshopId = _workshopId; + var result = _employeeApplication.CreateEmployeeByClient(command); + return new JsonResult(new + { + success = result.IsSuccedded, + message = result.Message, + }); + } - public async Task OnGetEmployeeDetailsWithNationalCode(string nationalCode,string birthDate) - { - var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, _workshopId); - return new JsonResult(result); - } + public async Task OnGetEmployeeDetailsWithNationalCode(string nationalCode, string birthDate) + { + var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, _workshopId); + return new JsonResult(result); + } - public IActionResult OnGetJobSearch(string jobName) - { - var jobViewModels = _jobApplication.GetJobListByText(jobName); + public IActionResult OnGetJobSearch(string jobName) + { + var jobViewModels = _jobApplication.GetJobListByText(jobName); - return new JsonResult(jobViewModels); - } - } + return new JsonResult(jobViewModels); + } + + private async Task SendEmbeddingsToApi(long employeeId, long workshopId, string picture1Path, string picture2Path) + { + try + { + var httpClient = _httpClientFactory.CreateClient(); + httpClient.Timeout = TimeSpan.FromSeconds(30); + + var employee = _employeeApplication.GetDetailsForClient(employeeId, workshopId); + string employeeFullName = employee?.EmployeeFullName ?? ""; + + using var content = new MultipartFormDataContent(); + + // Add form fields + content.Add(new StringContent(employeeId.ToString()), "employee_id"); + content.Add(new StringContent(workshopId.ToString()), "workshop_id"); + content.Add(new StringContent(employeeFullName), "employee_full_name"); + + // Add picture files + var picture1Bytes = await System.IO.File.ReadAllBytesAsync(picture1Path); + var picture1Content = new ByteArrayContent(picture1Bytes); + picture1Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg"); + content.Add(picture1Content, "picture1", "1.jpg"); + + var picture2Bytes = await System.IO.File.ReadAllBytesAsync(picture2Path); + var picture2Content = new ByteArrayContent(picture2Bytes); + picture2Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg"); + content.Add(picture2Content, "picture2", "2.jpg"); + + // Send request to Python API + var response = await httpClient.PostAsync("http://localhost:8000/embeddings", content); + + if (!response.IsSuccessStatusCode) + { + var errorContent = await response.Content.ReadAsStringAsync(); + Console.WriteLine($"Failed to generate embeddings. Status: {response.StatusCode}, Error: {errorContent}"); + } + else + { + var responseContent = await response.Content.ReadAsStringAsync(); + Console.WriteLine($"Embeddings generated successfully: {responseContent}"); + } + } + catch (HttpRequestException ex) + { + Console.WriteLine($"HTTP error while calling embeddings API: {ex.Message}"); + // Don't throw - we don't want to break the upload process if the API is unavailable + } + catch (Exception ex) + { + Console.WriteLine($"Error while calling embeddings API: {ex.Message}"); + // Don't throw - we don't want to break the upload process + } + } + } }