Instant Send Smms for reminder completed

This commit is contained in:
SamSys
2025-11-18 15:10:32 +03:30
parent f5cb6b276e
commit 4ba21db7c7
12 changed files with 512 additions and 34 deletions

View File

@@ -0,0 +1,20 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace CompanyManagment.App.Contracts.Hubs;
public class SendSmsHub : Hub
{
public async Task send(long id)
{
await Groups.AddToGroupAsync(Context.ConnectionId, GetGroupName(id));
}
public static string GetGroupName(long id)
{
return $"group-sms-{id}";
}
}

View File

@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using CompanyManagment.App.Contracts.InstitutionContract;
namespace CompanyManagment.App.Contracts.SmsResult;
@@ -46,4 +48,24 @@ public interface ISmsSettingApplication
/// <returns></returns>
Task RemoveSetting(long id);
/// <summary>
/// دریافت لیست بدهکاران
/// </summary>
/// <param name="typeOfSmsSetting"></param>
/// <returns></returns>
Task<List<SmsListData>> GetSmsListData(TypeOfSmsSetting typeOfSmsSetting);
/// <summary>
/// دریافت لیست کسانی که باید بلاک شوند
/// </summary>
/// <param name="typeOfSmsSetting"></param>
/// <returns></returns>
Task<List<BlockSmsListData>> GetBlockSmsListData(TypeOfSmsSetting typeOfSmsSetting);
/// <summary>
/// ارسال پیامک یاد آور آنی
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
Task<OperationResult> InstantSendReminderSms(List<SmsListData> command);
}

View File

@@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.SmsResultAgg;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.SmsResult;
namespace CompanyManagment.Application;
@@ -10,10 +14,12 @@ namespace CompanyManagment.Application;
public class SmsSettingApplication : ISmsSettingApplication
{
private readonly ISmsSettingsRepository _smsSettingsRepository;
private readonly IInstitutionContractRepository _institutionContractRepository;
public SmsSettingApplication(ISmsSettingsRepository smsSettingsRepository)
public SmsSettingApplication(ISmsSettingsRepository smsSettingsRepository, IInstitutionContractRepository institutionContractRepository)
{
_smsSettingsRepository = smsSettingsRepository;
_institutionContractRepository = institutionContractRepository;
}
@@ -103,4 +109,39 @@ public class SmsSettingApplication : ISmsSettingApplication
{
await _smsSettingsRepository.RemoveItem(id);
}
public async Task<List<SmsListData>> GetSmsListData(TypeOfSmsSetting typeOfSmsSetting)
{
return await _institutionContractRepository.GetSmsListData(DateTime.Now, typeOfSmsSetting);
}
public async Task<List<BlockSmsListData>> GetBlockSmsListData(TypeOfSmsSetting typeOfSmsSetting)
{
return await _institutionContractRepository.GetBlockListData(DateTime.Now);
}
public async Task<OperationResult> InstantSendReminderSms(List<SmsListData> command)
{
var op = new OperationResult();
string typeOfSms = "یادآور بدهی ماهانه";
string sendMessStart = "شروع یادآور آنی";
string sendMessEnd = "پایان یادآور آنی";
if (command.Any())
{
await _institutionContractRepository.SendReminderSmsToContractingParties(command, typeOfSms, sendMessStart, sendMessEnd);
return op.Succcedded();
}
else
{
return op.Failed("موردی انتخاب نشده است");
}
}
}

View File

