From 179de86840a3a98e08edc3d67e563427979d98c2 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 27 Jan 2026 21:10:18 +0330 Subject: [PATCH 1/8] update SMS report links in menu to use absolute URLs --- ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml | 2 +- ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml index 90b8007a..001698e1 100644 --- a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml @@ -190,7 +190,7 @@ بانک ها
  • - + diff --git a/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml index 7e246091..aaef7f4b 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml @@ -253,7 +253,7 @@ بانک ها
  • - + From 45b469006622afb510a450291ae98eb297ea69c0 Mon Sep 17 00:00:00 2001 From: gozareshgir Date: Thu, 29 Jan 2026 15:26:04 +0330 Subject: [PATCH 2/8] Test singnalR instandSms --- .../InstitutionContractSmsServiceRepository.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs index ef8b77e1..af92bbba 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs @@ -2109,6 +2109,18 @@ public class InstitutionContractSmsServiceRepository : RepositoryBase Date: Sun, 1 Feb 2026 13:20:22 +0330 Subject: [PATCH 3/8] HasRollCall Method Changeed --- .../Repository/RollCallEmployeeRepository.cs | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/CompanyManagment.EFCore/Repository/RollCallEmployeeRepository.cs b/CompanyManagment.EFCore/Repository/RollCallEmployeeRepository.cs index c34bf1e6..b0832169 100644 --- a/CompanyManagment.EFCore/Repository/RollCallEmployeeRepository.cs +++ b/CompanyManagment.EFCore/Repository/RollCallEmployeeRepository.cs @@ -82,25 +82,45 @@ public class RollCallEmployeeRepository : RepositoryBase var service = _rollCallServiceRepository.GetAllServiceByWorkshopId(workshopId); + //اگر سرویس حضور غیاب نداشت if (!service.Any(x => x.StartService.Date <= contractStart.Date && x.EndService.Date >= contractEnd.Date)) return false; //var rollCallEmployee = GetByEmployeeIdAndWorkshopId(employeeId, workshopId); //if (rollCallEmployee == null) // return false; - var rollCallEmployee = _context.RollCallEmployees - .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId) - .Include(x => x.EmployeesStatus); - if (!rollCallEmployee.Any()) + var rollCallEmployee = _context.RollCallEmployees.Include(xs => xs.EmployeesStatus) + .FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId); + //اگر تنظیمات حضور غیاب نداشت + if (rollCallEmployee == null) + return false; + + //اگر استاتوس نداشت + if (!rollCallEmployee.EmployeesStatus.Any()) return false; - var a = rollCallEmployee.Any(x => x.EmployeesStatus.Any(s => - (s.StartDate <= contractStart.Date && s.EndDate.Date >= contractEnd.Date) || - (s.StartDate.Date <= contractStart.Date && s.EndDate.Date > contractStart.Date))); - //var result = _employeeRollCallStatusRepository.w(x => x.RollCallEmployeeId == rollCallEmployee.Id && - // (x.StartDate.Date <= contractStart.Date && x.EndDate.Date >= contractEnd.Date) || - // (x.StartDate.Date <= contractStart.Date && x.EndDate.Date > contractStart.Date)); - return a; + var leftWork = + _context.LeftWorkList.FirstOrDefault(x => + x.StartWorkDate <= contractEnd.Date && x.LeftWorkDate > contractStart); + if (leftWork == null) + return false; + + var status = rollCallEmployee.EmployeesStatus.FirstOrDefault(s => + (s.StartDate <= contractStart.Date && s.EndDate.Date >= contractEnd.Date)); + //اگر استاتوس کامل پوشش داد + if (status != null) + return true; + + + status = rollCallEmployee.EmployeesStatus.FirstOrDefault(s => + (s.StartDate.Date <= contractStart.Date && s.EndDate.Date > contractStart.Date && + s.EndDate.Date < contractEnd.Date)); + //اگر قبل از پایان فیس استاتوس قطع شده ولی ترک کار داره + if (status != null && leftWork.HasLeft) + return true; + + + return false; } public List GetByWorkshopId(long workshopId) { From 7a065e9d168ed0cefcc75375aeb8521b17c90c40 Mon Sep 17 00:00:00 2001 From: gozareshgir Date: Mon, 2 Feb 2026 13:57:15 +0330 Subject: [PATCH 4/8] Checkout Except EmployeeId = 7175 --- .../Repository/YearlySalaryRepository.cs | 2 +- .../Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CompanyManagment.EFCore/Repository/YearlySalaryRepository.cs b/CompanyManagment.EFCore/Repository/YearlySalaryRepository.cs index edef4117..158a3de6 100644 --- a/CompanyManagment.EFCore/Repository/YearlySalaryRepository.cs +++ b/CompanyManagment.EFCore/Repository/YearlySalaryRepository.cs @@ -2859,7 +2859,7 @@ public class YearlySalaryRepository : RepositoryBase, IYearl var contactCanToleaveList = new List(); var allContractsBetween = _context.Contracts.AsSplitQuery().Include(x => x.WorkingHoursList) .Where(x => x.WorkshopIds == workshopId && x.EmployeeId == employeeId && - x.ContractEnd >= startDate && x.ContarctStart <= endDate).ToList(); + x.ContractEnd >= startDate && x.ContarctStart <= endDate).OrderBy(x=>x.ContarctStart).ToList(); var isWorkshopStaticCheckout = _context.Workshops.FirstOrDefault(x => x.id == workshopId)!.IsStaticCheckout; int mandatoryDays = 0; double allCanToLeave = 0; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs index 677ec096..548c701d 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs @@ -796,12 +796,17 @@ public class IndexModel : PageModel var firstContract = _contractApplication.GetDetails(ContractsId[0]); var workshop = _workshopApplication.GetDetails(firstContract.WorkshopIds); - + //int i = 0; foreach (var item in ContractsId) { var contract = _contractApplication.GetDetails(item); - + + //=============== استثنا علی خادم دهقان - میز اداری پویا======== + if (workshop.Id == 482 && contract.EmployeeId == 7175) + workshop.IsOldContract = false; + //============================================================== + //var workingHours = _workingHoursApplication.GetByContractId(contract.Id); var workingHours = _workingHoursTempApplication.GetByContractIdConvertToShiftwork4(contract.Id); var separation = _contractApplication.contractSeparation(ConvertYear, ConvertMonth, From 7cbb9eef698a411f2383be3b164f65bbbb938491 Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 2 Feb 2026 16:07:43 +0330 Subject: [PATCH 5/8] add validation and management for additional time entries in SetTimeProjectCommand --- .../SetTimeProject/SetTimeProjectCommand.cs | 1 + .../SetTimeProjectCommandHandler.cs | 78 ++++++++++++++++--- .../Entities/TaskSectionAdditionalTime.cs | 11 +++ 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs index b7ed7859..02f9c95c 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs @@ -12,6 +12,7 @@ public record SetTimeProjectCommand( public class SetTimeSectionTime { + public Guid? Id { get; set; } public string Description { get; set; } public int Hours { get; set; } public int Minutes { get; set; } diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs index a9ca3a61..49f43a88 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs @@ -349,6 +349,15 @@ public class SetTimeProjectCommandHandler : IBaseCommandHandler x.Id == existingTime.Id); + if (!stillExists) + { + section.RemoveAdditionalTime(existingTime.Id); + hasRealChange = true; + } + } + + // ویرایش یا اضافه کردن آیتم‌های جدید + foreach (var additionalTime in incomingAdditionalTimes) + { + var additionalTimeSpan = TimeSpan.FromHours(additionalTime.Hours) + .Add(TimeSpan.FromMinutes(additionalTime.Minutes)); + + if (additionalTimeSpan <= TimeSpan.Zero) + continue; + + var existingAdditionalTime = existingAdditionalTimes.FirstOrDefault(x => x.Id == additionalTime.Id); + + if (existingAdditionalTime != null) + { + // اگر آیتم با این ID وجود دارد، بررسی کن اگر تغییر کرده باشد + if (existingAdditionalTime.HasChanged(additionalTimeSpan, additionalTime.Description)) + { + var newTotalTime = section.InitialEstimatedHours + .Add(existingAdditionalTimes + .Where(x => x.Id != existingAdditionalTime.Id) + .Aggregate(TimeSpan.Zero, (acc, x) => acc.Add(x.Hours)) + .Add(additionalTimeSpan)); + + ValidateTotalTimeNotLessThanSpent(newTotalTime, currentTotalSpent); + + // ویرایش بدون حذف و ایجاد دوباره + existingAdditionalTime.Update(additionalTimeSpan, additionalTime.Description); + hasRealChange = true; + } + } + else + { + // اگر ID نداشت یا ID جدید بود، اضافه کن + if (additionalTime.Id == null || additionalTime.Id == Guid.Empty) + { + var newTotalTime = section.FinalEstimatedHours.Add(additionalTimeSpan); + ValidateTotalTimeNotLessThanSpent(newTotalTime, currentTotalSpent); + + section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); + hasRealChange = true; + } + } } - // تغییر status به Incomplete فقط اگر زمان اضافی اضافه شده باشد و در وضعیتی غیر از ReadyToStart باشد - if (hasAdditionalTime && section.Status != TaskSectionStatus.ReadyToStart) + // تغییر status به Incomplete فقط اگر تغییری واقعی اعمال شده باشد و در وضعیتی غیر از ReadyToStart باشد + if (hasRealChange && section.Status != TaskSectionStatus.ReadyToStart) { // اگر سکشن درحال انجام است، باید متوقف شود قبل از تغییر status if (section.Status == TaskSectionStatus.InProgress) diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs index 657f76cc..e4cf303b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs @@ -26,4 +26,15 @@ public class TaskSectionAdditionalTime : EntityBase { Reason = reason; } + + public void Update(TimeSpan hours, string? reason = null) + { + Hours = hours; + Reason = reason; + } + + public bool HasChanged(TimeSpan newHours, string? newReason) + { + return Hours != newHours || Reason != newReason; + } } From 57a5000124e72b6557abf9ab942c12d5130167da Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 2 Feb 2026 16:52:53 +0330 Subject: [PATCH 6/8] refactor GetProjectsListQueryHandler to improve task and phase status aggregation logic --- .../GetProjectsListQueryHandler.cs | 101 +++++++++++++----- 1 file changed, 77 insertions(+), 24 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs index 9d184312..dc510b13 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs @@ -228,28 +228,30 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler projectIds.Contains(ph.ProjectId)) - .Select(ph => ph.Id) + .Select(ph => new { ph.Id, ph.ProjectId }) .ToListAsync(cancellationToken); + var phaseIds = phases.Select(ph => ph.Id).ToList(); var tasks = await _context.ProjectTasks - .Where(t => phases.Contains(t.PhaseId)) - .Select(t => t.Id) + .Where(t => phaseIds.Contains(t.PhaseId)) + .Select(t => new { t.Id, t.PhaseId }) .ToListAsync(cancellationToken); + var taskIds = tasks.Select(t => t.Id).ToList(); var sections = await _context.TaskSections .Include(s => s.Skill) - .Where(s => tasks.Contains(s.TaskId)) + .Where(s => taskIds.Contains(s.TaskId)) .ToListAsync(cancellationToken); + // Convert to tuple list for AggregatePhaseStatuses + var tasksList = tasks.Select(t => (t.Id, t.PhaseId)).ToList(); + foreach (var item in items) { - var relatedPhases = phases; // used for filtering tasks by project - var relatedTasks = await _context.ProjectTasks - .Where(t => t.PhaseId != Guid.Empty && relatedPhases.Contains(t.PhaseId)) - .Select(t => t.Id) - .ToListAsync(cancellationToken); - var itemSections = sections.Where(s => relatedTasks.Contains(s.TaskId)); - item.Backend = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Backend")); - item.Front = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Frontend")); - item.Design = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "UI/UX Design")); + var projectPhaseIds = phases.Where(ph => ph.ProjectId == item.Id).Select(ph => ph.Id).ToList(); + + // برای هر Skill، وضعیت‌های تمام Phases را تجمیع کنیم + item.Backend = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "Backend"); + item.Front = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "Frontend"); + item.Design = AggregatePhaseStatuses(projectPhaseIds, tasksList, sections, "UI/UX Design"); } } @@ -259,24 +261,22 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler phaseIds.Contains(t.PhaseId)) - .Select(t => t.Id) + .Select(t => new { t.Id, t.PhaseId }) .ToListAsync(cancellationToken); + var taskIds = tasks.Select(t => t.Id).ToList(); var sections = await _context.TaskSections .Include(s => s.Skill) - .Where(s => tasks.Contains(s.TaskId)) + .Where(s => taskIds.Contains(s.TaskId)) .ToListAsync(cancellationToken); foreach (var item in items) { - // Filter tasks for this phase - var phaseTaskIds = await _context.ProjectTasks - .Where(t => t.PhaseId == item.Id) - .Select(t => t.Id) - .ToListAsync(cancellationToken); + var phaseTaskIds = tasks.Where(t => t.PhaseId == item.Id).Select(t => t.Id).ToList(); var itemSections = sections.Where(s => phaseTaskIds.Contains(s.TaskId)); - item.Backend = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Backend")); - item.Front = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "Frontend")); - item.Design = GetAssignmentStatus(itemSections.FirstOrDefault(x => x.Skill?.Name == "UI/UX Design")); + + item.Backend = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "Backend")); + item.Front = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "Frontend")); + item.Design = AggregateAssignmentStatus(itemSections.Where(x => x.Skill?.Name == "UI/UX Design")); } } @@ -380,4 +380,57 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler phaseIds, + List<(Guid Id, Guid PhaseId)> tasks, + List sections, + string skillName) + { + var phaseStatuses = new List(); + + foreach (var phaseId in phaseIds) + { + var phaseTaskIds = tasks.Where(t => t.PhaseId == phaseId).Select(t => t.Id).ToList(); + var phaseSections = sections.Where(s => phaseTaskIds.Contains(s.TaskId) && s.Skill?.Name == skillName); + var phaseStatus = AggregateAssignmentStatus(phaseSections); + phaseStatuses.Add(phaseStatus); + } + + // الآن تجمیع وضعیت‌های Phases + if (!phaseStatuses.Any()) + return AssignmentStatus.Unassigned; + + // اگر هر یکی Unassigned باشد → Unassigned + if (phaseStatuses.Any(s => s == AssignmentStatus.Unassigned)) + return AssignmentStatus.Unassigned; + + // اگر Unassigned نیست و هر یکی UserOnly باشد → UserOnly + if (phaseStatuses.Any(s => s == AssignmentStatus.UserOnly)) + return AssignmentStatus.UserOnly; + + // فقط اگر همه Assigned باشند → Assigned + return AssignmentStatus.Assigned; + } + + private static AssignmentStatus AggregateAssignmentStatus(IEnumerable sections) + { + var sectionList = sections.ToList(); + if (!sectionList.Any()) + return AssignmentStatus.Unassigned; + + var statuses = sectionList.Select(GetAssignmentStatus).ToList(); + + // اگر هر یکی Unassigned باشد → Unassigned (بدترین وضعیت) + if (statuses.Any(s => s == AssignmentStatus.Unassigned)) + return AssignmentStatus.Unassigned; + + // اگر Unassigned نیست و هر یکی UserOnly باشد → UserOnly (وضعیت متوسط) + if (statuses.Any(s => s == AssignmentStatus.UserOnly)) + return AssignmentStatus.UserOnly; + + // فقط اگر همه Assigned باشند → Assigned (بهترین وضعیت) + return AssignmentStatus.Assigned; + } +} + From 4ccade4c7a61b53635db08dd7ae0c3db180b2d74 Mon Sep 17 00:00:00 2001 From: gozareshgir Date: Mon, 2 Feb 2026 19:45:51 +0330 Subject: [PATCH 7/8] change sms url --- ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml | 2 +- ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml index 001698e1..c524234b 100644 --- a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml @@ -190,7 +190,7 @@ بانک ها
  • - + diff --git a/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml index aaef7f4b..753b0855 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/AdminNew/Pages/Shared/_Menu.cshtml @@ -253,7 +253,7 @@ بانک ها
  • - + From c493718452873f1a29ba450a0d6b75c157234ae1 Mon Sep 17 00:00:00 2001 From: gozareshgir Date: Tue, 3 Feb 2026 14:08:16 +0330 Subject: [PATCH 8/8] InstantSms change signalR --- .../Hubs/SendSmsHub.cs | 15 +++++ .../SmsSettingApplication.cs | 65 ++++++++++++++----- ...InstitutionContractSmsServiceRepository.cs | 62 ++++++++++++++---- .../Services/SmsService.cs | 17 ++--- .../Admin/Controllers/SmsReportController.cs | 12 ++-- 5 files changed, 127 insertions(+), 44 deletions(-) diff --git a/CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs b/CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs index 0327bf2d..d2a49ccd 100644 --- a/CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs +++ b/CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; +using _0_Framework.Application; using Microsoft.AspNetCore.SignalR; namespace CompanyManagment.App.Contracts.Hubs; @@ -7,6 +8,20 @@ namespace CompanyManagment.App.Contracts.Hubs; public class SendSmsHub : Hub { + private readonly IAuthHelper _authHelper; + + public SendSmsHub(IAuthHelper authHelper) + { + _authHelper = authHelper; + } + + public override async Task OnConnectedAsync() + { + var accountId = _authHelper.CurrentAccountId(); + var connectionId = Context.ConnectionId; + await send(accountId); + await base.OnConnectedAsync(); + } public async Task send(long id) { diff --git a/CompanyManagment.Application/SmsSettingApplication.cs b/CompanyManagment.Application/SmsSettingApplication.cs index 6b1d5651..8ffb12dc 100644 --- a/CompanyManagment.Application/SmsSettingApplication.cs +++ b/CompanyManagment.Application/SmsSettingApplication.cs @@ -136,11 +136,33 @@ public class SmsSettingApplication : ISmsSettingApplication public async Task InstantSendReminderSms(List command) { var op = new OperationResult(); + List devModeNumberList = []; if (_hostEnvironment.IsDevelopment()) { - - return op.Failed(" در محیط توسعه امکان ارسال وجود ندارد "); - + int taker = 0; + switch (command.Count) + { + case >= 3: + taker = 3; + break; + case > 0: + case < 3: + taker = command.Count; + break; + default: + taker = 0; + } + + if (taker > 0) + { + devModeNumberList = ["09114221321", "09116967898", "09116067106"]; + command = command.Take(taker).ToList(); + for (int i = 0; i < 3; i++) + { + command[i].PhoneNumber = devModeNumberList[i]; + } + } + } string typeOfSms = "یادآور بدهی ماهانه"; string sendMessStart = "شروع یادآور آنی"; @@ -163,10 +185,32 @@ public class SmsSettingApplication : ISmsSettingApplication { var op = new OperationResult(); + List devModeNumberList = []; if (_hostEnvironment.IsDevelopment()) { - - return op.Failed(" در محیط توسعه امکان ارسال وجود ندارد "); + int taker = 0; + switch (command.Count) + { + case >= 3: + taker = 3; + break; + case > 0: + case < 3: + taker = command.Count; + break; + default: + taker = 0; + } + + if (taker > 0) + { + devModeNumberList = ["09114221321", "09116967898", "09116067106"]; + command = command.Take(taker).ToList(); + for (int i = 0; i < 3; i++) + { + command[i].PhoneNumber = devModeNumberList[i]; + } + } } string typeOfSms = "اعلام مسدودی طرف حساب"; @@ -289,16 +333,7 @@ public class SmsSettingApplication : ISmsSettingApplication { var op = new OperationResult(); - if (_hostEnvironment.IsDevelopment()) - { - var str = ""; - foreach (var item in phoneNumbers) - { - str += $" {item}, "; - } - return op.Failed(" در محیط توسعه امکان ارسال وجود ندارد " + " لیست ارسال شما " + str); - - } + if (typeOfSmsSetting == TypeOfSmsSetting.InstitutionContractDebtReminder) { if (phoneNumbers.Any()) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs index fa3e9d70..ddb5bf0e 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractSmsServiceRepository.cs @@ -31,8 +31,9 @@ public class InstitutionContractSmsServiceRepository : RepositoryBase _hubContext; private readonly IPersonalContractingPartyRepository _personalContractingPartyRepository; + private readonly IAuthHelper _authHelper; - public InstitutionContractSmsServiceRepository(CompanyContext context, ISmsService smsService, ILogger logger, ISmsResultRepository smsResultRepository, IHubContext hubContext, IPersonalContractingPartyRepository personalContractingPartyRepository) : base(context) + public InstitutionContractSmsServiceRepository(CompanyContext context, ISmsService smsService, ILogger logger, ISmsResultRepository smsResultRepository, IHubContext hubContext, IPersonalContractingPartyRepository personalContractingPartyRepository, IAuthHelper authHelper) : base(context) { _context = context; _smsService = smsService; @@ -40,6 +41,7 @@ public class InstitutionContractSmsServiceRepository : RepositoryBase smsListData, string typeOfSms, string sendMessStart, string sendMessEnd) { + var currentAccountId = _authHelper.CurrentAccountId(); + var signalR = _hubContext.Clients.Group(SendSmsHub.GetGroupName(currentAccountId)); if (smsListData.Any()) { - await _smsService.Alarm("09114221321", sendMessStart); - Thread.Sleep(1000); - await _smsService.Alarm("09111485044", sendMessStart); - Thread.Sleep(1000); + try + { + var sendingStart = await _smsService.Alarm("09114221321", sendMessStart); + Thread.Sleep(1000); + + if (!sendingStart) + { + await signalR.SendAsync("sendToApi", "failed"); + return; + } + } + catch (Exception e) + { + await signalR.SendAsync("sendToApi", "failed"); + return; + } int successProcess = 1; int countList = smsListData.Count; @@ -960,6 +976,7 @@ public class InstitutionContractSmsServiceRepository : RepositoryBase 18 ? item.PartyName.Substring(0, 18) : item.PartyName; string errMess = $"{name}-خطا"; + await signalR.SendAsync("sendStatus", false, item.PhoneNumber); await _smsService.Alarm("09114221321", errMess); } Thread.Sleep(600); var percent = (successProcess / (double)countList) * 100; - await _hubContext.Clients.Group(SendSmsHub.GetGroupName(10)) - .SendAsync("showStatus", (int)percent); + await signalR.SendAsync("showStatus", (int)percent); successProcess += 1; } @@ -2099,13 +2117,27 @@ public class InstitutionContractSmsServiceRepository : RepositoryBase 18 ? item.PartyName.Substring(0, 18) : item.PartyName; string errMess = $"{name}-خطا"; + await signalR.SendAsync("sendStatus", false, item.PhoneNumber); _logger.LogError(errMess); await _smsService.Alarm("09114221321", errMess); } var percent = (successProcess / (double)countList) * 100; - await _hubContext.Clients.Group(SendSmsHub.GetGroupName(7)) - .SendAsync("showStatus", (int)percent); + await signalR.SendAsync("showStatus", (int)percent); successProcess += 1; } diff --git a/CompanyManagment.EFCore/Services/SmsService.cs b/CompanyManagment.EFCore/Services/SmsService.cs index d73ac87f..2703e8e7 100644 --- a/CompanyManagment.EFCore/Services/SmsService.cs +++ b/CompanyManagment.EFCore/Services/SmsService.cs @@ -607,17 +607,14 @@ public class SmsService : ISmsService //var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" }); - var verificationSendResult = + var verificationSendResult = await smsIr.VerifySendAsync(number, 662874, new VerifySendParameter[] { new("ALARM", message) }); - Thread.Sleep(1000); - var status = verificationSendResult.Result.Status; - var mess = verificationSendResult.Result.Message; - var messaeId = verificationSendResult.Result.Data.MessageId; - if (verificationSendResult.IsCompletedSuccessfully) return true; - - var resStartStatus = verificationSendResult.Result; - var resResult = verificationSendResult.Status; - var reseExceptiont = verificationSendResult.Exception; + Thread.Sleep(800); + if (verificationSendResult.Message == "موفق") + { + return true; + } + return false; } diff --git a/ServiceHost/Areas/Admin/Controllers/SmsReportController.cs b/ServiceHost/Areas/Admin/Controllers/SmsReportController.cs index fe24a1b9..327e4960 100644 --- a/ServiceHost/Areas/Admin/Controllers/SmsReportController.cs +++ b/ServiceHost/Areas/Admin/Controllers/SmsReportController.cs @@ -260,10 +260,10 @@ public class SmsReportController : AdminBaseController /// /// [HttpPost("InstantReminderSmsSend")] - public async Task> InstantReminderSmsSend([FromBody] List phoneNumbers) + public async Task InstantReminderSmsSend([FromBody] List phoneNumbers) { - var result = await _smsSettingApplication.InstantSmsSendApi(TypeOfSmsSetting.InstitutionContractDebtReminder, phoneNumbers); - return result; + var result = _smsSettingApplication.InstantSmsSendApi(TypeOfSmsSetting.InstitutionContractDebtReminder, phoneNumbers); + return Ok(); } /// @@ -272,10 +272,10 @@ public class SmsReportController : AdminBaseController /// /// [HttpPost("InstantBlockSmsSend")] - public async Task> InstantBlockSmsSend([FromBody] List phoneNumbers) + public async Task InstantBlockSmsSend([FromBody] List phoneNumbers) { - var result = await _smsSettingApplication.InstantSmsSendApi(TypeOfSmsSetting.BlockContractingParty, phoneNumbers); - return result; + var result = _smsSettingApplication.InstantSmsSendApi(TypeOfSmsSetting.BlockContractingParty, phoneNumbers); + return Ok(); } #endregion } \ No newline at end of file