Compare commits
93 Commits
Feature/ro
...
Feature/Ex
| Author | SHA1 | Date | |
|---|---|---|---|
| 8faaea0a1e | |||
| c874164ca2 | |||
| d2f0ed46ae | |||
| 40dd90074b | |||
| 452b0b6277 | |||
| 720e998a54 | |||
| 626722e805 | |||
| 5e5910e0fd | |||
| 5d81731512 | |||
| 511932fa58 | |||
| 95891d5bae | |||
| f3fa76c292 | |||
| ac6bbc3587 | |||
| 947d7590f4 | |||
| 91403a52a3 | |||
| 7e80342f80 | |||
| 5e92207778 | |||
|
|
29484e9565 | ||
| ba640494d2 | |||
| 6974a505b4 | |||
| 6d3d599449 | |||
| 2d28bd1f98 | |||
| 75ae3efb65 | |||
| eb53fd67ef | |||
| 8ec717916c | |||
| 64bdbcbd2d | |||
| 7e9ba23b97 | |||
|
|
e6640a1636 | ||
|
|
e9665c190b | ||
| ea3baf14e8 | |||
| 36f104f316 | |||
| 42cae1295f | |||
| 95b281c3a4 | |||
|
|
c239b094d7 | ||
| 9e61bd3f55 | |||
| 7025478417 | |||
|
|
b5ee4f01c7 | ||
| 3937cd8a9f | |||
|
|
3ed14bf2bd | ||
| 933dd3d937 | |||
| 90d7de4901 | |||
| 37aa57d773 | |||
| cce903f2ae | |||
| 873ad2f41f | |||
| 2035b6fff8 | |||
|
|
d31cf8470f | ||
|
|
5a34c9a6c9 | ||
|
|
4eb78996d5 | ||
|
|
9d8e40c841 | ||
|
|
4ba21db7c7 | ||
| 164388dac3 | |||
| e81a44dd2f | |||
| f238b5af6b | |||
|
|
f5cb6b276e | ||
| ed746cb60a | |||
| 07b2596a6a | |||
| 7dce7f5bc8 | |||
| 7ac078c631 | |||
| 265d5f8b22 | |||
| cf5c9f29cf | |||
| 7448ddc79c | |||
| 3f1a6f3387 | |||
| 95d4dfe568 | |||
|
|
a481e941c5 | ||
|
|
58637ab038 | ||
|
|
d10eff3dd5 | ||
| 6d3526fb30 | |||
|
|
ed35067ecc | ||
|
|
488ce6041a | ||
|
|
0f261684e9 | ||
|
|
a2c0cf126a | ||
|
|
09a1d6df38 | ||
|
|
39bacdf8d6 | ||
| ba2b402c04 | |||
| f3470de8b6 | |||
|
|
dad334a9bd | ||
|
|
193e9f587f | ||
|
|
2164aeb5bc | ||
|
|
7e08b44d4d | ||
|
|
eec53c8024 | ||
|
|
8c37826367 | ||
| 4a8f76c473 | |||
| 3e5520d8a0 | |||
| 0b439d0268 | |||
| 76666b3da7 | |||
|
|
2f15c2d54b | ||
|
|
9d9f0e14d3 | ||
|
|
4d45ee36b6 | ||
|
|
7ae08fe023 | ||
|
|
117b5df447 | ||
|
|
fee14c65ec | ||
|
|
31defcde7e | ||
|
|
a4dbb016d2 |
@@ -0,0 +1,22 @@
|
||||
namespace _0_Framework.Application.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// وضعیت تایید قرادا مالی
|
||||
/// </summary>
|
||||
public enum InstitutionContractVerificationStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// در انتظار تایید
|
||||
/// </summary>
|
||||
PendingForVerify = 0,
|
||||
|
||||
/// <summary>
|
||||
/// در انتظار کارپوشه
|
||||
/// </summary>
|
||||
PendingWorkflow = 1,
|
||||
|
||||
/// <summary>
|
||||
/// تایید شده
|
||||
/// </summary>
|
||||
Verified = 2
|
||||
}
|
||||
36
0_Framework/Application/Enums/TypeOfSmsSetting.cs
Normal file
36
0_Framework/Application/Enums/TypeOfSmsSetting.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace _0_Framework.Application.Enums;
|
||||
|
||||
public enum TypeOfSmsSetting
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// پیامک
|
||||
/// یادآور بدهی ماهیانه قرارداد مالی
|
||||
/// </summary>
|
||||
InstitutionContractDebtReminder,
|
||||
|
||||
/// <summary>
|
||||
/// پیامک
|
||||
/// صورت حساب ماهانه قرارداد مالی
|
||||
/// </summary>
|
||||
MonthlyInstitutionContract,
|
||||
|
||||
/// <summary>
|
||||
/// پیامک
|
||||
/// اعلام مسدودی طرف حساب
|
||||
/// </summary>
|
||||
BlockContractingParty,
|
||||
|
||||
/// <summary>
|
||||
/// پیامک
|
||||
/// هشدار اول
|
||||
/// </summary>
|
||||
Warning,
|
||||
|
||||
|
||||
/// <summary>
|
||||
///پیامک اقدام قضائی
|
||||
/// </summary>
|
||||
LegalAction,
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace _0_Framework.Application.FaceEmbedding;
|
||||
|
||||
/// <summary>
|
||||
/// سرویس اطلاعرسانی تغییرات Face Embedding
|
||||
/// </summary>
|
||||
public interface IFaceEmbeddingNotificationService
|
||||
{
|
||||
/// <summary>
|
||||
/// اطلاعرسانی ایجاد یا بهروزرسانی Embedding
|
||||
/// </summary>
|
||||
Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName);
|
||||
|
||||
/// <summary>
|
||||
/// اطلاعرسانی حذف Embedding
|
||||
/// </summary>
|
||||
Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId);
|
||||
|
||||
/// <summary>
|
||||
/// اطلاعرسانی بهبود Embedding
|
||||
/// </summary>
|
||||
Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace _0_Framework.Application.FaceEmbedding;
|
||||
|
||||
public interface IFaceEmbeddingService
|
||||
{
|
||||
Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId, string employeeFullName, string picture1Path, string picture2Path);
|
||||
Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, string employeeFullName, Stream picture1Stream, Stream picture2Stream);
|
||||
Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, float confidence, Dictionary<string, object> metadata = null);
|
||||
Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId);
|
||||
Task<OperationResult<FaceEmbeddingResponse>> 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<string, object> Metadata { get; set; }
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class AqayePardakhtPaymentGateway:IPaymentGateway
|
||||
amount = command.Amount,
|
||||
callback = command.CallBackUrl,
|
||||
card_number = command.CardNumber,
|
||||
invoice_id = command.InvoiceId,
|
||||
invoice_id = command.TransactionId,
|
||||
mobile = command.Mobile,
|
||||
email = command.Email??"",
|
||||
description = command.Description,
|
||||
@@ -73,7 +73,7 @@ public class AqayePardakhtPaymentGateway:IPaymentGateway
|
||||
amount = command.Amount,
|
||||
callback = command.CallBackUrl,
|
||||
card_number = command.Amount,
|
||||
invoice_id = command.InvoiceId,
|
||||
invoice_id = command.TransactionId,
|
||||
mobile = command.Mobile,
|
||||
email = command.Email,
|
||||
description = command.Email,
|
||||
|
||||
@@ -49,12 +49,13 @@ public class WalletAmountResponse
|
||||
public class CreatePaymentGatewayRequest
|
||||
{
|
||||
public double Amount { get; set; }
|
||||
public string TransactionId { get; set; }
|
||||
public string CallBackUrl { get; set; }
|
||||
public string InvoiceId { get; set; }
|
||||
public string CardNumber { get; set; }
|
||||
public string Mobile { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Description { get; set; }
|
||||
public long FinancialInvoiceId { get; set; }
|
||||
public IDictionary<string, object> ExtraData { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
@@ -16,18 +17,18 @@ public class SepehrPaymentGateway:IPaymentGateway
|
||||
{
|
||||
_httpClient = httpClient.CreateClient();
|
||||
_httpClient.BaseAddress = new Uri("https://sepehr.shaparak.ir/Rest/V1/PeymentApi/");
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
|
||||
{
|
||||
command.ExtraData ??= new Dictionary<string, object>();
|
||||
command.ExtraData.Add("financialInvoiceId", command.FinancialInvoiceId);
|
||||
var extraData = JsonConvert.SerializeObject(command.ExtraData);
|
||||
var res = await _httpClient.PostAsJsonAsync("GetToken", new
|
||||
{
|
||||
TerminalID = TerminalId,
|
||||
Amount = command.Amount,
|
||||
InvoiceID = command.InvoiceId,
|
||||
InvoiceID = command.TransactionId,
|
||||
callbackURL = command.CallBackUrl,
|
||||
payload = extraData
|
||||
}, cancellationToken: cancellationToken);
|
||||
|
||||
@@ -32,6 +32,60 @@ public interface ISmsService
|
||||
public Task<bool> SendInstitutionVerificationCode(string number, string code, string contractingPartyFullName,
|
||||
long contractingPartyId, long institutionContractId);
|
||||
|
||||
SmsResult TaskReminderSms(string number, string taskCount);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region InstitutionContractSMS
|
||||
/// <summary>
|
||||
/// پیامک اهانه جدید
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="tamplateId"></param>
|
||||
/// <param name="fullname"></param>
|
||||
/// <param name="amount"></param>
|
||||
/// <param name="code1"></param>
|
||||
/// <param name="code2"></param>
|
||||
/// <returns></returns>
|
||||
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBillNew(string number, int tamplateId, string fullname, string amount, string code1,
|
||||
string code2);
|
||||
/// <summary>
|
||||
/// پیامک ماهانه قدیم
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="tamplateId"></param>
|
||||
/// <param name="fullname"></param>
|
||||
/// <param name="amount"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="aprove"></param>
|
||||
/// <returns></returns>
|
||||
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBill(string number, int tamplateId, string fullname, string amount, string id, string aprove);
|
||||
|
||||
/// <summary>
|
||||
/// پیامک مسدودی طرف حساب
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="fullname"></param>
|
||||
/// <param name="amount"></param>
|
||||
/// <param name="accountType"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="aprove"></param>
|
||||
/// <returns></returns>
|
||||
Task<(byte status, string message, int messaeId, bool isSucceded)> BlockMessage(string number, string fullname, string amount, string accountType, string id, string aprove);
|
||||
|
||||
#endregion
|
||||
|
||||
#region AlarmMessage
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک های خطا یا اعمال ارسال
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Alarm(string number, string message);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
32
0_Framework/Application/Sms/SmsResult.cs
Normal file
32
0_Framework/Application/Sms/SmsResult.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace _0_Framework.Application.Sms;
|
||||
|
||||
public class SmsResult
|
||||
{
|
||||
public SmsResult()
|
||||
{
|
||||
IsSuccedded = false;
|
||||
}
|
||||
|
||||
public bool IsSuccedded { get; set; }
|
||||
public string Message { get; set; }
|
||||
public byte StatusCode { get; set; }
|
||||
public int MessageId { get; set; }
|
||||
|
||||
public SmsResult Succedded(byte statusCode, string message, int messageId)
|
||||
{
|
||||
IsSuccedded = true;
|
||||
Message = message;
|
||||
StatusCode = statusCode;
|
||||
MessageId = messageId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SmsResult Failed(byte statusCode, string message, int messageId)
|
||||
{
|
||||
IsSuccedded = false;
|
||||
Message = message;
|
||||
StatusCode = statusCode;
|
||||
MessageId = messageId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace _0_Framework.Application.Enums
|
||||
{
|
||||
public class CheckoutDynamicDeductionItem
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
public string Amount { get; set; }
|
||||
}
|
||||
}
|
||||
346
0_Framework/InfraStructure/FaceEmbeddingService.cs
Normal file
346
0_Framework/InfraStructure/FaceEmbeddingService.cs
Normal file
@@ -0,0 +1,346 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// پیادهسازی سرویس ارتباط با API پایتون برای مدیریت Embeddings چهره
|
||||
/// </summary>
|
||||
public class FaceEmbeddingService : IFaceEmbeddingService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ILogger<FaceEmbeddingService> _logger;
|
||||
private readonly IFaceEmbeddingNotificationService _notificationService;
|
||||
private readonly string _apiBaseUrl;
|
||||
|
||||
public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger<FaceEmbeddingService> logger,
|
||||
IFaceEmbeddingNotificationService notificationService = null)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger = logger;
|
||||
_notificationService = notificationService;
|
||||
_apiBaseUrl = "http://localhost:8000";
|
||||
}
|
||||
|
||||
public async Task<OperationResult> 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);
|
||||
|
||||
// ارسال اطلاعرسانی به سایر سیستمها
|
||||
if (_notificationService != null)
|
||||
{
|
||||
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
||||
}
|
||||
|
||||
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<OperationResult> 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);
|
||||
|
||||
// ارسال اطلاعرسانی به سایر سیستمها
|
||||
if (_notificationService != null)
|
||||
{
|
||||
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
||||
}
|
||||
|
||||
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<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding,
|
||||
float confidence, Dictionary<string, object> 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<string, object>()
|
||||
};
|
||||
|
||||
var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
_logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId);
|
||||
|
||||
// ارسال اطلاعرسانی به سایر سیستمها
|
||||
if (_notificationService != null)
|
||||
{
|
||||
await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, 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<OperationResult> 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);
|
||||
|
||||
// ارسال اطلاعرسانی به سایر سیستمها
|
||||
if (_notificationService != null)
|
||||
{
|
||||
await _notificationService.NotifyEmbeddingDeletedAsync(workshopId, 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<OperationResult<FaceEmbeddingResponse>> 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<FaceEmbeddingResponse>(content,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
|
||||
_logger.LogInformation("Embedding retrieved successfully for Employee {EmployeeId}", employeeId);
|
||||
|
||||
return new OperationResult<FaceEmbeddingResponse>
|
||||
{
|
||||
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<FaceEmbeddingResponse>
|
||||
{
|
||||
IsSuccedded = false,
|
||||
Message = $"خطا در دریافت Embedding: {response.StatusCode}"
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while getting embedding for Employee {EmployeeId}", employeeId);
|
||||
return new OperationResult<FaceEmbeddingResponse>
|
||||
{
|
||||
IsSuccedded = false,
|
||||
Message = "خطا در دریافت Embedding"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Application.FaceEmbedding;
|
||||
|
||||
namespace _0_Framework.InfraStructure;
|
||||
|
||||
/// <summary>
|
||||
/// پیادهسازی پیشفرض (بدون عملیات) برای IFaceEmbeddingNotificationService
|
||||
/// این کلاس زمانی استفاده میشود که SignalR در دسترس نباشد
|
||||
/// </summary>
|
||||
public class NullFaceEmbeddingNotificationService : IFaceEmbeddingNotificationService
|
||||
{
|
||||
public Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName)
|
||||
{
|
||||
// هیچ عملیاتی انجام نمیدهد
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId)
|
||||
{
|
||||
// هیچ عملیاتی انجام نمیدهد
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId)
|
||||
{
|
||||
// هیچ عملیاتی انجام نمیدهد
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
624
ANDROID_SIGNALR_GUIDE.md
Normal file
624
ANDROID_SIGNALR_GUIDE.md
Normal file
@@ -0,0 +1,624 @@
|
||||
# راهنمای اتصال اپلیکیشن Android به SignalR برای Face Embedding
|
||||
|
||||
## 1. افزودن کتابخانه SignalR به پروژه Android
|
||||
|
||||
در فایل `build.gradle` (Module: app) خود، dependency زیر را اضافه کنید:
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
// SignalR for Android
|
||||
implementation 'com.microsoft.signalr:signalr:7.0.0'
|
||||
|
||||
// اگر از Kotlin استفاده میکنید:
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1'
|
||||
|
||||
// برای JSON پردازش:
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
}
|
||||
```
|
||||
|
||||
## 2. اضافه کردن Permission در AndroidManifest.xml
|
||||
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
```
|
||||
|
||||
## 3. کد Java/Kotlin برای اتصال به SignalR
|
||||
|
||||
### نسخه Java:
|
||||
|
||||
```java
|
||||
import com.microsoft.signalr.HubConnection;
|
||||
import com.microsoft.signalr.HubConnectionBuilder;
|
||||
import com.microsoft.signalr.HubConnectionState;
|
||||
import com.google.gson.JsonObject;
|
||||
import android.util.Log;
|
||||
|
||||
public class FaceEmbeddingSignalRClient {
|
||||
private static final String TAG = "FaceEmbeddingHub";
|
||||
private HubConnection hubConnection;
|
||||
private String serverUrl = "http://YOUR_SERVER_IP:PORT/trackingFaceEmbeddingHub"; // آدرس سرور خود را وارد کنید
|
||||
private long workshopId;
|
||||
|
||||
public FaceEmbeddingSignalRClient(long workshopId) {
|
||||
this.workshopId = workshopId;
|
||||
initializeSignalR();
|
||||
}
|
||||
|
||||
private void initializeSignalR() {
|
||||
// ایجاد اتصال SignalR
|
||||
hubConnection = HubConnectionBuilder
|
||||
.create(serverUrl)
|
||||
.build();
|
||||
|
||||
// دریافت رویداد ایجاد Embedding
|
||||
hubConnection.on("EmbeddingCreated", (data) -> {
|
||||
JsonObject jsonData = (JsonObject) data;
|
||||
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||
String employeeFullName = jsonData.get("employeeFullName").getAsString();
|
||||
String timestamp = jsonData.get("timestamp").getAsString();
|
||||
|
||||
Log.d(TAG, "Embedding Created - Employee: " + employeeFullName + " (ID: " + employeeId + ")");
|
||||
|
||||
// اینجا میتوانید دادههای جدید را از سرور بگیرید یا UI را بروزرسانی کنید
|
||||
onEmbeddingCreated(employeeId, employeeFullName, timestamp);
|
||||
|
||||
}, JsonObject.class);
|
||||
|
||||
// دریافت رویداد حذف Embedding
|
||||
hubConnection.on("EmbeddingDeleted", (data) -> {
|
||||
JsonObject jsonData = (JsonObject) data;
|
||||
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||
String timestamp = jsonData.get("timestamp").getAsString();
|
||||
|
||||
Log.d(TAG, "Embedding Deleted - Employee ID: " + employeeId);
|
||||
onEmbeddingDeleted(employeeId, timestamp);
|
||||
|
||||
}, JsonObject.class);
|
||||
|
||||
// دریافت رویداد بهبود Embedding
|
||||
hubConnection.on("EmbeddingRefined", (data) -> {
|
||||
JsonObject jsonData = (JsonObject) data;
|
||||
long employeeId = jsonData.get("employeeId").getAsLong();
|
||||
String timestamp = jsonData.get("timestamp").getAsString();
|
||||
|
||||
Log.d(TAG, "Embedding Refined - Employee ID: " + employeeId);
|
||||
onEmbeddingRefined(employeeId, timestamp);
|
||||
|
||||
}, JsonObject.class);
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
if (hubConnection.getConnectionState() == HubConnectionState.DISCONNECTED) {
|
||||
hubConnection.start()
|
||||
.doOnComplete(() -> {
|
||||
Log.d(TAG, "Connected to SignalR Hub");
|
||||
joinWorkshopGroup();
|
||||
})
|
||||
.doOnError(error -> {
|
||||
Log.e(TAG, "Error connecting to SignalR: " + error.getMessage());
|
||||
})
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinWorkshopGroup() {
|
||||
// عضویت در گروه مخصوص این کارگاه
|
||||
hubConnection.send("JoinWorkshopGroup", workshopId);
|
||||
Log.d(TAG, "Joined workshop group: " + workshopId);
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (hubConnection.getConnectionState() == HubConnectionState.CONNECTED) {
|
||||
// خروج از گروه
|
||||
hubConnection.send("LeaveWorkshopGroup", workshopId);
|
||||
|
||||
hubConnection.stop();
|
||||
Log.d(TAG, "Disconnected from SignalR Hub");
|
||||
}
|
||||
}
|
||||
|
||||
// این متدها را در Activity/Fragment خود override کنید
|
||||
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||
// اینجا UI را بروزرسانی کنید یا داده جدید را بگیرید
|
||||
}
|
||||
|
||||
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||
// اینجا UI را بروزرسانی کنید
|
||||
}
|
||||
|
||||
protected void onEmbeddingRefined(long employeeId, String timestamp) {
|
||||
// اینجا UI را بروزرسانی کنید
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### نسخه Kotlin:
|
||||
|
||||
```kotlin
|
||||
import com.microsoft.signalr.HubConnection
|
||||
import com.microsoft.signalr.HubConnectionBuilder
|
||||
import com.microsoft.signalr.HubConnectionState
|
||||
import com.google.gson.JsonObject
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class FaceEmbeddingSignalRClient(private val workshopId: Long) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "FaceEmbeddingHub"
|
||||
}
|
||||
|
||||
private lateinit var hubConnection: HubConnection
|
||||
private val serverUrl = "http://YOUR_SERVER_IP:PORT/trackingFaceEmbeddingHub" // آدرس سرور خود را وارد کنید
|
||||
|
||||
init {
|
||||
initializeSignalR()
|
||||
}
|
||||
|
||||
private fun initializeSignalR() {
|
||||
hubConnection = HubConnectionBuilder
|
||||
.create(serverUrl)
|
||||
.build()
|
||||
|
||||
// دریافت رویداد ایجاد Embedding
|
||||
hubConnection.on("EmbeddingCreated", { data: JsonObject ->
|
||||
val employeeId = data.get("employeeId").asLong
|
||||
val employeeFullName = data.get("employeeFullName").asString
|
||||
val timestamp = data.get("timestamp").asString
|
||||
|
||||
Log.d(TAG, "Embedding Created - Employee: $employeeFullName (ID: $employeeId)")
|
||||
onEmbeddingCreated(employeeId, employeeFullName, timestamp)
|
||||
}, JsonObject::class.java)
|
||||
|
||||
// دریافت رویداد حذف Embedding
|
||||
hubConnection.on("EmbeddingDeleted", { data: JsonObject ->
|
||||
val employeeId = data.get("employeeId").asLong
|
||||
val timestamp = data.get("timestamp").asString
|
||||
|
||||
Log.d(TAG, "Embedding Deleted - Employee ID: $employeeId")
|
||||
onEmbeddingDeleted(employeeId, timestamp)
|
||||
}, JsonObject::class.java)
|
||||
|
||||
// دریافت رویداد بهبود Embedding
|
||||
hubConnection.on("EmbeddingRefined", { data: JsonObject ->
|
||||
val employeeId = data.get("employeeId").asLong
|
||||
val timestamp = data.get("timestamp").asString
|
||||
|
||||
Log.d(TAG, "Embedding Refined - Employee ID: $employeeId")
|
||||
onEmbeddingRefined(employeeId, timestamp)
|
||||
}, JsonObject::class.java)
|
||||
}
|
||||
|
||||
fun connect() {
|
||||
if (hubConnection.connectionState == HubConnectionState.DISCONNECTED) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
hubConnection.start().blockingAwait()
|
||||
Log.d(TAG, "Connected to SignalR Hub")
|
||||
joinWorkshopGroup()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error connecting to SignalR: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun joinWorkshopGroup() {
|
||||
hubConnection.send("JoinWorkshopGroup", workshopId)
|
||||
Log.d(TAG, "Joined workshop group: $workshopId")
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
if (hubConnection.connectionState == HubConnectionState.CONNECTED) {
|
||||
hubConnection.send("LeaveWorkshopGroup", workshopId)
|
||||
hubConnection.stop()
|
||||
Log.d(TAG, "Disconnected from SignalR Hub")
|
||||
}
|
||||
}
|
||||
|
||||
// این متدها را override کنید
|
||||
open fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||
// اینجا UI را بروزرسانی کنید یا داده جدید را بگیرید
|
||||
}
|
||||
|
||||
open fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||
// اینجا UI را بروزرسانی کنید
|
||||
}
|
||||
|
||||
open fun onEmbeddingRefined(employeeId: Long, timestamp: String) {
|
||||
// اینجا UI را بروزرسانی کنید
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. استفاده در Activity یا Fragment
|
||||
|
||||
### مثال با Login و دریافت WorkshopId
|
||||
|
||||
#### Java:
|
||||
```java
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_login);
|
||||
|
||||
Button btnLogin = findViewById(R.id.btnLogin);
|
||||
btnLogin.setOnClickListener(v -> performLogin());
|
||||
}
|
||||
|
||||
private void performLogin() {
|
||||
// فراخوانی API لاگین
|
||||
// فرض کنید response شامل workshopId است
|
||||
|
||||
// مثال ساده (باید از Retrofit یا کتابخانه مشابه استفاده کنید):
|
||||
// LoginResponse response = apiService.login(username, password);
|
||||
// long workshopId = response.getWorkshopId();
|
||||
|
||||
long workshopId = 123; // این را از response دریافت کنید
|
||||
|
||||
// ذخیره workshopId
|
||||
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||
prefs.edit().putLong("workshopId", workshopId).apply();
|
||||
|
||||
// رفتن به صفحه اصلی
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private FaceEmbeddingSignalRClient signalRClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// دریافت workshopId از SharedPreferences
|
||||
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||
long workshopId = prefs.getLong("workshopId", 0);
|
||||
|
||||
if (workshopId == 0) {
|
||||
// اگر workshopId وجود نداره، برگرد به صفحه لاگین
|
||||
Intent intent = new Intent(this, LoginActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// ایجاد و اتصال SignalR
|
||||
signalRClient = new FaceEmbeddingSignalRClient(workshopId) {
|
||||
@Override
|
||||
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||
runOnUiThread(() -> {
|
||||
// بروزرسانی UI
|
||||
Toast.makeText(MainActivity.this,
|
||||
"Embedding ایجاد شد برای: " + employeeFullName,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
// دریافت دادههای جدید از API
|
||||
refreshEmployeeList();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||
runOnUiThread(() -> {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEmbeddingRefined(long employeeId, String timestamp) {
|
||||
runOnUiThread(() -> {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
signalRClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (signalRClient != null) {
|
||||
signalRClient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshEmployeeList() {
|
||||
// دریافت لیست جدید کارمندان از API
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Kotlin:
|
||||
```kotlin
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_login)
|
||||
|
||||
val btnLogin = findViewById<Button>(R.id.btnLogin)
|
||||
btnLogin.setOnClickListener { performLogin() }
|
||||
}
|
||||
|
||||
private fun performLogin() {
|
||||
// فراخوانی API لاگین
|
||||
// فرض کنید response شامل workshopId است
|
||||
|
||||
// مثال ساده (باید از Retrofit یا کتابخانه مشابه استفاده کنید):
|
||||
// val response = apiService.login(username, password)
|
||||
// val workshopId = response.workshopId
|
||||
|
||||
val workshopId = 123L // این را از response دریافت کنید
|
||||
|
||||
// ذخیره workshopId
|
||||
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||
prefs.edit().putLong("workshopId", workshopId).apply()
|
||||
|
||||
// رفتن به صفحه اصلی
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var signalRClient: FaceEmbeddingSignalRClient
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
// دریافت workshopId از SharedPreferences
|
||||
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||
val workshopId = prefs.getLong("workshopId", 0L)
|
||||
|
||||
if (workshopId == 0L) {
|
||||
// اگر workshopId وجود نداره، برگرد به صفحه لاگین
|
||||
val intent = Intent(this, LoginActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
// ایجاد و اتصال SignalR
|
||||
signalRClient = object : FaceEmbeddingSignalRClient(workshopId) {
|
||||
override fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||
runOnUiThread {
|
||||
// بروزرسانی UI
|
||||
Toast.makeText(this@MainActivity,
|
||||
"Embedding ایجاد شد برای: $employeeFullName",
|
||||
Toast.LENGTH_SHORT).show()
|
||||
|
||||
// دریافت دادههای جدید از API
|
||||
refreshEmployeeList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||
runOnUiThread {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEmbeddingRefined(employeeId: Long, timestamp: String) {
|
||||
runOnUiThread {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signalRClient.connect()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
signalRClient.disconnect()
|
||||
}
|
||||
|
||||
private fun refreshEmployeeList() {
|
||||
// دریافت لیست جدید کارمندان از API
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### مثال ساده بدون Login:
|
||||
اگر workshopId را از قبل میدانید:
|
||||
|
||||
#### Java:
|
||||
```java
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private FaceEmbeddingSignalRClient signalRClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
long workshopId = 123; // شناسه کارگاه خود را وارد کنید
|
||||
|
||||
signalRClient = new FaceEmbeddingSignalRClient(workshopId) {
|
||||
@Override
|
||||
protected void onEmbeddingCreated(long employeeId, String employeeFullName, String timestamp) {
|
||||
runOnUiThread(() -> {
|
||||
// بروزرسانی UI
|
||||
Toast.makeText(MainActivity.this,
|
||||
"Embedding ایجاد شد برای: " + employeeFullName,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
// دریافت دادههای جدید از API
|
||||
refreshEmployeeList();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEmbeddingDeleted(long employeeId, String timestamp) {
|
||||
runOnUiThread(() -> {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
signalRClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (signalRClient != null) {
|
||||
signalRClient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshEmployeeList() {
|
||||
// دریافت لیست جدید کارمندان از API
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Kotlin:
|
||||
```kotlin
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var signalRClient: FaceEmbeddingSignalRClient
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val workshopId = 123L // شناسه کارگاه خود را وارد کنید
|
||||
|
||||
signalRClient = object : FaceEmbeddingSignalRClient(workshopId) {
|
||||
override fun onEmbeddingCreated(employeeId: Long, employeeFullName: String, timestamp: String) {
|
||||
runOnUiThread {
|
||||
// بروزرسانی UI
|
||||
Toast.makeText(this@MainActivity,
|
||||
"Embedding ایجاد شد برای: $employeeFullName",
|
||||
Toast.LENGTH_SHORT).show()
|
||||
|
||||
// دریافت دادههای جدید از API
|
||||
refreshEmployeeList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEmbeddingDeleted(employeeId: Long, timestamp: String) {
|
||||
runOnUiThread {
|
||||
// بروزرسانی UI
|
||||
refreshEmployeeList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signalRClient.connect()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
signalRClient.disconnect()
|
||||
}
|
||||
|
||||
private fun refreshEmployeeList() {
|
||||
// دریافت لیست جدید کارمندان از API
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. نکات مهم
|
||||
|
||||
### آدرس سرور
|
||||
- اگر روی شبیهساز اندروید تست میکنید و سرور روی localhost اجرا میشود، از آدرس `http://10.0.2.2:PORT` استفاده کنید
|
||||
- اگر روی دستگاه فیزیکی تست میکنید، از آدرس IP شبکه محلی سرور استفاده کنید (مثل `http://192.168.1.100:PORT`)
|
||||
- PORT پیشفرض معمولاً 5000 یا 5001 است (بسته به کانفیگ پروژه شما)
|
||||
|
||||
### دریافت WorkshopId از Login
|
||||
بعد از login موفق، workshopId را از سرور دریافت کنید و در SharedPreferences یا یک Singleton ذخیره کنید:
|
||||
|
||||
```java
|
||||
// بعد از login موفق
|
||||
SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
|
||||
prefs.edit().putLong("workshopId", workshopId).apply();
|
||||
|
||||
// استفاده در Activity
|
||||
long workshopId = prefs.getLong("workshopId", 0);
|
||||
```
|
||||
|
||||
یا در Kotlin:
|
||||
|
||||
```kotlin
|
||||
// بعد از login موفق
|
||||
val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
|
||||
prefs.edit().putLong("workshopId", workshopId).apply()
|
||||
|
||||
// استفاده در Activity
|
||||
val workshopId = prefs.getLong("workshopId", 0L)
|
||||
```
|
||||
|
||||
### مدیریت اتصال
|
||||
برای reconnection خودکار:
|
||||
|
||||
```java
|
||||
hubConnection.onClosed(exception -> {
|
||||
Log.e(TAG, "Connection closed. Attempting to reconnect...");
|
||||
new Handler().postDelayed(() -> connect(), 5000); // تلاش مجدد بعد از 5 ثانیه
|
||||
});
|
||||
```
|
||||
|
||||
### Thread Safety
|
||||
همیشه UI updates را در main thread انجام دهید:
|
||||
|
||||
```java
|
||||
runOnUiThread(() -> {
|
||||
// UI updates here
|
||||
});
|
||||
```
|
||||
|
||||
## 6. تست اتصال
|
||||
|
||||
برای تست میتوانید:
|
||||
1. اپلیکیشن را اجرا کنید
|
||||
2. از طریق Postman یا Swagger یک Embedding ایجاد کنید
|
||||
3. باید در Logcat پیام "Embedding Created" را ببینید
|
||||
|
||||
## 7. خطایابی (Debugging)
|
||||
|
||||
برای دیدن جزئیات بیشتر:
|
||||
|
||||
```java
|
||||
hubConnection = HubConnectionBuilder
|
||||
.create(serverUrl)
|
||||
.withHttpConnectionOptions(options -> {
|
||||
options.setLogging(LogLevel.TRACE);
|
||||
})
|
||||
.build();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## خلاصه Endpoints
|
||||
|
||||
| نوع رویداد | متد SignalR | پارامترهای دریافتی |
|
||||
|-----------|-------------|---------------------|
|
||||
| ایجاد Embedding | `EmbeddingCreated` | workshopId, employeeId, employeeFullName, timestamp |
|
||||
| حذف Embedding | `EmbeddingDeleted` | workshopId, employeeId, timestamp |
|
||||
| بهبود Embedding | `EmbeddingRefined` | workshopId, employeeId, timestamp |
|
||||
|
||||
| متد ارسالی | پارامتر | توضیحات |
|
||||
|-----------|---------|---------|
|
||||
| `JoinWorkshopGroup` | workshopId | عضویت در گروه کارگاه |
|
||||
| `LeaveWorkshopGroup` | workshopId | خروج از گروه کارگاه |
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AssemblyName>BackgroundInstitutionContract.Task</AssemblyName>
|
||||
<RootNamespace>BackgroundInstitutionContract.Task</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
|
||||
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" />
|
||||
<ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" />
|
||||
<ProjectReference Include="..\..\Query.Bootstrapper\Query.Bootstrapper.csproj" />
|
||||
<ProjectReference Include="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
using _0_Framework.Application;
|
||||
using Company.Domain.ContarctingPartyAgg;
|
||||
using Company.Domain.InstitutionContractAgg;
|
||||
using Hangfire;
|
||||
|
||||
namespace BackgroundInstitutionContract.Task.Jobs;
|
||||
|
||||
public class JobSchedulerRegistrator
|
||||
{
|
||||
private readonly IBackgroundJobClient _backgroundJobClient;
|
||||
private readonly SmsReminder _smsReminder;
|
||||
private readonly IInstitutionContractRepository _institutionContractRepository;
|
||||
private static DateTime? _lastRunCreateTransaction;
|
||||
private static DateTime? _lastRunSendMonthlySms;
|
||||
|
||||
|
||||
public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient, IInstitutionContractRepository institutionContractRepository)
|
||||
{
|
||||
_smsReminder = smsReminder;
|
||||
_backgroundJobClient = backgroundJobClient;
|
||||
_institutionContractRepository = institutionContractRepository;
|
||||
}
|
||||
|
||||
public void Register()
|
||||
{
|
||||
|
||||
RecurringJob.AddOrUpdate(
|
||||
"InstitutionContract.CreateFinancialTransaction",
|
||||
() => CreateFinancialTransaction(),
|
||||
"*/30 * * * *" // هر 30 دقیقه یکبار چک کن
|
||||
);
|
||||
|
||||
RecurringJob.AddOrUpdate(
|
||||
"InstitutionContract.SendMonthlySms",
|
||||
() => SendFirstDayOfMonthSms(),
|
||||
"*/20 * * * *" // هر 30 دقیقه یکبار چک کن
|
||||
);
|
||||
|
||||
RecurringJob.AddOrUpdate(
|
||||
"InstitutionContract.SendReminderSms",
|
||||
() => SendReminderSms(),
|
||||
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
|
||||
);
|
||||
RecurringJob.AddOrUpdate(
|
||||
"InstitutionContract.SendBlockSms",
|
||||
() => SendBlockSms(),
|
||||
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد سند بدهی ماهیانه برای قراداد مالی
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisableConcurrentExecution(timeoutInSeconds: 1200)]
|
||||
public async System.Threading.Tasks.Task CreateFinancialTransaction()
|
||||
{
|
||||
var now =DateTime.Now;
|
||||
var endOfMonth = now.ToFarsi().FindeEndOfMonth();
|
||||
var endOfMonthGr = endOfMonth.ToGeorgianDateTime();
|
||||
|
||||
if (now.Date == endOfMonthGr.Date && now.Hour >= 2 && now.Hour < 4 &&
|
||||
now.Date != _lastRunCreateTransaction?.Date)
|
||||
{
|
||||
|
||||
var month = endOfMonth.Substring(5, 2);
|
||||
var year = endOfMonth.Substring(0, 4);
|
||||
var monthName = month.ToFarsiMonthByNumber();
|
||||
var description = $"{monthName} {year}";
|
||||
|
||||
|
||||
|
||||
var endnew = ($"{endOfMonth.Substring(0, 8)}01").FindeEndOfMonth();
|
||||
|
||||
var endNewGr = endnew.ToGeorgianDateTime();
|
||||
var endNewFa = endNewGr.ToFarsi();
|
||||
|
||||
try
|
||||
{
|
||||
await _institutionContractRepository.CreateTransactionForInstitutionContracts(endNewGr, endNewFa, description);
|
||||
_lastRunCreateTransaction = now;
|
||||
Console.WriteLine("CreateTransAction executed");
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//_smsService.Alarm("09114221321", "خطا-ایجاد سند مالی");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک صورت حساب ماهانه
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisableConcurrentExecution(timeoutInSeconds: 600)]
|
||||
public async System.Threading.Tasks.Task SendFirstDayOfMonthSms()
|
||||
{
|
||||
//var now = new DateTime(2025,11,21, 10,30,0);
|
||||
var now = DateTime.Now;
|
||||
var endOfMonth = now.ToFarsi().FindeEndOfMonth();
|
||||
var endOfMonthGr = endOfMonth.ToGeorgianDateTime();
|
||||
|
||||
if (now.Date == endOfMonthGr.Date && now.Hour >= 10 && now.Hour < 11 &&
|
||||
now.Date != _lastRunSendMonthlySms?.Date)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await _institutionContractRepository.SendMonthlySms(now);
|
||||
_lastRunSendMonthlySms = now;
|
||||
Console.WriteLine("Send Monthly sms executed");
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//_smsService.Alarm("09114221321", "خطا-ایجاد سند مالی");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک یاد آور بدهی
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisableConcurrentExecution(timeoutInSeconds: 1200)]
|
||||
public async System.Threading.Tasks.Task SendReminderSms()
|
||||
{
|
||||
await _institutionContractRepository.SendReminderSmsForBackgroundTask();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک مسدودی
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisableConcurrentExecution(timeoutInSeconds: 100)]
|
||||
public async System.Threading.Tasks.Task SendBlockSms()
|
||||
{
|
||||
await _institutionContractRepository.SendBlockSmsForBackgroundTask();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<AccountViewModel>() { 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; }
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
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.App.Contracts.Hubs;
|
||||
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<IPasswordHasher, PasswordHasher>();
|
||||
builder.Services.AddTransient<IAuthHelper, AuthHelper>();
|
||||
builder.Services.AddTransient<ISmsService, SmsService>();
|
||||
builder.Services.AddTransient<IUidService, UidService>();
|
||||
builder.Services.AddTransient<IFileUploader, FileUploader>();
|
||||
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
|
||||
|
||||
#region MongoDb
|
||||
|
||||
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");
|
||||
var mongoDbSettings = mongoConnectionSection.Get<MongoDbConfig>();
|
||||
var mongoClient = new MongoClient(mongoDbSettings.ConnectionString);
|
||||
var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName);
|
||||
|
||||
builder.Services.AddSingleton<IMongoDatabase>(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();
|
||||
builder.Services.AddSignalR();
|
||||
|
||||
var app = builder.Build();
|
||||
app.MapHub<SendSmsHub>("/sendSmsHub");
|
||||
|
||||
app.MapHangfireDashboard();
|
||||
app.MapGet("/", () => "Hello World!");
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var jobScheduler = scope.ServiceProvider.GetRequiredService<JobSchedulerRegistrator>();
|
||||
jobScheduler.Register();
|
||||
}
|
||||
|
||||
app.Run();
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"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;",
|
||||
"HangfireDb": "Data Source=185.208.175.186;Initial Catalog=hangfire_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
|
||||
},
|
||||
|
||||
"GoogleRecaptchaV3": {
|
||||
"SiteKey": "6Lfhp_AnAAAAAB79WkrMoHd1k8ir4m8VvfjE7FTH",
|
||||
"SecretKey": "6Lfhp_AnAAAAANjDDY6DPrbbUQS7k6ZCRmrVP5Lb"
|
||||
},
|
||||
"SmsSecrets": {
|
||||
"ApiKey": "Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa",
|
||||
"SecretKey": "dadmehr"
|
||||
},
|
||||
"Domain": ".gozareshgir.ir",
|
||||
"MongoDb": {
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "Gozareshgir"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
|
||||
//local
|
||||
//"MesbahDb": "Data Source=.;Initial Catalog=mesbah_db;Integrated Security=True;TrustServerCertificate=true;",
|
||||
"MesbahDb": "Data Source=185.208.175.186;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;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;",
|
||||
"TestDb": "Data Source=185.208.175.186;Initial Catalog=TestDb;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;",
|
||||
//"MesbahDb": "Data Source=.\\MSSQLSERVER2019;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=mesbah_db;Password=sa142857$@;"
|
||||
//"HangfireDb": "Data Source=.;Initial Catalog=hangfire_db;Integrated Security=True;TrustServerCertificate=true;",
|
||||
"HangfireDb": "Data Source=185.208.175.186;Initial Catalog=hangfire_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
|
||||
},
|
||||
"MongoDb": {
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "Gozareshgir"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
|
||||
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" />
|
||||
<ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" />
|
||||
<ProjectReference Include="..\..\Query.Bootstrapper\Query.Bootstrapper.csproj" />
|
||||
<ProjectReference Include="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
32
BackgroundJobs/BackgroundJobs.Task/FileUploader.cs
Normal file
32
BackgroundJobs/BackgroundJobs.Task/FileUploader.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using _0_Framework.Application;
|
||||
|
||||
namespace BackgroundJobs.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}";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Hangfire;
|
||||
|
||||
namespace BackgroundJobs.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.SmsReminderChecker",
|
||||
() => SmsReminderCheckAndSchedule(),
|
||||
"*/5 * * * *" // هر 5 دقیقه یکبار چک کن
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
BackgroundJobs/BackgroundJobs.Task/Jobs/SmsReminder.cs
Normal file
116
BackgroundJobs/BackgroundJobs.Task/Jobs/SmsReminder.cs
Normal file
@@ -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 BackgroundJobs.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<AccountViewModel>() { 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; }
|
||||
}
|
||||
24
BackgroundJobs/BackgroundJobs.Task/JobsBootstrapper.cs
Normal file
24
BackgroundJobs/BackgroundJobs.Task/JobsBootstrapper.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using BackgroundJobs.Task.Jobs;
|
||||
|
||||
namespace BackgroundJobs.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
BackgroundJobs/BackgroundJobs.Task/Program.cs
Normal file
59
BackgroundJobs/BackgroundJobs.Task/Program.cs
Normal file
@@ -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 BackgroundJobs.Task;
|
||||
using BackgroundJobs.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<IPasswordHasher, PasswordHasher>();
|
||||
builder.Services.AddTransient<IAuthHelper, AuthHelper>();
|
||||
builder.Services.AddTransient<ISmsService, SmsService>();
|
||||
builder.Services.AddTransient<IUidService, UidService>();
|
||||
builder.Services.AddTransient<IFileUploader, FileUploader>();
|
||||
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
|
||||
|
||||
#region MongoDb
|
||||
|
||||
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");
|
||||
var mongoDbSettings = mongoConnectionSection.Get<MongoDbConfig>();
|
||||
var mongoClient = new MongoClient(mongoDbSettings.ConnectionString);
|
||||
var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName);
|
||||
|
||||
builder.Services.AddSingleton<IMongoDatabase>(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<JobSchedulerRegistrator>();
|
||||
jobScheduler.Register();
|
||||
}
|
||||
|
||||
app.Run();
|
||||
@@ -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:7222;http://localhost:5216",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
9
BackgroundJobs/BackgroundJobs.Task/appsettings.json
Normal file
9
BackgroundJobs/BackgroundJobs.Task/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@@ -75,5 +75,5 @@ public interface IPersonalContractingPartyRepository :IRepository<long, Personal
|
||||
Task<GetLegalContractingPartyDetailsViewModel> GetLegalDetails(long id);
|
||||
|
||||
Task<PersonalContractingParty> GetByNationalCode(string nationalCode);
|
||||
Task<PersonalContractingParty> GetByRegisterId(string registerId);
|
||||
Task<PersonalContractingParty> GetByNationalId(string registerId);
|
||||
}
|
||||
@@ -251,6 +251,35 @@ public class PersonalContractingParty : EntityBase
|
||||
this.IsAuthenticated = true;
|
||||
Phone = phone;
|
||||
}
|
||||
|
||||
public void UnAuthenticateRealEdit(string fName, string lName, string fatherName,string idNumber,
|
||||
string idNumberSeri, string idNumberSerial, string dateOfBirth, Gender gender,string phone)
|
||||
{
|
||||
this.FName = fName;
|
||||
this.LName = lName;
|
||||
this.FatherName = fatherName;
|
||||
this.IdNumberSeri = idNumberSeri;
|
||||
this.IdNumberSerial = idNumberSerial;
|
||||
this.DateOfBirth = !string.IsNullOrWhiteSpace(dateOfBirth) ? dateOfBirth.ToGeorgianDateTime() : null;
|
||||
this.IdNumber = idNumber;
|
||||
this.Gender = gender;
|
||||
Phone = phone;
|
||||
}
|
||||
|
||||
public void UnAuthenticateLegalEdit(string fName, string lName, string fatherName, string idNumber,
|
||||
string idNumberSeri,
|
||||
string idNumberSerial, string dateOfBirth, Gender gender, string phone)
|
||||
{
|
||||
CeoFName = fName;
|
||||
CeoLName = lName;
|
||||
this.FatherName = fatherName;
|
||||
this.IdNumberSeri = idNumberSeri;
|
||||
this.IdNumberSerial = idNumberSerial;
|
||||
this.DateOfBirth = !string.IsNullOrWhiteSpace(dateOfBirth) ? dateOfBirth.ToGeorgianDateTime() : null;
|
||||
this.IdNumber = idNumber;
|
||||
this.Gender = gender;
|
||||
Phone = phone;
|
||||
}
|
||||
|
||||
public void RegisterComplete(string fatherName, string idNumberSeri, string idNumberSerial, DateTime dateOfBirth, Gender gender)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||||
@@ -33,7 +34,8 @@ public class CustomizeCheckout : EntityBase
|
||||
ICollection<CustomizeCheckoutSalaryAid> customizeCheckoutSalaryAids,
|
||||
ICollection<CustomizeCheckoutReward> customizeCheckoutRewards, TimeSpan lateToWorkValue, double settingSalary,
|
||||
double dailyWage, WorkshopShiftStatus shiftStatus, IrregularShift irregularShift,
|
||||
ICollection<CustomizeRotatingShift> customizeRotatingShifts, ICollection<CustomizeCheckoutRegularShift> employeeSettingsShifts)
|
||||
ICollection<CustomizeRotatingShift> customizeRotatingShifts, ICollection<CustomizeCheckoutRegularShift> employeeSettingsShifts,
|
||||
ICollection<CheckoutDynamicDeductionItem> checkoutDynamicDeductions)
|
||||
{
|
||||
YearInt = Convert.ToInt32(contractStart.ToFarsi().Substring(0, 4));
|
||||
MonthInt = Convert.ToInt32(contractStart.ToFarsi().Substring(5, 2));
|
||||
@@ -83,6 +85,7 @@ public class CustomizeCheckout : EntityBase
|
||||
IrregularShift = irregularShift;
|
||||
CustomizeRotatingShifts = customizeRotatingShifts;
|
||||
RegularShifts = employeeSettingsShifts;
|
||||
CheckoutDynamicDeductions = checkoutDynamicDeductions;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +289,7 @@ public class CustomizeCheckout : EntityBase
|
||||
public ICollection<CustomizeCheckoutLoanInstallments> CustomizeCheckoutLoanInstallments { get; set; }
|
||||
public ICollection<CustomizeCheckoutSalaryAid> CustomizeCheckoutSalaryAids { get; set; }
|
||||
public ICollection<CustomizeCheckoutReward> CustomizeCheckoutRewards { get; set; }
|
||||
public ICollection<CheckoutDynamicDeductionItem> CheckoutDynamicDeductions { get; private set; }
|
||||
|
||||
public IrregularShift IrregularShift { get; set; }
|
||||
public ICollection<CustomizeRotatingShift> CustomizeRotatingShifts { get; set; }
|
||||
|
||||
@@ -9,6 +9,7 @@ using Company.Domain.CustomizeCheckoutTempAgg.ValueObjects;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||||
using System.Linq;
|
||||
using _0_Framework.Application.Enums;
|
||||
|
||||
|
||||
namespace Company.Domain.CustomizeCheckoutTempAgg;
|
||||
@@ -21,7 +22,8 @@ public class CustomizeCheckoutTemp : EntityBase
|
||||
{
|
||||
LateToWorkValue = lateToWorkValue;
|
||||
}
|
||||
public CustomizeCheckoutTemp(DateTime contractStart, DateTime contractEnd, long employeeId, string employeeFName,
|
||||
public CustomizeCheckoutTemp(
|
||||
DateTime contractStart, DateTime contractEnd, long employeeId, string employeeFName,
|
||||
string employeeLName, DateTime employeeDateOfBirth,
|
||||
string employeeNationalCode, string workshopFullName, long workshopId, long? contractId,
|
||||
double monthlySalary, double fridayPay, double overTimePay, double baseYearsPay, double bonusesPay,
|
||||
@@ -37,7 +39,8 @@ public class CustomizeCheckoutTemp : EntityBase
|
||||
ICollection<CustomizeCheckoutTempSalaryAid> customizeCheckoutSalaryAids,
|
||||
ICollection<CustomizeCheckoutTempReward> customizeCheckoutRewards,
|
||||
TimeSpan lateToWorkValue, double settingSalary, double dailyWage, WorkshopShiftStatus shiftStatus, IrregularShift irregularShift,
|
||||
ICollection<CustomizeRotatingShift> customizeRotatingShifts, ICollection<CustomizeCheckoutRegularShift> employeeSettingsShifts)
|
||||
ICollection<CustomizeRotatingShift> customizeRotatingShifts, ICollection<CustomizeCheckoutRegularShift> employeeSettingsShifts,
|
||||
ICollection<CheckoutDynamicDeductionItem> checkoutDynamicDeductions)
|
||||
{
|
||||
YearInt = Convert.ToInt32(contractStart.ToFarsi().Substring(0, 4));
|
||||
MonthInt = Convert.ToInt32(contractStart.ToFarsi().Substring(5, 2));
|
||||
@@ -87,6 +90,7 @@ public class CustomizeCheckoutTemp : EntityBase
|
||||
IrregularShift = irregularShift;
|
||||
CustomizeRotatingShifts = customizeRotatingShifts;
|
||||
RegularShifts = employeeSettingsShifts;
|
||||
CheckoutDynamicDeductions = checkoutDynamicDeductions;
|
||||
}
|
||||
|
||||
#region Getters
|
||||
@@ -123,6 +127,7 @@ public class CustomizeCheckoutTemp : EntityBase
|
||||
public IrregularShift IrregularShift { get; set; }
|
||||
public ICollection<CustomizeRotatingShift> CustomizeRotatingShifts { get; set; }
|
||||
public ICollection<CustomizeCheckoutRegularShift> RegularShifts { get; set; }
|
||||
public ICollection<CheckoutDynamicDeductionItem> CheckoutDynamicDeductions { get; private set; }
|
||||
|
||||
|
||||
#endregion
|
||||
@@ -389,4 +394,4 @@ public class CustomizeCheckoutTemp : EntityBase
|
||||
{
|
||||
HasAmountConflict = hasConflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
108
Company.Domain/FinancialInvoiceAgg/FinancialInvoice.cs
Normal file
108
Company.Domain/FinancialInvoiceAgg/FinancialInvoice.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _0_Framework.Domain;
|
||||
using Company.Domain.PaymentTransactionAgg;
|
||||
using CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
namespace Company.Domain.FinancialInvoiceAgg;
|
||||
|
||||
public class FinancialInvoice : EntityBase
|
||||
{
|
||||
|
||||
public string InvoiceNumber { get; private set; }
|
||||
public string Description { get; set; }
|
||||
public FinancialInvoiceStatus Status { get; private set; }
|
||||
public DateTime? PaidAt { get; private set; }
|
||||
public double Amount { get; private set; }
|
||||
public Guid PublicId { get; private set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public List<PaymentTransaction> PaymentTransactions { get; private set; }
|
||||
public long ContractingPartyId { get; private set; }
|
||||
|
||||
public List<FinancialInvoiceItem> Items { get; private set; }
|
||||
|
||||
public FinancialInvoice(double amount, long contractingPartyId, string description)
|
||||
{
|
||||
InvoiceNumber = GenerateInvoiceNumber();
|
||||
Status = FinancialInvoiceStatus.Unpaid;
|
||||
Amount = amount;
|
||||
PublicId = Guid.NewGuid();
|
||||
ContractingPartyId = contractingPartyId;
|
||||
Description = description;
|
||||
IsActive = true;
|
||||
Items = [];
|
||||
PaymentTransactions = [];
|
||||
}
|
||||
|
||||
public void AddItem(FinancialInvoiceItem item)
|
||||
{
|
||||
Items ??= [];
|
||||
|
||||
Items.Add(item);
|
||||
}
|
||||
|
||||
public void SetItems(List<FinancialInvoiceItem> items)
|
||||
{
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public void SetPaid(DateTime paidAt)
|
||||
{
|
||||
Status = FinancialInvoiceStatus.Paid;
|
||||
PaidAt = paidAt;
|
||||
}
|
||||
public void SetUnpaid()
|
||||
{
|
||||
Status = FinancialInvoiceStatus.Unpaid;
|
||||
PaidAt = null;
|
||||
}
|
||||
public void SetCancelled()
|
||||
{
|
||||
Status = FinancialInvoiceStatus.Cancelled;
|
||||
PaidAt = null;
|
||||
}
|
||||
public void SetRefunded()
|
||||
{
|
||||
Status = FinancialInvoiceStatus.Refunded;
|
||||
PaidAt = null;
|
||||
}
|
||||
|
||||
public void DeActivate()
|
||||
{
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
public void SetInvoiceNumber(string invoiceNumber)
|
||||
{
|
||||
InvoiceNumber = invoiceNumber;
|
||||
}
|
||||
|
||||
private string GenerateInvoiceNumber()
|
||||
{
|
||||
var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||
var random = new Random().Next(1000, 9999);
|
||||
return $"GZ_{timestamp}{random}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FinancialInvoiceItem : EntityBase
|
||||
{
|
||||
public string Description { get; private set; }
|
||||
public double Amount { get; private set; }
|
||||
public FinancialInvoiceItemType Type { get; set; }
|
||||
public long EntityId { get; set; }
|
||||
public FinancialInvoice FinancialInvoice { get; set; }
|
||||
public long FinancialInvoiceId { get; set; }
|
||||
public FinancialInvoiceItem(string description, double amount,
|
||||
long financialInvoiceId, FinancialInvoiceItemType type, long entityId)
|
||||
{
|
||||
Description = description;
|
||||
Amount = amount;
|
||||
FinancialInvoiceId = financialInvoiceId;
|
||||
Type = type;
|
||||
EntityId = entityId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Domain;
|
||||
using CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
namespace Company.Domain.FinancialInvoiceAgg;
|
||||
|
||||
public interface IFinancialInvoiceRepository : IRepository<long, FinancialInvoice>
|
||||
{
|
||||
EditFinancialInvoice GetDetails(long id);
|
||||
List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel);
|
||||
Task<FinancialInvoice> GetUnPaidByEntityId(long entityId, FinancialInvoiceItemType financialInvoiceItemType);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Domain;
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using Company.Domain.FinancialTransactionAgg;
|
||||
|
||||
namespace Company.Domain.FinancialStatmentAgg;
|
||||
|
||||
@@ -22,6 +22,8 @@ public interface IFinancialStatmentRepository : IRepository<long, FinancialStatm
|
||||
Task<OperationResult<ClientFinancialStatementViewModel>> GetDetailsByPublicId(string publicId);
|
||||
Task<GetFinancialStatementBalanceAmount> GetBalanceAmount(long id);
|
||||
Task<double> GetClientDebtAmount(long accountId);
|
||||
Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel);
|
||||
Task<double> GetClientDebtAmountByContractingPartyId(long contractingPartyId);
|
||||
|
||||
Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel);
|
||||
Task<FinancialStatment> GetByContractingPartyId(long contractingPartyId);
|
||||
}
|
||||
@@ -26,6 +26,35 @@ public class FinancialTransaction : EntityBase
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد از طرف بک گراند سرویس
|
||||
/// </summary>
|
||||
/// <param name="financialStatementId"></param>
|
||||
/// <param name="tdateGr"></param>
|
||||
/// <param name="tdateFa"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <param name="typeOfTransaction"></param>
|
||||
/// <param name="descriptionOption"></param>
|
||||
/// <param name="deptor"></param>
|
||||
/// <param name="creditor"></param>
|
||||
/// <param name="balance"></param>
|
||||
/// <param name="sentSms"></param>
|
||||
public FinancialTransaction(long financialStatementId, DateTime tdateGr, string tdateFa, string description,
|
||||
string typeOfTransaction, string descriptionOption, double deptor, double creditor, double balance,
|
||||
bool sentSms)
|
||||
{
|
||||
FinancialStatementId = financialStatementId;
|
||||
TdateGr = tdateGr;
|
||||
TdateFa = tdateFa;
|
||||
Description = description;
|
||||
TypeOfTransaction = typeOfTransaction;
|
||||
DescriptionOption = descriptionOption;
|
||||
Deptor = deptor;
|
||||
Creditor = creditor;
|
||||
Balance = balance;
|
||||
SentSms = sentSms;
|
||||
}
|
||||
|
||||
public long FinancialStatementId { get; private set; }
|
||||
public DateTime TdateGr { get; private set; }
|
||||
public string TdateFa { get; private set; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain;
|
||||
using CompanyManagment.App.Contracts.InstitutionContract;
|
||||
using CompanyManagment.App.Contracts.Workshop;
|
||||
@@ -44,7 +45,7 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
|
||||
/// <param name="endOfMonthGr"></param>
|
||||
/// <param name="endOfMonth"></param>
|
||||
/// <param name="description"></param>
|
||||
void RollcallServiceCreateTransaction();
|
||||
Task RollCallServiceCreateTransaction();
|
||||
|
||||
Task<PagedResult<GetInstitutionContractListItemsViewModel>> GetList(InstitutionContractListSearchModel searchModel);
|
||||
Task<GetInstitutionContractListStatsViewModel> GetListStats(InstitutionContractListSearchModel searchModel);
|
||||
@@ -55,6 +56,9 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
|
||||
void UpdateStatusIfNeeded(long institutionContractId);
|
||||
Task<GetInstitutionVerificationDetailsViewModel> GetVerificationDetails(Guid id);
|
||||
Task<InstitutionContract> GetByPublicIdAsync(Guid id);
|
||||
InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request);
|
||||
InstitutionContractDiscountResponse ResetDiscountCreate(InstitutionContractResetDiscountForCreateRequest request);
|
||||
|
||||
|
||||
#region Extension
|
||||
|
||||
@@ -62,9 +66,13 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
|
||||
Task<InstitutionContractExtensionWorkshopsResponse> GetExtensionWorkshops(InstitutionContractExtensionWorkshopsRequest request);
|
||||
Task<InstitutionContractExtensionPlanResponse> GetExtensionInstitutionPlan(InstitutionContractExtensionPlanRequest request);
|
||||
Task<InstitutionContractExtensionPaymentResponse> GetExtensionPaymentMethod(InstitutionContractExtensionPaymentRequest request);
|
||||
Task<InstitutionContractDiscountResponse> SetDiscountForExtension(
|
||||
InstitutionContractSetDiscountForExtensionRequest request);
|
||||
Task<InstitutionContractDiscountResponse> ResetDiscountForExtension(InstitutionContractResetDiscountForExtensionRequest request);
|
||||
|
||||
Task<OperationResult> ExtensionComplete(InstitutionContractExtensionCompleteRequest request);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Upgrade(Amendment)
|
||||
|
||||
@@ -77,4 +85,73 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
|
||||
|
||||
Task<List<InstitutionContractSelectListViewModel>> GetInstitutionContractSelectList(string search, string selected);
|
||||
Task<List<InstitutionContractPrintViewModel>> PrintAllAsync(List<long> ids);
|
||||
|
||||
|
||||
#region ReminderSMS
|
||||
/// <summary>
|
||||
/// دریافت لیست - ارسال پیامک
|
||||
/// فراخوانی از سمت بک گراند سرویس
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<bool> SendReminderSmsForBackgroundTask();
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک صورت حساب ماهانه
|
||||
/// </summary>
|
||||
/// <param name="now"></param>
|
||||
/// <returns></returns>
|
||||
Task SendMonthlySms(DateTime now);
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک مسدودی از طرف بک گراند سرویس
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task SendBlockSmsForBackgroundTask();
|
||||
|
||||
/// <summary>
|
||||
/// دریافت لیست واجد شرایط بلاک
|
||||
/// جهت ارسال پیامک مسدودی
|
||||
/// </summary>
|
||||
/// <param name="checkDate"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<BlockSmsListData>> GetBlockListData(DateTime checkDate);
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک مسدودی
|
||||
/// </summary>
|
||||
/// <param name="smsListData"></param>
|
||||
/// <param name="typeOfSms"></param>
|
||||
/// <param name="sendMessStart"></param>
|
||||
/// <param name="sendMessEnd"></param>
|
||||
/// <returns></returns>
|
||||
Task SendBlockSmsToContractingParties(List<BlockSmsListData> smsListData, string typeOfSms,
|
||||
string sendMessStart, string sendMessEnd);
|
||||
|
||||
/// <summary>
|
||||
///دریافت لیست بدهکارن
|
||||
/// جهت ارسال پیامک
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<SmsListData>> GetSmsListData(DateTime checkDate, TypeOfSmsSetting typeOfSmsSetting);
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک های یاد آور بدهی
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task SendReminderSmsToContractingParties(List<SmsListData> smsListData, string typeOfSms, string sendMessStart, string sendMessEnd);
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateMontlyTransaction
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد سند مالی برای قرارداد ها
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task CreateTransactionForInstitutionContracts(DateTime endOfMonthGr, string endOfMonthFa, string description);
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
Task<long> GetIdByInstallmentId(long installmentId);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain;
|
||||
using Company.Domain.InstitutionContractContactInfoAgg;
|
||||
using CompanyManagment.App.Contracts.InstitutionContract;
|
||||
@@ -18,7 +19,8 @@ public class InstitutionContract : EntityBase
|
||||
string contractEndFa, double contractAmount, double dailyCompenseation, double obligation,
|
||||
double totalAmount, int extensionNo, string workshopManualCount, string employeeManualCount, string description,
|
||||
string officialCompany, string typeOfcontract, string hasValueAddedTax, double valueAddedTax,
|
||||
List<InstitutionContractWorkshopInitial> workshopDetails, long lawId)
|
||||
List<InstitutionContractWorkshopInitial> workshopDetails, long lawId,
|
||||
int discountPercentage, double discountAmount)
|
||||
{
|
||||
ContractNo = contractNo;
|
||||
RepresentativeId = representativeId;
|
||||
@@ -56,8 +58,12 @@ public class InstitutionContract : EntityBase
|
||||
WorkshopGroup = new InstitutionContractWorkshopGroup(id, workshopDetails);
|
||||
PublicId = Guid.NewGuid();
|
||||
LawId = lawId;
|
||||
DiscountPercentage = discountPercentage;
|
||||
DiscountAmount = discountAmount;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public long LawId { get; private set; }
|
||||
|
||||
public string ContractNo { get; private set; }
|
||||
@@ -127,6 +133,10 @@ public class InstitutionContract : EntityBase
|
||||
public DateTime VerifyCodeCreation { get; private set; }
|
||||
public string VerifierFullName { get; private set; }
|
||||
public string VerifierPhoneNumber { get; private set; }
|
||||
|
||||
public double DiscountAmount { get; private set; }
|
||||
|
||||
public int DiscountPercentage { get; private set; }
|
||||
|
||||
[NotMapped] public bool VerifyCodeExpired => VerifyCodeCreation.Add(ExpireTime) <= DateTime.Now;
|
||||
|
||||
@@ -371,20 +381,3 @@ public enum InstitutionContractAmendmentChangeType
|
||||
WorkshopCreated
|
||||
}
|
||||
|
||||
public enum InstitutionContractVerificationStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// در انتظار تایید
|
||||
/// </summary>
|
||||
PendingForVerify = 0,
|
||||
|
||||
/// <summary>
|
||||
/// در انتظار کارپوشه
|
||||
/// </summary>
|
||||
PendingWorkflow = 1,
|
||||
|
||||
/// <summary>
|
||||
/// تایید شده
|
||||
/// </summary>
|
||||
Verified = 2
|
||||
}
|
||||
@@ -65,6 +65,7 @@ public class InstitutionContractExtensionTemp
|
||||
MonthlyPayment = monthly;
|
||||
OneTimePayment = oneTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using _0_Framework.Domain;
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using CompanyManagment.App.Contracts.PaymentTransaction;
|
||||
|
||||
namespace Company.Domain.PaymentTransactionAgg;
|
||||
@@ -9,14 +10,15 @@ namespace Company.Domain.PaymentTransactionAgg;
|
||||
/// </summary>
|
||||
public class PaymentTransaction:EntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// سازنده کلاس PaymentTransaction با دریافت اطلاعات تراکنش.
|
||||
/// </summary>
|
||||
/// <param name="contractingPartyId">شناسه طرف قرارداد</param>
|
||||
/// <param name="amount">مبلغ تراکنش</param>
|
||||
/// <param name="contractingPartyName"></param>
|
||||
/// <param name="callBackUrl"></param>
|
||||
public PaymentTransaction(long contractingPartyId,
|
||||
/// <summary>
|
||||
/// سازنده کلاس PaymentTransaction با دریافت اطلاعات تراکنش.
|
||||
/// </summary>
|
||||
/// <param name="contractingPartyId">شناسه طرف قرارداد</param>
|
||||
/// <param name="amount">مبلغ تراکنش</param>
|
||||
/// <param name="contractingPartyName"></param>
|
||||
/// <param name="callBackUrl"></param>
|
||||
/// <param name="gateway"></param>
|
||||
public PaymentTransaction(long contractingPartyId,
|
||||
double amount,
|
||||
string contractingPartyName,string callBackUrl,
|
||||
PaymentTransactionGateWay gateway)
|
||||
@@ -74,6 +76,9 @@ public class PaymentTransaction:EntityBase
|
||||
public string Rrn { get; private set; }
|
||||
public string DigitalReceipt { get; private set; }
|
||||
|
||||
public FinancialInvoice FinancialInvoice { get; set; }
|
||||
public long? FinancialInvoiceId { get; set; }
|
||||
|
||||
|
||||
public void SetPaid(string cardNumber,string bankName,string rrn,string digitalReceipt)
|
||||
{
|
||||
|
||||
30
Company.Domain/SmsResultAgg/ISmsSettingsRepository.cs
Normal file
30
Company.Domain/SmsResultAgg/ISmsSettingsRepository.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain;
|
||||
using CompanyManagment.App.Contracts.SmsResult;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Company.Domain.SmsResultAgg;
|
||||
|
||||
public interface ISmsSettingsRepository : IRepository<long, SmsSetting>
|
||||
{
|
||||
/// <summary>
|
||||
/// ویرایش پیامک خودکار
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<EditSmsSetting> GetSmsSettingToEdit(long id);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت لیست پیامک های خودکار بر اساس نوع آن
|
||||
/// </summary>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <returns></returns>
|
||||
Task<SmsSettingViewModel> GetSmsSettingsByType(TypeOfSmsSetting typeOfSmsSetting);
|
||||
|
||||
/// <summary>
|
||||
/// حذف از دیتابیس
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task RemoveItem(long id);
|
||||
}
|
||||
72
Company.Domain/SmsResultAgg/SmsSetting.cs
Normal file
72
Company.Domain/SmsResultAgg/SmsSetting.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain;
|
||||
using System;
|
||||
|
||||
namespace Company.Domain.SmsResultAgg;
|
||||
|
||||
public class SmsSetting : EntityBaseWithoutCreationDate
|
||||
{
|
||||
/// <summary>
|
||||
/// ایجاد تنظیمات پیامک
|
||||
/// </summary>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <param name="dayOfMonth"></param>
|
||||
/// <param name="timeOfDay"></param>
|
||||
public SmsSetting(TypeOfSmsSetting typeOfSmsSetting, int dayOfMonth, TimeSpan timeOfDay)
|
||||
{
|
||||
TypeOfSmsSetting = typeOfSmsSetting;
|
||||
DayOfMonth = dayOfMonth;
|
||||
TimeOfDay = timeOfDay;
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// نوع پیامک
|
||||
/// </summary>
|
||||
public TypeOfSmsSetting TypeOfSmsSetting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// عدد روز از ماه
|
||||
/// </summary>
|
||||
public int DayOfMonth { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ساعت
|
||||
/// </summary>
|
||||
public TimeSpan TimeOfDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// فعال/غیرفعال
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ویرایش تنظیمات پیامک
|
||||
/// </summary>
|
||||
/// <param name="dayOfMonth"></param>
|
||||
/// <param name="timeOfDay"></param>
|
||||
public void Edit(int dayOfMonth, TimeSpan timeOfDay)
|
||||
{
|
||||
DayOfMonth = dayOfMonth;
|
||||
TimeOfDay = timeOfDay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// فعال نمودن
|
||||
/// </summary>
|
||||
public void Active()
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// غیر فعال نمودن
|
||||
/// </summary>
|
||||
public void DeActive()
|
||||
{
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
using OfficeOpenXml;
|
||||
using OfficeOpenXml.Style;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CompanyManagement.Infrastructure.Excel.ContractingParty;
|
||||
public static class InstitutionContractDetailExcelGenerator
|
||||
{
|
||||
public static byte[] Generate(List<InstitutionContractDetailExcelViewModel> items)
|
||||
{
|
||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||||
using var package = new ExcelPackage();
|
||||
var worksheet = package.Workbook.Worksheets.Add("جزئیات طرف قرارداد");
|
||||
|
||||
// Headers (فارسی)
|
||||
worksheet.Cells[1, 1].Value = "نام";
|
||||
worksheet.Cells[1, 2].Value = "نام خانوادگی";
|
||||
worksheet.Cells[1, 3].Value = "کد ملی";
|
||||
worksheet.Cells[1, 4].Value = "تاریخ تولد";
|
||||
worksheet.Cells[1, 5].Value = "شماره تماس";
|
||||
worksheet.Cells[1, 6].Value = "شماره ملی";
|
||||
|
||||
// Header style
|
||||
using (var headerRange = worksheet.Cells[1, 1, 1, 6])
|
||||
{
|
||||
headerRange.Style.Font.Bold = true;
|
||||
headerRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
|
||||
headerRange.Style.Fill.BackgroundColor.SetColor(Color.LightGray);
|
||||
headerRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
|
||||
headerRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
|
||||
headerRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||||
}
|
||||
|
||||
// Data rows
|
||||
int row = 2;
|
||||
if (items != null)
|
||||
{
|
||||
foreach (var it in items)
|
||||
{
|
||||
worksheet.Cells[row, 1].Value = it.FirstName;
|
||||
worksheet.Cells[row, 2].Value = it.LastName;
|
||||
worksheet.Cells[row, 3].Value = it.NationalCode;
|
||||
worksheet.Cells[row, 4].Value = it.BirthDate;
|
||||
worksheet.Cells[row, 5].Value = it.PhoneNumber;
|
||||
worksheet.Cells[row, 6].Value = it.NationalNumber;
|
||||
|
||||
using (var dataRange = worksheet.Cells[row, 1, row, 6])
|
||||
{
|
||||
dataRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right; // راستچین
|
||||
dataRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
|
||||
dataRange.Style.WrapText = true;
|
||||
}
|
||||
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-fit columns to largest content
|
||||
if (worksheet.Dimension != null)
|
||||
{
|
||||
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
|
||||
}
|
||||
|
||||
// Set sheet to RTL for Persian
|
||||
worksheet.View.RightToLeft = true;
|
||||
|
||||
return package.GetAsByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public class InstitutionContractDetailExcelViewModel
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string NationalCode { get; set; }
|
||||
public string BirthDate { get; set; } // accept Persian date strings
|
||||
public string PhoneNumber { get; set; }
|
||||
public string NationalNumber { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using OfficeOpenXml;
|
||||
using OfficeOpenXml.Style;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CompanyManagement.Infrastructure.Excel.ContractingParty;
|
||||
public static class InstitutionContractLegalExcelGenerator
|
||||
{
|
||||
public static byte[] Generate(List<InstitutionContractLegalExcelViewModel> items)
|
||||
{
|
||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||||
using var package = new ExcelPackage();
|
||||
var worksheet = package.Workbook.Worksheets.Add("جزئیات حقوقی طرف قرارداد");
|
||||
|
||||
// Headers (فارسی)
|
||||
worksheet.Cells[1, 1].Value = "نام شرکت";
|
||||
worksheet.Cells[1, 2].Value = "نام";
|
||||
worksheet.Cells[1, 3].Value = "نام خانوادگی";
|
||||
worksheet.Cells[1, 4].Value = "کد ملی";
|
||||
worksheet.Cells[1, 5].Value = "شماره ثبت";
|
||||
worksheet.Cells[1, 6].Value = "تاریخ تولد";
|
||||
worksheet.Cells[1, 7].Value = "شماره تماس";
|
||||
worksheet.Cells[1, 8].Value = "شماره ملی";
|
||||
|
||||
// Header style
|
||||
using (var headerRange = worksheet.Cells[1, 1, 1, 8])
|
||||
{
|
||||
headerRange.Style.Font.Bold = true;
|
||||
headerRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
|
||||
headerRange.Style.Fill.BackgroundColor.SetColor(Color.LightGray);
|
||||
headerRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
|
||||
headerRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
|
||||
headerRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||||
headerRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||||
}
|
||||
|
||||
// Data rows
|
||||
int row = 2;
|
||||
if (items != null)
|
||||
{
|
||||
foreach (var it in items)
|
||||
{
|
||||
worksheet.Cells[row, 1].Value = it.CompanyName;
|
||||
worksheet.Cells[row, 2].Value = it.FirstName;
|
||||
worksheet.Cells[row, 3].Value = it.LastName;
|
||||
worksheet.Cells[row, 4].Value = it.NationalCode;
|
||||
worksheet.Cells[row, 5].Value = it.RegistrationNumber;
|
||||
worksheet.Cells[row, 6].Value = it.BirthDate;
|
||||
worksheet.Cells[row, 7].Value = it.PhoneNumber;
|
||||
worksheet.Cells[row, 8].Value = it.NationalNumber;
|
||||
|
||||
using (var dataRange = worksheet.Cells[row, 1, row, 8])
|
||||
{
|
||||
dataRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||||
dataRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right; // راستچین
|
||||
dataRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
|
||||
dataRange.Style.WrapText = true;
|
||||
}
|
||||
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-fit columns to largest content
|
||||
if (worksheet.Dimension != null)
|
||||
{
|
||||
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
|
||||
}
|
||||
|
||||
// Set sheet to RTL for Persian
|
||||
worksheet.View.RightToLeft = true;
|
||||
|
||||
return package.GetAsByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public class InstitutionContractLegalExcelViewModel
|
||||
{
|
||||
public string CompanyName { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string NationalCode { get; set; }
|
||||
public string RegistrationNumber { get; set; }
|
||||
public string BirthDate { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
public string NationalNumber { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Drawing;
|
||||
using CompanyManagment.App.Contracts.Workshop;
|
||||
using OfficeOpenXml;
|
||||
using OfficeOpenXml.Style;
|
||||
|
||||
namespace CompanyManagement.Infrastructure.Excel.WorkshopsRollCall;
|
||||
|
||||
public class WorkshopRollCallExcelExporter
|
||||
{
|
||||
public static byte[] Export(List<WorkshopRollCallExcelViewModel> workshops)
|
||||
{
|
||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||||
using (var package = new ExcelPackage())
|
||||
{
|
||||
var ws = package.Workbook.Worksheets.Add("Workshops");
|
||||
// Header
|
||||
ws.Cells[1, 1].Value = "نام کارگاه";
|
||||
ws.Cells[1, 2].Value = "فعال/غیرفعال";
|
||||
ws.Cells[1, 3].Value = "تعداد پرسنل";
|
||||
ws.Cells[1, 4].Value = "نام کارفرما";
|
||||
ws.Row(1).Style.Font.Bold = true;
|
||||
ws.Row(1).Style.Fill.PatternType = ExcelFillStyle.Solid;
|
||||
ws.Row(1).Style.Fill.BackgroundColor.SetColor(Color.LightGray);
|
||||
|
||||
int row = 2;
|
||||
foreach (var w in workshops)
|
||||
{
|
||||
ws.Cells[row, 1].Value = w.WorkshopName;
|
||||
ws.Cells[row, 2].Value = w.IsActive ? "فعال" : "غیرفعال";
|
||||
ws.Cells[row, 3].Value = w.PersonnelCount;
|
||||
ws.Cells[row, 4].Value = w.EmployerName;
|
||||
if (!w.IsActive)
|
||||
{
|
||||
using (var range = ws.Cells[row, 1, row, 4])
|
||||
{
|
||||
range.Style.Fill.PatternType = ExcelFillStyle.Solid;
|
||||
range.Style.Fill.BackgroundColor.SetColor(Color.LightGray);
|
||||
}
|
||||
}
|
||||
row++;
|
||||
}
|
||||
ws.Cells[ws.Dimension.Address].AutoFitColumns();
|
||||
return package.GetAsByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace CompanyManagement.Infrastructure.Excel.WorkshopsRollCall
|
||||
{
|
||||
public class WorkshopRollCallExcelViewModel
|
||||
{
|
||||
public string WorkshopName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public int PersonnelCount { get; set; }
|
||||
public string EmployerName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ public record AndroidApkVersionInfo(int LatestVersionCode, string LatestVersionN
|
||||
|
||||
public interface IAndroidApkVersionApplication
|
||||
{
|
||||
Task<OperationResult> CreateAndActive(IFormFile file, ApkType apkType, bool isForce = false);
|
||||
Task<OperationResult> CreateAndDeActive(IFormFile file, ApkType apkType, bool isForce = false);
|
||||
Task<OperationResult> CreateAndActive(IFormFile file, ApkType apkType, string versionName, string versionCode, bool isForce = false);
|
||||
Task<OperationResult> CreateAndDeActive(IFormFile file, ApkType apkType, string versionName, string versionCode, bool isForce = false);
|
||||
Task<string> GetLatestActiveVersionPath(ApkType apkType);
|
||||
Task<AndroidApkVersionInfo> GetLatestActiveInfo(ApkType apkType, int currentVersionCode);
|
||||
OperationResult Remove(long id);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.AccessControl;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Base;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||||
@@ -18,8 +20,6 @@ namespace CompanyManagment.App.Contracts.CustomizeCheckout;
|
||||
public class CustomizeCheckoutMandatoryViewModel
|
||||
{
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// حقوق ماهانه
|
||||
/// </summary>
|
||||
@@ -159,7 +159,7 @@ public class CustomizeCheckoutMandatoryViewModel
|
||||
/// </summary>
|
||||
public double TotalDeductionsDouble => FineAbsenceDeduction + InsuranceDeduction + LateToWorkDeduction +
|
||||
EarlyExitDeduction + SalaryAidDeduction + InstallmentDeduction +
|
||||
FineDeduction + TaxDeduction;
|
||||
FineDeduction + TaxDeduction+ DynamicDeductions.Sum(x=>x.Amount.MoneyToDouble());
|
||||
|
||||
/// <summary>
|
||||
/// مجموع مطالبات
|
||||
@@ -207,6 +207,8 @@ public class CustomizeCheckoutMandatoryViewModel
|
||||
public ICollection<CustomizeRotatingShift> CustomizeRotatingShifts { get; set; } = [];
|
||||
|
||||
public ICollection<CustomizeSifts> EmployeeSettingsShifts { get; set; } = [];
|
||||
public List<CheckoutDynamicDeductionItem> DynamicDeductions { get; set; } = new();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
using System.Security.AccessControl;
|
||||
using _0_Framework.Application.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Base;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||||
@@ -12,113 +13,115 @@ using CompanyManagment.App.Contracts.Loan;
|
||||
using CompanyManagment.App.Contracts.Reward;
|
||||
using CompanyManagment.App.Contracts.SalaryAid;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.CustomizeCheckout
|
||||
namespace CompanyManagment.App.Contracts.CustomizeCheckout;
|
||||
|
||||
public class CustomizeCheckoutViewModel
|
||||
{
|
||||
public class CustomizeCheckoutViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public DateTime CreationDate { get; set; }
|
||||
public string Month { get; set; }
|
||||
public string Year { get; set; }
|
||||
public int PrintCounter { get; set; }
|
||||
public long Id { get; set; }
|
||||
public DateTime CreationDate { get; set; }
|
||||
public string Month { get; set; }
|
||||
public string Year { get; set; }
|
||||
public int PrintCounter { get; set; }
|
||||
|
||||
|
||||
public long EmployeeId { get; set; }
|
||||
public string EmployeeFName { get; set; }
|
||||
public string EmployeeLName { get; set; }
|
||||
public string EmployeeFullName => $"{EmployeeFName} {EmployeeLName}";
|
||||
public string FatherName { get; set; }
|
||||
public string NationalCode { get; set; }
|
||||
public string DateOfBirth { get; set; }
|
||||
public long PersonnelCode { get; set; }
|
||||
public string PersonnelCodeString => PersonnelCode.ToString();
|
||||
public long EmployeeId { get; set; }
|
||||
public string EmployeeFName { get; set; }
|
||||
public string EmployeeLName { get; set; }
|
||||
public string EmployeeFullName => $"{EmployeeFName} {EmployeeLName}";
|
||||
public string FatherName { get; set; }
|
||||
public string NationalCode { get; set; }
|
||||
public string DateOfBirth { get; set; }
|
||||
public long PersonnelCode { get; set; }
|
||||
public string PersonnelCodeString => PersonnelCode.ToString();
|
||||
|
||||
public string WorkshopName { get; set; }
|
||||
public long WorkshopId { get; set; }
|
||||
public string WorkshopName { get; set; }
|
||||
public long WorkshopId { get; set; }
|
||||
|
||||
|
||||
public long EmployerId { get; set; }
|
||||
public string EmployerName { get; set; }
|
||||
public List<EmployerViewModel> EmployerList { get; set; }
|
||||
public long EmployerId { get; set; }
|
||||
public string EmployerName { get; set; }
|
||||
public List<EmployerViewModel> EmployerList { get; set; }
|
||||
|
||||
|
||||
public long ContractId { get; set; }
|
||||
public string ContractNo { get; set; }
|
||||
public DateTime ContractStartGr { get; set; }
|
||||
public DateTime ContractEndGr { get; set; }
|
||||
public string ContractStartFa { get; set; }
|
||||
public string ContractEndFa { get; set; }
|
||||
//[JsonIgnore]
|
||||
//public string LastDayOfWork => LeftWorkDateGr.AddDays(-1).ToFarsi();
|
||||
//[JsonIgnore]
|
||||
//public string LeftWorkDateFa => LeftWorkDateGr.ToFarsi();
|
||||
public DateTime LeftWorkDateGr { get; set; }
|
||||
public long ContractId { get; set; }
|
||||
public string ContractNo { get; set; }
|
||||
public DateTime ContractStartGr { get; set; }
|
||||
public DateTime ContractEndGr { get; set; }
|
||||
public string ContractStartFa { get; set; }
|
||||
public string ContractEndFa { get; set; }
|
||||
//[JsonIgnore]
|
||||
//public string LastDayOfWork => LeftWorkDateGr.AddDays(-1).ToFarsi();
|
||||
//[JsonIgnore]
|
||||
//public string LeftWorkDateFa => LeftWorkDateGr.ToFarsi();
|
||||
public DateTime LeftWorkDateGr { get; set; }
|
||||
|
||||
public string SumOfWorkingDays { get; set; }
|
||||
public string SumOfWorkingDays { get; set; }
|
||||
|
||||
|
||||
public string MonthlySalary { get; set; }
|
||||
public string BaseYearsPay { get; set; }
|
||||
public string MonthlySalary { get; set; }
|
||||
public string BaseYearsPay { get; set; }
|
||||
|
||||
public string MarriedAllowance { get; set; }
|
||||
public string OvertimePay { get; set; }
|
||||
public string NightworkPay { get; set; }
|
||||
public string FridayPay { get; set; }
|
||||
public string MissionPay { get; set; }
|
||||
public string ShiftPay { get; set; }
|
||||
public string FamilyAllowance { get; set; }
|
||||
public string BonusesPay { get; set; }
|
||||
public string LeavePay { get; set; }
|
||||
public string RewardPay { get; set; }
|
||||
public string MarriedAllowance { get; set; }
|
||||
public string OvertimePay { get; set; }
|
||||
public string NightworkPay { get; set; }
|
||||
public string FridayPay { get; set; }
|
||||
public string MissionPay { get; set; }
|
||||
public string ShiftPay { get; set; }
|
||||
public string FamilyAllowance { get; set; }
|
||||
public string BonusesPay { get; set; }
|
||||
public string LeavePay { get; set; }
|
||||
public string RewardPay { get; set; }
|
||||
|
||||
public bool IsBirthday { get; set; } = true;
|
||||
public string FineDeduction { get; set; }
|
||||
public string InsuranceDeduction { get; set; }
|
||||
public string TaxDeducation { get; set; }
|
||||
public string InstallmentDeduction { get; set; }
|
||||
public string SalaryAidDeduction { get; set; }
|
||||
public string AbsenceDeduction { get; set; }
|
||||
public string EarlyExitDeduction { get; set; }
|
||||
public string LateToWorkDeduction { get; set; }
|
||||
public bool IsBirthday { get; set; } = true;
|
||||
public string FineDeduction { get; set; }
|
||||
public string InsuranceDeduction { get; set; }
|
||||
public string TaxDeducation { get; set; }
|
||||
public string InstallmentDeduction { get; set; }
|
||||
public string SalaryAidDeduction { get; set; }
|
||||
public string AbsenceDeduction { get; set; }
|
||||
public string EarlyExitDeduction { get; set; }
|
||||
public string LateToWorkDeduction { get; set; }
|
||||
|
||||
|
||||
public string TotalClaims { get; set; }
|
||||
public string TotalDeductions { get; set; }
|
||||
public string TotalPayment { get; set; }
|
||||
public string TotalClaims { get; set; }
|
||||
public string TotalDeductions { get; set; }
|
||||
public string TotalPayment { get; set; }
|
||||
|
||||
public List<FineViewModel> FineViewModelList { get; set; }
|
||||
public List<RewardViewModel> RewardViewModels { get; set; }
|
||||
public List<LoanInstallmentViewModel> InstallmentViewModels { get; set; }
|
||||
public List<SalaryAidViewModel> SalaryAidViewModels { get; set; }
|
||||
public bool TotalPaymentHide { get; set; }
|
||||
public PersonnelCheckoutDailyRollCallViewModel MonthlyRollCall { get; set; }
|
||||
public double TotalPaymentD { get; set; }
|
||||
public List<FineViewModel> FineViewModelList { get; set; }
|
||||
public List<RewardViewModel> RewardViewModels { get; set; }
|
||||
public List<LoanInstallmentViewModel> InstallmentViewModels { get; set; }
|
||||
public List<SalaryAidViewModel> SalaryAidViewModels { get; set; }
|
||||
public bool TotalPaymentHide { get; set; }
|
||||
public PersonnelCheckoutDailyRollCallViewModel MonthlyRollCall { get; set; }
|
||||
public double TotalPaymentD { get; set; }
|
||||
|
||||
public string TotalLateToWorkDeduction { get; set; }
|
||||
public string TotalLateToWorkDeduction { get; set; }
|
||||
|
||||
public string LateToWorkValue { get; set; }
|
||||
public string LateToWorkValue { get; set; }
|
||||
|
||||
public string SettingSalary { get; set; }
|
||||
public string DailyWage { get; set; }
|
||||
public WorkshopShiftStatus ShiftStatus { get; set; }
|
||||
public string SettingSalary { get; set; }
|
||||
public string DailyWage { get; set; }
|
||||
public WorkshopShiftStatus ShiftStatus { get; set; }
|
||||
|
||||
public string EmployeePicture { get; set; }
|
||||
public string EmployeePicture { get; set; }
|
||||
|
||||
|
||||
public IrregularShift IrregularShift { get; set; }
|
||||
public List<CustomizeRotatingShift> CustomizeRotatingShifts { get; set; }
|
||||
public List<CustomizeSifts> RegularShift { get; set; }
|
||||
public IrregularShift IrregularShift { get; set; }
|
||||
public List<CustomizeRotatingShift> CustomizeRotatingShifts { get; set; }
|
||||
public List<CustomizeSifts> RegularShift { get; set; }
|
||||
|
||||
public bool HasAmountConflict { get; set; }
|
||||
public bool HasAmountConflict { get; set; }
|
||||
|
||||
//public bool HasLeft { get; set; }
|
||||
//public string IsBlockCantracingParty { get; set; }
|
||||
//public string IsActiveString { get; set; }
|
||||
//public long WorkingHoursId { get; set; }
|
||||
//public string ArchiveCode { get; set; }
|
||||
//public string ConsumableItems { get; set; }
|
||||
//public string HousingAllowance { get; set; }
|
||||
//public string YearsPay { get; set; }
|
||||
// New: up to three dynamic deduction items (name, count, amount)
|
||||
public List<CheckoutDynamicDeductionItem> CheckoutDynamicDeductions { get; set; } = new List<CheckoutDynamicDeductionItem>();
|
||||
|
||||
//public bool HasLeft { get; set; }
|
||||
//public string IsBlockCantracingParty { get; set; }
|
||||
//public string IsActiveString { get; set; }
|
||||
//public long WorkingHoursId { get; set; }
|
||||
//public string ArchiveCode { get; set; }
|
||||
//public string ConsumableItems { get; set; }
|
||||
//public string HousingAllowance { get; set; }
|
||||
//public string YearsPay { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public class CreateFinancialInvoice
|
||||
{
|
||||
public double Amount { get; set; }
|
||||
public long ContractingPartyId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public List<CreateFinancialInvoiceItem>? Items { get; set; }
|
||||
}
|
||||
|
||||
public class CreateFinancialInvoiceItem
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public double Amount { get; set; }
|
||||
public FinancialInvoiceItemType Type { get; set; }
|
||||
public long EntityId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public class EditFinancialInvoice
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string InvoiceNumber { get; set; }
|
||||
public string Description { get; set; }
|
||||
public double Amount { get; set; }
|
||||
public FinancialInvoiceStatus Status { get; set; }
|
||||
|
||||
public List<EditFinancialInvoiceItem>? Items { get; set; }
|
||||
}
|
||||
|
||||
public class EditFinancialInvoiceItem
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
public double Amount { get; set; }
|
||||
public FinancialInvoiceItemType Type { get; set; }
|
||||
public long EntityId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public enum FinancialInvoiceItemType
|
||||
{
|
||||
/// <summary>
|
||||
/// قسط قرارداد خرید از موسسه
|
||||
/// </summary>
|
||||
BuyInstitutionContractInstallment,
|
||||
/// <summary>
|
||||
/// خرید قرارداد از موسسه
|
||||
/// </summary>
|
||||
BuyInstitutionContract,
|
||||
/// <summary>
|
||||
///قسط ارتقا قرارداد موسسه
|
||||
/// </summary>
|
||||
AmendmentInstitutionContractInstallment,
|
||||
/// <summary>
|
||||
/// ارتقا قرارداد موسسه
|
||||
/// </summary>
|
||||
AmendmentInstitutionContract,
|
||||
/// <summary>
|
||||
/// بدهی قبلی
|
||||
/// </summary>
|
||||
PreviousDebt,
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public class FinancialInvoiceSearchModel
|
||||
{
|
||||
public string? Description { get; set; }
|
||||
public FinancialInvoiceStatus? Status { get; set; }
|
||||
public long? ContractingPartyId { get; set; }
|
||||
public string? FromDate { get; set; }
|
||||
public string? ToDate { get; set; }
|
||||
public double? MinAmount { get; set; }
|
||||
public double? MaxAmount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public enum FinancialInvoiceStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// پرداخت نشده
|
||||
/// </summary>
|
||||
Unpaid = 0,
|
||||
/// <summary>
|
||||
/// پرداخت شده کامل
|
||||
/// </summary>
|
||||
Paid = 1,
|
||||
/// <summary>
|
||||
/// فاکتور لغو شده
|
||||
/// </summary>
|
||||
Cancelled = 4,
|
||||
/// <summary>
|
||||
/// // بازپرداخت شده (در صورت برگشت وجه)
|
||||
/// </summary>
|
||||
Refunded = 5,
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public class FinancialInvoiceViewModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string InvoiceNumber { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Status { get; set; }
|
||||
public string PaidAt { get; set; }
|
||||
public double Amount { get; set; }
|
||||
public Guid PublicId { get; set; }
|
||||
public long ContractingPartyId { get; set; }
|
||||
public string ContractingPartyName { get; set; }
|
||||
public string CreationDate { get; set; }
|
||||
public int ItemsCount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _0_Framework.Application;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
|
||||
public interface IFinancialInvoiceApplication
|
||||
{
|
||||
OperationResult Create(CreateFinancialInvoice command);
|
||||
OperationResult Edit(EditFinancialInvoice command);
|
||||
OperationResult SetPaid(long id, DateTime paidAt);
|
||||
OperationResult SetUnpaid(long id);
|
||||
OperationResult SetCancelled(long id);
|
||||
OperationResult SetRefunded(long id);
|
||||
EditFinancialInvoice GetDetails(long id);
|
||||
List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel);
|
||||
}
|
||||
@@ -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<FinancialTransactionViewModel> FinancialTransactionViewModels { get; set; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
20
CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs
Normal file
20
CompanyManagment.App.Contracts/Hubs/SendSmsHub.cs
Normal 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}";
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class CreateInstitutionContractRequest
|
||||
/// <summary>
|
||||
/// مبلغ کل قرارداد
|
||||
/// </summary>
|
||||
public double TotalAmount { get; set; }
|
||||
public double PaymentAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// آیا قرارداد اقساطی است؟
|
||||
@@ -102,6 +102,10 @@ public class CreateInstitutionContractRequest
|
||||
public double OneMonthAmount { get; set; }
|
||||
|
||||
public long LawId { get; set; }
|
||||
|
||||
public int DiscountPercentage { get; set; }
|
||||
|
||||
public double DiscountAmount { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// مدت زمان قرارداد نهاد
|
||||
|
||||
@@ -213,9 +213,11 @@ public interface IInstitutionContractApplication
|
||||
|
||||
Task<GetInstitutionVerificationDetailsViewModel> GetVerificationDetails(Guid id);
|
||||
Task<OperationResult<OtpResultViewModel>> SendVerifyOtp(Guid id);
|
||||
Task<OperationResult> VerifyOtp(Guid publicId, string code);
|
||||
Task<OperationResult<string>> VerifyOtpAndMakeGateway(Guid publicId, string code, string callbackUrl);
|
||||
Task<InstitutionContractWorkshopDetailViewModel> GetWorkshopInitialDetails(long workshopDetailsId);
|
||||
|
||||
InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request);
|
||||
InstitutionContractDiscountResponse ResetDiscountCreate(InstitutionContractResetDiscountForCreateRequest request);
|
||||
|
||||
#region Extension
|
||||
|
||||
Task<InstitutionContractExtensionInquiryResult> GetExtensionInquiry(long previousContractId);
|
||||
@@ -228,6 +230,12 @@ public interface IInstitutionContractApplication
|
||||
|
||||
Task<InstitutionContractExtensionPaymentResponse> GetExtensionPaymentMethod(
|
||||
InstitutionContractExtensionPaymentRequest request);
|
||||
|
||||
Task<InstitutionContractDiscountResponse> SetDiscountForExtension(
|
||||
InstitutionContractSetDiscountForExtensionRequest request);
|
||||
Task<InstitutionContractDiscountResponse> ResetDiscountForExtension(
|
||||
InstitutionContractResetDiscountForExtensionRequest request);
|
||||
|
||||
|
||||
Task<OperationResult> ExtensionComplete(InstitutionContractExtensionCompleteRequest request);
|
||||
Task<List<InstitutionContractSelectListViewModel>> GetInstitutionContractSelectList(string search,string selected);
|
||||
@@ -251,6 +259,77 @@ public interface IInstitutionContractApplication
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<InstitutionContractPrintViewModel> PrintOneAsync(long id);
|
||||
|
||||
Task<OperationResult> SetPendingWorkflow(long entityId);
|
||||
Task<long> GetIdByInstallmentId(long installmentId);
|
||||
|
||||
}
|
||||
|
||||
public class InstitutionContractDiscountResponse
|
||||
{
|
||||
public InstitutionContractDiscountOneTimeViewModel OneTime { get; set; }
|
||||
public InstitutionContractDiscountMonthlyViewModel Monthly { get; set; }
|
||||
}
|
||||
|
||||
public class InstitutionContractDiscountMonthlyViewModel:InstitutionContractDiscountOneTimeViewModel
|
||||
{
|
||||
public List<MonthlyInstallment> Installments { get; set; }
|
||||
}
|
||||
|
||||
public class InstitutionContractDiscountOneTimeViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// مجموع مبالغ
|
||||
/// </summary>
|
||||
public string TotalAmount { get; set; }
|
||||
/// <summary>
|
||||
/// ارزش افزوده
|
||||
/// </summary>
|
||||
public string Tax { get; set; }
|
||||
/// <summary>
|
||||
/// مبلغ قابل پرداخت
|
||||
/// </summary>
|
||||
public string PaymentAmount { get; set; }
|
||||
|
||||
public string DiscountedAmount { get; set; }
|
||||
|
||||
public int DiscountPercetage { get; set; }
|
||||
|
||||
public string Obligation { get; set; }
|
||||
|
||||
public string OneMonthAmount { get; set; }
|
||||
}
|
||||
|
||||
public class InstitutionContractResetDiscountForCreateRequest
|
||||
{
|
||||
public int DiscountPercentage { get; set; }
|
||||
public double TotalAmount { get; set; }
|
||||
public bool IsInstallment { get; set; }
|
||||
public InstitutionContractDuration Duration { get; set; }
|
||||
public double OneMonthAmount { get; set; }
|
||||
}
|
||||
|
||||
public class InstitutionContractSetDiscountForExtensionRequest
|
||||
{
|
||||
public Guid TempId { get; set; }
|
||||
public int DiscountPercentage { get; set; }
|
||||
public double TotalAmount { get; set; }
|
||||
public bool IsInstallment { get; set; }
|
||||
}
|
||||
public class InstitutionContractResetDiscountForExtensionRequest
|
||||
{
|
||||
public Guid TempId { get; set; }
|
||||
public bool IsInstallment { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class InstitutionContractSetDiscountRequest
|
||||
{
|
||||
public int DiscountPercentage { get; set; }
|
||||
public double TotalAmount { get; set; }
|
||||
public InstitutionContractDuration Duration { get; set; }
|
||||
public double OneMonthAmount { get; set; }
|
||||
public bool IsInstallment { get; set; }
|
||||
}
|
||||
|
||||
public class InstitutionContractPrintViewModel
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _0_Framework.Application.Enums;
|
||||
using CompanyManagment.App.Contracts.InstitutionContractContactinfo;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.InstitutionContract;
|
||||
@@ -11,4 +12,15 @@ public class InstitutionContractExtensionWorkshopsRequest
|
||||
public string Province { get; set; }
|
||||
public string Address { get; set; }
|
||||
public List<EditContactInfo> ContactInfos { get; set; }
|
||||
/// <summary>
|
||||
/// اطلاعات شخص حقیقی
|
||||
/// </summary>
|
||||
public CreateInstitutionContractRealPartyRequest RealParty { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// اطلاعات شخص حقوقی
|
||||
/// </summary>
|
||||
public CreateInstitutionContractLegalPartyRequest LegalParty { get; set; }
|
||||
|
||||
public LegalType LegalType { get; set; }
|
||||
}
|
||||
@@ -27,7 +27,13 @@ public class InstitutionContractInstallmentViewModel
|
||||
/// مبلغ قسط
|
||||
/// </summary>
|
||||
public string Amount { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ قسط
|
||||
/// Double
|
||||
/// </summary>
|
||||
public double AmountDouble { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// عدد قسط فارسی
|
||||
/// </summary>
|
||||
|
||||
@@ -17,6 +17,9 @@ public class InstitutionContractPaymentOneTimeViewModel
|
||||
/// مبلغ قابل پرداخت
|
||||
/// </summary>
|
||||
public string PaymentAmount { get; set; }
|
||||
|
||||
public string DiscountedAmount { get; set; }
|
||||
public int DiscountPercetage { get; set; }
|
||||
}
|
||||
public class InstitutionContractPaymentMonthlyViewModel:InstitutionContractPaymentOneTimeViewModel
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _0_Framework.Application.Enums;
|
||||
using CompanyManagment.App.Contracts.Employer;
|
||||
using CompanyManagment.App.Contracts.Workshop;
|
||||
|
||||
@@ -25,6 +26,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; }
|
||||
@@ -70,4 +72,9 @@ public class InstitutionContractViewModel
|
||||
public int LeftWorkEmployeeCount { get; set; }
|
||||
public int InsuranceLeftWorkEmployeeCount { get; set; }
|
||||
public string IsExpier { get; set; }
|
||||
|
||||
public bool IsInstallment { get; set; }
|
||||
public InstitutionContractVerificationStatus VerificationStatus { get; set; }
|
||||
|
||||
public List<InstitutionContractInstallmentViewModel> InstallmentList { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
namespace CompanyManagment.App.Contracts.InstitutionContract;
|
||||
|
||||
/// <summary>
|
||||
/// لیست پیامکهای بدهکاران قرارداد ملی
|
||||
/// </summary>
|
||||
public class SmsListData
|
||||
{
|
||||
/// <summary>
|
||||
/// شماره تماس طرف حساب
|
||||
/// </summary>
|
||||
public string PhoneNumber { get; set; }
|
||||
/// <summary>
|
||||
/// تمپلیت آی دی
|
||||
/// </summary>
|
||||
public int TemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نام طرف حساب
|
||||
/// </summary>
|
||||
public string PartyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ بدهی
|
||||
/// </summary>
|
||||
public string Amount { get; set; }
|
||||
/// <summary>
|
||||
/// آی دی طرف حساب
|
||||
/// </summary>
|
||||
public long ContractingPartyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// آی دی صورت حساب مالی
|
||||
/// </summary>
|
||||
public string AproveId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نوع متد ارسال پیامک
|
||||
/// </summary>
|
||||
public string TypeOfSmsMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// پابلیک آی دی بخش یک
|
||||
/// </summary>
|
||||
public string Code1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// پابلیک آی دی بخش دو
|
||||
/// </summary>
|
||||
public string Code2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ای دی قراداد مالی
|
||||
/// </summary>
|
||||
public long InstitutionContractId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// لیست پیامک های بلاک
|
||||
/// </summary>
|
||||
public class BlockSmsListData
|
||||
{
|
||||
/// <summary>
|
||||
/// شماره تماس طرف حساب
|
||||
/// </summary>
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نام طرف حساب
|
||||
/// </summary>
|
||||
public string PartyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ بدهی
|
||||
/// </summary>
|
||||
public string Amount { get; set; }
|
||||
/// <summary>
|
||||
/// آی دی طرف حساب
|
||||
/// </summary>
|
||||
public long ContractingPartyId { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// نوع حساب - رسمی یا غیر رسمی
|
||||
/// </summary>
|
||||
public string AccountType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ای دی قراداد مالی
|
||||
/// </summary>
|
||||
public long InstitutionContractId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// آی دی صورت حساب مالی
|
||||
/// </summary>
|
||||
public string AproveId { get; set; }
|
||||
}
|
||||
62
CompanyManagment.App.Contracts/SmsResult/CreateSmsSetting.cs
Normal file
62
CompanyManagment.App.Contracts/SmsResult/CreateSmsSetting.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using _0_Framework.Application.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _0_Framework.Domain;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.SmsResult;
|
||||
|
||||
/// <summary>
|
||||
/// مدل ایجاد تنظیمات پیامک
|
||||
/// </summary>
|
||||
public class CreateSmsSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// نوع پیامک
|
||||
/// </summary>
|
||||
public TypeOfSmsSetting TypeOfSmsSetting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// عدد روز از ماه
|
||||
/// </summary>
|
||||
public int DayOfMonth { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ساعت
|
||||
/// </summary>
|
||||
public TimeSpan TimeOfDay { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ویرایش تنظیمات پیامک
|
||||
/// </summary>
|
||||
public class EditSmsSetting : CreateSmsSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// آی دی
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// فعال/غیرفعال
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نمایش ساعت و دقیقه
|
||||
/// </summary>
|
||||
public string TimeOfDayDisplay { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ویو مدل تنظیمات پیامک
|
||||
/// </summary>
|
||||
public class SmsSettingViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// لیست تنظیمات پیامک
|
||||
/// </summary>
|
||||
public List<EditSmsSetting> EditSmsSettings { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
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;
|
||||
|
||||
public interface ISmsSettingApplication
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// دریافت لیست پیامک های خودکار بر اساس نوع آن
|
||||
/// </summary>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <returns></returns>
|
||||
public Task<SmsSettingViewModel> GetSmsSettingsByType(TypeOfSmsSetting typeOfSmsSetting);
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد تنظیمات پیامک یادآور
|
||||
/// </summary>
|
||||
/// <param name="dayOfMonth"></param>
|
||||
/// <param name="timeOfDay"></param>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <returns></returns>
|
||||
Task<OperationResult> CreateSmsSetting(int dayOfMonth, string timeOfDay, TypeOfSmsSetting typeOfSmsSetting);
|
||||
|
||||
/// <summary>
|
||||
/// ویرایش پیامک خودکار
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<EditSmsSetting> GetSmsSettingToEdit(long id);
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد تنظیمات پیامک یادآور
|
||||
/// </summary>
|
||||
/// <param name="dayOfMonth"></param>
|
||||
/// <param name="timeOfDay"></param>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <returns></returns>
|
||||
Task<OperationResult> EditeSmsSetting(EditSmsSetting command);
|
||||
|
||||
/// <summary>
|
||||
/// حذف از دیتابیس
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <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);
|
||||
|
||||
/// <summary>
|
||||
/// ارسال پیامک مسدودس
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <returns></returns>
|
||||
Task<OperationResult> InstantSendBlockSms(List<BlockSmsListData> command);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
_taskRepository = taskRepository;
|
||||
}
|
||||
|
||||
public async Task<OperationResult> CreateAndActive(IFormFile file, ApkType apkType, bool isForce = false)
|
||||
public async Task<OperationResult> CreateAndActive(IFormFile file, ApkType apkType, string versionName, string versionCode, bool isForce = false)
|
||||
{
|
||||
OperationResult op = new OperationResult();
|
||||
|
||||
@@ -34,6 +34,12 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".apk")
|
||||
return op.Failed("لطفا فایلی با پسوند .apk وارد کنید");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(versionName))
|
||||
return op.Failed("لطفا نام ورژن را وارد کنید");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(versionCode))
|
||||
return op.Failed("لطفا کد ورژن را وارد کنید");
|
||||
|
||||
#endregion
|
||||
|
||||
var activeApks = _androidApkVersionRepository.GetActives(apkType);
|
||||
@@ -47,30 +53,8 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
// Read APK metadata with error handling
|
||||
ApkInfo apk;
|
||||
try
|
||||
{
|
||||
apk = ApkHelper.ReadApkInfo(file.OpenReadStream());
|
||||
|
||||
// Validate APK info
|
||||
if (string.IsNullOrEmpty(apk.VersionName) || string.IsNullOrEmpty(apk.VersionCode))
|
||||
{
|
||||
return op.Failed("فایل APK معتبر نیست - اطلاعات نسخه یافت نشد");
|
||||
}
|
||||
|
||||
// Validate version code is numeric
|
||||
if (!int.TryParse(apk.VersionCode, out _))
|
||||
{
|
||||
return op.Failed("فایل APK معتبر نیست - کد نسخه باید عددی باشد");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return op.Failed("خطا در خواندن فایل APK: " + ex.Message);
|
||||
}
|
||||
string uniqueFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}.v{versionName}{Path.GetExtension(file.FileName)}";
|
||||
|
||||
string uniqueFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}.v{apk.VersionName}{Path.GetExtension(file.FileName)}";
|
||||
string filepath = Path.Combine(path, uniqueFileName);
|
||||
|
||||
await using (var stream = new FileStream(filepath, FileMode.Create))
|
||||
@@ -78,13 +62,13 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
await file.CopyToAsync(stream);
|
||||
}
|
||||
|
||||
var entity = new AndroidApkVersion(apk.VersionName, apk.VersionCode, IsActive.True, filepath, apkType, isForce);
|
||||
var entity = new AndroidApkVersion(versionName, versionCode, IsActive.True, filepath,apkType,isForce);
|
||||
_androidApkVersionRepository.Create(entity);
|
||||
_androidApkVersionRepository.SaveChanges();
|
||||
return op.Succcedded();
|
||||
}
|
||||
|
||||
public async Task<OperationResult> CreateAndDeActive(IFormFile file, ApkType apkType, bool isForce = false)
|
||||
public async Task<OperationResult> CreateAndDeActive(IFormFile file, ApkType apkType, string versionName, string versionCode, bool isForce = false)
|
||||
{
|
||||
OperationResult op = new OperationResult();
|
||||
|
||||
@@ -96,6 +80,12 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".apk")
|
||||
return op.Failed("لطفا فایلی با پسوند .apk وارد کنید");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(versionName))
|
||||
return op.Failed("لطفا نام ورژن را وارد کنید");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(versionCode))
|
||||
return op.Failed("لطفا کد ورژن را وارد کنید");
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -105,31 +95,7 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
// Read APK metadata with error handling
|
||||
ApkInfo apk;
|
||||
try
|
||||
{
|
||||
apk = ApkHelper.ReadApkInfo(file.OpenReadStream());
|
||||
|
||||
// Validate APK info
|
||||
if (string.IsNullOrEmpty(apk.VersionName) || string.IsNullOrEmpty(apk.VersionCode))
|
||||
{
|
||||
return op.Failed("فایل APK معتبر نیست - اطلاعات نسخه یافت نشد");
|
||||
}
|
||||
|
||||
// Validate version code is numeric
|
||||
if (!int.TryParse(apk.VersionCode, out _))
|
||||
{
|
||||
return op.Failed("فایل APK معتبر نیست - کد نسخه باید عددی باشد");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return op.Failed("خطا در خواندن فایل APK: " + ex.Message);
|
||||
}
|
||||
|
||||
string uniqueFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}.v{apk.VersionName}{Path.GetExtension(file.FileName)}";
|
||||
|
||||
string uniqueFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}.v{versionName}{Path.GetExtension(file.FileName)}";
|
||||
|
||||
string filepath = Path.Combine(path, uniqueFileName);
|
||||
|
||||
@@ -138,7 +104,7 @@ public class AndroidApkVersionApplication : IAndroidApkVersionApplication
|
||||
await file.CopyToAsync(stream);
|
||||
}
|
||||
|
||||
var entity = new AndroidApkVersion(apk.VersionName, apk.VersionCode, IsActive.False, filepath, apkType, isForce);
|
||||
var entity = new AndroidApkVersion(versionName, versionCode, IsActive.False, filepath,apkType);
|
||||
_androidApkVersionRepository.Create(entity);
|
||||
_androidApkVersionRepository.SaveChanges();
|
||||
return op.Succcedded();
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace CompanyManagment.Application
|
||||
result.LateToWorkDeduction, result.EarlyExitDeduction, result.RewardPay, result.SalaryAidDeduction, result.InstallmentDeduction, result.FineDeduction,
|
||||
result.TaxDeduction, result.SumOfWorkingDays, result.TotalClaimsStr, result.TotalDeductionsStr, result.TotalPayment, contract?.ContractNo ?? "-",
|
||||
fines, loanInstallments, salaryAids, rewards, result.LateToWorkValue, result.SettingSalary, result.DailyWage, result.ShiftStatus, result.IrregularShift, result.CustomizeRotatingShifts,
|
||||
regularShift);
|
||||
regularShift,result.DynamicDeductions);
|
||||
|
||||
|
||||
_customizeCheckoutRepository.Create(entity);
|
||||
@@ -187,7 +187,7 @@ namespace CompanyManagment.Application
|
||||
computations.LateToWorkDeduction, computations.EarlyExitDeduction, computations.RewardPay, computations.SalaryAidDeduction, computations.InstallmentDeduction, computations.FineDeduction,
|
||||
computations.TaxDeduction, computations.SumOfWorkingDays, computations.TotalClaimsStr, computations.TotalDeductionsStr, computations.TotalPayment, contract?.ContractNo ?? "-",
|
||||
fines, loanInstallments, salaryAids, rewards, computations.LateToWorkValue, computations.SettingSalary, computations.DailyWage, computations.ShiftStatus, computations.IrregularShift,
|
||||
computations.CustomizeRotatingShifts, regularShift);
|
||||
computations.CustomizeRotatingShifts, regularShift,computations.DynamicDeductions);
|
||||
|
||||
_customizeCheckoutRepository.Create(entity);
|
||||
_customizeCheckoutRepository.RemoveEmployeeCustomizeCheckoutInDates(command.WorkshopId, employeeId, command.ContractStart, command.ContractEnd);
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace CompanyManagment.Application
|
||||
result.LateToWorkDeduction, result.EarlyExitDeduction, result.RewardPay, result.SalaryAidDeduction, result.InstallmentDeduction, result.FineDeduction,
|
||||
result.TaxDeduction, result.SumOfWorkingDays, result.TotalClaimsStr, result.TotalDeductionsStr, result.TotalPayment, contract?.ContractNo ?? "-",
|
||||
fines, loanInstallments, salaryAids, rewards, result.LateToWorkValue, result.SettingSalary, result.DailyWage, result.ShiftStatus, result.IrregularShift, result.CustomizeRotatingShifts,
|
||||
regularShift);
|
||||
regularShift,result.DynamicDeductions);
|
||||
|
||||
|
||||
_customizeCheckoutTempRepository.Create(entity);
|
||||
@@ -146,7 +146,8 @@ namespace CompanyManagment.Application
|
||||
|
||||
var regularShift = computations.EmployeeSettingsShifts.Select(x =>
|
||||
new CustomizeCheckoutRegularShift(x.StartTime, x.EndTime, x.Placement)).ToList();
|
||||
|
||||
|
||||
|
||||
var entity = new CustomizeCheckoutTemp(command.ContractStart, command.ContractEnd, employeeId, employee.FName, employee.LName, employee.DateOfBirth, employee.NationalCode,
|
||||
workshop.WorkshopFullName, command.WorkshopId, contract?.Id,
|
||||
computations.MonthlySalary, computations.FridayPay, computations.OverTimePay, computations.BaseYearsPay,
|
||||
@@ -155,7 +156,7 @@ namespace CompanyManagment.Application
|
||||
computations.LateToWorkDeduction, computations.EarlyExitDeduction, computations.RewardPay, computations.SalaryAidDeduction, computations.InstallmentDeduction, computations.FineDeduction,
|
||||
computations.TaxDeduction, computations.SumOfWorkingDays, computations.TotalClaimsStr, computations.TotalDeductionsStr, computations.TotalPayment, contract?.ContractNo ?? "-",
|
||||
fines, loanInstallments, salaryAids, rewards, computations.LateToWorkValue, computations.SettingSalary, computations.DailyWage, computations.ShiftStatus, computations.IrregularShift,
|
||||
computations.CustomizeRotatingShifts, regularShift);
|
||||
computations.CustomizeRotatingShifts, regularShift,computations.DynamicDeductions);
|
||||
_customizeCheckoutTempRepository.Create(entity);
|
||||
_customizeCheckoutTempRepository.RemoveEmployeeTemporaryCheckoutInDates(command.WorkshopId, employeeId, command.ContractStart, command.ContractEnd);
|
||||
}
|
||||
|
||||
@@ -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<long, Employee>, 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<long, Employee>, 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1635,7 +1644,12 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
|
||||
};
|
||||
return op.Succcedded(data);
|
||||
}
|
||||
|
||||
var apiResult = await _uidService.GetPersonalInfo(nationalCode, birthDate);
|
||||
if (apiResult == null)
|
||||
{
|
||||
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeDataFromApiViewModel() { AuthorizedCanceled = true });
|
||||
}
|
||||
if (apiResult.ResponseContext.Status.Code == 14)
|
||||
{
|
||||
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeDataFromApiViewModel() { AuthorizedCanceled = true });
|
||||
|
||||
@@ -1485,12 +1485,12 @@ public class EmployerApplication : IEmployerApplication
|
||||
return opration.Failed("نام شرکت وارد شده تکراری است");
|
||||
}
|
||||
|
||||
if (_EmployerRepository.Exists(x =>
|
||||
x.RegisterId == command.RegisterId && !string.IsNullOrWhiteSpace(command.RegisterId) &&
|
||||
x.RegisterId != null))
|
||||
{
|
||||
return opration.Failed(" شماره ثبت وارد شده تکراری است");
|
||||
}
|
||||
// if (_EmployerRepository.Exists(x =>
|
||||
// x.RegisterId == command.RegisterId && !string.IsNullOrWhiteSpace(command.RegisterId) &&
|
||||
// x.RegisterId != null))
|
||||
// {
|
||||
// return opration.Failed(" شماره ثبت وارد شده تکراری است");
|
||||
// }
|
||||
|
||||
if (!string.IsNullOrEmpty(command.NationalId) && command.NationalId.Length != 11)
|
||||
{
|
||||
|
||||
214
CompanyManagment.Application/FinancialInvoiceApplication.cs
Normal file
214
CompanyManagment.Application/FinancialInvoiceApplication.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.InfraStructure;
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using CompanyManagment.App.Contracts.FinancialInvoice;
|
||||
using CompanyManagment.EFCore;
|
||||
|
||||
namespace CompanyManagment.Application;
|
||||
|
||||
public class FinancialInvoiceApplication : RepositoryBase<long, FinancialInvoice>, IFinancialInvoiceApplication
|
||||
{
|
||||
private readonly IFinancialInvoiceRepository _financialInvoiceRepository;
|
||||
private readonly CompanyContext _context;
|
||||
|
||||
public FinancialInvoiceApplication(IFinancialInvoiceRepository financialInvoiceRepository, CompanyContext context) : base(context)
|
||||
{
|
||||
_financialInvoiceRepository = financialInvoiceRepository;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public OperationResult Create(CreateFinancialInvoice command)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
|
||||
if (command.Amount <= 0)
|
||||
return operation.Failed("مبلغ فاکتور باید بزرگتر از صفر باشد");
|
||||
|
||||
if (command.ContractingPartyId <= 0)
|
||||
return operation.Failed("طرف قرارداد نامعتبر است");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(command.Description))
|
||||
return operation.Failed("توضیحات فاکتور الزامی است");
|
||||
|
||||
var financialInvoice = new FinancialInvoice(command.Amount, command.ContractingPartyId, command.Description);
|
||||
|
||||
if (command.Items != null && command.Items.Any())
|
||||
{
|
||||
foreach (var item in command.Items)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.Description))
|
||||
return operation.Failed("توضیحات آیتم الزامی است");
|
||||
|
||||
if (item.Amount <= 0)
|
||||
return operation.Failed("مبلغ آیتم باید بزرگتر از صفر باشد");
|
||||
|
||||
var invoiceItem = new FinancialInvoiceItem(item.Description, item.Amount,
|
||||
financialInvoice.id, item.Type, item.EntityId);
|
||||
|
||||
financialInvoice.AddItem(invoiceItem);
|
||||
}
|
||||
}
|
||||
|
||||
_financialInvoiceRepository.Create(financialInvoice);
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public OperationResult Edit(EditFinancialInvoice command)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
var financialInvoice = _financialInvoiceRepository.Get(command.Id);
|
||||
|
||||
if (financialInvoice == null)
|
||||
return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
|
||||
return operation.Failed("امکان ویرایش فاکتور پرداخت شده وجود ندارد");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(command.Description))
|
||||
return operation.Failed("توضیحات فاکتور الزامی است");
|
||||
|
||||
// Update description
|
||||
financialInvoice.Description = command.Description;
|
||||
|
||||
// Update items if provided
|
||||
if (command.Items != null)
|
||||
{
|
||||
// Clear existing items
|
||||
if (financialInvoice.Items != null)
|
||||
{
|
||||
financialInvoice.Items.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
financialInvoice.SetItems([]);
|
||||
}
|
||||
|
||||
// Add updated items
|
||||
foreach (var item in command.Items)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.Description))
|
||||
return operation.Failed("توضیحات آیتم الزامی است");
|
||||
|
||||
if (item.Amount <= 0)
|
||||
return operation.Failed("مبلغ آیتم باید بزرگتر از صفر باشد");
|
||||
|
||||
var invoiceItem = new FinancialInvoiceItem(item.Description, item.Amount,
|
||||
financialInvoice.id, item.Type, item.EntityId);
|
||||
|
||||
financialInvoice.AddItem(invoiceItem);
|
||||
}
|
||||
}
|
||||
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public OperationResult SetPaid(long id, DateTime paidAt)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
var financialInvoice = _financialInvoiceRepository.Get(id);
|
||||
|
||||
if (financialInvoice == null)
|
||||
return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
|
||||
return operation.Failed("فاکتور قبلاً پرداخت شده است");
|
||||
|
||||
if (financialInvoice.Status == FinancialInvoiceStatus.Cancelled)
|
||||
return operation.Failed("امکان پرداخت فاکتور لغو شده وجود ندارد");
|
||||
|
||||
financialInvoice.SetPaid(paidAt);
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public OperationResult SetUnpaid(long id)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
var financialInvoice = _financialInvoiceRepository.Get(id);
|
||||
|
||||
if (financialInvoice == null)
|
||||
return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
financialInvoice.SetUnpaid();
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public OperationResult SetCancelled(long id)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
var financialInvoice = _financialInvoiceRepository.Get(id);
|
||||
|
||||
if (financialInvoice == null)
|
||||
return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
|
||||
return operation.Failed("امکان لغو فاکتور پرداخت شده وجود ندارد");
|
||||
|
||||
financialInvoice.SetCancelled();
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public OperationResult SetRefunded(long id)
|
||||
{
|
||||
var operation = new OperationResult();
|
||||
var financialInvoice = _financialInvoiceRepository.Get(id);
|
||||
|
||||
if (financialInvoice == null)
|
||||
return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
if (financialInvoice.Status != FinancialInvoiceStatus.Paid)
|
||||
return operation.Failed("فقط فاکتورهای پرداخت شده قابل بازپرداخت هستند");
|
||||
|
||||
financialInvoice.SetRefunded();
|
||||
_financialInvoiceRepository.SaveChanges();
|
||||
|
||||
return operation.Succcedded();
|
||||
}
|
||||
|
||||
public EditFinancialInvoice GetDetails(long id)
|
||||
{
|
||||
return _financialInvoiceRepository.GetDetails(id);
|
||||
}
|
||||
|
||||
public List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel)
|
||||
{
|
||||
return _financialInvoiceRepository.Search(searchModel);
|
||||
}
|
||||
|
||||
//public OperationResult Remove(long id)
|
||||
//{
|
||||
// var operation = new OperationResult();
|
||||
|
||||
// try
|
||||
// {
|
||||
// var financialInvoice = _financialInvoiceRepository.Get(id);
|
||||
|
||||
// if (financialInvoice == null)
|
||||
// return operation.Failed("فاکتور مورد نظر یافت نشد");
|
||||
|
||||
// if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
|
||||
// return operation.Failed("امکان حذف فاکتور پرداخت شده وجود ندارد");
|
||||
|
||||
// // Remove the entity using the context directly since Remove method might not be available
|
||||
// _context.FinancialInvoiceSet.Remove(financialInvoice);
|
||||
// _financialInvoiceRepository.SaveChanges();
|
||||
|
||||
// return operation.Succcedded();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return operation.Failed("خطا در حذف فاکتور");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
165
CompanyManagment.Application/SmsSettingApplication.cs
Normal file
165
CompanyManagment.Application/SmsSettingApplication.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
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;
|
||||
|
||||
public class SmsSettingApplication : ISmsSettingApplication
|
||||
{
|
||||
private readonly ISmsSettingsRepository _smsSettingsRepository;
|
||||
private readonly IInstitutionContractRepository _institutionContractRepository;
|
||||
|
||||
public SmsSettingApplication(ISmsSettingsRepository smsSettingsRepository, IInstitutionContractRepository institutionContractRepository)
|
||||
{
|
||||
_smsSettingsRepository = smsSettingsRepository;
|
||||
_institutionContractRepository = institutionContractRepository;
|
||||
}
|
||||
|
||||
|
||||
public async Task<SmsSettingViewModel> GetSmsSettingsByType(TypeOfSmsSetting typeOfSmsSetting)
|
||||
{
|
||||
return await _smsSettingsRepository.GetSmsSettingsByType(typeOfSmsSetting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد تنظیمات پیامک یادآور
|
||||
/// </summary>
|
||||
/// <param name="dayOfMonth"></param>
|
||||
/// <param name="timeOfDay"></param>
|
||||
/// <param name="typeOfSmsSetting"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperationResult> CreateSmsSetting(int dayOfMonth, string timeOfDay,
|
||||
TypeOfSmsSetting typeOfSmsSetting)
|
||||
{
|
||||
var op = new OperationResult();
|
||||
var timeSpan = new TimeSpan();
|
||||
if (string.IsNullOrWhiteSpace(timeOfDay))
|
||||
return op.Failed("ساعت وارد نشده است");
|
||||
|
||||
try
|
||||
{
|
||||
timeSpan = TimeSpan.ParseExact(timeOfDay, @"hh\:mm", null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return op.Failed("فرمت ساعت اشتباه است");
|
||||
}
|
||||
|
||||
|
||||
if (dayOfMonth < 1 || dayOfMonth > 31)
|
||||
{
|
||||
return op.Failed("عدد روز می بایست بین 1 تا 31 باشد");
|
||||
}
|
||||
|
||||
if (_smsSettingsRepository.Exists(x => x.DayOfMonth == dayOfMonth && x.TimeOfDay == timeSpan && x.TypeOfSmsSetting == typeOfSmsSetting))
|
||||
return op.Failed("رکورد ایجاد شده تکراری است");
|
||||
|
||||
var create = new SmsSetting(typeOfSmsSetting, dayOfMonth, timeSpan);
|
||||
await _smsSettingsRepository.CreateAsync(create);
|
||||
await _smsSettingsRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
return op.Succcedded();
|
||||
}
|
||||
|
||||
public async Task<EditSmsSetting> GetSmsSettingToEdit(long id)
|
||||
{
|
||||
return await _smsSettingsRepository.GetSmsSettingToEdit(id);
|
||||
}
|
||||
|
||||
public async Task<OperationResult> EditeSmsSetting(EditSmsSetting command)
|
||||
{
|
||||
var op = new OperationResult();
|
||||
var timeSpan = new TimeSpan();
|
||||
if (string.IsNullOrWhiteSpace(command.TimeOfDayDisplay))
|
||||
return op.Failed("ساعت وارد نشده است");
|
||||
|
||||
try
|
||||
{
|
||||
timeSpan = TimeSpan.ParseExact(command.TimeOfDayDisplay, @"hh\:mm", null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return op.Failed("فرمت ساعت اشتباه است");
|
||||
}
|
||||
|
||||
if (command.DayOfMonth < 1 || command.DayOfMonth > 31)
|
||||
{
|
||||
return op.Failed("عدد روز می بایست بین 1 تا 31 باشد");
|
||||
}
|
||||
|
||||
if (_smsSettingsRepository.Exists(x => x.DayOfMonth == command.DayOfMonth && x.TimeOfDay == timeSpan && x.TypeOfSmsSetting == command.TypeOfSmsSetting && x.id != command.Id))
|
||||
return op.Failed("رکورد ایجاد شده تکراری است");
|
||||
|
||||
var editSmsSetting = _smsSettingsRepository.Get(command.Id);
|
||||
editSmsSetting.Edit(command.DayOfMonth, timeSpan);
|
||||
await _smsSettingsRepository.SaveChangesAsync();
|
||||
|
||||
return op.Succcedded();
|
||||
}
|
||||
|
||||
public async Task RemoveSetting(long id)
|
||||
{
|
||||
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("موردی انتخاب نشده است");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<OperationResult> InstantSendBlockSms(List<BlockSmsListData> command)
|
||||
{
|
||||
var op = new OperationResult();
|
||||
string typeOfSms = "اعلام مسدودی طرف حساب";
|
||||
string sendMessStart = "شروع مسدودی آنی";
|
||||
string sendMessEnd = "پایان مسدودی آنی ";
|
||||
if (command.Any())
|
||||
{
|
||||
await _institutionContractRepository.SendBlockSmsToContractingParties(command, typeOfSms, sendMessStart,
|
||||
sendMessEnd);
|
||||
return op.Succcedded();
|
||||
}
|
||||
else
|
||||
{
|
||||
return op.Failed("موردی انتخاب نشده است");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,27 +119,29 @@ public class TemporaryClientRegistrationApplication : ITemporaryClientRegistrati
|
||||
|
||||
//دریافت اطلاعات احراز هویت
|
||||
var apiResponsParty = await _uidService.GetPersonalInfo(nationalCode, dateOfBirth);
|
||||
|
||||
//چک کردن مطابقت شماره همراه و کد ملی
|
||||
var isMachMobilAndNationalCode = await _uidService.IsMachPhoneWithNationalCode(nationalCode, mobile);
|
||||
if (isMachMobilAndNationalCode == null)
|
||||
return op.Failed("خطا در سرویس احراز هویت");
|
||||
if (!isMachMobilAndNationalCode.IsMatched)
|
||||
return op.Failed("شماره همراه وارد شده با کد ملی مطابقت ندارد");
|
||||
|
||||
if (apiResponsParty == null)
|
||||
throw new InternalServerException("خطا در سرویس احراز هویت");
|
||||
|
||||
if (apiResponsParty.ResponseContext.Status.Code ==14)
|
||||
if (apiResponsParty.ResponseContext.Status.Code is 14 or 3)
|
||||
throw new InternalServerException("سیستم احراز هویت در دسترس نمی باشد");
|
||||
|
||||
if (apiResponsParty.ResponseContext.Status.Code != 0)
|
||||
return op.Failed($"{apiResponsParty.ResponseContext.Status.Message}");
|
||||
|
||||
idNumberParty = apiResponsParty.IdentificationInformation.ShenasnamehNumber == "0"
|
||||
idNumberParty = apiResponsParty.IdentificationInformation.ShenasnamehNumber == "0"
|
||||
? apiResponsParty.IdentificationInformation.NationalId
|
||||
: apiResponsParty.IdentificationInformation.ShenasnamehNumber;
|
||||
|
||||
|
||||
|
||||
//چک کردن مطابقت شماره همراه و کد ملی
|
||||
var isMachMobilAndNationalCode = await _uidService.IsMachPhoneWithNationalCode(nationalCode, mobile);
|
||||
|
||||
if (isMachMobilAndNationalCode == null)
|
||||
throw new InternalServerException("خطا در سرویس تطابق کد ملی و شماره همراه");
|
||||
if (!isMachMobilAndNationalCode.IsMatched)
|
||||
return op.Failed("شماره همراه وارد شده با کد ملی مطابقت ندارد");
|
||||
|
||||
contractingParty.Authentication(apiResponsParty.BasicInformation.FirstName, apiResponsParty.BasicInformation.LastName,
|
||||
apiResponsParty.BasicInformation.FatherName,idNumberParty,apiResponsParty.IdentificationInformation.ShenasnameSeri,
|
||||
apiResponsParty.IdentificationInformation.ShenasnameSerial,dateOfBirth,apiResponsParty.BasicInformation.GenderEnum,
|
||||
@@ -147,12 +149,11 @@ public class TemporaryClientRegistrationApplication : ITemporaryClientRegistrati
|
||||
|
||||
|
||||
await _contractingPartyTempRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
}
|
||||
if (contractingParty.Phone != mobile)
|
||||
return op.Failed("شما قبلا با شماره همراه دیگری احراز هویت شده اید");
|
||||
|
||||
|
||||
result.Id = contractingParty.id;
|
||||
result.FName = contractingParty.FName;
|
||||
result.LName = contractingParty.LName;
|
||||
@@ -206,9 +207,14 @@ public class TemporaryClientRegistrationApplication : ITemporaryClientRegistrati
|
||||
if (apiRespons == null)
|
||||
throw new InternalServerException("خطا در سرویس احراز هویت");
|
||||
|
||||
if (apiRespons.ResponseContext.Status.Code == 14)
|
||||
if (apiRespons.ResponseContext.Status.Code is 14 or 3)
|
||||
throw new InternalServerException("سیستم احراز هویت در دسترس نمی باشد");
|
||||
|
||||
if (apiRespons.ResponseContext.Status.Code == 2)
|
||||
{
|
||||
throw new InternalServerException("سیستم احراز هویت در دسترس نمی باشد");
|
||||
}
|
||||
|
||||
if (apiRespons.ResponseContext.Status.Code != 0)
|
||||
return op.Failed($"{apiRespons.ResponseContext.Status.Message}");
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ using Company.Domain.FileEmployerAgg;
|
||||
using Company.Domain.FileState;
|
||||
using Company.Domain.FileTiming;
|
||||
using Company.Domain.FileTitle;
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using Company.Domain.FinancialStatmentAgg;
|
||||
using Company.Domain.FinancialTransactionAgg;
|
||||
using Company.Domain.FineAgg;
|
||||
@@ -162,6 +163,12 @@ public class CompanyContext : DbContext
|
||||
|
||||
//-------Main-Project----------------------------
|
||||
|
||||
#region SmsSettings
|
||||
|
||||
public DbSet<SmsSetting> SmsSettings { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mahan
|
||||
|
||||
//-----------------------------RollCallWorkshopSettings-----------------------------
|
||||
@@ -204,12 +211,13 @@ public class CompanyContext : DbContext
|
||||
|
||||
public DbSet<AuthorizedBankDetails> AuthorizedBankDetails { get; set; }
|
||||
|
||||
|
||||
#endregion
|
||||
public DbSet<FinancialInvoice> FinancialInvoices { get; set; }
|
||||
|
||||
#region Pooya
|
||||
#endregion
|
||||
|
||||
public DbSet<EmployeeDocumentItem> EmployeeDocumentItems { get; set; }
|
||||
#region Pooya
|
||||
|
||||
public DbSet<EmployeeDocumentItem> EmployeeDocumentItems { get; set; }
|
||||
public DbSet<EmployeeDocuments> EmployeeDocuments { get; set; }
|
||||
|
||||
public DbSet<WorkshopSubAccount> WorkshopSubAccounts { get; set; }
|
||||
|
||||
@@ -22,7 +22,7 @@ public class AndroidApkVersionMapping:IEntityTypeConfiguration<AndroidApkVersion
|
||||
v => v.ToString(),
|
||||
v => (ApkType)Enum.Parse(typeof(ApkType), v)).HasMaxLength(20);
|
||||
|
||||
builder.Property(x => x.Title).HasMaxLength(50);
|
||||
builder.Property(x => x.Title).HasMaxLength(200);
|
||||
builder.Property(x => x.VersionCode).HasMaxLength(20);
|
||||
builder.Property(x => x.VersionName).HasMaxLength(35);
|
||||
builder.Property(x => x.Path).HasMaxLength(255);
|
||||
|
||||
@@ -131,5 +131,12 @@ public class CustomizeCheckoutMapping : IEntityTypeConfiguration<CustomizeChecko
|
||||
// .HasForeignKey(x => x.EmployeeId);
|
||||
|
||||
#endregion
|
||||
|
||||
builder.OwnsMany(x => x.CheckoutDynamicDeductions, dynamicDeduction =>
|
||||
{
|
||||
dynamicDeduction.Property(x => x.Name).HasMaxLength(100);
|
||||
dynamicDeduction.Property(x => x.Count);
|
||||
dynamicDeduction.Property(x => x.Amount).HasMaxLength(30);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -129,5 +129,12 @@ public class CustomizeCheckoutTempMapping : IEntityTypeConfiguration<CustomizeCh
|
||||
// .HasForeignKey(x => x.EmployeeId);
|
||||
|
||||
#endregion
|
||||
|
||||
builder.OwnsMany(x => x.CheckoutDynamicDeductions, dynamicDeduction =>
|
||||
{
|
||||
dynamicDeduction.Property(x => x.Name).HasMaxLength(100);
|
||||
dynamicDeduction.Property(x => x.Count);
|
||||
dynamicDeduction.Property(x => x.Amount).HasMaxLength(30);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace CompanyManagment.EFCore.Mapping;
|
||||
|
||||
public class FinancialInvoiceItemMapping : IEntityTypeConfiguration<FinancialInvoiceItem>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<FinancialInvoiceItem> builder)
|
||||
{
|
||||
builder.Property(x=>x.Description).HasMaxLength(800);
|
||||
builder.Property(x => x.Type).HasConversion<string>().HasMaxLength(50);
|
||||
|
||||
builder.HasOne(x => x.FinancialInvoice).WithMany(x => x.Items)
|
||||
.HasForeignKey(x => x.FinancialInvoiceId);
|
||||
}
|
||||
}
|
||||
25
CompanyManagment.EFCore/Mapping/FinancialInvoiceMapping.cs
Normal file
25
CompanyManagment.EFCore/Mapping/FinancialInvoiceMapping.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Company.Domain.FinancialInvoiceAgg;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace CompanyManagment.EFCore.Mapping;
|
||||
|
||||
public class FinancialInvoiceMapping:IEntityTypeConfiguration<FinancialInvoice>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<FinancialInvoice> builder)
|
||||
{
|
||||
builder.HasKey(x => x.id);
|
||||
|
||||
builder.Property(x => x.Status).HasConversion<string>().HasMaxLength(20);
|
||||
builder.Property(x => x.PaidAt).IsRequired(false);
|
||||
builder.Property(x => x.Description).HasMaxLength(800);
|
||||
builder.Property(x => x.InvoiceNumber).HasMaxLength(22);
|
||||
|
||||
builder.HasMany(x => x.Items).WithOne(x => x.FinancialInvoice)
|
||||
.HasForeignKey(x => x.FinancialInvoiceId).IsRequired().OnDelete(DeleteBehavior.Cascade);
|
||||
builder.HasMany(x => x.PaymentTransactions).WithOne(x => x.FinancialInvoice)
|
||||
.HasForeignKey(x => x.FinancialInvoiceId).IsRequired(false).OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public class FinancialTransactionMapping : IEntityTypeConfiguration<FinancialTra
|
||||
builder.Property(x => x.TdateFa);
|
||||
builder.Property(x => x.TdateFa).HasMaxLength(10);
|
||||
builder.Property(x => x.TypeOfTransaction).HasMaxLength(10);
|
||||
builder.Property(x => x.DescriptionOption).HasMaxLength(50);
|
||||
builder.Property(x => x.DescriptionOption).HasMaxLength(100);
|
||||
builder.Property(x => x.Description).HasMaxLength(600);
|
||||
builder.Property(x => x.Deptor);
|
||||
builder.Property(x => x.Creditor);
|
||||
|
||||
@@ -11,7 +11,7 @@ public class InstitutinContractContactInfoMapping : IEntityTypeConfiguration<Ins
|
||||
builder.ToTable("InstitutinContractContactInfo");
|
||||
builder.HasKey(x => x.id);
|
||||
|
||||
builder.Property(x => x.FnameLname).HasMaxLength(50);
|
||||
builder.Property(x => x.FnameLname).HasMaxLength(150);
|
||||
builder.Property(x => x.PhoneNumber).HasMaxLength(20);
|
||||
builder.Property(x => x.PhoneType).HasMaxLength(20);
|
||||
builder.Property(x => x.Position).HasMaxLength(50);
|
||||
|
||||
@@ -14,8 +14,8 @@ public class PersonalContractingpartyMapping : IEntityTypeConfiguration<Personal
|
||||
builder.HasKey(x => x.id);
|
||||
|
||||
//builder.Property(x => x.LegalName).HasMaxLength(255).IsRequired();
|
||||
builder.Property(x => x.FName).HasMaxLength(50).IsRequired();
|
||||
builder.Property(x => x.LName).HasMaxLength(50).IsRequired();
|
||||
builder.Property(x => x.FName).HasMaxLength(150).IsRequired();
|
||||
builder.Property(x => x.LName).HasMaxLength(150).IsRequired();
|
||||
builder.Property(x => x.SureName).HasMaxLength(50).IsRequired(false);
|
||||
builder.Property(x => x.Nationalcode).HasMaxLength(10).IsRequired();
|
||||
builder.Property(x => x.IdNumber).HasMaxLength(20).IsRequired(false);
|
||||
|
||||
30
CompanyManagment.EFCore/Mapping/SmsSettingMapping.cs
Normal file
30
CompanyManagment.EFCore/Mapping/SmsSettingMapping.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using _0_Framework.Application.Enums;
|
||||
using Company.Domain.SmsResultAgg;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace CompanyManagment.EFCore.Mapping;
|
||||
|
||||
public class SmsSettingMapping : IEntityTypeConfiguration<SmsSetting>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<SmsSetting> builder)
|
||||
{
|
||||
builder.ToTable("SmsSettings");
|
||||
builder.HasKey(x => x.id);
|
||||
|
||||
|
||||
builder.Property(x => x.DayOfMonth)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.TimeOfDay)
|
||||
.HasColumnType("time(0)")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.TypeOfSmsSetting).HasConversion(
|
||||
v => v.ToString(),
|
||||
v => (TypeOfSmsSetting)Enum.Parse(typeof(TypeOfSmsSetting), v)).HasMaxLength(70);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
10013
CompanyManagment.EFCore/Migrations/20250715100203_Add financialInvoiceTable.Designer.cs
generated
Normal file
10013
CompanyManagment.EFCore/Migrations/20250715100203_Add financialInvoiceTable.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace CompanyManagment.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddfinancialInvoiceTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FinancialInvoice",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Month = table.Column<int>(type: "int", nullable: false),
|
||||
Year = table.Column<int>(type: "int", nullable: false),
|
||||
Status = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: false),
|
||||
PaidAt = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||
Amount = table.Column<double>(type: "float", nullable: false),
|
||||
SmsCode = table.Column<string>(type: "nvarchar(122)", maxLength: 122, nullable: true),
|
||||
FinancialStatementId = table.Column<long>(type: "bigint", nullable: true),
|
||||
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FinancialInvoice", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FinancialInvoice_FinancialStatments_FinancialStatementId",
|
||||
column: x => x.FinancialStatementId,
|
||||
principalTable: "FinancialStatments",
|
||||
principalColumn: "id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FinancialInvoice_FinancialStatementId",
|
||||
table: "FinancialInvoice",
|
||||
column: "FinancialStatementId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "FinancialInvoice");
|
||||
}
|
||||
}
|
||||
}
|
||||
11252
CompanyManagment.EFCore/Migrations/20251113072842_add financial invoice .Designer.cs
generated
Normal file
11252
CompanyManagment.EFCore/Migrations/20251113072842_add financial invoice .Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace CompanyManagment.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class addfinancialinvoice : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_FinancialInvoice_FinancialStatments_FinancialStatementId",
|
||||
table: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_FinancialInvoice",
|
||||
table: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Month",
|
||||
table: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SmsCode",
|
||||
table: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Year",
|
||||
table: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "FinancialInvoice",
|
||||
newName: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "FinancialStatementId",
|
||||
table: "FinancialInvoices",
|
||||
newName: "FinancialStatmentid");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_FinancialInvoice_FinancialStatementId",
|
||||
table: "FinancialInvoices",
|
||||
newName: "IX_FinancialInvoices_FinancialStatmentid");
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "FinancialInvoiceId",
|
||||
table: "PaymentTransactions",
|
||||
type: "bigint",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "ContractingPartyId",
|
||||
table: "FinancialInvoices",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Description",
|
||||
table: "FinancialInvoices",
|
||||
type: "nvarchar(800)",
|
||||
maxLength: 800,
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsActive",
|
||||
table: "FinancialInvoices",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PublicId",
|
||||
table: "FinancialInvoices",
|
||||
type: "uniqueidentifier",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_FinancialInvoices",
|
||||
table: "FinancialInvoices",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FinancialInvoiceItem",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Description = table.Column<string>(type: "nvarchar(800)", maxLength: 800, nullable: true),
|
||||
Amount = table.Column<double>(type: "float", nullable: false),
|
||||
Type = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
||||
EntityId = table.Column<long>(type: "bigint", nullable: false),
|
||||
FinancialInvoiceId = table.Column<long>(type: "bigint", nullable: false),
|
||||
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FinancialInvoiceItem", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FinancialInvoiceItem_FinancialInvoices_FinancialInvoiceId",
|
||||
column: x => x.FinancialInvoiceId,
|
||||
principalTable: "FinancialInvoices",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PaymentTransactions_FinancialInvoiceId",
|
||||
table: "PaymentTransactions",
|
||||
column: "FinancialInvoiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FinancialInvoiceItem_FinancialInvoiceId",
|
||||
table: "FinancialInvoiceItem",
|
||||
column: "FinancialInvoiceId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_FinancialInvoices_FinancialStatments_FinancialStatmentid",
|
||||
table: "FinancialInvoices",
|
||||
column: "FinancialStatmentid",
|
||||
principalTable: "FinancialStatments",
|
||||
principalColumn: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PaymentTransactions_FinancialInvoices_FinancialInvoiceId",
|
||||
table: "PaymentTransactions",
|
||||
column: "FinancialInvoiceId",
|
||||
principalTable: "FinancialInvoices",
|
||||
principalColumn: "id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_FinancialInvoices_FinancialStatments_FinancialStatmentid",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PaymentTransactions_FinancialInvoices_FinancialInvoiceId",
|
||||
table: "PaymentTransactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "FinancialInvoiceItem");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_PaymentTransactions_FinancialInvoiceId",
|
||||
table: "PaymentTransactions");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_FinancialInvoices",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FinancialInvoiceId",
|
||||
table: "PaymentTransactions");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ContractingPartyId",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Description",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsActive",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PublicId",
|
||||
table: "FinancialInvoices");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "FinancialInvoices",
|
||||
newName: "FinancialInvoice");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "FinancialStatmentid",
|
||||
table: "FinancialInvoice",
|
||||
newName: "FinancialStatementId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_FinancialInvoices_FinancialStatmentid",
|
||||
table: "FinancialInvoice",
|
||||
newName: "IX_FinancialInvoice_FinancialStatementId");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Month",
|
||||
table: "FinancialInvoice",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "SmsCode",
|
||||
table: "FinancialInvoice",
|
||||
type: "nvarchar(122)",
|
||||
maxLength: 122,
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Year",
|
||||
table: "FinancialInvoice",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_FinancialInvoice",
|
||||
table: "FinancialInvoice",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_FinancialInvoice_FinancialStatments_FinancialStatementId",
|
||||
table: "FinancialInvoice",
|
||||
column: "FinancialStatementId",
|
||||
principalTable: "FinancialStatments",
|
||||
principalColumn: "id");
|
||||
}
|
||||
}
|
||||
}
|
||||
11140
CompanyManagment.EFCore/Migrations/20251115080049_SmsSettingsTable.Designer.cs
generated
Normal file
11140
CompanyManagment.EFCore/Migrations/20251115080049_SmsSettingsTable.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace CompanyManagment.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SmsSettingsTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SmsSettings",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TypeOfSmsSetting = table.Column<string>(type: "nvarchar(30)", maxLength: 30, nullable: false),
|
||||
DayOfMonth = table.Column<int>(type: "int", nullable: false),
|
||||
TimeOfDay = table.Column<TimeSpan>(type: "time(0)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SmsSettings", x => x.id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "SmsSettings");
|
||||
}
|
||||
}
|
||||
}
|
||||
11140
CompanyManagment.EFCore/Migrations/20251115092700_SmsSettingsTableChange.Designer.cs
generated
Normal file
11140
CompanyManagment.EFCore/Migrations/20251115092700_SmsSettingsTableChange.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace CompanyManagment.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SmsSettingsTableChange : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TypeOfSmsSetting",
|
||||
table: "SmsSettings",
|
||||
type: "nvarchar(70)",
|
||||
maxLength: 70,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(30)",
|
||||
oldMaxLength: 30);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TypeOfSmsSetting",
|
||||
table: "SmsSettings",
|
||||
type: "nvarchar(30)",
|
||||
maxLength: 30,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(70)",
|
||||
oldMaxLength: 70);
|
||||
}
|
||||
}
|
||||
}
|
||||
11143
CompanyManagment.EFCore/Migrations/20251116133447_addIsActiveToSmsSeting.Designer.cs
generated
Normal file
11143
CompanyManagment.EFCore/Migrations/20251116133447_addIsActiveToSmsSeting.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user