From 193e9f587f6219d0bf3615b99fdf3631aae05dbb Mon Sep 17 00:00:00 2001 From: SamSys Date: Wed, 12 Nov 2025 15:37:24 +0330 Subject: [PATCH] institutioncontract task --- .../BackgroundInstitutionContract.Task.csproj | 19 + .../FileUploader.cs | 32 ++ .../Jobs/JobSchedulerRegistrator.cs | 80 ++++ .../Jobs/SmsReminder.cs | 116 +++++ .../JobsBootstrapper.cs | 25 ++ .../Program.cs | 59 +++ .../Properties/launchSettings.json | 38 ++ .../appsettings.Development.json | 46 ++ .../appsettings.json | 9 + .../IInstitutionContractRepository.cs | 10 + .../FinancialStatmentViewModel.cs | 1 + .../FinancialTransactionViewModel.cs | 4 + .../InstitutionContractViewModel.cs | 1 + .../InstitutionContractRepository.cs | 399 +++++++++++++++++- DadmehrGostar.sln | 9 + 15 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/FileUploader.cs create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/JobSchedulerRegistrator.cs create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/SmsReminder.cs create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/JobsBootstrapper.cs create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Program.cs create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Properties/launchSettings.json create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.Development.json create mode 100644 BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.json diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj new file mode 100644 index 00000000..d30ce3b8 --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + BackgroundInstitutionContract.Task + BackgroundInstitutionContract.Task + + + + + + + + + + + diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/FileUploader.cs b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/FileUploader.cs new file mode 100644 index 00000000..2334c491 --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/FileUploader.cs @@ -0,0 +1,32 @@ +using _0_Framework.Application; + +namespace BackgroundInstitutionContract.Task +{ + public class FileUploader : IFileUploader + { + private readonly IWebHostEnvironment _webHostEnvironment; + + public FileUploader(IWebHostEnvironment webHostEnvironment) + { + _webHostEnvironment = webHostEnvironment; + } + + public string Upload(IFormFile file, string path) + { + if (file == null) return ""; + + var directoryPath = $"{_webHostEnvironment.WebRootPath}\\ProductPictures\\{path}"; + + if (!Directory.Exists(directoryPath)) + Directory.CreateDirectory(directoryPath); + + var fileName = $"{DateTime.Now.ToFileName()}-{file.FileName}"; + var filePath = $"{directoryPath}\\{fileName}"; + var output = System.IO.File.Create(filePath); + file.CopyTo(output); + return $"{path}/{fileName}"; + } + + + } +} diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/JobSchedulerRegistrator.cs b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/JobSchedulerRegistrator.cs new file mode 100644 index 00000000..2270044a --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/JobSchedulerRegistrator.cs @@ -0,0 +1,80 @@ + +using Hangfire; + +namespace BackgroundInstitutionContract.Task.Jobs; + +public class JobSchedulerRegistrator +{ + private readonly IBackgroundJobClient _backgroundJobClient; + private readonly SmsReminder _smsReminder; + private static DateTime? _lastRunDateMorning; + private static DateTime? _lastRunDateEvening; + + public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient) + { + _smsReminder = smsReminder; + _backgroundJobClient = backgroundJobClient; + } + + public void Register() + { + RecurringJob.AddOrUpdate( + "Task.Test", + () => SmsReminderCheckAndSchedule(), + "*/1 * * * *" // هر 5 دقیقه یکبار چک کن + ); + + RecurringJob.AddOrUpdate( + "Task.ReminderDebtSMS", + () => DebtSmsReminder(), + "*/1 * * * *" // هر 1 دقیقه یکبار چک کن + ); + } + + /// + /// پیامک های یاد آور + /// + /// + public void DebtSmsReminder() + { + var now = DateTime.Now; + _backgroundJobClient.Enqueue(() => _smsReminder.Execute()); + _lastRunDateMorning = now; + } + + public void SmsReminderCheckAndSchedule() + { + var now = DateTime.Now; + + var startMorning = new TimeSpan(9, 0, 0); + var endMorning = new TimeSpan(9, 40, 0); + + var startEvening = new TimeSpan(15, 30, 0); + var endEvening = new TimeSpan(15, 40, 0); + + // صبح + if (now.DayOfWeek != DayOfWeek.Friday && + now.TimeOfDay >= startMorning && + now.TimeOfDay < endMorning) + { + if (_lastRunDateMorning?.Date != now.Date) + { + _backgroundJobClient.Enqueue(() => _smsReminder.Execute()); + _lastRunDateMorning = now; + } + } + + // عصر - پنجشنبه و جمعه تعطیل است + if (now.DayOfWeek != DayOfWeek.Friday && + now.DayOfWeek != DayOfWeek.Thursday && + now.TimeOfDay >= startEvening && + now.TimeOfDay < endEvening) + { + if (_lastRunDateEvening?.Date != now.Date) + { + _backgroundJobClient.Enqueue(() => _smsReminder.Execute()); + _lastRunDateEvening = now; + } + } + } +} \ No newline at end of file diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/SmsReminder.cs b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/SmsReminder.cs new file mode 100644 index 00000000..c9f1aeaf --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Jobs/SmsReminder.cs @@ -0,0 +1,116 @@ +using _0_Framework.Application.Sms; +using AccountManagement.Application.Contracts.Account; +using AccountMangement.Infrastructure.EFCore; +using Company.Domain.SmsResultAgg; +using Microsoft.EntityFrameworkCore; +using SmsResult = Company.Domain.SmsResultAgg.SmsResult; + +namespace BackgroundInstitutionContract.Task.Jobs; +public class SmsReminder +{ + private readonly AccountContext _accountContext; + private readonly ISmsService _smsService; + private readonly ISmsResultRepository _smsResultRepository; + + public SmsReminder(ISmsService smsService, AccountContext accountContext, ISmsResultRepository smsResultRepository) + { + _smsService = smsService; + _accountContext = accountContext; + _smsResultRepository = smsResultRepository; + } + + public void Execute() + { + //var accounts = _accountContext.Accounts.Where(x => x.PositionId > 0 && x.IsActiveString == "true").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList(); + //Thread.Sleep(300); + //var accounts = new List() { new AccountViewModel() { Mobile = "09114221321", Id = 2 } }; + var accounts= _accountContext.Accounts.Where(x => x.Username.ToLower()=="mahan").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList(); + var smsVM = accounts.Select(x => new AccountSmsTaskViewModel() + { + Mobile = x.Mobile, + AccountId = x.Id, + FullName = x.Fullname, + TaskCount = GetLateTasksCount(x.Id) + }).Where(x => x.TaskCount > 0 && !string.IsNullOrEmpty(x.Mobile) && x.Mobile.Length == 11).ToList(); + Thread.Sleep(300); + + + foreach (var viewmodel in smsVM) + { + var smsResult = _smsService.TaskReminderSms(viewmodel.Mobile, $"{viewmodel.TaskCount}"); + Thread.Sleep(1000); + var createSmsResult = new SmsResult(smsResult.MessageId, smsResult.Message, "یادآور وظایف", + viewmodel.FullName, viewmodel.Mobile, viewmodel.AccountId, viewmodel.AccountId); + _smsResultRepository.Create(createSmsResult); + _smsResultRepository.SaveChanges(); + Thread.Sleep(1000); + } + } + private int GetLateTasksCount(long accountId) + { + var positionValue = _accountContext.Accounts + .Where(x => x.id == accountId) + .Include(p => p.Position) + .Select(x => x.Position.PositionValue) + .FirstOrDefault(); + + if (positionValue == 0) + return 0; + + + DateTime now = DateTime.Now; + int overdueTasksCount; + + if (positionValue == 1) + { + overdueTasksCount = _accountContext.Assigns.Include(x => x.Task).Where(x => x.AssignedId == accountId && + x.AssignerId == accountId && x.Task.Assigns.Count == 1 && + !x.IsCancel && !x.IsCanceledRequest && + !x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true") + .GroupBy(x => x.TaskId).Select(x => x.First()).Count(); + + //overdueTasksCount = _accountContext.Tasks.Include(x => + // x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) && + // !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) && + // !x.Assigns.Any(a => a.TimeRequest) + // && x.Assigns.Any(a => a.AssignedId == accountId && a.AssignerId == accountId) && + // (x.Assigns.First(a => a.AssignedId == accountId && a.AssignerId == accountId) + // .EndTaskDate.Date <= DateTime.Now.Date) && x.Assigns.Count == 1); + } + else + { + + overdueTasksCount = _accountContext.Assigns + .Include(x => x.Task) + .Where(x => x.AssignedId == accountId && + !x.IsCancel && !x.IsCanceledRequest && + !x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true") + .GroupBy(x => x.TaskId).Select(x => x.First()).Count(); + } + + + //overdueTasksCount = _accountContext.Tasks.Include(x => + // x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) && + // !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) && + // !x.Assigns.Any(a => a.TimeRequest) + // && x.Assigns.Any(a => a.AssignedId == accountId) && + // (x.Assigns.First(a => a.AssignedId == accountId).EndTaskDate.Date <= DateTime.Now.Date)); + + + var overdueRequestsCount = _accountContext.Assigns.Include(x => x.Task) + .Where(x => (x.IsCanceledRequest + || x.IsDoneRequest || x.TimeRequest) && !x.IsCancel && !x.IsDone && + x.Task.IsActiveString == "true" && + x.Task.SenderId == accountId).GroupBy(x => x.TaskId).Select(x => x.First()).Count(); + + return overdueTasksCount + overdueRequestsCount; + } + +} +public class AccountSmsTaskViewModel +{ + public int TaskCount { get; set; } + public long AccountId { get; set; } + public string Mobile { get; set; } + public string FullName { get; set; } +} \ No newline at end of file diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/JobsBootstrapper.cs b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/JobsBootstrapper.cs new file mode 100644 index 00000000..67c287f7 --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/JobsBootstrapper.cs @@ -0,0 +1,25 @@ +using BackgroundInstitutionContract.Task.Jobs; + + +namespace BackgroundInstitutionContract.Task; + +public class JobsBootstrapper +{ + public static void Configure(IServiceCollection services) + { + var currentNamespace = typeof(JobSchedulerRegistrator).Namespace; // همون namespace کلاس + + var assembly = typeof(JobSchedulerRegistrator).Assembly; + + var jobTypes = assembly.GetTypes() + .Where(t => + t is { IsClass: true, IsAbstract: false, Namespace: not null } && + t.Namespace.StartsWith(currentNamespace, StringComparison.Ordinal)) + .ToList(); + + foreach (var jobType in jobTypes) + { + services.AddTransient(jobType); + } + } +} \ No newline at end of file diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Program.cs b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Program.cs new file mode 100644 index 00000000..0c6798e6 --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Program.cs @@ -0,0 +1,59 @@ +using _0_Framework.Application; +using _0_Framework.Application.Sms; +using _0_Framework.Application.UID; +using _0_Framework.InfraStructure.Mongo; +using AccountManagement.Configuration; +using BackgroundInstitutionContract.Task; +using BackgroundInstitutionContract.Task.Jobs; +using CompanyManagment.EFCore.Services; +using Hangfire; +using Microsoft.AspNetCore.Identity; +using MongoDB.Driver; +using PersonalContractingParty.Config; +using Query.Bootstrapper; +using WorkFlow.Infrastructure.Config; + +var builder = WebApplication.CreateBuilder(args); +var hangfireConnectionString = builder.Configuration.GetConnectionString("HangfireDb"); +builder.Services.AddHangfire(x => x.UseSqlServerStorage(hangfireConnectionString)); +builder.Services.AddHangfireServer(); +var connectionString = builder.Configuration.GetConnectionString("MesbahDb"); +var connectionStringTestDb = builder.Configuration.GetConnectionString("TestDb"); +builder.Services.AddSingleton(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.Configure(builder.Configuration); + +#region MongoDb + +var mongoConnectionSection = builder.Configuration.GetSection("MongoDb"); +var mongoDbSettings = mongoConnectionSection.Get(); +var mongoClient = new MongoClient(mongoDbSettings.ConnectionString); +var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName); + +builder.Services.AddSingleton(mongoDatabase); + +#endregion + +PersonalBootstrapper.Configure(builder.Services, connectionString); +TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb); +AccountManagementBootstrapper.Configure(builder.Services, connectionString); +WorkFlowBootstrapper.Configure(builder.Services, connectionString); +QueryBootstrapper.Configure(builder.Services); +JobsBootstrapper.Configure(builder.Services); +builder.Services.AddHttpClient(); +builder.Services.AddHttpContextAccessor(); +var app = builder.Build(); + +app.MapHangfireDashboard(); +app.MapGet("/", () => "Hello World!"); + +using (var scope = app.Services.CreateScope()) +{ + var jobScheduler = scope.ServiceProvider.GetRequiredService(); + jobScheduler.Register(); +} + +app.Run(); \ No newline at end of file diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Properties/launchSettings.json b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Properties/launchSettings.json new file mode 100644 index 00000000..e9f19892 --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:56492", + "sslPort": 44378 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5216", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7223;http://localhost:5217", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.Development.json b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.Development.json new file mode 100644 index 00000000..2dc32b9b --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.Development.json @@ -0,0 +1,46 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ConnectionStrings": { + //تست + //"MesbahDb": "Data Source=DESKTOP-NUE119G\\MSNEW;Initial Catalog=Mesbah_db;Integrated Security=True" + + //server + //"MesbahDb": "Data Source=171.22.24.15;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;", + + + //local + "MesbahDb": "Data Source=.;Initial Catalog=mesbah_db;Integrated Security=True;TrustServerCertificate=true;", + + //dad-mehr + //"MesbahDb": "Data Source=.;Initial Catalog=teamWork;Integrated Security=True;TrustServerCertificate=true;", + + "TestDb": "Data Source=.;Initial Catalog=TestDb;Integrated Security=True;TrustServerCertificate=true;", + + //mahan Docker + //"MesbahDb": "Data Source=localhost,5069;Initial Catalog=mesbah_db;User ID=sa;Password=YourPassword123;TrustServerCertificate=True;", + "HangfireDb": "Data Source=.;Initial Catalog=hangfire_db;Integrated Security=True;TrustServerCertificate=true;" + }, + + "GoogleRecaptchaV3": { + "SiteKey": "6Lfhp_AnAAAAAB79WkrMoHd1k8ir4m8VvfjE7FTH", + "SecretKey": "6Lfhp_AnAAAAANjDDY6DPrbbUQS7k6ZCRmrVP5Lb" + }, + "SmsSecrets": { + "ApiKey": "Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa", + "SecretKey": "dadmehr" + }, + "Domain": ".gozareshgir.ir", + "MongoDb": { + "ConnectionString": "mongodb://localhost:27017", + "DatabaseName": "Gozareshgir" + } + + +} \ No newline at end of file diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.json b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs index 3a91fcdf..94a30142 100644 --- a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs +++ b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs @@ -77,4 +77,14 @@ public interface IInstitutionContractRepository : IRepository> GetInstitutionContractSelectList(string search, string selected); Task> PrintAllAsync(List ids); + + + #region DebtReminderSMS + /// + /// ارسال پیامک های یاد آور بدهی + /// + /// + Task DebtReminderSMS(); + + #endregion } \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/FinancialStatment/FinancialStatmentViewModel.cs b/CompanyManagment.App.Contracts/FinancialStatment/FinancialStatmentViewModel.cs index 4b63cb82..01976a5e 100644 --- a/CompanyManagment.App.Contracts/FinancialStatment/FinancialStatmentViewModel.cs +++ b/CompanyManagment.App.Contracts/FinancialStatment/FinancialStatmentViewModel.cs @@ -9,6 +9,7 @@ public class FinancialStatmentViewModel public long Id { get; set; } public long ContractingPartyId { get; set; } public string ContractingPartyName { get; set; } + public string PublicId { get; set; } public List FinancialTransactionViewModels { get; set; } diff --git a/CompanyManagment.App.Contracts/FinancilTransaction/FinancialTransactionViewModel.cs b/CompanyManagment.App.Contracts/FinancilTransaction/FinancialTransactionViewModel.cs index 42b0b017..9866db57 100644 --- a/CompanyManagment.App.Contracts/FinancilTransaction/FinancialTransactionViewModel.cs +++ b/CompanyManagment.App.Contracts/FinancilTransaction/FinancialTransactionViewModel.cs @@ -10,6 +10,7 @@ public class FinancialTransactionViewModel public string TdateFa { get; set; } public string Description { get; set; } public string TypeOfTransaction { get; set; } + public string DescriptionOption { get; set; } public double Deptor { get; set; } public string DeptorString { get; set; } public double Creditor { get; set; } @@ -20,4 +21,7 @@ public class FinancialTransactionViewModel public string MessageText { get; set; } public string SentSmsDateFa { get; set; } public int Counter { get; set; } + + + } \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractViewModel.cs b/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractViewModel.cs index 5a4478fe..8371e5cd 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractViewModel.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractViewModel.cs @@ -25,6 +25,7 @@ public class InstitutionContractViewModel public DateTime ContractEndGr { get; set; } public string ContractEndFa { get; set; } public string ContractAmount { get; set; } + public double ContractAmountDouble { get; set; } public string DailyCompenseation { get; set; } public string Obligation { get; set; } diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 12ca036f..e20a13e0 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Linq; +using System.Threading; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework.Application.Enums; @@ -21,8 +22,11 @@ using Company.Domain.InstitutionContractAmendmentTempAgg; using Company.Domain.InstitutionContractContactInfoAgg; using Company.Domain.InstitutionContractExtensionTempAgg; using Company.Domain.InstitutionPlanAgg; +using Company.Domain.SmsResultAgg; using Company.Domain.WorkshopAgg; using CompanyManagment.App.Contracts.Employer; +using CompanyManagment.App.Contracts.FinancialStatment; +using CompanyManagment.App.Contracts.FinancilTransaction; using CompanyManagment.App.Contracts.InstitutionContract; using CompanyManagment.App.Contracts.InstitutionContractContactinfo; using CompanyManagment.App.Contracts.Law; @@ -37,6 +41,7 @@ using MongoDB.Driver; using OfficeOpenXml.Packaging.Ionic.Zip; using PersianTools.Core; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; +using SmsResult = CompanyManagment.EFCore.Migrations.SmsResult; namespace CompanyManagment.EFCore.Repository; @@ -2941,8 +2946,400 @@ public class InstitutionContractRepository : RepositoryBase x.StartService.Date <= previusMonthStart.Date && x.EndService.Date >= previusMonthEnd.Date).ToList(); + var institutionContracts =await _context.InstitutionContractSet.AsSplitQuery().Select(x => new InstitutionContractViewModel + { + Id = x.id, + ContractingPartyId = x.ContractingPartyId, + ContractingPartyName = x.ContractingPartyName, + ContractStartGr = x.ContractStartGr, + ContractStartFa = x.ContractStartFa, + ContractEndGr = x.ContractEndGr, + ContractEndFa = x.ContractEndFa, + IsActiveString = x.IsActiveString, + ContractAmountDouble = x.ContractAmount, + OfficialCompany = x.OfficialCompany + }).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate && + x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First()).ToListAsync(); + + + foreach (var item in institutionContracts) + { + try + { + var contractingParty =await _context.PersonalContractingParties.FirstOrDefaultAsync(x=>x.id == item.ContractingPartyId); + //var isSend = sendedSms.Any(x => x.ContractingPatyId == contractingParty.Id); + if (!string.IsNullOrWhiteSpace(contractingParty.LName)) + { + //Thread.Sleep(500); + var partyName = contractingParty.LName; + + if (partyName.Length > 25) partyName = $"{partyName.Substring(0, 25)}"; + + var isLegal = contractingParty.IsLegal == "حقوقی" ? true : false; + var isBlock = contractingParty.IsBlock == "true" ? true : false; + var isActive = contractingParty.IsActiveString == "true" ? true : false; + if (!string.IsNullOrWhiteSpace(contractingParty.IsActiveString) && isActive) + { + var hasFinancialStatement =await _context.FinancialStatments.Include(x => x.FinancialTransactionList).AnyAsync( + x => x.ContractingPartyId == item.ContractingPartyId && x.FinancialTransactionList.Count > 0); + + Thread.Sleep(500); + var hasPhonNumber =await _context.InstitutionContractContactInfos + .AnyAsync(x => x.InstitutionContractId == item.Id && x.SendSms && x.PhoneType == "شماره همراه" && + x.PhoneNumber.Length == 11); + + Thread.Sleep(500); + if (hasFinancialStatement && hasPhonNumber) + { + + var phoneNumbers =await _context.InstitutionContractContactInfos.Where(n => + n.InstitutionContractId == item.Id && n.SendSms && n.PhoneType == "شماره همراه" && + !string.IsNullOrWhiteSpace(n.PhoneNumber)) + .Select(x => new CreateContactInfo + { + PhoneType = x.PhoneType, + PhoneNumber = x.PhoneNumber, + + InstitutionContractId = x.InstitutionContractId, + SendSms = x.SendSms + }).Where(x => x.PhoneNumber.Length == 11).ToListAsync(); + var transactions = GetFinancialByContractingPartyId(contractingParty.id).GetAwaiter().GetResult(); + Thread.Sleep(500); + var debtor = transactions.FinancialTransactionViewModels.Sum(x => x.Deptor); + var creditor = transactions.FinancialTransactionViewModels.Sum(x => x.Creditor); + Thread.Sleep(500); + + var id = $"{item.ContractingPartyId}"; + var aprove = $"{transactions.Id}"; + var balance = debtor - creditor; + + if (balance > 0) // اگر بدهکار بود + { + //var employers = _context.Employers.Where(x => x.ContractingPartyId == item.ContractingPartyId) + // .Select(x => x.id); + //var workshops = _context.WorkshopEmployers.Where(x => employers.Contains(x.EmployerId)) + // .Select(x => x.WorkshopId).Distinct().ToList(); + + + //var services = + // rollcallServiceList.Where(x => workshops.Contains(x.WorkshopId)).ToList(); + + //var hasRollCallService = services.Count > 0; + + //موقت + var hasRollCallService = false; + + //if (hasRollCallService) + //{ + // var employees = + // _context.RollCallEmployees.Where(x => workshops.Contains(x.WorkshopId)) + // .Select(x => x.id); + + // var employeeCount = _context.RollCallEmployeesStatus + // .Where(x => employees.Contains(x.RollCallEmployeeId)) + // .Count(x => x.EndDate.Date == activeStatusDate.Date); + + // if (employeeCount == 0) + // hasRollCallService = false; + //} + + if (isLegal) + { + if (item.OfficialCompany == "Official") // حقوقی بدهکار رسمی + { + var balanceToMoney = balance.ToMoney(); + + foreach (var number in phoneNumbers) + { + if (!string.IsNullOrWhiteSpace(number.PhoneNumber) && + number.PhoneNumber.Length == 11) + { + + int messageId = 0; + string message = ""; + bool isSuccessSend = false; + if (hasRollCallService) + { + string publicId = transactions.PublicId; + string code1 = publicId.Substring(0, 25); + string code2 = publicId.Substring(25); + var newSmsResult = _smsService.MonthlyBillNew(number.PhoneNumber, 789638, + partyName, balanceToMoney, code1, code2); + Thread.Sleep(1000); + messageId = newSmsResult.MessageId; + message = newSmsResult.Message; + isSuccessSend = newSmsResult.IsSuccedded; + } + else + { + var smsResult = _smsService.MonthlyBill(number.PhoneNumber, 161233, + partyName, + balanceToMoney, id, aprove); + Thread.Sleep(1000); + isSuccessSend = smsResult.IsSuccedded; + messageId = smsResult.MessageId; + message = smsResult.Message; + } + + if (isSuccessSend) + { + var createSmsResult = new SmsResult(messageId, + message, typeOfSms, partyName, number.PhoneNumber, + item.ContractingPartyId, item.Id); + _smsResultRepository.Create(createSmsResult); + _smsResultRepository.SaveChanges(); + Thread.Sleep(1000); + } + + //Console.ForegroundColor = ConsoleColor.Black; + //Console.BackgroundColor = ConsoleColor.Yellow; + //Console.WriteLine(number.PhoneNumber + " debt : " + balance + " contractId = " + item.Id); + //Console.ResetColor(); + } + } + + + } + else if (item.OfficialCompany == "NotOfficial") // حقوقی بدهکار غیر رسمی + { + var balanceToMoney = balance.ToMoney(); + foreach (var number in phoneNumbers) + { + if (!string.IsNullOrWhiteSpace(number.PhoneNumber) && + number.PhoneNumber.Length == 11) + { + + int messageId = 0; + string message = ""; + bool isSuccessSend = false; + if (hasRollCallService) + { + string publicId = transactions.PublicId; + string code1 = publicId.Substring(0, 25); + string code2 = publicId.Substring(25); + var newSmsResult = _smsService.MonthlyBillNew(number.PhoneNumber, 789638, + partyName, balanceToMoney, code1, code2); + Thread.Sleep(1000); + messageId = newSmsResult.MessageId; + message = newSmsResult.Message; + isSuccessSend = newSmsResult.IsSuccedded; + } + else + { + var smsResult = _smsService.MonthlyBill(number.PhoneNumber, 347415, + partyName, + balanceToMoney, id, aprove); + Thread.Sleep(1000); + isSuccessSend = smsResult.IsSuccedded; + messageId = smsResult.MessageId; + message = smsResult.Message; + } + + if (isSuccessSend) + { + var createSmsResult = new SmsResult(messageId, + message, typeOfSms, partyName, number.PhoneNumber, + item.ContractingPartyId, item.Id); + _smsResultRepository.Create(createSmsResult); + _smsResultRepository.SaveChanges(); + Thread.Sleep(1000); + } + + //Console.ForegroundColor = ConsoleColor.Black; + //Console.BackgroundColor = ConsoleColor.Yellow; + //Console.WriteLine(number.PhoneNumber + " debt : " + balance + " contractId = " + item.Id); + //Console.ResetColor(); + } + } + + + } + } + else + { + if (item.OfficialCompany == "Official") // حقیقی بدهکار رسمی + { + var balanceToMoney = balance.ToMoney(); + + foreach (var number in phoneNumbers) + { + if (!string.IsNullOrWhiteSpace(number.PhoneNumber) && + number.PhoneNumber.Length == 11) + { + + int messageId = 0; + string message = ""; + bool isSuccessSend = false; + if (hasRollCallService) + { + string publicId = transactions.PublicId; + string code1 = publicId.Substring(0, 25); + string code2 = publicId.Substring(25); + var newSmsResult = _smsService.MonthlyBillNew(number.PhoneNumber, 768277, + partyName, balanceToMoney, code1, code2); + Thread.Sleep(1000); + messageId = newSmsResult.MessageId; + message = newSmsResult.Message; + isSuccessSend = newSmsResult.IsSuccedded; + } + else + { + var smsResult = _smsService.MonthlyBill(number.PhoneNumber, 998180, + partyName, + balanceToMoney, id, aprove); + Thread.Sleep(1000); + isSuccessSend = smsResult.IsSuccedded; + messageId = smsResult.MessageId; + message = smsResult.Message; + } + + if (isSuccessSend) + { + var createSmsResult = new SmsResult(messageId, + message, typeOfSms, partyName, number.PhoneNumber, + item.ContractingPartyId, item.Id); + _smsResultRepository.Create(createSmsResult); + _smsResultRepository.SaveChanges(); + Thread.Sleep(1000); + } + + //Console.ForegroundColor = ConsoleColor.Black; + //Console.BackgroundColor = ConsoleColor.Yellow; + //Console.WriteLine(number.PhoneNumber + " debt : " + balance + " contractId = " + item.Id); + //Console.ResetColor(); + } + } + + + } + else if (item.OfficialCompany == "NotOfficial") // حقیقی بدهکار غیر رسمی + { + var balanceToMoney = balance.ToMoney(); + + foreach (var number in phoneNumbers) + { + if (!string.IsNullOrWhiteSpace(number.PhoneNumber) && + number.PhoneNumber.Length == 11) + { + + int messageId = 0; + string message = ""; + bool isSuccessSend = false; + if (hasRollCallService) + { + string publicId = transactions.PublicId; + string code1 = publicId.Substring(0, 25); + string code2 = publicId.Substring(25); + var newSmsResult = _smsService.MonthlyBillNew(number.PhoneNumber, 768277, + partyName, balanceToMoney, code1, code2); + Thread.Sleep(1000); + messageId = newSmsResult.MessageId; + message = newSmsResult.Message; + isSuccessSend = newSmsResult.IsSuccedded; + } + else + { + var smsResult = _smsService.MonthlyBill(number.PhoneNumber, 810539, + partyName, + balanceToMoney, id, aprove); + Thread.Sleep(1000); + isSuccessSend = smsResult.IsSuccedded; + messageId = smsResult.MessageId; + message = smsResult.Message; + } + + if (isSuccessSend) + { + var createSmsResult = new SmsResult(messageId, + message, typeOfSms, partyName, number.PhoneNumber, + item.ContractingPartyId, item.Id); + _smsResultRepository.Create(createSmsResult); + _smsResultRepository.SaveChanges(); + Thread.Sleep(1000); + } + + //Console.ForegroundColor = ConsoleColor.Black; + //Console.BackgroundColor = ConsoleColor.Yellow; + //Console.WriteLine(number.PhoneNumber + " debt : " + balance + " contractId = " + item.Id); + ////_logger.LogInformation(number.PhoneNumber + " debt : " + balance + " nolegal" + "NotOfficial"); + //Console.ResetColor(); + } + } + + + } + } + } + + + phoneNumbers = new List(); + } + } + } + } + catch (Exception e) + { + + string name = item.ContractingPartyName.Length > 18 ? item.ContractingPartyName.Substring(0, 18) : item.ContractingPartyName; + string errMess = $"{name}-خطا"; + _smsService.Alarm("09114221321", errMess); + _logger.LogError(e, "ReminderSms"); + } + } + } + + + #region ExternalMetods + + private async Task? GetFinancialByContractingPartyId(long contractingPartyId) + { + return await _context.FinancialStatments.Include(x => x.FinancialTransactionList) + .Select(x => new FinancialStatmentViewModel + { + Id = x.id, + ContractingPartyId = x.ContractingPartyId, + ContractingPartyName = x.ContractingPartyName, + PublicId = x.PublicIdStr, + FinancialTransactionViewModels = x.FinancialTransactionList.Select(t => new FinancialTransactionViewModel + { + Id = t.id, + TdateFa = t.TdateFa, + TdateGr = t.TdateGr, + Description = t.TypeOfTransaction == "debt" + ? "ایجاد درآمد" + " " + t.DescriptionOption + " " + t.Description + : "دریافت درآمد" + " " + t.DescriptionOption + " " + t.Description, + Deptor = t.Deptor, + DeptorString = t.Deptor != 0 ? t.Deptor.ToMoney() : "", + Creditor = t.Creditor, + CreditorString = t.Creditor != 0 ? t.Creditor.ToMoney() : "", + Balance = t.Balance, + MessageText = t.MessageText, + SentSms = t.SentSms, + SentSmsDateFa = t.SentSmsDateFa, + FinancialStatementId = t.FinancialStatementId, + TypeOfTransaction = t.TypeOfTransaction, + DescriptionOption = t.DescriptionOption + }).OrderBy(t => t.TdateGr).ToList() + }) + .FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId); + + + } + + #endregion #region CustomViewModels public class WorkshopsAndEmployeeViewModel diff --git a/DadmehrGostar.sln b/DadmehrGostar.sln index f25fd06c..478f82b4 100644 --- a/DadmehrGostar.sln +++ b/DadmehrGostar.sln @@ -86,6 +86,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BackgroundJobs", "Backgroun EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompanyManagement.Infrastructure.Mongo", "CompanyManagement.Infrastructure.Mongo\CompanyManagement.Infrastructure.Mongo.csproj", "{4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackgroundInstitutionContract.Task", "BackgroundInstitutionContract\BackgroundInstitutionContract.Task\BackgroundInstitutionContract.Task.csproj", "{F78FBB92-294B-88BA-168D-F0C578B0D7D6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -192,6 +194,10 @@ Global {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|Any CPU.Build.0 = Debug|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|Any CPU.ActiveCfg = Release|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|Any CPU.Build.0 = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -226,6 +232,9 @@ Global {339E05B6-E99F-4403-AFDF-CD0540E96C8D} = {708E8D7E-F190-47C5-B78E-F43131FB7D6D} {02892882-2A02-484B-BAF9-7E63F6BDCFA0} = {708E8D7E-F190-47C5-B78E-F43131FB7D6D} {BF98173C-42AF-4897-A7CB-4CACEB2B52A2} = {86921E1B-2AFA-4B8A-9403-EE16D58B5B26} + {97E148FA-3C36-40DD-B121-D90C1C0F3B47} = {C10E256D-7E7D-4C77-B416-E577A34AF924} + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3} = {00000000-0000-0000-0000-000000000000} + {F78FBB92-294B-88BA-168D-F0C578B0D7D6} = {C10E256D-7E7D-4C77-B416-E577A34AF924} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E6CFB3A7-A7C8-4E82-8F06-F750408F0BA9}