@@ -28,6 +28,7 @@ using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.Employer;
using CompanyManagment.App.Contracts.FinancialStatment;
using CompanyManagment.App.Contracts.FinancilTransaction;
using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.InstitutionContractContactinfo;
using CompanyManagment.App.Contracts.Law;
@@ -35,6 +36,7 @@ using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop;
using CompanyManagment.App.Contracts.WorkshopPlan;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@@ -60,6 +62,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
private readonly ISmsResultRepository _smsResultRepository;
private readonly IFinancialTransactionRepository _financialTransactionRepository;
private readonly IFinancialStatmentRepository _financialStatmentRepository;
private readonly IHubContext<SendSmsHub> _hubContext;
private readonly InstitutionContratVerificationParty _firstParty = new()
{
@@ -73,7 +76,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
public InstitutionContractRepository(CompanyContext context, IEmployerRepository employerRepository,
IWorkshopRepository workshopRepository, IMongoDatabase database,
IPlanPercentageRepository planPercentageRepository, ISmsService smsService, ISmsResultRepository smsResultRepository, IFinancialTransactionRepository financialTransactionRepository, IFinancialStatmentRepository financialStatmentRepository) : base(context)
IPlanPercentageRepository planPercentageRepository, ISmsService smsService, ISmsResultRepository smsResultRepository, IFinancialTransactionRepository financialTransactionRepository, IFinancialStatmentRepository financialStatmentRepository, IHubContext<SendSmsHub> hubContext) : base(context)
{
_context = context;
_employerRepository = employerRepository;
@@ -83,6 +86,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
_smsResultRepository = smsResultRepository;
_financialTransactionRepository = financialTransactionRepository;
_financialStatmentRepository = financialStatmentRepository;
_hubContext = hubContext;
_institutionExtensionTemp =
database.GetCollection<InstitutionContractExtensionTemp>("InstitutionContractExtensionTemp");
_institutionAmendmentTemp =
@@ -3625,11 +3629,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
if (smsListData.Any())
{
await _smsService.Alarm("09114221321", sendMessStart);
Thread.Sleep(1000);
await _smsService.Alarm("09111485044", sendMessStart);
Thread.Sleep(1000);
//await _smsService.Alarm("09114221321", sendMessStart);
//Thread.Sleep(1000);
//await _smsService.Alarm("09111485044", sendMessStart);
//Thread.Sleep(1000);
int successProcess = 1;
int countList = smsListData.Count;
foreach (var item in smsListData)
{
@@ -3637,35 +3645,35 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
{
if (item.TypeOfSmsMethod == "MonthlyBill")
{
var res = await _smsService.MonthlyBill(item.PhoneNumber, item.TemplateId, item.PartyName, item.Amount,
$"{item.ContractingPartyId}", item.AproveId);
//var res = await _smsService.MonthlyBill(item.PhoneNumber, item.TemplateId, item.PartyName, item.Amount,
// $"{item.ContractingPartyId}", item.AproveId);
if (res.isSucceded)
{
var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
res.message, typeOfSms, item.PartyName, item.PhoneNumber,
item.ContractingPartyId, item.InstitutionContractId);
//if (res.isSucceded)
//{
// var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
// res.message, typeOfSms, item.PartyName, item.PhoneNumber,
// item.ContractingPartyId, item.InstitutionContractId);
await _smsResultRepository.CreateAsync(createSmsResult);
await _smsResultRepository.SaveChangesAsync();
// await _smsResultRepository.CreateAsync(createSmsResult);
// await _smsResultRepository.SaveChangesAsync();
}
//}
}
else
{
var res = await _smsService.MonthlyBillNew(item.PhoneNumber, item.TemplateId, item.PartyName, item.Amount, item.Code1, item.Code2);
if (res.isSucceded)
{
var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
res.message, typeOfSms, item.PartyName, item.PhoneNumber,
item.ContractingPartyId, item.InstitutionContractId);
//var res = await _smsService.MonthlyBillNew(item.PhoneNumber, item.TemplateId, item.PartyName, item.Amount, item.Code1, item.Code2);
//if (res.isSucceded)
//{
// var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
// res.message, typeOfSms, item.PartyName, item.PhoneNumber,
// item.ContractingPartyId, item.InstitutionContractId);
await _smsResultRepository.CreateAsync(createSmsResult);
await _smsResultRepository.SaveChangesAsync();
// await _smsResultRepository.CreateAsync(createSmsResult);
// await _smsResultRepository.SaveChangesAsync();
}
//}
}
Thread.Sleep(1000);
Thread.Sleep(600);
}
catch (Exception e)
{
@@ -3674,13 +3682,21 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
await _smsService.Alarm("09114221321", errMess);
}
var percent =(successProcess / (double)countList) * 100;
await _hubContext.Clients.Group(SendSmsHub.GetGroupName(7))
.SendAsync("showStatus", (int)percent);
successProcess += 1;
}
await _smsService.Alarm("09114221321", sendMessEnd);
Thread.Sleep(1000);
await _smsService.Alarm("09111485044", sendMessEnd);
//await _smsService.Alarm("09114221321", sendMessEnd);
//Thread.Sleep(1000);
//await _smsService.Alarm("09111485044", sendMessEnd);
}

View File

@@ -120,6 +120,7 @@
<script src="~/AdminTheme/assets/js/site.js"></script>
<script src="~/AdminTheme/js/numeral.min.js"></script>
<script src="~/admintheme/js/jquery.mask_1.14.16.min.js"></script>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script>
$(document).ready(function () {

View File

@@ -1,5 +1,7 @@
using _0_Framework.Application.Enums;
using Company.Domain.SmsResultAgg;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.Module;
using CompanyManagment.App.Contracts.SmsResult;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -118,6 +120,44 @@ namespace ServiceHost.Areas.Admin.Pages.Company.SmsResult
}
//=================================== ارسال آنی ========================================//
/// <summary>
/// لود مودال ارسال پیامک
/// </summary>
/// <param name="typeOfSmsSetting"></param>
/// <returns></returns>
public async Task<IActionResult> OnGetInstantSendSms(TypeOfSmsSetting typeOfSmsSetting)
{
return Partial("_SmsSettingPartials/InstantSms");
}
/// <summary>
/// لود دیتای ارسال پیامک آنی
/// </summary>
/// <returns></returns>
public async Task<IActionResult> OnGetInstantReminderSendSms()
{
var dataModel = await _smsSettingApplication.GetSmsListData(TypeOfSmsSetting.InstitutionContractDebtReminder);
return Partial("_SmsSettingPartials/_InstantReminderSms", dataModel);
}
/// <summary>
/// ارسال پیامک آنی
/// </summary>
/// <returns></returns>
public async Task<JsonResult> OnPostInstantReminderSendSms([FromBody] List<SmsListData> command)
{
var result = await _smsSettingApplication.InstantSendReminderSms(command);
return new JsonResult(new
{
isSuccess = result.IsSuccedded,
message = result.Message
});
}
//=================================== تب ها ========================================//
#region Tabs

View File

@@ -0,0 +1,235 @@
@Html.AntiForgeryToken()
@{
<style>
.modal .modal-dialog .modal-content{
padding-bottom: 10px !important;
}
.modal-title{
position: absolute;
width: 291px;
font-size: 18px;
background-color: inherit;
left: 47%;
top: 19px;
margin-left: -100px;
text-align: center;
color: black;
border: 1px solid #00000030;
border-radius: 9px;
padding: 2px 0px;
}
.skeleton-loader {
width: 100%;
height: 35px;
background: linear-gradient(90deg, #EEEEEE 25%, #DEDEDE 50%, #EEEEEE 75%);
background-size: 200% 100%;
animation: loading 2s infinite ease-in-out;
border-radius: 8px;
margin-bottom: 3px
}
.progBar {
display: none;
}
#createProcess {
background-color: #fdfdfd;
height: 70px;
border-radius: 7px;
margin: 4px 2px 4px 2px;
box-shadow: 0px 1px 7px 0 #155c5c;
}
.progress-bar {
color: #fff !important;
font-size: 17px !important;
line-height: 23px !important;
border-radius: 10px !important;
}
@@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
</style>
}
<div class="modal-header">
<h5 class="modal-title">ارسال آنی پیامک یادآور</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="بستن">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="card card-pattern m-t-10" style="border-radius: 15px 15px 0px 0px;">
<div class="container-fluid">
<!-- هدر -->
<div class="row fw-bold mb-2 head-table">
<div class="col-2 col-md-1">ردیف</div>
<div class="col-10 col-md-3"> نام طرف حساب </div>
<div class="col-6 col-md-3"> شماره تماس </div>
<div class="col-6 col-md-3" style="text-align:left; left:1.2%"> مبلغ بدهی </div>
<div class="col-12 col-md-2" style="float:right;text-align:right; direction:ltr; left: 1.2%">
تیک ارسال
<label class="switch">
<input id="checkAll" type="checkbox" checked />
<span class="slider round"></span>
</label>
</div>
</div>
</div>
</div>
<div id="createProcess" class="row progress-bar-striped progBar">
<div class="form-group" style="padding: 0px 10px;">
<span style="text-align: center">
<h3 style="font-size: 15px;color: #767575;margin-top: 3px;margin-bottom:0px">درصد ارسال پیامک ها</h3>
</span>
<div class="progress" style="height: 20px">
<div id="progress-bar-w" style="background-color: rgb(16 170 18)" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
<div class="card card-pattern " style="margin-top:2px;height:600px; overflow-y:scroll; border-radius: 0 0 15px 15px">
<div class="container-fluid" id="partialAppend">
<div id="loading">
@for (var j = 0; j < 16; j++)
{
<div class="skeleton-loader"></div>
}
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" onclick="sendToSms()" class="btn btn-success px-4 rounded-pill">ارسال پیامک</button>
<button type="button" class="btn btn-outline-secondary px-4 rounded-pill" data-dismiss="modal">بستن</button>
</div>
<script>
$(document).ready(function () {
var url = "/Admin/Company/SmsResult/SmsSettings?handler=InstantReminderSendSms";
$.get(url, function (data) {
$("#loading").hide();
$("#partialAppend").html(data);
});
var gNo = Number(7);
setTimeout(function () {
connectToGroupW(gNo);
},
2000);
});
console.log('befor start ...');
var connection = new signalR.HubConnectionBuilder().withUrl("/trackingSendSmsHub").build();
connection.start().then(function () {
console.log("connect.....!");
}).catch(function (err) {
return console.error(err.toString());
});
function connectToGroupW(id) {
connection.invoke("send", id)
.catch(function (err) {
console.error(err.toString());
});
console.log(`connected to group...${id}`);
}
connection.on('showStatus',
function (percent) {
$('#progress-bar-w').css("width", percent + "%");
$('#progress-bar-w').text(percent + '%');
});
//ارسال پیامک
function sendToSms() {
const recordItems = document.querySelectorAll(".record");
const command = [];
recordItems.forEach(recordItem => {
const checkbox = recordItem.querySelector('input[type="checkbox"]');
if (checkbox && checkbox.checked) {
const SmsListData = {
PhoneNumber: checkbox.dataset.phonenumber,
TemplateId: Number(checkbox.dataset.templateid),
PartyName: checkbox.dataset.partyname,
Amount: checkbox.dataset.amount,
ContractingPartyId: Number(checkbox.dataset.contractingpartyid),
AproveId: checkbox.dataset.aproveid,
TypeOfSmsMethod: checkbox.dataset.typeofsmsmethod,
Code1: checkbox.dataset.code1,
Code2: checkbox.dataset.code2,
InstitutionContractId: Number(checkbox.dataset.institutioncontractid)
};
command.push(SmsListData);
}
});
if (command.length === 0) {
$.Notification.autoHideNotify('error', 'top center', 'پیام سیستم ', "هیچ موردی انتخاب نشده است");
return;
}
$('#createProcess').removeClass("progBar");
var urlAjaxToSendSms = '@Url.Page("/Company/SmsResult/SmsSettings", "InstantReminderSendSms")';
$.ajax({
url: urlAjaxToSendSms,
type: "POST",
contentType: "application/json",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
data: JSON.stringify(command),
success: function (response) {
if (response.isSuccess) {
$.Notification.autoHideNotify('success', 'top center', 'پیام سیستم ', response.message);
} else {
$.Notification.autoHideNotify('error', 'top center', 'پیام سیستم ', response.message);
}
},
error: function () {
$.Notification.autoHideNotify('error', 'top center', 'پیام سیستم ', "خطا در ارسال اطلاعات");
}
});
}
//روشن یا خاموش کردن تیک برای همه
$('#checkAll').on('change', function () {
const status = this.checked; // true یا false
$('input[type="checkbox"]').each(function () {
$(this).prop('checked', status);
});
});
</script>

View File

@@ -67,7 +67,7 @@
</span>
</a>
<a class="btn btn-success instantSendSms"
style="border-radius:5px;" href="#showmodal=@Url.Page("./SmsSettings", "InstantSendReminderSms")">
style="border-radius:5px;" href="#showmodal=@Url.Page("./SmsSettings", "InstantSendSms", new {typeOfSmsSetting = TypeOfSmsSetting.InstitutionContractDebtReminder})">
<span class="icon-span">

View File

@@ -0,0 +1,101 @@
@model List<CompanyManagment.App.Contracts.InstitutionContract.SmsListData>
@{
int countIndex = 1;
<style>
/* Toggle Switch */
.switch {
position: relative;
display: inline-block;
width: 46px;
height: 24px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .3s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: .3s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #28a745; /* رنگ سبز مشابه Bootstrap */
}
input:checked + .slider:before {
transform: translateX(22px);
}
</style>
}
<!-- لیست -->
@foreach (var item in Model)
{
<div class="row align-items-center p-2 tr-table record">
<div class="col-2 col-md-1"><div class="row-number">@countIndex</div></div>
<div class="col-10 col-md-3">@item.PartyName</div>
<div class="col-6 col-md-3">@item.PhoneNumber</div>
<div class="col-6 col-md-3" style="text-align:left;">@item.Amount</div>
<div class="col-6 col-md-2">
<label class="switch">
<input data-id="@countIndex"
type="checkbox" checked
data-PartyName="@item.PartyName"
data-PhoneNumber="@item.PhoneNumber"
data-Amount="@item.Amount"
data-TemplateId="@item.TemplateId"
data-ContractingPartyId="@item.ContractingPartyId"
data-AproveId="@item.AproveId"
data-TypeOfSmsMethod="@item.TypeOfSmsMethod"
data-Code1="@item.Code1"
data-Code2="@item.Code2"
data-InstitutionContractId="@item.InstitutionContractId" />
<span class="slider round"></span>
</label>
</div>
@{
countIndex++;
}
<div class="col-12 col-md-3 align-items-center" style="float:left; direction:ltr">
</div>
</div>
}

View File

@@ -24,6 +24,7 @@ using ServiceHost.Test;
using System.Text.Json.Serialization;
using System.Text.Json;
using _0_Framework.InfraStructure.Mongo;
using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.EFCore.Services;
using Microsoft.AspNetCore.CookiePolicy;
using Microsoft.AspNetCore.Mvc.Infrastructure;
@@ -384,6 +385,7 @@ app.MapHub<CreateContractTarckingHub>("/trackingHub");
app.MapHub<SendAccountMessage>("/trackingSmsHub");
app.MapHub<HolidayApiHub>("/trackingHolidayHub");
app.MapHub<CheckoutHub>("/trackingCheckoutHub");
app.MapHub<SendSmsHub>("/trackingSendSmsHub");
app.MapRazorPages();
app.MapControllers();

View File

@@ -19,7 +19,7 @@
"sqlDebugging": true,
"dotnetRunMessages": "true",
"nativeDebugging": true,
"applicationUrl": "https://localhost:5004;http://localhost:5003;https://192.168.0.118:8080;http://192.168.0.118:8081",
"applicationUrl": "https://localhost:5004;http://localhost:5003",
"jsWebView2Debugging": false,
"hotReloadEnabled": true
},

View File

@@ -12,7 +12,7 @@
//"MesbahDb": "Data Source=DESKTOP-NUE119G\\MSNEW;Initial Catalog=Mesbah_db;Integrated Security=True"
//server
"MesbahDbServer": "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;",
//"MesbahDbServer": "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;",