Merge branch 'master' into Main

# Conflicts:
#	0_Framework/Application/Sms/ISmsService.cs
#	ServiceHost/Program.cs
#	ServiceHost/Properties/launchSettings.json
This commit is contained in:
2025-12-18 11:01:54 +03:30
121 changed files with 3342 additions and 1634 deletions

View File

@@ -6,6 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentValidation" Version="12.1.1" />
<PackageReference Include="IPE.SmsIR" Version="1.2.7" /> <PackageReference Include="IPE.SmsIR" Version="1.2.7" />
<PackageReference Include="EPPlus" Version="8.4.0" /> <PackageReference Include="EPPlus" Version="8.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.3.0" />

View File

@@ -56,6 +56,11 @@ public class AuthHelper : IAuthHelper
return Tools.DeserializeFromBsonList<int>(permissions); //Mahan return Tools.DeserializeFromBsonList<int>(permissions); //Mahan
} }
public bool HasPermission(int permission)
{
return GetPermissions().Any(x => x == permission);
}
public long CurrentAccountId() public long CurrentAccountId()
{ {
return IsAuthenticated() return IsAuthenticated()

View File

@@ -11,6 +11,7 @@ public interface IFaceEmbeddingService
Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, float confidence, Dictionary<string, object> metadata = null); 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> DeleteEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId); Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId, string newFullName);
} }
public class FaceEmbeddingResponse public class FaceEmbeddingResponse

View File

@@ -12,6 +12,7 @@ public interface IAuthHelper
string CurrentAccountRole(); string CurrentAccountRole();
AuthViewModel CurrentAccountInfo(); AuthViewModel CurrentAccountInfo();
List<int> GetPermissions(); List<int> GetPermissions();
bool HasPermission(int permission);
long CurrentAccountId(); long CurrentAccountId();
string CurrentAccountMobile(); string CurrentAccountMobile();

View File

@@ -27,7 +27,7 @@ public interface ISmsService
Task<double> GetCreditAmount(); Task<double> GetCreditAmount();
public Task<bool> SendInstitutionCreationVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId); public Task<bool> SendInstitutionCreationVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId, string typeOfSms = null);
public Task<bool> SendInstitutionAmendmentVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId); public Task<bool> SendInstitutionAmendmentVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId);
public Task<bool> SendInstitutionVerificationCode(string number, string code, string contractingPartyFullName, public Task<bool> SendInstitutionVerificationCode(string number, string code, string contractingPartyFullName,

View File

@@ -17,7 +17,7 @@ public class ExcelGenerator
{ {
public ExcelGenerator() public ExcelGenerator()
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
} }
public static byte[] GenerateExcel<T>(List<T> obj, string date = "") where T : class public static byte[] GenerateExcel<T>(List<T> obj, string date = "") where T : class
{ {

View File

@@ -1,7 +1,10 @@
using System; #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentValidation;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -27,6 +30,14 @@ public class CustomExceptionHandler : IExceptionHandler
(string Detail, string Title, int StatusCode, Dictionary<string, object>? Extra) details = exception switch (string Detail, string Title, int StatusCode, Dictionary<string, object>? Extra) details = exception switch
{ {
ValidationException validationException =>
(
validationException.Errors.FirstOrDefault()?.ErrorMessage ?? "One or more validation errors occurred.",
"Validation Error",
context.Response.StatusCode = StatusCodes.Status400BadRequest,
null
),
InternalServerException => InternalServerException =>
( (
exception.Message, exception.Message,
@@ -34,6 +45,7 @@ public class CustomExceptionHandler : IExceptionHandler
context.Response.StatusCode = StatusCodes.Status500InternalServerError, context.Response.StatusCode = StatusCodes.Status500InternalServerError,
null null
), ),
BadRequestException bre => BadRequestException bre =>
( (
exception.Message, exception.Message,
@@ -41,6 +53,7 @@ public class CustomExceptionHandler : IExceptionHandler
context.Response.StatusCode = StatusCodes.Status400BadRequest, context.Response.StatusCode = StatusCodes.Status400BadRequest,
bre.Extra bre.Extra
), ),
NotFoundException => NotFoundException =>
( (
exception.Message, exception.Message,
@@ -48,6 +61,7 @@ public class CustomExceptionHandler : IExceptionHandler
context.Response.StatusCode = StatusCodes.Status404NotFound, context.Response.StatusCode = StatusCodes.Status404NotFound,
null null
), ),
UnAuthorizeException => UnAuthorizeException =>
( (
exception.Message, exception.Message,
@@ -55,6 +69,7 @@ public class CustomExceptionHandler : IExceptionHandler
context.Response.StatusCode = StatusCodes.Status401Unauthorized, context.Response.StatusCode = StatusCodes.Status401Unauthorized,
null null
), ),
_ => _ =>
( (
exception.Message, exception.Message,
@@ -73,8 +88,6 @@ public class CustomExceptionHandler : IExceptionHandler
Extensions = details.Extra ?? new Dictionary<string, object>() Extensions = details.Extra ?? new Dictionary<string, object>()
}; };
problemDetails.Extensions.Add("traceId", context.TraceIdentifier); problemDetails.Extensions.Add("traceId", context.TraceIdentifier);
await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken); await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);

View File

@@ -18,329 +18,387 @@ namespace _0_Framework.Infrastructure;
/// </summary> /// </summary>
public class FaceEmbeddingService : IFaceEmbeddingService public class FaceEmbeddingService : IFaceEmbeddingService
{ {
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<FaceEmbeddingService> _logger; private readonly ILogger<FaceEmbeddingService> _logger;
private readonly IFaceEmbeddingNotificationService _notificationService; private readonly IFaceEmbeddingNotificationService _notificationService;
private readonly string _apiBaseUrl; private readonly string _apiBaseUrl;
public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger<FaceEmbeddingService> logger, public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger<FaceEmbeddingService> logger,
IFaceEmbeddingNotificationService notificationService = null) IFaceEmbeddingNotificationService notificationService = null)
{ {
_httpClientFactory = httpClientFactory; _httpClientFactory = httpClientFactory;
_logger = logger; _logger = logger;
_notificationService = notificationService; _notificationService = notificationService;
_apiBaseUrl = "http://localhost:8000"; _apiBaseUrl = "http://localhost:8000";
} }
public async Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId, public async Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId,
string employeeFullName, string picture1Path, string picture2Path) string employeeFullName, string picture1Path, string picture2Path)
{ {
try try
{ {
var httpClient = _httpClientFactory.CreateClient(); var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(_apiBaseUrl); httpClient.BaseAddress = new Uri(_apiBaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(30); httpClient.Timeout = TimeSpan.FromSeconds(30);
using var content = new MultipartFormDataContent(); using var content = new MultipartFormDataContent();
// Add form fields // Add form fields
content.Add(new StringContent(employeeId.ToString()), "employee_id"); content.Add(new StringContent(employeeId.ToString()), "employee_id");
content.Add(new StringContent(workshopId.ToString()), "workshop_id"); content.Add(new StringContent(workshopId.ToString()), "workshop_id");
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name"); content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
// Add picture files // Add picture files
if (File.Exists(picture1Path)) if (File.Exists(picture1Path))
{ {
var picture1Bytes = await File.ReadAllBytesAsync(picture1Path); var picture1Bytes = await File.ReadAllBytesAsync(picture1Path);
var picture1Content = new ByteArrayContent(picture1Bytes); var picture1Content = new ByteArrayContent(picture1Bytes);
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(picture1Content, "picture1", "1.jpg"); content.Add(picture1Content, "picture1", "1.jpg");
} }
else else
{ {
_logger.LogWarning("Picture1 not found at path: {Path}", picture1Path); _logger.LogWarning("Picture1 not found at path: {Path}", picture1Path);
return new OperationResult { IsSuccedded = false, Message = "تصویر اول یافت نشد" }; return new OperationResult { IsSuccedded = false, Message = "تصویر اول یافت نشد" };
} }
if (File.Exists(picture2Path)) if (File.Exists(picture2Path))
{ {
var picture2Bytes = await File.ReadAllBytesAsync(picture2Path); var picture2Bytes = await File.ReadAllBytesAsync(picture2Path);
var picture2Content = new ByteArrayContent(picture2Bytes); var picture2Content = new ByteArrayContent(picture2Bytes);
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(picture2Content, "picture2", "2.jpg"); content.Add(picture2Content, "picture2", "2.jpg");
} }
else else
{ {
_logger.LogWarning("Picture2 not found at path: {Path}", picture2Path); _logger.LogWarning("Picture2 not found at path: {Path}", picture2Path);
return new OperationResult { IsSuccedded = false, Message = "تصویر دوم یافت نشد" }; return new OperationResult { IsSuccedded = false, Message = "تصویر دوم یافت نشد" };
} }
// Send request to Python API // Send request to Python API
var response = await httpClient.PostAsync("embeddings", content); var response = await httpClient.PostAsync("embeddings", content);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var responseContent = await response.Content.ReadAsStringAsync(); var responseContent = await response.Content.ReadAsStringAsync();
_logger.LogInformation("Embeddings generated successfully for Employee {EmployeeId}, Workshop {WorkshopId}", _logger.LogInformation(
employeeId, workshopId); "Embeddings generated successfully for Employee {EmployeeId}, Workshop {WorkshopId}",
employeeId, workshopId);
// ارسال اطلاع‌رسانی به سایر سیستم‌ها // ارسال اطلاع‌رسانی به سایر سیستم‌ها
if (_notificationService != null) if (_notificationService != null)
{ {
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName); await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
} }
return new OperationResult return new OperationResult
{ {
IsSuccedded = true, IsSuccedded = true,
Message = "Embedding با موفقیت ایجاد شد" Message = "Embedding با موفقیت ایجاد شد"
}; };
} }
else else
{ {
var errorContent = await response.Content.ReadAsStringAsync(); var errorContent = await response.Content.ReadAsStringAsync();
_logger.LogError("Failed to generate embeddings. Status: {StatusCode}, Error: {Error}", _logger.LogError("Failed to generate embeddings. Status: {StatusCode}, Error: {Error}",
response.StatusCode, errorContent); response.StatusCode, errorContent);
return new OperationResult return new OperationResult
{ {
IsSuccedded = false, IsSuccedded = false,
Message = $"خطا در تولید Embedding: {response.StatusCode}" Message = $"خطا در تولید Embedding: {response.StatusCode}"
}; };
} }
} }
catch (HttpRequestException ex) catch (HttpRequestException ex)
{ {
_logger.LogError(ex, "HTTP error while calling embeddings API for Employee {EmployeeId}", employeeId); _logger.LogError(ex, "HTTP error while calling embeddings API for Employee {EmployeeId}", employeeId);
return new OperationResult return new OperationResult
{ {
IsSuccedded = false, IsSuccedded = false,
Message = "خطا در ارتباط با سرور Embedding" Message = "خطا در ارتباط با سرور Embedding"
}; };
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error while calling embeddings API for Employee {EmployeeId}", employeeId); _logger.LogError(ex, "Error while calling embeddings API for Employee {EmployeeId}", employeeId);
return new OperationResult return new OperationResult
{ {
IsSuccedded = false, IsSuccedded = false,
Message = "خطای غیرمنتظره در تولید Embedding" Message = "خطای غیرمنتظره در تولید Embedding"
}; };
} }
} }
public async Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, public async Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId,
string employeeFullName, Stream picture1Stream, Stream picture2Stream) string employeeFullName, Stream picture1Stream, Stream picture2Stream)
{ {
try try
{ {
var httpClient = _httpClientFactory.CreateClient(); var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(_apiBaseUrl); httpClient.BaseAddress = new Uri(_apiBaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(30); httpClient.Timeout = TimeSpan.FromSeconds(30);
using var content = new MultipartFormDataContent(); using var content = new MultipartFormDataContent();
// Add form fields // Add form fields
content.Add(new StringContent(employeeId.ToString()), "employee_id"); content.Add(new StringContent(employeeId.ToString()), "employee_id");
content.Add(new StringContent(workshopId.ToString()), "workshop_id"); content.Add(new StringContent(workshopId.ToString()), "workshop_id");
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name"); content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
// Add picture streams // Add picture streams
var picture1Content = new StreamContent(picture1Stream); var picture1Content = new StreamContent(picture1Stream);
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(picture1Content, "picture1", "1.jpg"); content.Add(picture1Content, "picture1", "1.jpg");
var picture2Content = new StreamContent(picture2Stream); var picture2Content = new StreamContent(picture2Stream);
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(picture2Content, "picture2", "2.jpg"); content.Add(picture2Content, "picture2", "2.jpg");
// Send request to Python API // Send request to Python API
var response = await httpClient.PostAsync("embeddings", content); var response = await httpClient.PostAsync("embeddings", content);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
_logger.LogInformation("Embeddings generated successfully from streams for Employee {EmployeeId}", employeeId); _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 // ارسال اطلاع‌رسانی به سایر سیستم‌ها
{ if (_notificationService != null)
IsSuccedded = false, {
Message = $"خطا در تولید Embedding: {response.StatusCode}" await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
}; }
}
}
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, return new OperationResult { IsSuccedded = true, Message = "Embedding با موفقیت ایجاد شد" };
float confidence, Dictionary<string, object> metadata = null) }
{ else
try {
{ var errorContent = await response.Content.ReadAsStringAsync();
var httpClient = _httpClientFactory.CreateClient(); _logger.LogError("Failed to generate embeddings from streams. Status: {StatusCode}, Error: {Error}",
httpClient.BaseAddress = new Uri(_apiBaseUrl); response.StatusCode, errorContent);
httpClient.Timeout = TimeSpan.FromSeconds(30);
var requestBody = new return new OperationResult
{ {
employeeId, IsSuccedded = false,
workshopId, Message = $"خطا در تولید Embedding: {response.StatusCode}"
embedding, };
confidence, }
metadata = metadata ?? new Dictionary<string, object>() }
}; catch (Exception ex)
{
_logger.LogError(ex, "Error while generating embeddings from streams for Employee {EmployeeId}",
employeeId);
return new OperationResult
{
IsSuccedded = false,
Message = "خطا در تولید Embedding"
};
}
}
var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody); 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);
if (response.IsSuccessStatusCode) var requestBody = new
{ {
_logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId); employeeId,
workshopId,
// ارسال اطلاع‌رسانی به سایر سیستم‌ها embedding,
if (_notificationService != null) confidence,
{ metadata = metadata ?? new Dictionary<string, object>()
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 var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody);
{
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) if (response.IsSuccessStatusCode)
{ {
try _logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId);
{
var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(_apiBaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(30);
var response = await httpClient.DeleteAsync($"embeddings/{workshopId}/{employeeId}"); // ارسال اطلاع‌رسانی به سایر سیستم‌ها
if (_notificationService != null)
{
await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, employeeId);
}
if (response.IsSuccessStatusCode) return new OperationResult { IsSuccedded = true, Message = "Embedding بهبود یافت" };
{ }
_logger.LogInformation("Embedding deleted successfully for Employee {EmployeeId}", employeeId); else
{
// ارسال اطلاع‌رسانی به سایر سیستم‌ها var errorContent = await response.Content.ReadAsStringAsync();
if (_notificationService != null) _logger.LogError("Failed to refine embedding. Status: {StatusCode}, Error: {Error}",
{ response.StatusCode, errorContent);
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 return new OperationResult
{ {
IsSuccedded = false, IsSuccedded = false,
Message = $"خطا در حذف Embedding: {response.StatusCode}" Message = $"خطا در بهبود Embedding: {response.StatusCode}"
}; };
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error while deleting embedding for Employee {EmployeeId}", employeeId); _logger.LogError(ex, "Error while refining embedding for Employee {EmployeeId}", employeeId);
return new OperationResult return new OperationResult
{ {
IsSuccedded = false, IsSuccedded = false,
Message = "خطا در حذف Embedding" Message = "خطا در بهبود Embedding"
}; };
} }
} }
public async Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId) public async Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId)
{ {
try try
{ {
var httpClient = _httpClientFactory.CreateClient(); var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(_apiBaseUrl); httpClient.BaseAddress = new Uri(_apiBaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(30); httpClient.Timeout = TimeSpan.FromSeconds(30);
var response = await httpClient.GetAsync($"embeddings/{workshopId}/{employeeId}"); var response = await httpClient.DeleteAsync($"embeddings/{workshopId}/{employeeId}");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var content = await response.Content.ReadAsStringAsync(); _logger.LogInformation("Embedding deleted successfully for Employee {EmployeeId}", employeeId);
var embeddingData = JsonSerializer.Deserialize<FaceEmbeddingResponse>(content,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
_logger.LogInformation("Embedding retrieved successfully for Employee {EmployeeId}", employeeId); // ارسال اطلاع‌رسانی به سایر سیستم‌ها
if (_notificationService != null)
{
await _notificationService.NotifyEmbeddingDeletedAsync(workshopId, employeeId);
}
return new OperationResult<FaceEmbeddingResponse> return new OperationResult { IsSuccedded = true, Message = "Embedding حذف شد" };
{ }
IsSuccedded = true, else
Message = "Embedding دریافت شد", {
Data = embeddingData var errorContent = await response.Content.ReadAsStringAsync();
}; _logger.LogError("Failed to delete embedding. Status: {StatusCode}, Error: {Error}",
} response.StatusCode, errorContent);
else
{ return new OperationResult
var errorContent = await response.Content.ReadAsStringAsync(); {
_logger.LogError("Failed to get embedding. Status: {StatusCode}, Error: {Error}", IsSuccedded = false,
response.StatusCode, errorContent); Message = $"خطا در حذف Embedding: {response.StatusCode}"
};
return new OperationResult<FaceEmbeddingResponse> }
{ }
IsSuccedded = false, catch (Exception ex)
Message = $"خطا در دریافت Embedding: {response.StatusCode}" {
}; _logger.LogError(ex, "Error while deleting embedding for Employee {EmployeeId}", employeeId);
} return new OperationResult
} {
catch (Exception ex) IsSuccedded = false,
{ Message = "خطا در حذف Embedding"
_logger.LogError(ex, "Error while getting embedding for Employee {EmployeeId}", employeeId); };
return new OperationResult<FaceEmbeddingResponse> }
{ }
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"
};
}
}
public async Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId,
string newFullName)
{
try
{
var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(_apiBaseUrl);
httpClient.Timeout = TimeSpan.FromSeconds(30);
var requestBody = new
{
employee_id = employeeId,
workshop_id = workshopId,
employee_full_name = newFullName
};
var response = await httpClient.PutAsJsonAsync("embeddings/update-name", requestBody);
if (response.IsSuccessStatusCode)
{
_logger.LogInformation("Employee Name Changed For {EmployeeId} In workshop ={WorkshopId}", employeeId,
workshopId);
// ارسال اطلاع‌رسانی به سایر سیستم‌ها
if (_notificationService != null)
{
//await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, employeeId);
}
return new OperationResult { IsSuccedded = true, Message = "عملیات با موفقیت انجام شد" };
}
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 Changing EmployeeFullName for Employee {EmployeeId}", employeeId);
return new OperationResult
{
IsSuccedded = false,
Message = "خطا در بهبود Embedding"
};
}
}
}

View File

@@ -1,6 +1,4 @@
using System.Collections.Generic; namespace AccountManagement.Application.Contracts.Account;
namespace AccountManagement.Application.Contracts.Account;
public class EditAccount : CreateAccount public class EditAccount : CreateAccount
{ {

View File

@@ -1,10 +1,4 @@
using System; namespace AccountManagement.Application.Contracts.Account;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AccountManagement.Application.Contracts.Account;
public class EditClientAccount : RegisterAccount public class EditClientAccount : RegisterAccount
{ {

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using AccountManagement.Application.Contracts.ProgramManager;
using Shared.Contracts.PmUser.Queries; using Shared.Contracts.PmUser.Queries;
namespace AccountManagement.Application.Contracts.Account; namespace AccountManagement.Application.Contracts.Account;
@@ -75,12 +74,8 @@ public interface IAccountApplication
void CameraLogin(CameraLoginRequest request); void CameraLogin(CameraLoginRequest request);
/// <summary> Task<GetPmUserDto> GetPmUserAsync(long accountId);
/// دریافت کاربر پروگرام منیجر با اکانت آی دی
/// </summary>
/// <param name="accountId"></param>
/// <returns></returns>
Task<GetPmUserDto> GetPmUserByAccountId(long accountId);
} }
public class CameraLoginRequest public class CameraLoginRequest

View File

@@ -1,10 +1,4 @@
using System; using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _0_Framework.Application;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace AccountManagement.Application.Contracts.Account; namespace AccountManagement.Application.Contracts.Account;

View File

@@ -1,10 +1,4 @@
using System; namespace AccountManagement.Application.Contracts.Account;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AccountManagement.Application.Contracts.Account;
public class WorkshopSelectList public class WorkshopSelectList
{ {

View File

@@ -1,28 +0,0 @@
using System.Collections.Generic;
namespace AccountManagement.Application.Contracts.ProgramManager;
public record GetPmRolesDto
{
/// <summary>
/// آی دی نقش
/// </summary>
public long Id { get; set; }
/// <summary>
/// نام نقش
/// </summary>
public string RoleName { get; set; }
/// <summary>
/// آی دی نقش در گزارشگیر
/// </summary>
public long? GozareshgirRoleId { get; set; }
/// <summary>
/// لیست کدهای دسترسی
/// </summary>
public List<int> Permissions { get; set; }
}

View File

@@ -2,13 +2,9 @@
using _0_Framework.Application.Sms; using _0_Framework.Application.Sms;
using _0_Framework.Exceptions; using _0_Framework.Exceptions;
using AccountManagement.Application.Contracts.Account; using AccountManagement.Application.Contracts.Account;
using AccountManagement.Application.Contracts.ProgramManagerApiResult;
using AccountManagement.Domain.AccountAgg; using AccountManagement.Domain.AccountAgg;
using AccountManagement.Domain.AccountLeftWorkAgg; using AccountManagement.Domain.AccountLeftWorkAgg;
using AccountManagement.Domain.CameraAccountAgg; using AccountManagement.Domain.CameraAccountAgg;
using AccountManagement.Domain.InternalApiCaller;
using AccountManagement.Domain.PmDomains.PmRoleUserAgg;
using AccountManagement.Domain.PmDomains.PmUserAgg;
using AccountManagement.Domain.PositionAgg; using AccountManagement.Domain.PositionAgg;
using AccountManagement.Domain.RoleAgg; using AccountManagement.Domain.RoleAgg;
using AccountManagement.Domain.SubAccountAgg; using AccountManagement.Domain.SubAccountAgg;
@@ -17,25 +13,13 @@ using AccountManagement.Domain.SubAccountRoleAgg;
using Company.Domain._common; using Company.Domain._common;
using Company.Domain.WorkshopAgg; using Company.Domain.WorkshopAgg;
using Company.Domain.WorkshopSubAccountAgg; using Company.Domain.WorkshopSubAccountAgg;
using CompanyManagment.App.Contracts.Workshop;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch.Operations;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AccountManagement.Application.Contracts.ProgramManager;
using Shared.Contracts.PmUser.Commands; using Shared.Contracts.PmUser.Commands;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
using Shared.Contracts.PmUser.Queries; using Shared.Contracts.PmUser.Queries;
//using AccountManagement.Domain.RoleAgg; //using AccountManagement.Domain.RoleAgg;
@@ -58,13 +42,13 @@ public class AccountApplication : IAccountApplication
private readonly ISubAccountRoleRepository _subAccountRoleRepository; private readonly ISubAccountRoleRepository _subAccountRoleRepository;
private readonly IWorkshopSubAccountRepository _workshopSubAccountRepository; private readonly IWorkshopSubAccountRepository _workshopSubAccountRepository;
private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository; private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository;
private readonly IPmUserRepository _pmUserRepository;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IPmUserQueryService _pmUserQueryService; private readonly IPmUserQueryService _pmUserQueryService;
private readonly IPmUserCommandService _pmUserCommandService; private readonly IPmUserCommandService _pmUserCommandService;
public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher, public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher,
IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, IPmUserRepository pmUserRepository, IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService) IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService)
{ {
_authHelper = authHelper; _authHelper = authHelper;
_roleRepository = roleRepository; _roleRepository = roleRepository;
@@ -78,7 +62,7 @@ public class AccountApplication : IAccountApplication
_workshopSubAccountRepository = workshopSubAccountRepository; _workshopSubAccountRepository = workshopSubAccountRepository;
_accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository; _accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository;
_unitOfWork = unitOfWork; _unitOfWork = unitOfWork;
_pmUserRepository = pmUserRepository;
_pmUserQueryService = pmUserQueryService; _pmUserQueryService = pmUserQueryService;
_pmUserCommandService = pmUserCommandService; _pmUserCommandService = pmUserCommandService;
_fileUploader = fileUploader; _fileUploader = fileUploader;
@@ -171,6 +155,8 @@ public class AccountApplication : IAccountApplication
if (command.IsProgramManagerUser) if (command.IsProgramManagerUser)
{ {
if (command.UserRoles == null)
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList(); var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, account.Password, command.Mobile, var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, account.Password, command.Mobile,
null, account.id, pmUserRoles)); null, account.id, pmUserRoles));
@@ -268,6 +254,8 @@ public class AccountApplication : IAccountApplication
//); //);
var userResult =await _pmUserQueryService.GetPmUserDataByAccountId(account.id); var userResult =await _pmUserQueryService.GetPmUserDataByAccountId(account.id);
if (command.UserRoles == null)
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList(); var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
//اگر کاربر در پروگرام منیجر قبلا ایجاد شده //اگر کاربر در پروگرام منیجر قبلا ایجاد شده
@@ -412,6 +400,23 @@ public class AccountApplication : IAccountApplication
.Permissions .Permissions
.Select(x => x.Code) .Select(x => x.Code)
.ToList(); .ToList();
//PmPermission
var PmUserData = _pmUserQueryService.GetPmUserDataByAccountId(account.id).GetAwaiter().GetResult();
if (PmUserData.AccountId > 0 && PmUserData.IsActive)
{
var pmUserPermissions =
PmUserData.RoleListDto != null
? PmUserData.RoleListDto
.SelectMany(x => x.Permissions)
.Where(p => p != 99)
.Distinct()
.ToList()
: new List<int>();
permissions.AddRange(pmUserPermissions);
}
int? positionValue; int? positionValue;
if (account.PositionId != null) if (account.PositionId != null)
{ {
@@ -421,7 +426,7 @@ public class AccountApplication : IAccountApplication
{ {
positionValue = null; positionValue = null;
} }
var pmUserId = _pmUserQueryService.GetCurrentPmUserIdFromAccountId(account.id).GetAwaiter().GetResult(); var pmUserId = PmUserData.AccountId > 0 ? PmUserData.AccountId : null;
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
, account.Username, account.Mobile, account.ProfilePhoto, , account.Username, account.Mobile, account.ProfilePhoto,
permissions, account.RoleName, account.AdminAreaPermission, permissions, account.RoleName, account.AdminAreaPermission,
@@ -1015,8 +1020,8 @@ public class AccountApplication : IAccountApplication
_authHelper.CameraSignIn(authViewModel); _authHelper.CameraSignIn(authViewModel);
} }
public async Task<GetPmUserDto> GetPmUserByAccountId(long accountId) public async Task<GetPmUserDto> GetPmUserAsync(long accountId)
{ {
return await _pmUserRepository.GetPmUserByAccountId(accountId); return await _pmUserQueryService.GetPmUserDataByAccountId(accountId);
} }
} }

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _0_Framework.Application; using _0_Framework.Application;
using AccountManagement.Application.Contracts.Account; using AccountManagement.Application.Contracts.Account;
using AccountManagement.Application.Contracts.CameraAccount; using AccountManagement.Application.Contracts.CameraAccount;

View File

@@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using _0_Framework.Application; using _0_Framework.Application;

View File

@@ -4,13 +4,7 @@ using AccountManagement.Domain.RoleAgg;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AccountManagement.Application.Contracts.ProgramManagerApiResult;
using AccountManagement.Domain.InternalApiCaller;
using Company.Domain._common; using Company.Domain._common;
using AccountManagement.Application.Contracts.Ticket;
using AccountManagement.Domain.PmDomains.PmPermissionAgg;
using AccountManagement.Domain.PmDomains.PmRoleAgg;
using AccountManagement.Domain.PmDomains.PmUserAgg;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Shared.Contracts.PmRole.Commands; using Shared.Contracts.PmRole.Commands;
using GetPmRolesDto = Shared.Contracts.PmRole.Queries.GetPmRolesDto; using GetPmRolesDto = Shared.Contracts.PmRole.Queries.GetPmRolesDto;
@@ -22,18 +16,15 @@ namespace AccountManagement.Application;
public class RoleApplication : IRoleApplication public class RoleApplication : IRoleApplication
{ {
private readonly IRoleRepository _roleRepository; private readonly IRoleRepository _roleRepository;
private readonly IPmRoleRepository _pmRoleRepository;
private readonly IPmUserRepository _pmUserRepository;
private readonly IPmRoleQueryService _pmRoleQueryService; private readonly IPmRoleQueryService _pmRoleQueryService;
private readonly IPmRoleCommandService _pmRoleCommandService; private readonly IPmRoleCommandService _pmRoleCommandService;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleRepository pmRoleRepository, IPmUserRepository pmUserRepository, IPmRoleQueryService pmRoleQueryService, IPmRoleCommandService pmRoleCommandService) public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleQueryService pmRoleQueryService, IPmRoleCommandService pmRoleCommandService)
{ {
_roleRepository = roleRepository; _roleRepository = roleRepository;
_unitOfWork = unitOfWork; _unitOfWork = unitOfWork;
_pmRoleRepository = pmRoleRepository;
_pmUserRepository = pmUserRepository;
_pmRoleQueryService = pmRoleQueryService; _pmRoleQueryService = pmRoleQueryService;
_pmRoleCommandService = pmRoleCommandService; _pmRoleCommandService = pmRoleCommandService;
} }

View File

@@ -5,14 +5,11 @@ using AccountManagement.Domain.AccountAgg;
using AccountManagement.Domain.CameraAccountAgg; using AccountManagement.Domain.CameraAccountAgg;
using AccountManagement.Domain.SubAccountAgg; using AccountManagement.Domain.SubAccountAgg;
using AccountManagement.Domain.SubAccountRoleAgg; using AccountManagement.Domain.SubAccountRoleAgg;
using Company.Domain.WorkshopAccountAgg;
using Company.Domain.WorkshopSubAccountAgg; using Company.Domain.WorkshopSubAccountAgg;
using CompanyManagment.App.Contracts.Workshop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace AccountManagement.Application namespace AccountManagement.Application

View File

@@ -1,9 +1,7 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using _0_Framework.Application; using _0_Framework.Application;
using AccountManagement.Application.Contracts.TaskSubject; using AccountManagement.Application.Contracts.TaskSubject;
using AccountManagement.Domain.TaskSubjectAgg; using AccountManagement.Domain.TaskSubjectAgg;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace AccountManagement.Application; namespace AccountManagement.Application;

View File

@@ -1,18 +0,0 @@
using AccountManagement.Domain.PmDomains.PmRoleAgg;
using AccountManagement.Domain.PmDomains.PmUserAgg;
using AccountMangement.Infrastructure.EFCore.PmDbConetxt;
using AccountMangement.Infrastructure.EFCore.Repository.PmRepositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace AccountManagement.Configuration;
public class PmDbBootstrapper
{
public static void Configure(IServiceCollection services, string connectionString)
{
services.AddTransient<IPmRoleRepository, PmRoleRepository>();
services.AddTransient<IPmUserRepository, PmUserRepository>();
services.AddDbContext<PmDbContext>(x => x.UseSqlServer(connectionString));
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AccountManagement.Domain.PmDomains.PmRoleAgg;
namespace AccountManagement.Domain.PmDomains.PmPermissionAgg;
public class PmPermission
{
public long Id { get; private set; }
public int Code { get; private set; }
public PmRole Role { get; private set; }
public PmPermission(int code)
{
Code = code;
}
}

View File

@@ -1,15 +0,0 @@
using _0_Framework.Domain;
using System.Collections.Generic;
using System.Threading.Tasks;
using AccountManagement.Application.Contracts.ProgramManager;
namespace AccountManagement.Domain.PmDomains.PmRoleAgg;
public interface IPmRoleRepository :IRepository<long, PmRole>
{
Task<List<GetPmRolesDto>> GetPmRoleList(long? gozareshgirRoleId);
Task<PmRole?> GetPmRoleToEdit(long gozareshgirRoleId);
}

View File

@@ -1,46 +0,0 @@
using System.Collections.Generic;
using _0_Framework.Domain;
using AccountManagement.Domain.PmDomains.PmPermissionAgg;
namespace AccountManagement.Domain.PmDomains.PmRoleAgg;
public class PmRole : EntityBase
{
/// <summary>
/// نام نقش
/// </summary>
public string RoleName { get; private set; }
/// <summary>
/// لیست پرمیشن کد ها
/// </summary>
public List<PmPermission> PmPermission { get; private set; }
/// <summary>
/// ای دی نقش در گزارشگیر
/// </summary>
public long? GozareshgirRoleId { get; private set; }
protected PmRole()
{
}
public PmRole(string roleName,long? gozareshgirRolId, List<PmPermission> permissions)
{
RoleName = roleName;
PmPermission = permissions;
GozareshgirRoleId = gozareshgirRolId;
}
public void Edit(string roleName, List<PmPermission> permissions)
{
RoleName = roleName;
PmPermission = permissions;
}
}

View File

@@ -1,19 +0,0 @@
using AccountManagement.Domain.PmDomains.PmUserAgg;
namespace AccountManagement.Domain.PmDomains.PmRoleUserAgg;
public class PmRoleUser
{
public PmRoleUser(long roleId)
{
RoleId = roleId;
}
public long Id { get; private set; }
public long RoleId { get; private set; }
public PmUser User { get; set; }
}

View File

@@ -1,22 +0,0 @@
using _0_Framework.Domain;
using AccountManagement.Application.Contracts.ProgramManager;
using System.Threading.Tasks;
using Shared.Contracts.PmUser.Queries;
namespace AccountManagement.Domain.PmDomains.PmUserAgg;
public interface IPmUserRepository : IRepository<long, PmUser>
{
/// <summary>
/// دریافت کاربر پروگرام منیجر جهتد ویرایش
/// </summary>
/// <param name="accountId"></param>
/// <returns></returns>
Task<PmUser?> GetByPmUsertoEditbyAccountId(long accountId);
/// <summary>
/// دریافت کرابر پروگرام منیجر با اکانت آی دی در گزارشگیر
/// </summary>
/// <param name="accountId"></param>
/// <returns></returns>
Task<GetPmUserDto> GetPmUserByAccountId(long accountId);
}

View File

@@ -1,127 +0,0 @@
using System;
using System.Collections.Generic;
using _0_Framework.Domain;
using AccountManagement.Domain.PmDomains.PmRoleUserAgg;
namespace AccountManagement.Domain.PmDomains.PmUserAgg;
/// <summary>
/// کاربر
/// </summary>
public class PmUser : EntityBase
{
/// <summary>
/// ایجاد
/// </summary>
/// <param name="fullName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="mobile"></param>
/// <param name="email"></param>
/// <param name="accountId"></param>
/// <param name="roles"></param>
public PmUser(string fullName, string userName, string password, string mobile, string email, long? accountId, List<PmRoleUser> roles)
{
FullName = fullName;
UserName = userName;
Password = password;
Mobile = mobile;
Email = email;
IsActive = true;
AccountId = accountId;
RoleUser = roles;
}
protected PmUser()
{
}
/// <summary>
/// نام و نام خانوادگی
/// </summary>
public string FullName { get; private set; }
/// <summary>
/// نام کاربری
/// </summary>
public string UserName { get; private set; }
/// <summary>
/// گذرواژه
/// </summary>
public string Password { get; private set; }
/// <summary>
/// مسیر عکس پروفایل
/// </summary>
public string ProfilePhotoPath { get; private set; }
/// <summary>
/// شماره موبایل
/// </summary>
public string Mobile { get; set; }
/// <summary>
/// ایمیل
/// </summary>
public string Email { get; private set; }
/// <summary>
/// فعال/غیر فعال بودن یوزر
/// </summary>
public bool IsActive { get; private set; }
/// <summary>
/// کد یکبارمصرف ورود
/// </summary>
public string VerifyCode { get; private set; }
/// <summary>
/// آی دی کاربر در گزارشگیر
/// </summary>
public long? AccountId { get; private set; }
/// <summary>
/// لیست پرمیشن کد ها
/// </summary>
public List<PmRoleUser> RoleUser { get; private set; }
/// <summary>
/// آپدیت کاربر
/// </summary>
/// <param name="fullName"></param>
/// <param name="userName"></param>
/// <param name="mobile"></param>
/// <param name="roles"></param>
/// <param name="isActive"></param>
public void Edit(string fullName, string userName, string mobile, List<PmRoleUser> roles, bool isActive)
{
FullName = fullName;
UserName = userName;
Mobile = mobile;
RoleUser = roles;
IsActive = isActive;
}
/// <summary>
/// غیرفعال سازی
/// </summary>
public void DeActive()
{
IsActive = false;
}
/// <summary>
/// فعال سازی
/// </summary>
public void ReActive()
{
IsActive = true;
}
}

View File

@@ -1,24 +0,0 @@
using AccountManagement.Domain.PmDomains.PmRoleAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace AccountMangement.Infrastructure.EFCore.Mappings.PmMappings;
public class PmRoleMapping : IEntityTypeConfiguration<PmRole>
{
public void Configure(EntityTypeBuilder<PmRole> builder)
{
builder.ToTable("PmRoles", t => t.ExcludeFromMigrations());
builder.HasKey(x => x.id);
builder.Property(x => x.RoleName).HasMaxLength(100).IsRequired();
builder.OwnsMany(x => x.PmPermission, navigationBuilder =>
{
navigationBuilder.HasKey(x => x.Id);
navigationBuilder.ToTable("PmRolePermissions", t => t.ExcludeFromMigrations());
navigationBuilder.WithOwner(x => x.Role);
});
}
}

View File

@@ -1,30 +0,0 @@
using AccountManagement.Domain.PmDomains.PmUserAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace AccountMangement.Infrastructure.EFCore.Mappings.PmMappings;
public class PmUserMapping :IEntityTypeConfiguration<PmUser>
{
public void Configure(EntityTypeBuilder<PmUser> builder)
{
builder.ToTable("Users");
builder.HasKey(x => x.id);
builder.Property(x => x.FullName).HasMaxLength(100).IsRequired();
builder.Property(x => x.UserName).HasMaxLength(100).IsRequired();
builder.Property(x => x.Password).HasMaxLength(1000).IsRequired();
builder.Property(x => x.ProfilePhotoPath).HasMaxLength(500).IsRequired(false);
builder.Property(x => x.Mobile).HasMaxLength(20).IsRequired();
builder.Property(x => x.Email).HasMaxLength(150).IsRequired(false); ;
builder.Property(x => x.VerifyCode).HasMaxLength(10).IsRequired(false);
builder.OwnsMany(x => x.RoleUser, navigationBuilder =>
{
navigationBuilder.HasKey(x => x.Id);
navigationBuilder.ToTable("RoleUsers");
navigationBuilder.WithOwner(x => x.User);
});
}
}

View File

@@ -1,32 +0,0 @@
using AccountManagement.Domain.PmDomains.PmRoleAgg;
using AccountManagement.Domain.PmDomains.PmUserAgg;
using AccountMangement.Infrastructure.EFCore.Mappings;
using AccountMangement.Infrastructure.EFCore.Mappings.PmMappings;
using Microsoft.EntityFrameworkCore;
namespace AccountMangement.Infrastructure.EFCore.PmDbConetxt;
public class PmDbContext : DbContext
{
public PmDbContext(DbContextOptions<PmDbContext> options) : base(options)
{
}
public DbSet<PmUser> Users { get; set; } = null!;
public DbSet<PmRole> PmRoles { get; set; } = null!;
public PmDbContext()
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var assembly = typeof(PmUserMapping).Assembly;
modelBuilder.ApplyConfigurationsFromAssembly(assembly);
//SubAccountPermissionSeeder.Seed(modelBuilder);
base.OnModelCreating(modelBuilder);
}
}

View File

@@ -1,49 +0,0 @@
using _0_Framework.InfraStructure;
using AccountManagement.Application.Contracts.ProgramManager;
using AccountManagement.Domain.PmDomains.PmRoleAgg;
using AccountMangement.Infrastructure.EFCore.PmDbConetxt;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace AccountMangement.Infrastructure.EFCore.Repository.PmRepositories;
public class PmRoleRepository : RepositoryBase<long, PmRole>, IPmRoleRepository
{
private readonly PmDbContext _pmDbContext;
public PmRoleRepository(PmDbContext context) : base(context)
{
_pmDbContext = context;
}
public async Task<List<GetPmRolesDto>> GetPmRoleList(long? gozareshgirRoleId)
{
var query = _pmDbContext.PmRoles.AsQueryable();
if (gozareshgirRoleId != null && gozareshgirRoleId > 0)
query = query.Where(x => x.GozareshgirRoleId == gozareshgirRoleId);
var res = await query
.Select(p => new GetPmRolesDto()
{
Id = p.id,
RoleName = p.RoleName,
GozareshgirRoleId = p.GozareshgirRoleId,
Permissions = p.PmPermission.Select(x => x.Code).ToList()
})
.ToListAsync();
return res;
}
public async Task<PmRole?> GetPmRoleToEdit(long gozareshgirRoleId)
{
return await _pmDbContext.PmRoles.FirstOrDefaultAsync(x => x.GozareshgirRoleId == gozareshgirRoleId);
}
}

View File

@@ -1,48 +0,0 @@
using _0_Framework.InfraStructure;
using AccountManagement.Application.Contracts.ProgramManager;
using AccountManagement.Domain.PmDomains.PmUserAgg;
using AccountMangement.Infrastructure.EFCore.PmDbConetxt;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Shared.Contracts.PmUser.Queries;
namespace AccountMangement.Infrastructure.EFCore.Repository.PmRepositories;
public class PmUserRepository :RepositoryBase<long, PmUser>, IPmUserRepository
{
private readonly PmDbContext _pmDbContext;
public PmUserRepository(PmDbContext context, PmDbContext pmDbContext) : base(context)
{
_pmDbContext = pmDbContext;
}
public async Task<PmUser?> GetByPmUsertoEditbyAccountId(long accountId)
{
return await _pmDbContext.Users.FirstOrDefaultAsync(x => x.AccountId == accountId);
}
public async Task<GetPmUserDto> GetPmUserByAccountId(long accountId)
{
var query = await _pmDbContext.Users.FirstOrDefaultAsync(x => x.AccountId == accountId);
if (query == null)
return new GetPmUserDto();
List<long> roles = query.RoleUser.Select(x => x.RoleId).ToList();
return new GetPmUserDto()
{
FullName = query.FullName,
UserName = query.UserName,
ProfilePhotoPath = query.ProfilePhotoPath,
Mobile = query.Mobile,
IsActive = query.IsActive,
AccountId = query.AccountId,
Roles = roles,
RoleListDto = await _pmDbContext.PmRoles.Where(x => roles.Contains(x.id)).Select(x => new RoleListDto()
{
RoleName = x.RoleName,
RoleId = x.id,
Permissions = x.PmPermission.Select(x => x.Code).ToList()
}).ToListAsync(),
};
}
}

View File

@@ -12,6 +12,7 @@
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" /> <ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" /> <ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" />
<ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" /> <ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" />
<ProjectReference Include="..\..\ProgramManager\src\Infrastructure\GozareshgirProgramManager.Infrastructure\GozareshgirProgramManager.Infrastructure.csproj" />
<ProjectReference Include="..\..\Query.Bootstrapper\Query.Bootstrapper.csproj" /> <ProjectReference Include="..\..\Query.Bootstrapper\Query.Bootstrapper.csproj" />
<ProjectReference Include="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" /> <ProjectReference Include="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -47,6 +47,11 @@ public class JobSchedulerRegistrator
() => SendBlockSms(), () => SendBlockSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن "*/1 * * * *" // هر 1 دقیقه یکبار چک کن
); );
RecurringJob.AddOrUpdate(
"InstitutionContract.SendInstitutionContractConfirmSms",
() => SendInstitutionContractConfirmSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
} }
@@ -146,4 +151,15 @@ public class JobSchedulerRegistrator
await _institutionContractRepository.SendBlockSmsForBackgroundTask(); await _institutionContractRepository.SendBlockSmsForBackgroundTask();
} }
/// <summary>
/// ارسال پیامک یادآور تایید قراداد مالی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task SendInstitutionContractConfirmSms()
{
await _institutionContractRepository.SendInstitutionContractConfirmSmsTask();
}
} }

View File

@@ -7,11 +7,16 @@ using BackgroundInstitutionContract.Task;
using BackgroundInstitutionContract.Task.Jobs; using BackgroundInstitutionContract.Task.Jobs;
using CompanyManagment.App.Contracts.Hubs; using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.EFCore.Services; using CompanyManagment.EFCore.Services;
using GozareshgirProgramManager.Application._Bootstrapper;
using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser;
using GozareshgirProgramManager.Infrastructure;
using GozareshgirProgramManager.Infrastructure.Persistence.Seed;
using Hangfire; using Hangfire;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using MongoDB.Driver; using MongoDB.Driver;
using PersonalContractingParty.Config; using PersonalContractingParty.Config;
using Query.Bootstrapper; using Query.Bootstrapper;
using Shared.Contracts.PmUser.Queries;
using WorkFlow.Infrastructure.Config; using WorkFlow.Infrastructure.Config;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -38,10 +43,15 @@ builder.Services.AddSingleton<IMongoDatabase>(mongoDatabase);
#endregion #endregion
builder.Services.AddProgramManagerApplication();
builder.Services.AddProgramManagerInfrastructure(builder.Configuration);
PersonalBootstrapper.Configure(builder.Services, connectionString); PersonalBootstrapper.Configure(builder.Services, connectionString);
TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb); TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb);
AccountManagementBootstrapper.Configure(builder.Services, connectionString); AccountManagementBootstrapper.Configure(builder.Services, connectionString);
WorkFlowBootstrapper.Configure(builder.Services, connectionString); WorkFlowBootstrapper.Configure(builder.Services, connectionString);
QueryBootstrapper.Configure(builder.Services); QueryBootstrapper.Configure(builder.Services);
JobsBootstrapper.Configure(builder.Services); JobsBootstrapper.Configure(builder.Services);
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();

View File

@@ -142,6 +142,11 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
/// <returns></returns> /// <returns></returns>
Task SendReminderSmsToContractingParties(List<SmsListData> smsListData, string typeOfSms, string sendMessStart, string sendMessEnd); Task SendReminderSmsToContractingParties(List<SmsListData> smsListData, string typeOfSms, string sendMessStart, string sendMessEnd);
/// <summary>
/// ارسال پیامک یادآور تایید قراداد مالی
/// </summary>
/// <returns></returns>
Task SendInstitutionContractConfirmSmsTask();
#endregion #endregion
#region CreateMontlyTransaction #region CreateMontlyTransaction

View File

@@ -73,6 +73,7 @@ public interface IInsuranceListRepository:IRepository<long, InsuranceList>
Task<InsuranceListConfirmOperation> GetInsuranceOperationDetails(long id); Task<InsuranceListConfirmOperation> GetInsuranceOperationDetails(long id);
Task<InsuranceListTabsCountViewModel> GetTabCounts(InsuranceListSearchModel searchModel); Task<InsuranceListTabsCountViewModel> GetTabCounts(InsuranceListSearchModel searchModel);
Task<PagedResult<InsuranceClientListViewModel>> GetInsuranceClientList(InsuranceClientSearchModel searchModel);
#endregion #endregion

View File

@@ -26,7 +26,7 @@ public class CustomizeWorkshopGroupSettingExcelGenerator
{ {
public static byte[] Generate(List<CustomizeWorkshopGroupExcelViewModel> groups) public static byte[] Generate(List<CustomizeWorkshopGroupExcelViewModel> groups)
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using (var package = new ExcelPackage()) using (var package = new ExcelPackage())
{ {
var worksheet = package.Workbook.Worksheets.Add("GroupsAndEmployees"); var worksheet = package.Workbook.Worksheets.Add("GroupsAndEmployees");

View File

@@ -24,7 +24,7 @@ public class CaseManagementExcelGenerator
}; };
public static byte[] GenerateCheckoutTempExcelInfo(List<FileExcelViewModel> data) public static byte[] GenerateCheckoutTempExcelInfo(List<FileExcelViewModel> data)
{ {
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial; OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage(); using var package = new ExcelPackage();
CreateSheet(data, package,"همه"); CreateSheet(data, package,"همه");
CreateSheet(data.Where(x=>x.Status ==2).ToList(), package,"فعال"); CreateSheet(data.Where(x=>x.Status ==2).ToList(), package,"فعال");

View File

@@ -46,7 +46,7 @@ public class CustomizeCheckoutExcelGenerator
}; };
public static byte[] GenerateCheckoutTempExcelInfo(List<CustomizeCheckoutTempExcelViewModel> data, List<string> selectedParameters) public static byte[] GenerateCheckoutTempExcelInfo(List<CustomizeCheckoutTempExcelViewModel> data, List<string> selectedParameters)
{ {
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage(); using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1"); var worksheet = package.Workbook.Worksheets.Add("Sheet1");

View File

@@ -7,7 +7,7 @@ public class EmployeeBankInfoExcelGenerator
{ {
public static byte[] Generate(List<EmployeeBankInfoExcelViewModel> list) public static byte[] Generate(List<EmployeeBankInfoExcelViewModel> list)
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage(); using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("EmployeeBankInfo"); var worksheet = package.Workbook.Worksheets.Add("EmployeeBankInfo");
@@ -166,7 +166,7 @@ public class EmployeeBankInfoExcelGenerator
public static byte[] Generate2(List<EmployeeBankInfoExcelViewModel> list) public static byte[] Generate2(List<EmployeeBankInfoExcelViewModel> list)
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage(); using var package = new ExcelPackage();
foreach (var employee in list) foreach (var employee in list)
{ {
@@ -220,4 +220,4 @@ public class EmployeeBankInfoExcelGenerator
cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center; cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
cell.Style.Fill.PatternType = ExcelFillStyle.Solid; cell.Style.Fill.PatternType = ExcelFillStyle.Solid;
} }
} }

View File

@@ -13,7 +13,7 @@ public class InstitutionContractExcelGenerator
public static byte[] GenerateExcel(List<InstitutionContractViewModel> institutionContractViewModels) public static byte[] GenerateExcel(List<InstitutionContractViewModel> institutionContractViewModels)
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage(); using var package = new ExcelPackage();
var allWorksheet = package.Workbook.Worksheets.Add("همه"); var allWorksheet = package.Workbook.Worksheets.Add("همه");

View File

@@ -8,7 +8,7 @@ public class RollCallExcelGenerator : ExcelGenerator
{ {
public static byte[] CaseHistoryExcelForEmployee(CaseHistoryRollCallExcelForEmployeeViewModel data) public static byte[] CaseHistoryExcelForEmployee(CaseHistoryRollCallExcelForEmployeeViewModel data)
{ {
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial; OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new OfficeOpenXml.ExcelPackage(); using var package = new OfficeOpenXml.ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1"); var worksheet = package.Workbook.Worksheets.Add("Sheet1");
var rollCalls = data.RollCalls; var rollCalls = data.RollCalls;
@@ -181,7 +181,7 @@ public class RollCallExcelGenerator : ExcelGenerator
public static byte[] CaseHistoryExcelForOneDay(CaseHistoryRollCallForOneDayViewModel data) public static byte[] CaseHistoryExcelForOneDay(CaseHistoryRollCallForOneDayViewModel data)
{ {
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial; OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new OfficeOpenXml.ExcelPackage(); using var package = new OfficeOpenXml.ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1"); var worksheet = package.Workbook.Worksheets.Add("Sheet1");
var rollCalls = data.RollCalls; var rollCalls = data.RollCalls;

View File

@@ -43,7 +43,7 @@ public class SalaryAidImportExcel
ValidData = [] ValidData = []
}; };
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
if (file == null || file.Length == 0) if (file == null || file.Length == 0)
{ {

View File

@@ -9,7 +9,7 @@ public class WorkshopRollCallExcelExporter
{ {
public static byte[] Export(List<WorkshopRollCallExcelViewModel> workshops) public static byte[] Export(List<WorkshopRollCallExcelViewModel> workshops)
{ {
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using (var package = new ExcelPackage()) using (var package = new ExcelPackage())
{ {
var ws = package.Workbook.Worksheets.Add("Workshops"); var ws = package.Workbook.Worksheets.Add("Workshops");

View File

@@ -60,7 +60,7 @@ public interface IEmployeeApplication
/// <returns></returns> /// <returns></returns>
Task<OperationResult<EmployeeByNationalCodeInWorkshopViewModel>> Task<OperationResult<EmployeeByNationalCodeInWorkshopViewModel>>
ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(string nationalCode, ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(string nationalCode,
string birthDate, long workshopId); string birthDate,bool authorizedCanceled, long workshopId);
/// <summary> /// <summary>
/// پرسنل هایی که در کارگاهی از سمت ادمین شروع به کار کرده اند /// پرسنل هایی که در کارگاهی از سمت ادمین شروع به کار کرده اند

View File

@@ -13,5 +13,6 @@ namespace CompanyManagment.App.Contracts.EmployeeDocuments
public string EmployerName { get; set; } public string EmployerName { get; set; }
public List<EmployeeDocumentItemViewModel> SubmittedItems { get; set; } public List<EmployeeDocumentItemViewModel> SubmittedItems { get; set; }
public int EmployeesWithoutDocumentCount { get; set; } public int EmployeesWithoutDocumentCount { get; set; }
public long EmployeeId { get; set; }
} }
} }

View File

@@ -0,0 +1,12 @@
using System;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public record InstitutionCreationVerificationSmsDto
{
public string Number{ get; set; }
public string FullName { get; set; }
public Guid InstitutionId { get; set; }
public long ContractingPartyId { get; set; }
public long InstitutionContractId { get; set; }
};

View File

@@ -90,8 +90,27 @@ public interface IInsuranceListApplication
Task<InsuranceListConfirmOperation> GetInsuranceOperationDetails(long id); Task<InsuranceListConfirmOperation> GetInsuranceOperationDetails(long id);
Task<InsuranceListTabsCountViewModel> GetTabCounts(InsuranceListSearchModel searchModel); Task<InsuranceListTabsCountViewModel> GetTabCounts(InsuranceListSearchModel searchModel);
Task<PagedResult<InsuranceClientListViewModel>> GetInsuranceClientList(InsuranceClientSearchModel searchModel);
#endregion #endregion
Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel); Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel);
}
public class InsuranceClientSearchModel:PaginationRequest
{
public int Year { get; set; }
public int Month { get; set; }
public string Sorting { get; set; }
}
public class InsuranceClientListViewModel
{
public long Id { get; set; }
public string Year { get; set; }
public string Month { get; set; }
public long WorkShopId { get; set; }
public int YearInt { get; set; }
public string MonthName { get; set; }
public int MonthInt { get; set; }
} }

View File

@@ -1,6 +1,7 @@
using _0_Framework.Application; using _0_Framework.Application;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace CompanyManagment.App.Contracts.RollCallEmployee; namespace CompanyManagment.App.Contracts.RollCallEmployee;

View File

@@ -1263,7 +1263,7 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
System.IO.File.WriteAllBytes(filePath, bytes); System.IO.File.WriteAllBytes(filePath, bytes);
} }
public async Task<OperationResult<EmployeeByNationalCodeInWorkshopViewModel>> public async Task<OperationResult<EmployeeByNationalCodeInWorkshopViewModel>>
ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(string nationalCode, string birthDate, long workshopId) ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(string nationalCode, string birthDate,bool authorizedCanceled, long workshopId)
{ {
var op = new OperationResult<EmployeeByNationalCodeInWorkshopViewModel>(); var op = new OperationResult<EmployeeByNationalCodeInWorkshopViewModel>();
@@ -1279,65 +1279,25 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
var employee = _EmployeeRepository.GetByNationalCodeIgnoreQueryFilter(nationalCode); var employee = _EmployeeRepository.GetByNationalCodeIgnoreQueryFilter(nationalCode);
if (employee == null) if (employee == null && !authorizedCanceled)
{ {
var personalInfo = await _uidService.GetPersonalInfo(nationalCode, birthDate); var personalInfo = await _uidService.GetPersonalInfo(nationalCode, birthDate);
if (personalInfo != null)
if (personalInfo.ResponseContext.Status.Code == 14)
{ {
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeByNationalCodeInWorkshopViewModel() { AuthorizedCanceled = true }); if (personalInfo.ResponseContext.Status.Code == 14)
} {
if (personalInfo.ResponseContext.Status.Code != 0) return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeByNationalCodeInWorkshopViewModel() { AuthorizedCanceled = true });
{ }
return op.Failed("کد ملی و تاریخ تولد با هم همخانی ندارند"); if (personalInfo.ResponseContext.Status.Code != 0)
} {
return op.Failed("کد ملی و تاریخ تولد با هم همخانی ندارند");
}
var basicInfo = personalInfo.BasicInformation; var basicInfo = personalInfo.BasicInformation;
var identityInfo = personalInfo.IdentificationInformation; var identityInfo = personalInfo.IdentificationInformation;
DateTime apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime(); DateTime apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime();
var dateOfIssue = new DateTime(1922, 1, 1); var dateOfIssue = new DateTime(1922, 1, 1);
var gender = basicInfo.GenderEnum switch
{
Gender.Female => "زن",
Gender.Male => "مرد",
_ => throw new AggregateException()
};
var idNumber = identityInfo.ShenasnamehNumber == "0" ? identityInfo.NationalId : identityInfo.ShenasnamehNumber;
var newEmployee = new Employee(basicInfo.FirstName, basicInfo.LastName, basicInfo.FatherName, apiBirthDate,
dateOfIssue, null, identityInfo.NationalId, idNumber, gender, "ایرانی", identityInfo.ShenasnameSerial, identityInfo.ShenasnameSeri);
newEmployee.Authorized();
await _EmployeeRepository.CreateAsync(newEmployee);
await _EmployeeRepository.SaveChangesAsync();
return op.Succcedded(new EmployeeByNationalCodeInWorkshopViewModel()
{
EmployeeId = newEmployee.id,
EmployeeFName = newEmployee.FName,
Gender = newEmployee.Gender,
Nationality = newEmployee.Nationality,
EmployeeLName = newEmployee.LName
});
}
if (_leftWorkTempRepository.ExistsIgnoreQueryFilter(x =>
x.EmployeeId == employee.id && x.WorkshopId == workshopId && x.LeftWorkType == LeftWorkTempType.StartWork))
{
return op.Failed("این پرسنل در کارگاه شما قبلا افزوده شده است و در انتظار تایید میباشد");
}
if (employee.IsAuthorized == false)
{
var personalInfoResponse = await _uidService.GetPersonalInfo(nationalCode, birthDate);
if (personalInfoResponse.ResponseContext.Status.Code == 0)
{
var basicInfo = personalInfoResponse.BasicInformation;
var identityInfo = personalInfoResponse.IdentificationInformation;
var apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime();
var gender = basicInfo.GenderEnum switch var gender = basicInfo.GenderEnum switch
{ {
@@ -1348,31 +1308,90 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
var idNumber = identityInfo.ShenasnamehNumber == "0" ? identityInfo.NationalId : identityInfo.ShenasnamehNumber; var idNumber = identityInfo.ShenasnamehNumber == "0" ? identityInfo.NationalId : identityInfo.ShenasnamehNumber;
var newEmployee = new Employee(basicInfo.FirstName, basicInfo.LastName, basicInfo.FatherName, apiBirthDate,
employee.Edit(basicInfo.FirstName, basicInfo.LastName, basicInfo.FatherName, apiBirthDate, dateOfIssue, null, identityInfo.NationalId, idNumber, gender, "ایرانی", identityInfo.ShenasnameSerial, identityInfo.ShenasnameSeri);
employee.DateOfIssue, employee.PlaceOfIssue, identityInfo.NationalId, idNumber, newEmployee.Authorized();
gender, "ایرانی", employee.Phone, employee.Address, employee.State, employee.City, await _EmployeeRepository.CreateAsync(newEmployee);
employee.MaritalStatus, employee.MilitaryService, employee.LevelOfEducation,
employee.FieldOfStudy, employee.BankCardNumber, employee.BankBranch, employee.InsuranceCode, employee.InsuranceHistoryByYear,
employee.InsuranceHistoryByMonth, employee.NumberOfChildren,
employee.OfficePhone, employee.MclsUserName, employee.MclsPassword,
employee.EserviceUserName, employee.EservicePassword, employee.TaxOfficeUserName,
employee.TaxOfficepassword, employee.SanaUserName, employee.SanaPassword);
employee.Authorized();
await _EmployeeRepository.SaveChangesAsync(); await _EmployeeRepository.SaveChangesAsync();
return op.Succcedded(new EmployeeByNationalCodeInWorkshopViewModel()
{
EmployeeId = newEmployee.id,
EmployeeFName = newEmployee.FName,
Gender = newEmployee.Gender,
Nationality = newEmployee.Nationality,
EmployeeLName = newEmployee.LName
});
} }
else else
{
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeByNationalCodeInWorkshopViewModel() { AuthorizedCanceled = true });
}
}
else if (employee == null && authorizedCanceled)
{
return op.Succcedded(new EmployeeByNationalCodeInWorkshopViewModel());
}
if (_leftWorkTempRepository.ExistsIgnoreQueryFilter(x =>
x.EmployeeId == employee.id && x.WorkshopId == workshopId && x.LeftWorkType == LeftWorkTempType.StartWork))
{
return op.Failed("این پرسنل در کارگاه شما قبلا افزوده شده است و در انتظار تایید میباشد");
}
var personalInfoResponse = await _uidService.GetPersonalInfo(nationalCode, birthDate);
if (personalInfoResponse != null)
{
if (employee.IsAuthorized == false)
{
if (personalInfoResponse.ResponseContext.Status.Code == 0)
{
var basicInfo = personalInfoResponse.BasicInformation;
var identityInfo = personalInfoResponse.IdentificationInformation;
var apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime();
var gender = basicInfo.GenderEnum switch
{
Gender.Female => "زن",
Gender.Male => "مرد",
_ => throw new AggregateException()
};
var idNumber = identityInfo.ShenasnamehNumber == "0" ? identityInfo.NationalId : identityInfo.ShenasnamehNumber;
employee.Edit(basicInfo.FirstName, basicInfo.LastName, basicInfo.FatherName, apiBirthDate,
employee.DateOfIssue, employee.PlaceOfIssue, identityInfo.NationalId, idNumber,
gender, "ایرانی", employee.Phone, employee.Address, employee.State, employee.City,
employee.MaritalStatus, employee.MilitaryService, employee.LevelOfEducation,
employee.FieldOfStudy, employee.BankCardNumber, employee.BankBranch, employee.InsuranceCode, employee.InsuranceHistoryByYear,
employee.InsuranceHistoryByMonth, employee.NumberOfChildren,
employee.OfficePhone, employee.MclsUserName, employee.MclsPassword,
employee.EserviceUserName, employee.EservicePassword, employee.TaxOfficeUserName,
employee.TaxOfficepassword, employee.SanaUserName, employee.SanaPassword);
employee.Authorized();
await _EmployeeRepository.SaveChangesAsync();
}
else
{
return op.Failed("کد ملی با تاریخ تولد وارد شده مطابقت ندارد");
}
}
else if (employee.DateOfBirth.ToFarsi() != birthDate || employee.NationalCode != nationalCode)
{ {
return op.Failed("کد ملی با تاریخ تولد وارد شده مطابقت ندارد"); return op.Failed("کد ملی با تاریخ تولد وارد شده مطابقت ندارد");
} }
} }
else if (employee.DateOfBirth.ToFarsi() != birthDate || employee.NationalCode != nationalCode)
{
return op.Failed("کد ملی با تاریخ تولد وارد شده مطابقت ندارد");
}
var leftWorkViewModel = _leftWorkRepository.GetLastLeftWorkByEmployeeIdAndWorkshopId(workshopId, employee.id); var leftWorkViewModel = _leftWorkRepository.GetLastLeftWorkByEmployeeIdAndWorkshopId(workshopId, employee.id);
if (leftWorkViewModel == null) if (leftWorkViewModel == null)

View File

@@ -2371,6 +2371,11 @@ public class InsuranceListApplication : IInsuranceListApplication
return _insuranceListRepositpry.GetTabCounts(searchModel); return _insuranceListRepositpry.GetTabCounts(searchModel);
} }
public async Task<PagedResult<InsuranceClientListViewModel>> GetInsuranceClientList(InsuranceClientSearchModel searchModel)
{
return await _insuranceListRepositpry.GetInsuranceClientList(searchModel);
}
public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel) public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel)
{ {
return await _insuranceListRepositpry.GetNotCreatedWorkshop(searchModel); return await _insuranceListRepositpry.GetNotCreatedWorkshop(searchModel);

View File

@@ -384,6 +384,7 @@ public class RollCallApplication : IRollCallApplication
var workshopSettings = _customizeWorkshopSettingsRepository.GetBy(command.WorkshopId); var workshopSettings = _customizeWorkshopSettingsRepository.GetBy(command.WorkshopId);
var employeeSettings = var employeeSettings =
_customizeWorkshopEmployeeSettingsRepository.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings( _customizeWorkshopEmployeeSettingsRepository.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings(
command.WorkshopId, command.EmployeeId)?.WorkshopShiftStatus; command.WorkshopId, command.EmployeeId)?.WorkshopShiftStatus;

View File

@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Transactions; using System.Transactions;
using _0_Framework.Application.FaceEmbedding;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace CompanyManagment.Application; namespace CompanyManagment.Application;
@@ -23,7 +24,9 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
private readonly ILeftWorkRepository _leftWorkRepository; private readonly ILeftWorkRepository _leftWorkRepository;
private readonly IRollCallEmployeeStatusRepository _rollCallEmployeeStatusRepository; private readonly IRollCallEmployeeStatusRepository _rollCallEmployeeStatusRepository;
private readonly IWebHostEnvironment _webHostEnvironment; private readonly IWebHostEnvironment _webHostEnvironment;
public RollCallEmployeeApplication(IRollCallEmployeeRepository rollCallEmployeeRepository, IEmployeeRepository employeeRepository, IRollCallEmployeeStatusApplication rollCallEmployeeStatusApplication, ILeftWorkRepository leftWorkRepository, IRollCallEmployeeStatusRepository rollCallEmployeeStatusRepository, IWebHostEnvironment webHostEnvironment) private readonly IFaceEmbeddingService _faceEmbeddingService;
public RollCallEmployeeApplication(IRollCallEmployeeRepository rollCallEmployeeRepository, IEmployeeRepository employeeRepository, IRollCallEmployeeStatusApplication rollCallEmployeeStatusApplication, ILeftWorkRepository leftWorkRepository, IRollCallEmployeeStatusRepository rollCallEmployeeStatusRepository, IWebHostEnvironment webHostEnvironment, IFaceEmbeddingService faceEmbeddingService)
{ {
_rollCallEmployeeRepository = rollCallEmployeeRepository; _rollCallEmployeeRepository = rollCallEmployeeRepository;
_employeeRepository = employeeRepository; _employeeRepository = employeeRepository;
@@ -31,6 +34,7 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
_leftWorkRepository = leftWorkRepository; _leftWorkRepository = leftWorkRepository;
_rollCallEmployeeStatusRepository = rollCallEmployeeStatusRepository; _rollCallEmployeeStatusRepository = rollCallEmployeeStatusRepository;
_webHostEnvironment = webHostEnvironment; _webHostEnvironment = webHostEnvironment;
_faceEmbeddingService = faceEmbeddingService;
} }
public OperationResult Create(CreateRollCallEmployee command) public OperationResult Create(CreateRollCallEmployee command)
@@ -213,9 +217,18 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
if (entity.IsActiveString != "true") if (entity.IsActiveString != "true")
return result.Failed("امکان تغییر نام برای کارمند غیر فعال وجود ندارد"); return result.Failed("امکان تغییر نام برای کارمند غیر فعال وجود ندارد");
var transaction = _rollCallEmployeeRepository.BeginTransactionAsync().GetAwaiter().GetResult();
entity.ChangeName(fName, lName); entity.ChangeName(fName, lName);
_rollCallEmployeeRepository.SaveChanges(); _rollCallEmployeeRepository.SaveChanges();
var embeddingRes =_faceEmbeddingService
.UpdateEmbeddingFullNameAsync(entity.EmployeeId, entity.WorkshopId, fullName)
.GetAwaiter().GetResult();
if (!embeddingRes.IsSuccedded)
return result.Failed("خطا در به روز رسانی نام در سیستم تشخیص چهره: " + embeddingRes.Message);
transaction.Commit();
return result.Succcedded(); return result.Succcedded();
} }
#endregion #endregion

View File

@@ -64,7 +64,7 @@ public class CheckoutRepository : RepositoryBase<long, Checkout>, ICheckoutRepos
} }
/// <summary> /// <summary>
/// چیک میکند که آیا پرسنل در سال و ماه درخواستی در این کارگاه فیش حقوقی دارد یا خیر /// چک میکند که آیا پرسنل در سال و ماه درخواستی در این کارگاه فیش حقوقی دارد یا خیر
/// </summary> /// </summary>
/// <param name="workshopId"></param> /// <param name="workshopId"></param>
/// <param name="employeId"></param> /// <param name="employeId"></param>
@@ -74,12 +74,21 @@ public class CheckoutRepository : RepositoryBase<long, Checkout>, ICheckoutRepos
public (bool hasChekout, double FamilyAlloance, double OverTimePay, double RotatingShift, double Nightwork, double Fridaywork, double YraesPay) HasCheckout(long workshopId, long employeId, string year, string month) public (bool hasChekout, double FamilyAlloance, double OverTimePay, double RotatingShift, double Nightwork, double Fridaywork, double YraesPay) HasCheckout(long workshopId, long employeId, string year, string month)
{ {
var farisMonthName = Tools.ToFarsiMonthByNumber(month); var farisMonthName = Tools.ToFarsiMonthByNumber(month);
var res = _context.CheckoutSet.FirstOrDefault(x => var res = _context.CheckoutSet.FirstOrDefault(x =>
x.WorkshopId == workshopId && x.EmployeeId == employeId && x.Year == year && x.Month == farisMonthName && x.WorkshopId == workshopId && x.EmployeeId == employeId && x.Year == year && x.Month == farisMonthName &&
x.IsActiveString == "true"); x.IsActiveString == "true");
if (res == null) if (res == null)
return (false, 0, 0,0,0,0,0); {
var checkLeftDate = ($"{year}/{month}/01").ToGeorgianDateTime();
var hasLeftwork = _context.LeftWorkList.Any(x =>
x.EmployeeId == employeId && x.WorkshopId == workshopId && x.LeftWorkDate == checkLeftDate);
if(hasLeftwork)
return (true, 0, 0, 0, 0, 0, 0);
return (false, 0, 0, 0, 0, 0, 0);
}
return (true, res.FamilyAllowance, res.OvertimePay, res.ShiftPay, res.NightworkPay, res.FridayPay,res.YearsPay); return (true, res.FamilyAllowance, res.OvertimePay, res.ShiftPay, res.NightworkPay, res.FridayPay,res.YearsPay);
} }

View File

@@ -1194,41 +1194,99 @@ public class EmployeeDocumentsRepository : RepositoryBase<long, EmployeeDocument
{ {
return new List<WorkshopWithEmployeeDocumentsViewModel>(); return new List<WorkshopWithEmployeeDocumentsViewModel>();
} }
// Step 1: Get employee client temps in memory
var employeeClientTempData = await _companyContext.EmployeeClientTemps
.Where(x => workshops.Contains(x.WorkshopId))
.Select(x => new { x.WorkshopId, x.EmployeeId })
.ToListAsync();
// Step 2: Get employee documents with simplified filter
var employeeDocuments = await _companyContext.EmployeeDocuments
.Where(x => workshops.Contains(x.WorkshopId) && !x.IsConfirmed && !x.IsSentToChecker)
.Select(x => new
{
x.id,
x.WorkshopId,
x.EmployeeId,
x.IsConfirmed,
x.IsSentToChecker,
WorkshopName = x.Workshop.WorkshopName
})
.ToListAsync();
var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => workshops.Contains(x.WorkshopId)); var filteredDocuments = employeeDocuments
.Where(x => employeeClientTempData.Any(temp =>
temp.WorkshopId == x.WorkshopId && temp.EmployeeId == x.EmployeeId))
.ToList();
var groupedByWorkshop = filteredDocuments
.GroupBy(x => x.WorkshopId)
.Select(g => new
{
WorkshopId = g.Key,
WorkshopName = g.First().WorkshopName,
Count = g.Count()
})
.ToList();
var query = _companyContext.EmployeeDocuments // Step 5: Get workshop employers for the filtered workshops
.Where(x => workshops.Contains(x.WorkshopId) && var workshopIds = groupedByWorkshop.Select(x => x.WorkshopId).ToList();
employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId) && x.IsConfirmed == false &&x.IsSentToChecker == false) var workshopEmployers = await _companyContext.WorkshopEmployers
.Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) .Where(x => workshopIds.Contains(x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() .Include(x => x.Employer)
{ .GroupBy(x => x.WorkshopId)
WorkshopId = x.Key, .Select(g => g.FirstOrDefault())
WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopFullName, .ToListAsync();
EmployeesWithoutDocumentCount = x.Count()
}); // Step 6: Build result
var res = groupedByWorkshop
.Select(x => new WorkshopWithEmployeeDocumentsViewModel()
{
WorkshopId = x.WorkshopId,
WorkshopFullName = x.WorkshopName,
EmployeesWithoutDocumentCount = x.Count,
EmployerName = workshopEmployers
.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?
.Employer?.FullName
})
.Where(x => x.EmployeesWithoutDocumentCount > 0)
.OrderByDescending(x => x.EmployeesWithoutDocumentCount)
.ToList();
return res;
//var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => workshops.Contains(x.WorkshopId));
// var query = _companyContext.EmployeeDocuments
// .Where(x => workshops.Contains(x.WorkshopId) &&
// employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId) && x.IsConfirmed == false &&x.IsSentToChecker == false)
// .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection)
// .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel()
// {
// WorkshopId = x.Key,
// WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopFullName,
// EmployeesWithoutDocumentCount = x.Count()
// });
var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer) // var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer)
.Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) // .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync(); // .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync();
var result = await query.ToListAsync(); // var result = await query.ToListAsync();
result.ForEach(x => // result.ForEach(x =>
{ // {
var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer; // var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer;
x.EmployerName = employer?.FullName; // x.EmployerName = employer?.FullName;
//x.SubmittedItems.ForEach(y=>y.PicturePath= medias.FirstOrDefault(z=>z.id == y.MediaId)?.Path ?? ""); // //x.SubmittedItems.ForEach(y=>y.PicturePath= medias.FirstOrDefault(z=>z.id == y.MediaId)?.Path ?? "");
}); // });
return result.Where(x => x.EmployeesWithoutDocumentCount > 0).OrderByDescending(x => x.EmployeesWithoutDocumentCount).ToList(); // return result.Where(x => x.EmployeesWithoutDocumentCount > 0).OrderByDescending(x => x.EmployeesWithoutDocumentCount).ToList();
} }
public async Task<List<EmployeeDocumentsViewModel>> GetCreatedEmployeesDocumentByWorkshopIdForAdmin(long workshopId) public async Task<List<EmployeeDocumentsViewModel>> GetCreatedEmployeesDocumentByWorkshopIdForAdmin(long workshopId)
@@ -1347,33 +1405,37 @@ public class EmployeeDocumentsRepository : RepositoryBase<long, EmployeeDocument
// ترکیب کل لیست‌ها در حافظه // ترکیب کل لیست‌ها در حافظه
var allActiveEmployees = activeEmployees var allActiveEmployees = activeEmployees
.Concat(clientTemp) .Concat(clientTemp)
.Concat(leftWorkTemp); .Concat(leftWorkTemp).ToList();
var contractingPartyIds = _companyContext.WorkshopEmployers.Where(x => workshops.Contains(x.WorkshopId)) var contractingPartyIds = _companyContext.WorkshopEmployers.Where(x => workshops.Contains(x.WorkshopId))
.Include(x => x.Employer).Select(x => x.Employer.ContractingPartyId).Distinct(); .Include(x => x.Employer).Select(x => x.Employer.ContractingPartyId).Distinct().ToList();
var accountIds = await _companyContext.ContractingPartyAccounts var accountIds = await _companyContext.ContractingPartyAccounts
.Where(x => contractingPartyIds.Contains(x.PersonalContractingPartyId)).Select(x => x.AccountId) .Where(x => contractingPartyIds.Contains(x.PersonalContractingPartyId)).Select(x => x.AccountId)
.ToListAsync(); .ToListAsync();
var query = _companyContext.EmployeeDocuments var query =await _companyContext.EmployeeDocuments
.Where(x => workshops.Contains(x.WorkshopId) && .Where(x => workshops.Contains(x.WorkshopId))
(allActiveEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId)))
.Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection)
.Where(x => x.IsSentToChecker == false && x.HasRejectedItems && x.EmployeeDocumentItemCollection.Any(i => i.DocumentStatus == DocumentStatus.Rejected && accountIds.Contains(i.UploaderId))) .Where(x => x.IsSentToChecker == false && x.HasRejectedItems && x.EmployeeDocumentItemCollection.Any(i => i.DocumentStatus == DocumentStatus.Rejected && accountIds.Contains(i.UploaderId)))
.GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel()
{ {
WorkshopId = x.Key, WorkshopId = x.Key,
WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName,
EmployeesWithoutDocumentCount = x.Count() EmployeesWithoutDocumentCount = x.Count(),
}); EmployeeId = x.First().EmployeeId
}).ToListAsync();
query = query.Where(x =>
(allActiveEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId))).ToList();
var resWorkshopIds = query.Select(x => x.WorkshopId).ToList();
var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer) var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer)
.Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) .Where(x => resWorkshopIds.Contains(x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync(); .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync();
var result = await query.ToListAsync(); var result = query;
result.ForEach(x => result.ForEach(x =>

View File

@@ -1,15 +1,4 @@
using System; using _0_Framework.Application;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using _0_Framework.Application;
using _0_Framework.Application.Enums; using _0_Framework.Application.Enums;
using _0_Framework.Application.Sms; using _0_Framework.Application.Sms;
using _0_Framework.Exceptions; using _0_Framework.Exceptions;
@@ -38,6 +27,7 @@ using CompanyManagment.App.Contracts.Law;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop; using CompanyManagment.App.Contracts.Workshop;
using CompanyManagment.App.Contracts.WorkshopPlan; using CompanyManagment.App.Contracts.WorkshopPlan;
using CompanyManagment.EFCore.Migrations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -47,10 +37,23 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MongoDB.Driver; using MongoDB.Driver;
using OfficeOpenXml.Packaging.Ionic.Zip; using OfficeOpenXml.Packaging.Ionic.Zip;
using PersianTools.Core; using PersianTools.Core;
using static System.Runtime.InteropServices.JavaScript.JSType; using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
using SmsResult = CompanyManagment.EFCore.Migrations.SmsResult; using static System.Runtime.InteropServices.JavaScript.JSType;
using ContractingPartyAccount = Company.Domain.ContractingPartyAccountAgg.ContractingPartyAccount;
using FinancialStatment = Company.Domain.FinancialStatmentAgg.FinancialStatment;
using String = System.String; using String = System.String;
using Workshop = Company.Domain.WorkshopAgg.Workshop;
namespace CompanyManagment.EFCore.Repository; namespace CompanyManagment.EFCore.Repository;
@@ -102,69 +105,69 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
public EditInstitutionContract GetDetails(long id) public EditInstitutionContract GetDetails(long id)
{ {
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract() return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{ {
Id = x.id, Id = x.id,
ContractNo = x.ContractNo, ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr, ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa, ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr, ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa, ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName, RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName, ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId, RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId, ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa, ContractDateFa = x.ContractDateFa,
State = x.State, State = x.State,
City = x.City, City = x.City,
Address = x.Address, Address = x.Address,
Description = x.Description, Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount, WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount, EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(), ContractAmountString = x.ContractAmount.ToMoney(),
ContractAmount = x.ContractAmount, ContractAmount = x.ContractAmount,
DailyCompenseationString = x.DailyCompenseation.ToMoney(), DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(), ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(), TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo, ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany, OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract, TypeOfContract = x.TypeOfContract,
Signature = x.Signature, Signature = x.Signature,
HasValueAddedTax = x.HasValueAddedTax, HasValueAddedTax = x.HasValueAddedTax,
ValueAddedTax = x.ValueAddedTax, ValueAddedTax = x.ValueAddedTax,
}) })
.FirstOrDefault(x => x.Id == id); .FirstOrDefault(x => x.Id == id);
} }
public EditInstitutionContract GetFirstContract(long contractingPartyId, string typeOfContract) public EditInstitutionContract GetFirstContract(long contractingPartyId, string typeOfContract)
{ {
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract() return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{ {
Id = x.id, Id = x.id,
ContractNo = x.ContractNo, ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr, ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa, ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr, ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa, ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName, RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName, ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId, RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId, ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa, ContractDateFa = x.ContractDateFa,
State = x.State, State = x.State,
City = x.City, City = x.City,
Address = x.Address, Address = x.Address,
Description = x.Description, Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount, WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount, EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(), ContractAmountString = x.ContractAmount.ToMoney(),
DailyCompenseationString = x.DailyCompenseation.ToMoney(), DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(), ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(), TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo, ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany, OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract, TypeOfContract = x.TypeOfContract,
Signature = x.Signature Signature = x.Signature
}) })
.Where(x => x.ContractingPartyId == contractingPartyId && x.TypeOfContract == typeOfContract) .Where(x => x.ContractingPartyId == contractingPartyId && x.TypeOfContract == typeOfContract)
.OrderBy(x => x.ExtensionNo).FirstOrDefault(); .OrderBy(x => x.ExtensionNo).FirstOrDefault();
} }
@@ -582,40 +585,40 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
}).ToList(), }).ToList(),
}).ToList(); }).ToList();
listQuery = listQuery.Select(x => new InstitutionContractViewModel() listQuery = listQuery.Select(x => new InstitutionContractViewModel()
{ {
Id = x.Id, Id = x.Id,
ContractNo = x.ContractNo, ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr, ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa, ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr, ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa, ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId, RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName, RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName, ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId, ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount, ContractAmount = x.ContractAmount,
TotalAmount = x.TotalAmount, TotalAmount = x.TotalAmount,
SearchAmount = x.SearchAmount, SearchAmount = x.SearchAmount,
IsActiveString = x.IsActiveString, IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany, OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract, TypeOfContract = x.TypeOfContract,
Signature = x.Signature, Signature = x.Signature,
ExpireColor = x.ExpireColor, ExpireColor = x.ExpireColor,
IsExpier = x.IsExpier, IsExpier = x.IsExpier,
BalanceDouble = x.BalanceDouble, BalanceDouble = x.BalanceDouble,
BalanceStr = x.BalanceStr, BalanceStr = x.BalanceStr,
EmployerViewModels = x.EmployerViewModels, EmployerViewModels = x.EmployerViewModels,
EmployerNo = x.EmployerNo, EmployerNo = x.EmployerNo,
EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(), EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(),
WorkshopViewModels = x.WorkshopViewModels, WorkshopViewModels = x.WorkshopViewModels,
WorkshopCount = x.WorkshopCount, WorkshopCount = x.WorkshopCount,
IsContractingPartyBlock = x.IsContractingPartyBlock, IsContractingPartyBlock = x.IsContractingPartyBlock,
BlockTimes = x.BlockTimes, BlockTimes = x.BlockTimes,
EmployeeCount = EmployeeCount =
((x.WorkshopViewModels.Sum(w => w.LeftWorkIds.Count)) + (x.WorkshopViewModels.Sum(w => ((x.WorkshopViewModels.Sum(w => w.LeftWorkIds.Count)) + (x.WorkshopViewModels.Sum(w =>
w.InsuranceLeftWorkIds.Count(c => !w.LeftWorkIds.Contains(c))))).ToString(), w.InsuranceLeftWorkIds.Count(c => !w.LeftWorkIds.Contains(c))))).ToString(),
ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0, ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0,
}).OrderBy(x => x.WorkshopCount != "0" && string.IsNullOrWhiteSpace(x.ExpireColor)) }).OrderBy(x => x.WorkshopCount != "0" && string.IsNullOrWhiteSpace(x.ExpireColor))
.ThenBy(x => x.WorkshopCount == "0" && string.IsNullOrWhiteSpace(x.ExpireColor)) .ThenBy(x => x.WorkshopCount == "0" && string.IsNullOrWhiteSpace(x.ExpireColor))
.ThenBy(x => x.IsExpier == "true") .ThenBy(x => x.IsExpier == "true")
.ThenBy(x => x.ExpireColor == "purple") .ThenBy(x => x.ExpireColor == "purple")
@@ -640,17 +643,17 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var op = new OperationResult(); var op = new OperationResult();
var institutionContarct = _context.InstitutionContractSet var institutionContarct = _context.InstitutionContractSet
.FirstOrDefault(x => x.id == id); .FirstOrDefault(x => x.id == id);
var prevInstitutionContracts = _context.InstitutionContractSet var prevInstitutionContracts = _context.InstitutionContractSet
.Where(x => x.ContractingPartyId == institutionContarct.ContractingPartyId) .Where(x => x.ContractingPartyId == institutionContarct.ContractingPartyId)
.OrderByDescending(x => x.ContractEndGr).Skip(1).FirstOrDefault(); .OrderByDescending(x => x.ContractEndGr).Skip(1).FirstOrDefault();
var transaction = _context.Database.BeginTransaction(); var transaction = _context.Database.BeginTransaction();
var contactInfo = _context.InstitutionContractContactInfos var contactInfo = _context.InstitutionContractContactInfos
.Where(x => x.InstitutionContractId == id) .Where(x => x.InstitutionContractId == id)
.ToList(); .ToList();
if (contactInfo.Count > 0) if (contactInfo.Count > 0)
{ {
foreach (var item in contactInfo) foreach (var item in contactInfo)
@@ -673,20 +676,20 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var financialStatement = var financialStatement =
_context.FinancialStatments _context.FinancialStatments
.Include(x => x.FinancialTransactionList) .Include(x => x.FinancialTransactionList)
.FirstOrDefault(x=>x.ContractingPartyId == institutionContarct.ContractingPartyId); .FirstOrDefault(x => x.ContractingPartyId == institutionContarct.ContractingPartyId);
if (financialStatement != null) if (financialStatement != null)
{ {
var sumDebtor = financialStatement.FinancialTransactionList var sumDebtor = financialStatement.FinancialTransactionList
.Sum(x => x.Deptor); .Sum(x => x.Deptor);
var sumCreditor = financialStatement.FinancialTransactionList var sumCreditor = financialStatement.FinancialTransactionList
.Sum(x => x.Creditor); .Sum(x => x.Creditor);
var balance = sumDebtor - sumCreditor; var balance = sumDebtor - sumCreditor;
if (balance>0 && prevInstitutionContracts.ContractEndGr<now) if (balance > 0 && prevInstitutionContracts.ContractEndGr < now)
{ {
prevInstitutionContracts.DeActiveBlue(); prevInstitutionContracts.DeActiveBlue();
_context.SaveChanges(); _context.SaveChanges();
} }
} }
} }
@@ -3822,19 +3825,19 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var smsList = new List<BlockSmsListData>(); var smsList = new List<BlockSmsListData>();
var institutionContracts = await _context.InstitutionContractSet.Select(x => new InstitutionContractViewModel var institutionContracts = await _context.InstitutionContractSet.Select(x => new InstitutionContractViewModel
{ {
Id = x.id, Id = x.id,
ContractingPartyId = x.ContractingPartyId, ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName, ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr, ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa, ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr, ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa, ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString, IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount, ContractAmountDouble = x.ContractAmount,
OfficialCompany = x.OfficialCompany OfficialCompany = x.OfficialCompany
}).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate && }).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate &&
x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First()) x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First())
.ToListAsync(); .ToListAsync();
@@ -3928,9 +3931,12 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
{ {
smsList.Add(new BlockSmsListData() smsList.Add(new BlockSmsListData()
{ {
PhoneNumber = number.PhoneNumber, PartyName = partyName, PhoneNumber = number.PhoneNumber,
AccountType = accountType, Amount = amount, PartyName = partyName,
ContractingPartyId = contractingParty.id, InstitutionContractId = item.Id, AccountType = accountType,
Amount = amount,
ContractingPartyId = contractingParty.id,
InstitutionContractId = item.Id,
AproveId = aprove AproveId = aprove
}); });
} }
@@ -4118,11 +4124,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1, Amount = balanceToMoney,
Code2 = code2, InstitutionContractId = item.Id ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
}); });
} }
else else
@@ -4136,10 +4147,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "", Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id InstitutionContractId = item.Id
}); });
} }
@@ -4171,11 +4187,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1, Amount = balanceToMoney,
Code2 = code2, InstitutionContractId = item.Id ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
}); });
} }
else else
@@ -4189,10 +4210,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "", Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id InstitutionContractId = item.Id
}); });
} }
@@ -4228,11 +4254,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1, Amount = balanceToMoney,
Code2 = code2, InstitutionContractId = item.Id ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
}); });
} }
else else
@@ -4246,10 +4277,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "", Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id InstitutionContractId = item.Id
}); });
} }
@@ -4284,11 +4320,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
string code2 = publicId.Substring(25); string code2 = publicId.Substring(25);
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1, Amount = balanceToMoney,
Code2 = code2, InstitutionContractId = item.Id ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
}); });
} }
else else
@@ -4302,10 +4343,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData() smsList.Add(new SmsListData()
{ {
PhoneNumber = number.PhoneNumber, TemplateId = templateId, PhoneNumber = number.PhoneNumber,
PartyName = partyName, Amount = balanceToMoney, TemplateId = templateId,
ContractingPartyId = contractingParty.id, AproveId = aprove, PartyName = partyName,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "", Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id InstitutionContractId = item.Id
}); });
} }
@@ -4466,6 +4512,9 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
#endregion #endregion
} }
#region PrivateMetods #region PrivateMetods
/// <summary> /// <summary>
@@ -4507,6 +4556,88 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId); .FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
} }
#endregion
#region InstitutionContractConfirm
/// <summary>
/// ارسال پیامک یادآور تایید قراداد مالی
/// </summary>
/// <returns></returns>
public async Task SendInstitutionContractConfirmSmsTask()
{
var now = DateTime.Now;
// تبدیل تاریخ میلادی به شمسی
var persianNow = now.ToFarsi();
var persianEndOfMonth = int.Parse(persianNow.FindeEndOfMonth().Substring(8, 2));
var dayOfMonth = int.Parse(persianNow.Substring(8, 2));
var hour = now.Hour;
var minute = now.Minute;
var checkAnyToExecute = false;
//اگر آخرین روز ماه باشد
//اگر روز مثلا عدد روز 31 بود ولی آخرین روز ماه 30 بود
if (dayOfMonth == persianEndOfMonth)
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth >= dayOfMonth && /// اگر بزرگتر یا مساوی رو جاری بود
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractConfirm &&
x.IsActive
);
}
else
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth == dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractConfirm &&
x.IsActive
);
}
if (checkAnyToExecute)
{
//اجرای تسک
//دریافت لیست قراداد های تایید نشده
var fromAmonthAgo = now.AddDays(-30);
var pendingContracts = await _context.InstitutionContractSet
.Where(x => x.CreationDate >= fromAmonthAgo && x.CreationDate.Date != now.Date && x.VerificationStatus == InstitutionContractVerificationStatus.PendingForVerify)
.Join(_context.PersonalContractingParties,
contract => contract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, contractingParty) => new { contract, contractingParty }).Select(x => new InstitutionCreationVerificationSmsDto
{
Number = x.contractingParty.Phone,
FullName = x.contractingParty.IsLegal == "حقیقی" ? $"{x.contractingParty.FName} {x.contractingParty.LName}" : $"{x.contractingParty.LName}",
ContractingPartyId = x.contract.ContractingPartyId,
InstitutionContractId = x.contract.id,
InstitutionId = x.contract.PublicId,
}).ToListAsync();
string typeOfSms = "یادآور تایید قرارداد مالی";
foreach (var item in pendingContracts)
{
var sendResult = await _smsService.SendInstitutionCreationVerificationLink(item.Number, item.FullName,
item.InstitutionId, item.ContractingPartyId, item.InstitutionContractId, typeOfSms);
}
Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute);
}
}
#endregion #endregion
#endregion #endregion
@@ -4550,7 +4681,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
VerificationStatus = x.VerificationStatus, VerificationStatus = x.VerificationStatus,
InstallmentList = x.Installments InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel .Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr }) { AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(), .OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).Where(x => }).Where(x =>
x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0) x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0)
@@ -4594,7 +4725,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
VerificationStatus = x.VerificationStatus, VerificationStatus = x.VerificationStatus,
InstallmentList = x.Installments InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel .Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr }) { AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(), .OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).ToListAsync(); }).ToListAsync();

View File

@@ -1777,6 +1777,49 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
return res; return res;
} }
public async Task<PagedResult<InsuranceClientListViewModel>> GetInsuranceClientList(InsuranceClientSearchModel searchModel)
{
var workshopId = _authHelper.GetWorkshopId();
var query = _context.InsuranceListSet
.Select(x => new InsuranceClientListViewModel
{
Id = x.id,
WorkShopId = x.WorkshopId,
Year = x.Year,
YearInt = Convert.ToInt32(x.Year),
Month = x.Month,
MonthName = x.Month.ToFarsiMonthByNumber(),
MonthInt = Convert.ToInt32(x.Month),
}).Where(x => x.WorkShopId == workshopId);
if (searchModel.Year>0)
{
query = query.Where(x => x.YearInt == searchModel.Year);
}
if (searchModel.Month > 0)
{
query = query.Where(x => x.MonthInt == searchModel.Month);
}
var res = new PagedResult<InsuranceClientListViewModel>
{
TotalCount = query.Count()
};
query = searchModel.Sorting switch
{
"CreationDate-Max" => query.OrderByDescending(x => x.Id),
"CreationDate-Min" => query.OrderBy(x => x.Id),
"Month-Max" => query.OrderByDescending(x => x.MonthInt),
"Month-Min" => query.OrderBy(x => x.MonthInt),
"Year-Max" => query.OrderByDescending(x => x.YearInt),
"Year-Min" => query.OrderBy(x => x.YearInt),
_ => query.OrderByDescending(x => x.Id),
};
res.List =await query.ApplyPagination(searchModel.PageIndex,searchModel.PageSize).ToListAsync();
return res;
}
public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel) public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel)
{ {
if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year)) if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year))

View File

@@ -1994,8 +1994,9 @@ public class RollCallMandatoryRepository : RepositoryBase<long, RollCall>, IRoll
case "شنبه": case "شنبه":
w1 = 7; w1 = 7;
w2 = 14; w2 = 14;
w3 = 28; w3 = 21;
w4 = 31; w4 = 28;
w5 = 31;
break; break;
case "یکشنبه": case "یکشنبه":
w1 = 6; w1 = 6;
@@ -2361,6 +2362,7 @@ public class RollCallMandatoryRepository : RepositoryBase<long, RollCall>, IRoll
break; break;
} }
} }
} }
#endregion #endregion

View File

@@ -1,14 +1,32 @@
using System; using Microsoft.EntityFrameworkCore;
using System.Collections.Generic; using PersianTools.Core;
using System.Threading.Tasks;
using Shared.Contracts.Holidays; using Shared.Contracts.Holidays;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CompanyManagment.EFCore.Services; namespace CompanyManagment.EFCore.Services;
public class HolidayQueryService : IHolidayQueryService public class HolidayQueryService : IHolidayQueryService
{ {
public Task<List<HolidayDto>> GetHolidaysInDates(DateTime startDate, DateTime endDate) private readonly CompanyContext _context;
public HolidayQueryService(CompanyContext context)
{ {
throw new NotImplementedException(); _context = context;
}
public async Task<List<HolidayDto>> GetHolidaysInDates(DateTime startDate, DateTime endDate)
{
return await _context.HolidayItems.Where(x => x.Holidaydate >= startDate && x.Holidaydate <= endDate).Select(x=> new HolidayDto()
{
Holidaydate = x.Holidaydate,
HolidayId = x.id,
HolidayYear = x.HolidayYear
})
.ToListAsync();
} }
} }

View File

@@ -350,9 +350,12 @@ public class SmsService : ISmsService
} }
public async Task<bool> SendInstitutionCreationVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId) public async Task<bool> SendInstitutionCreationVerificationLink(string number, string fullName, Guid institutionId, long contractingPartyId, long institutionContractId, string typeOfSms)
{ {
var full = fullName; typeOfSms = string.IsNullOrWhiteSpace(typeOfSms) ? "لینک تاییدیه ایجاد قرارداد مالی" : typeOfSms;
var full = fullName;
var fullName1 = fullName; var fullName1 = fullName;
if (fullName.Length >= 25) if (fullName.Length >= 25)
{ {
@@ -377,8 +380,9 @@ public class SmsService : ISmsService
new("CODE1",firstPart), new("CODE1",firstPart),
new("CODE2",secondPart) new("CODE2",secondPart)
}); });
var smsResult = new SmsResult(verificationSendResult.Data.MessageId, verificationSendResult.Message, "لینک تاییدیه ایجاد قرارداد مالی", var smsResult = new SmsResult(verificationSendResult.Data.MessageId, verificationSendResult.Message, typeOfSms,
fullName, number, contractingPartyId, institutionContractId); fullName, number, contractingPartyId, institutionContractId);
await _smsResultRepository.CreateAsync(smsResult); await _smsResultRepository.CreateAsync(smsResult);
await _smsResultRepository.SaveChangesAsync(); await _smsResultRepository.SaveChangesAsync();

View File

@@ -106,6 +106,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.I
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Contracts", "Shared.Contracts\Shared.Contracts.csproj", "{08B234B6-783B-44E9-9961-4F97EAD16308}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Contracts", "Shared.Contracts\Shared.Contracts.csproj", "{08B234B6-783B-44E9-9961-4F97EAD16308}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{F61F77F5-9B14-49CC-870B-1C61D2636586}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -275,6 +277,7 @@ Global
{B57EB542-C028-4A77-9386-9DFF1E60FDCB} = {9D85672B-D48E-40B5-9804-0CE220E0E64C} {B57EB542-C028-4A77-9386-9DFF1E60FDCB} = {9D85672B-D48E-40B5-9804-0CE220E0E64C}
{D2B4F1D7-6336-4B30-910C-219F4119303F} = {D74D1E3B-3BE3-47EE-9914-785A8AD536E5} {D2B4F1D7-6336-4B30-910C-219F4119303F} = {D74D1E3B-3BE3-47EE-9914-785A8AD536E5}
{408281FE-615F-4CBE-BD95-2E86F5ACC6C3} = {C0AE9368-D4E7-450B-9713-929D319DE690} {408281FE-615F-4CBE-BD95-2E86F5ACC6C3} = {C0AE9368-D4E7-450B-9713-929D319DE690}
{08B234B6-783B-44E9-9961-4F97EAD16308} = {F61F77F5-9B14-49CC-870B-1C61D2636586}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E6CFB3A7-A7C8-4E82-8F06-F750408F0BA9} SolutionGuid = {E6CFB3A7-A7C8-4E82-8F06-F750408F0BA9}

View File

@@ -185,7 +185,7 @@ public class CreateOrEditCheckoutCommandHandler : IBaseCommandHandler<CreateOrEd
var endMonth = Convert.ToInt32(endDate.Substring(5, 2)); var endMonth = Convert.ToInt32(endDate.Substring(5, 2));
var endDay = Convert.ToInt32(endDate.Substring(8, 2)); var endDay = Convert.ToInt32(endDate.Substring(8, 2));
var persianEnd = new PersianDateTime(endYear, endMonth, endDay); var persianEnd = new PersianDateTime(endYear, endMonth, endDay);
var holidays = await _holidayQueryService.GetHolidaysInDates(start, end) ; var holidays = await _holidayQueryService.GetHolidaysInDates(start, end);
int mandatoryHours = 0; int mandatoryHours = 0;
for (var currentDay = persianStart; currentDay <= persianEnd; currentDay = currentDay.AddDays(1)) for (var currentDay = persianStart; currentDay <= persianEnd; currentDay = currentDay.AddDays(1))
{ {
@@ -205,13 +205,9 @@ public class CreateOrEditCheckoutCommandHandler : IBaseCommandHandler<CreateOrEd
Console.WriteLine((int)getDaySetting.ShiftDuration.TotalMinutes + " " + currentDay + " - " + day); Console.WriteLine((int)getDaySetting.ShiftDuration.TotalMinutes + " " + currentDay + " - " + day);
} }
} }
} }
//حقوق نهایی //حقوق نهایی
var monthlySalaryPay = (totalHoursWorked * monthlySalaryDefined) / mandatoryHours; var monthlySalaryPay = (totalHoursWorked * monthlySalaryDefined) / mandatoryHours;

View File

@@ -45,12 +45,15 @@ public class ChangeStatusSectionCommandHandler : IBaseCommandHandler<ChangeStatu
if (section.Status == TaskSectionStatus.InProgress) if (section.Status == TaskSectionStatus.InProgress)
{ {
// Coming FROM InProgress: Stop the active activity // Coming FROM InProgress: Stop the active activity
section.StopWork(currentUser, request.Status); section.StopWork(request.Status);
} }
else if (request.Status == TaskSectionStatus.InProgress) else if (request.Status == TaskSectionStatus.InProgress)
{ {
// Going TO InProgress: Start work and create activity // Going TO InProgress: Check if section has remaining time, then start work
section.StartWork(currentUser); if (!section.HasRemainingTime())
return OperationResult.ValidationError("زمان این بخش به پایان رسیده است");
section.StartWork();
} }
else else
{ {
@@ -82,11 +85,11 @@ public class ChangeStatusSectionCommandHandler : IBaseCommandHandler<ChangeStatu
// Valid transitions matrix // Valid transitions matrix
var validTransitions = new Dictionary<TaskSectionStatus, List<TaskSectionStatus>> var validTransitions = new Dictionary<TaskSectionStatus, List<TaskSectionStatus>>
{ {
{ TaskSectionStatus.ReadyToStart, new List<TaskSectionStatus> { TaskSectionStatus.InProgress } }, { TaskSectionStatus.ReadyToStart, [TaskSectionStatus.InProgress] },
{ TaskSectionStatus.InProgress, new List<TaskSectionStatus> { TaskSectionStatus.Incomplete, TaskSectionStatus.Completed } }, { TaskSectionStatus.InProgress, [TaskSectionStatus.Incomplete, TaskSectionStatus.Completed] },
{ TaskSectionStatus.Incomplete, new List<TaskSectionStatus> { TaskSectionStatus.InProgress, TaskSectionStatus.Completed } }, { TaskSectionStatus.Incomplete, [TaskSectionStatus.InProgress, TaskSectionStatus.Completed] },
{ TaskSectionStatus.Completed, new List<TaskSectionStatus> { TaskSectionStatus.InProgress, TaskSectionStatus.Incomplete } }, // Can return to InProgress or Incomplete { TaskSectionStatus.Completed, [TaskSectionStatus.InProgress, TaskSectionStatus.Incomplete] }, // Can return to InProgress or Incomplete
{ TaskSectionStatus.NotAssigned, new List<TaskSectionStatus> { TaskSectionStatus.InProgress, TaskSectionStatus.ReadyToStart } } { TaskSectionStatus.NotAssigned, [TaskSectionStatus.InProgress, TaskSectionStatus.ReadyToStart] }
}; };
if (!validTransitions.TryGetValue(currentStatus, out var allowedTargets)) if (!validTransitions.TryGetValue(currentStatus, out var allowedTargets))

View File

@@ -8,6 +8,8 @@ public class CreateProjectCommandValidator:AbstractValidator<CreateProjectComman
public CreateProjectCommandValidator() public CreateProjectCommandValidator()
{ {
RuleFor(x => x.Name) RuleFor(x => x.Name)
.MaximumLength(25)
.WithMessage("نام نمیتواند بیشتر از 25 کاراکتر باشد")
.NotEmpty() .NotEmpty()
.NotNull() .NotNull()
.WithMessage("نام نمیتواند خالی باشد"); .WithMessage("نام نمیتواند خالی باشد");

View File

@@ -2,13 +2,14 @@ using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Application.Modules.Projects.DTOs;
using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain._Common.Exceptions;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject;
public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectCommand> public class SetTimeProjectCommandHandler : IBaseCommandHandler<SetTimeProjectCommand>
{ {
private readonly IProjectRepository _projectRepository; private readonly IProjectRepository _projectRepository;
private readonly IProjectPhaseRepository _projectPhaseRepository; private readonly IProjectPhaseRepository _projectPhaseRepository;
@@ -16,7 +17,7 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IAuthHelper _authHelper; private readonly IAuthHelper _authHelper;
private long? _userId; private long? _userId;
public SetTimeProjectCommandHandler( public SetTimeProjectCommandHandler(
IProjectRepository projectRepository, IProjectRepository projectRepository,
@@ -40,11 +41,11 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
return await SetTimeForProjectTask(request, cancellationToken); return await SetTimeForProjectTask(request, cancellationToken);
default: default:
return OperationResult.Failure("سطح پروژه نامعتبر است"); return OperationResult.Failure("سطح پروژه نامعتبر است");
} }
} }
private async Task<OperationResult> SetTimeForProject(SetTimeProjectCommand request, CancellationToken cancellationToken) private async Task<OperationResult> SetTimeForProject(SetTimeProjectCommand request,
CancellationToken cancellationToken)
{ {
var project = await _projectRepository.GetWithFullHierarchyAsync(request.Id); var project = await _projectRepository.GetWithFullHierarchyAsync(request.Id);
if (project == null) if (project == null)
@@ -75,7 +76,8 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
return OperationResult.Success(); return OperationResult.Success();
} }
private async Task<OperationResult> SetTimeForProjectPhase(SetTimeProjectCommand request, CancellationToken cancellationToken) private async Task<OperationResult> SetTimeForProjectPhase(SetTimeProjectCommand request,
CancellationToken cancellationToken)
{ {
var phase = await _projectPhaseRepository.GetWithTasksAsync(request.Id); var phase = await _projectPhaseRepository.GetWithTasksAsync(request.Id);
if (phase == null) if (phase == null)
@@ -103,13 +105,13 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
return OperationResult.Success(); return OperationResult.Success();
} }
private async Task<OperationResult> SetTimeForProjectTask(SetTimeProjectCommand request, CancellationToken cancellationToken) private async Task<OperationResult> SetTimeForProjectTask(SetTimeProjectCommand request,
CancellationToken cancellationToken)
{ {
var task = await _projectTaskRepository.GetWithSectionsAsync(request.Id); var task = await _projectTaskRepository.GetWithSectionsAsync(request.Id);
if (task == null) if (task == null)
{ {
return OperationResult.NotFound("تسک یافت نشد"); return OperationResult.NotFound("تسک یافت نشد");
return OperationResult.NotFound("<22>Ә <20><><EFBFBD><EFBFBD> <20><><EFBFBD>");
} }
long? addedByUserId = _userId; long? addedByUserId = _userId;
@@ -127,12 +129,17 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
await _unitOfWork.SaveChangesAsync(cancellationToken); await _unitOfWork.SaveChangesAsync(cancellationToken);
return OperationResult.Success(); return OperationResult.Success();
} }
private void SetSectionTime(TaskSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId) private void SetSectionTime(TaskSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId)
{ {
var initData = sectionItem.InitData; var initData = sectionItem.InitData;
var initialTime = TimeSpan.FromHours(initData.Hours); var initialTime = TimeSpan.FromHours(initData.Hours);
if (initialTime <= TimeSpan.Zero)
{
return;
}
// تنظیم زمان اولیه // تنظیم زمان اولیه
section.UpdateInitialEstimatedHours(initialTime, initData.Description); section.UpdateInitialEstimatedHours(initialTime, initData.Description);
@@ -144,7 +151,7 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId);
} }
} }
// private void SetSectionTime(ProjectSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId) // private void SetSectionTime(ProjectSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId)
// { // {
// var initData = sectionItem.InitData; // var initData = sectionItem.InitData;
@@ -161,4 +168,4 @@ public class SetTimeProjectCommandHandler:IBaseCommandHandler<SetTimeProjectComm
// section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); // section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId);
// } // }
// } // }
} }

View File

@@ -1,4 +1,5 @@
using FluentValidation; using FluentValidation;
using FluentValidation.Validators;
using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Application.Modules.Projects.DTOs;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject;
@@ -15,6 +16,9 @@ public class SetTimeProjectCommandValidator:AbstractValidator<SetTimeProjectComm
RuleForEach(x => x.SectionItems) RuleForEach(x => x.SectionItems)
.SetValidator(command => new SetTimeProjectSectionItemValidator()); .SetValidator(command => new SetTimeProjectSectionItemValidator());
RuleFor(x => x.SectionItems)
.Must(sectionItems => sectionItems.Any(si => si.InitData?.Hours > 0))
.WithMessage("حداقل یکی از بخش‌ها باید مقدار ساعت معتبری داشته باشد.");
} }
} }
public class SetTimeProjectSectionItemValidator:AbstractValidator<SetTimeProjectSectionItem> public class SetTimeProjectSectionItemValidator:AbstractValidator<SetTimeProjectSectionItem>
@@ -30,13 +34,14 @@ public class SetTimeProjectSectionItemValidator:AbstractValidator<SetTimeProject
.SetValidator(new TimeDataValidator()); .SetValidator(new TimeDataValidator());
RuleForEach(x=>x.AdditionalTime) RuleForEach(x=>x.AdditionalTime)
.SetValidator(new TimeDataValidator()); .SetValidator(new AdditionalTimeDataValidator());
} }
} }
public class TimeDataValidator : AbstractValidator<SetTimeSectionTime> public class AdditionalTimeDataValidator: AbstractValidator<SetTimeSectionTime>
{ {
public TimeDataValidator() public AdditionalTimeDataValidator()
{ {
RuleFor(x => x.Hours) RuleFor(x => x.Hours)
.GreaterThanOrEqualTo(0) .GreaterThanOrEqualTo(0)
@@ -45,6 +50,13 @@ public class TimeDataValidator : AbstractValidator<SetTimeSectionTime>
RuleFor(x=>x.Description) RuleFor(x=>x.Description)
.MaximumLength(500) .MaximumLength(500)
.WithMessage("توضیحات نمی‌تواند بیشتر از 500 کاراکتر باشد."); .WithMessage("توضیحات نمی‌تواند بیشتر از 500 کاراکتر باشد.");
}
}
public class TimeDataValidator : AbstractValidator<SetTimeSectionTime>
{
public TimeDataValidator()
{
} }
} }

View File

@@ -132,91 +132,82 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler<GetProjectsListQuer
private async Task SetSkillFlags(List<GetProjectListDto> projects, CancellationToken cancellationToken) private async Task SetSkillFlags(List<GetProjectListDto> projects, CancellationToken cancellationToken)
{ {
if (!projects.Any())
return;
var projectIds = projects.Select(x => x.Id).ToList(); var projectIds = projects.Select(x => x.Id).ToList();
var hierarchyLevel = projects.First().Level;
// تنها تسک‌ها sections دارند، بنابراین برای سطوح مختلف باید متفاوت عمل کنیم
List<Guid> taskIds; switch (hierarchyLevel)
switch (projects.FirstOrDefault()?.Level)
{ {
case ProjectHierarchyLevel.Project: case ProjectHierarchyLevel.Project:
// برای پروژه‌ها، باید تمام تسک‌های زیرمجموعه را پیدا کنیم await SetSkillFlagsForProjects(projects, projectIds, cancellationToken);
var phaseIds = await _context.ProjectPhases
.Where(ph => projectIds.Contains(ph.ProjectId))
.Select(ph => ph.Id)
.ToListAsync(cancellationToken);
taskIds = await _context.ProjectTasks
.Where(t => phaseIds.Contains(t.PhaseId))
.Select(t => t.Id)
.ToListAsync(cancellationToken);
break; break;
case ProjectHierarchyLevel.Phase: case ProjectHierarchyLevel.Phase:
// برای فازها، تمام تسک‌های آن فازها را پیدا کنیم await SetSkillFlagsForPhases(projects, projectIds, cancellationToken);
taskIds = await _context.ProjectTasks
.Where(t => projectIds.Contains(t.PhaseId))
.Select(t => t.Id)
.ToListAsync(cancellationToken);
break; break;
case ProjectHierarchyLevel.Task: case ProjectHierarchyLevel.Task:
// برای تسک‌ها، خود آنها taskIds هستند await SetSkillFlagsForTasks(projects, projectIds, cancellationToken);
taskIds = projectIds;
break; break;
default:
return;
} }
}
if (!taskIds.Any()) private async Task SetSkillFlagsForProjects(List<GetProjectListDto> projects, List<Guid> projectIds, CancellationToken cancellationToken)
return; {
var projectSections = await _context.ProjectSections
var sections = await _context.TaskSections
.Include(x => x.Skill) .Include(x => x.Skill)
.Where(x => taskIds.Contains(x.TaskId)) .Where(s => projectIds.Contains(s.ProjectId))
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
if (!projectSections.Any())
return;
foreach (var project in projects) foreach (var project in projects)
{ {
List<Guid> relevantTaskIds; var sections = projectSections.Where(s => s.ProjectId == project.Id).ToList();
project.HasBackend = sections.Any(x => x.Skill?.Name == "Backend");
switch (project.Level) project.HasFront = sections.Any(x => x.Skill?.Name == "Frontend");
{ project.HasDesign = sections.Any(x => x.Skill?.Name == "UI/UX Design");
case ProjectHierarchyLevel.Project: }
// برای پروژه، تمام تسک‌های زیرمجموعه }
var projectPhaseIds = await _context.ProjectPhases
.Where(ph => ph.ProjectId == project.Id) private async Task SetSkillFlagsForPhases(List<GetProjectListDto> projects, List<Guid> phaseIds, CancellationToken cancellationToken)
.Select(ph => ph.Id) {
.ToListAsync(cancellationToken); var phaseSections = await _context.PhaseSections
.Include(x => x.Skill)
relevantTaskIds = await _context.ProjectTasks .Where(s => phaseIds.Contains(s.PhaseId))
.Where(t => projectPhaseIds.Contains(t.PhaseId)) .ToListAsync(cancellationToken);
.Select(t => t.Id)
.ToListAsync(cancellationToken); if (!phaseSections.Any())
break; return;
case ProjectHierarchyLevel.Phase: foreach (var phase in projects)
// برای فاز، تمام تسک‌های آن فاز {
relevantTaskIds = await _context.ProjectTasks var sections = phaseSections.Where(s => s.PhaseId == phase.Id).ToList();
.Where(t => t.PhaseId == project.Id) phase.HasBackend = sections.Any(x => x.Skill?.Name == "Backend");
.Select(t => t.Id) phase.HasFront = sections.Any(x => x.Skill?.Name == "Frontend");
.ToListAsync(cancellationToken); phase.HasDesign = sections.Any(x => x.Skill?.Name == "UI/UX Design");
break; }
}
case ProjectHierarchyLevel.Task:
// برای تسک، خود آن private async Task SetSkillFlagsForTasks(List<GetProjectListDto> projects, List<Guid> taskIds, CancellationToken cancellationToken)
relevantTaskIds = new List<Guid> { project.Id }; {
break; var taskSections = await _context.TaskSections
.Include(x => x.Skill)
default: .Where(s => taskIds.Contains(s.TaskId))
continue; .ToListAsync(cancellationToken);
}
if (!taskSections.Any())
var projectSections = sections.Where(x => relevantTaskIds.Contains(x.TaskId)).ToList(); return;
project.HasBackend = projectSections.Any(x => x.Skill.Name == "Backend");
project.HasFront = projectSections.Any(x => x.Skill.Name == "Frontend"); foreach (var task in projects)
project.HasDesign = projectSections.Any(x => x.Skill.Name == "UI/UX Design"); {
var sections = taskSections.Where(s => s.TaskId == task.Id).ToList();
task.HasBackend = sections.Any(x => x.Skill?.Name == "Backend");
task.HasFront = sections.Any(x => x.Skill?.Name == "Frontend");
task.HasDesign = sections.Any(x => x.Skill?.Name == "UI/UX Design");
} }
} }

View File

@@ -0,0 +1,74 @@
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain._Common;
using Microsoft.EntityFrameworkCore;
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail;
public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery<ProjectBoardDetailResponse>;
public record ProjectBoardDetailResponse(List<ProjectBoardDetailUserResponse> Users, string TotalTime);
public record ProjectBoardDetailUserResponse
{
public List<ProjectBoardDetailUserHistoryResponse> Histories { get; set; } = new();
public string UserFullName { get; set; }
public long UserId { get; set; }
}
public class ProjectBoardDetailUserHistoryResponse
{
public string Date { get; set; }
public string startTime { get; set; }
public string EndTime { get; set; }
public string TotalTime { get; set; }
}
public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDetailQuery, ProjectBoardDetailResponse>
{
private readonly IProgramManagerDbContext _programManagerDbContext;
public ProjectBoardDetailQueryHandler(IProgramManagerDbContext programManagerDbContext)
{
_programManagerDbContext = programManagerDbContext;
}
public async Task<OperationResult<ProjectBoardDetailResponse>> Handle(ProjectBoardDetailQuery request,
CancellationToken cancellationToken)
{
var section = await _programManagerDbContext.TaskSections
.Include(x => x.Activities)
.FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken);
if (section == null)
return OperationResult<ProjectBoardDetailResponse>.NotFound("بخش مورد نظر یافت نشد");
var userIds = section.Activities.Select(x => x.UserId).Distinct().ToList();
var usersDict = await _programManagerDbContext.Users
.Where(x => userIds.Contains(x.Id))
.ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken);
var totalTimeSpan = section.Activities
.Select(x => x.GetTimeSpent())
.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next));
var users = section.Activities.GroupBy(x => x.UserId).Select(x =>
{
return new ProjectBoardDetailUserResponse()
{
UserId = x.Key,
UserFullName = usersDict[x.Key],
Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse()
{
Date = h.StartDate.ToFarsi(),
startTime = h.StartDate.ToString("HH:mm"),
EndTime = h.EndDate?.ToString("HH:mm") ?? "-",
TotalTime = h.GetTimeSpent().ToString(@"hh\:mm")
}).ToList()
};
}).ToList();
var response = new ProjectBoardDetailResponse(users, $"{(int)totalTimeSpan.TotalHours}:{totalTimeSpan.Minutes:D2}");
return OperationResult<ProjectBoardDetailResponse>.Success(response);
}
}

View File

@@ -6,5 +6,5 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project
public record ProjectBoardListQuery: IBaseQuery<List<ProjectBoardListResponse>> public record ProjectBoardListQuery: IBaseQuery<List<ProjectBoardListResponse>>
{ {
} public TaskSectionStatus? Status { get; set; }
}

View File

@@ -1,6 +1,9 @@
using GozareshgirProgramManager.Application._Common.Constants;
using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList;
@@ -19,21 +22,35 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler<ProjectBoardListQu
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var currentUserId = _authHelper.GetCurrentUserId(); var currentUserId = _authHelper.GetCurrentUserId();
var data = await _programManagerDbContext.TaskSections.AsNoTracking() var queryable = _programManagerDbContext.TaskSections.AsNoTracking()
.Where(x => x.CurrentAssignedUserId == currentUserId)
.Where(x => x.InitialEstimatedHours > TimeSpan.Zero) .Where(x => x.InitialEstimatedHours > TimeSpan.Zero)
.Include(x => x.Task) .Include(x => x.Task)
.ThenInclude(x => x.Phase) .ThenInclude(x => x.Phase)
.ThenInclude(x => x.Project) .ThenInclude(x => x.Project)
.Include(x => x.Activities) .Include(x => x.Activities)
.Include(x => x.AdditionalTimes) .Include(x => x.AdditionalTimes).AsQueryable().
.ToListAsync(cancellationToken); Include(x => x.Skill).AsQueryable();
if (!_authHelper.HasPermission(ProgramManagerPermissionCode.Board.ViewAllUsersProjects.Code))
{
queryable = queryable.Where(x => x.CurrentAssignedUserId == currentUserId);
}
if (request.Status != null)
{
queryable = queryable.Where(x => x.Status == request.Status);
}
var data = await queryable.ToListAsync(cancellationToken);
var activityUserIds = data.SelectMany(x => x.Activities).Select(a => a.UserId).Distinct().ToList(); var activityUserIds = data.SelectMany(x => x.Activities).Select(a => a.UserId).Distinct().ToList();
var assignedUser = data.Select(x => x.CurrentAssignedUserId)
.Concat(data.Select(x => x.OriginalAssignedUserId)).ToList();
var allUserIds = activityUserIds.Concat(assignedUser).Distinct().ToList();
var users = await _programManagerDbContext.Users.AsNoTracking() var users = await _programManagerDbContext.Users.AsNoTracking()
.Where(x => activityUserIds.Contains(x.Id)) .Where(x => allUserIds.Contains(x.Id))
.Select(x => new { x.Id, x.FullName }) .Select(x => new { x.Id, x.FullName })
.ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken);
var result = data.Select(x => var result = data.Select(x =>
{ {
@@ -89,7 +106,11 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler<ProjectBoardListQu
CompleteSecond = x.FinalEstimatedHours.TotalSeconds, CompleteSecond = x.FinalEstimatedHours.TotalSeconds,
CurrentSecond = activityTimeData.Sum(a => a.TotalSeconds), CurrentSecond = activityTimeData.Sum(a => a.TotalSeconds),
Histories = mergedHistories Histories = mergedHistories
} },
OriginalUser = users.GetValueOrDefault(x.OriginalAssignedUserId, "ناشناس"),
AssignedUser = x.CurrentAssignedUserId == x.OriginalAssignedUserId ? null
: users.GetValueOrDefault(x.CurrentAssignedUserId, "ناشناس"),
SkillName = x.Skill?.Name??"-",
}; };
}).ToList(); }).ToList();

View File

@@ -10,6 +10,10 @@ public class ProjectBoardListResponse
public string TaskName { get; set; } public string TaskName { get; set; }
public ProjectProgressDto Progress { get; set; } public ProjectProgressDto Progress { get; set; }
public TaskSectionStatus SectionStatus { get; set; } public TaskSectionStatus SectionStatus { get; set; }
public string? AssignedUser { get; set; }
public string OriginalUser { get; set; }
public string SkillName { get; set; }
} }
public class ProjectProgressDto public class ProjectProgressDto
{ {

View File

@@ -0,0 +1,270 @@
using System.Reflection;
namespace GozareshgirProgramManager.Application._Common.Constants;
public static class ProgramManagerPermissionCode
{
/// <summary>
/// دسترسی به بخش مدیریت پروژه
/// </summary>
public const int Code = 99;
#region DeveloperUsers[تب کاربران برنامه نویسی]
/// <summary>
/// تب کاربران برنامه نویسی
/// </summary>
public static class DeveloperUsers
{
public const int Code = 9900;
/// <summary>
/// تب تعیین حقوق
/// </summary>
public static class SalaryDetermination
{
public const int Code = 990001;
/// <summary>
/// تعیین زمان
/// </summary>
public const int WorkingHoursDetermination = 990001;
}
/// <summary>
/// تب وضعیت کارکرد
/// </summary>
public static class WorkingStatus
{
public const int Code = 990002;
}
/// <summary>
/// تب فیش حقوقی
/// </summary>
public static class Checkout
{
public const int Code = 990003;
/// <summary>
/// ایجاد فیش
/// </summary>
public const int Create = 99000301;
/// <summary>
/// حذف تکی فیش
/// </summary>
public const int SingleDeletion = 99000302;
/// <summary>
/// حذف گروهی فیش ها
/// </summary>
public const int GroupDeletion = 99000303;
/// <summary>
/// محاسبه مجدد گروهی فیش ها
/// </summary>
public const int GroupReCompute = 99000304;
/// <summary>
/// محاسبه مجدد تکی فیش
/// </summary>
public const int SingleReCompute = 99000305;
}
}
#endregion
#region ProgramManager[تب مدیریت پروژه]
/// <summary>
/// تب مدیریت پروژه
/// </summary>
public static class ProgramManager
{
public const int Code = 9901;
/// <summary>
/// ایجاد پروژه
/// </summary>
public static class CreateProject
{
public const int Code = 9901;
}
/// <summary>
/// همه پروژه ها
/// </summary>
public static class AllProjects
{
public const int Code = 990102;
}
/// <summary>
/// تعیین کاربر
/// </summary>
public static class UserDetermination
{
public const int Code = 990106;
}
/// <summary>
/// تعیین زمان پروژه
/// </summary>
public static class ProjectTimeSetting
{
public const int Code = 990107;
}
/// <summary>
/// ویرایش پروژه
/// </summary>
public static class EditProject
{
public const int Code = 990108;
}
/// <summary>
/// حذف پروژه
/// </summary>
public static class DeleteProject
{
public const int Code = 990109;
}
/// <summary>
/// ایجاد بخش اصلی
/// </summary>
public static class CreateMainSection
{
public const int Code = 990110;
}
/// <summary>
/// ایجاد بخش فرعی
/// </summary>
public static class CreateSubSection
{
public const int Code = 990111;
}
}
#endregion
#region Board[تب اجرا]
/// <summary>
///تب اجرا
/// </summary>
public static class Board
{
public const int Code = 9902;
/// <summary>
/// تب همه
/// </summary>
public static class All
{
public const int Code = 990201;
}
/// <summary>
/// آماده اجرا
/// </summary>
public static class ReadyToRun
{
public const int Code = 990202;
}
/// <summary>
/// در حال اجرا
/// </summary>
public static class Running
{
public const int Code = 990203;
}
/// <summary>
/// نیمه کاره
/// </summary>
public static class Unfinished
{
public const int Code = 990204;
}
/// <summary>
/// اتمام اجرا
/// </summary>
public static class Finished
{
public const int Code = 990204;
}
/// <summary>
/// دیدن پروژه همه کاربران
/// </summary>
public static class ViewAllUsersProjects
{
public const int Code = 990206;
}
/// <summary>
/// ارجاع به دیگران
/// </summary>
public static class ReferralToOthers
{
public const int Code = 990207;
}
/// <summary>
/// چت
/// </summary>
public static class Chat
{
public const int Code = 990208;
}
}
#endregion
public static Dictionary<string, object> GetAllCodes()
{
var result = new Dictionary<string, object>();
void Collect(Type type, Dictionary<string, object> dict)
{
// Collect const int fields directly declared on this type
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach (var f in fields)
{
if (f.FieldType == typeof(int) && f.IsLiteral && !f.IsInitOnly)
{
var raw = f.GetRawConstantValue();
if (raw is int value)
{
dict[f.Name] = value;
}
}
}
// Recurse into nested types
var nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
foreach (var nt in nestedTypes)
{
var nestedDict = new Dictionary<string, object>();
Collect(nt, nestedDict);
if (nestedDict.Count > 0)
{
dict[nt.Name] = nestedDict;
}
}
}
Collect(typeof(ProgramManagerPermissionCode), result);
return result;
}
}

View File

@@ -71,6 +71,10 @@ public interface IAuthHelper
/// دریافت نام کامل کاربر جاری از Claims /// دریافت نام کامل کاربر جاری از Claims
/// </summary> /// </summary>
string? GetCurrentFullName(); string? GetCurrentFullName();
bool HasPermission(int permission);
List<int> GetPermissions();
} }

View File

@@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DNTPersianUtils.Core" Version="6.7.1" /> <PackageReference Include="DNTPersianUtils.Core" Version="6.7.1" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3" />
<PackageReference Include="PersianTools.Core" Version="2.0.4" /> <PackageReference Include="PersianTools.Core" Version="2.0.4" />
</ItemGroup> </ItemGroup>

View File

@@ -1,25 +0,0 @@
using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.HolidayItemAgg;
namespace GozareshgirProgramManager.Domain.HolidayAgg;
public class Holiday : EntityBase<long>
{
public Holiday(string year)
{
Year = year;
}
public string Year { get; private set; }
public List<HolidayItem> HolidayItems { get; set; }
public Holiday()
{
HolidayItems = new List<HolidayItem>();
}
public void Edit(string year)
{
Year = year;
}
}

View File

@@ -1,28 +0,0 @@
using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.HolidayAgg;
namespace GozareshgirProgramManager.Domain.HolidayItemAgg;
public class HolidayItem : EntityBase<long>
{
public HolidayItem(DateTime holidaydate, long holidayId, string holidayYear)
{
Holidaydate = holidaydate;
HolidayId = holidayId;
HolidayYear = holidayYear;
}
public DateTime Holidaydate { get; private set; }
public long HolidayId { get; private set; }
public string HolidayYear { get; private set; }
public Holiday Holidayss { get; set; }
public void Edit(DateTime holidaydate, long holidayId, string holidayYear)
{
Holidaydate = holidaydate;
HolidayId = holidayId;
HolidayYear = holidayYear;
}
}

View File

@@ -1,4 +1,5 @@
using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.SkillAgg.Entities;
namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities;
@@ -22,6 +23,7 @@ public class PhaseSection : EntityBase<Guid>
// Navigation property // Navigation property
public ProjectPhase Phase { get; private set; } = null!; public ProjectPhase Phase { get; private set; } = null!;
public Skill? Skill { get; set; }
public void UpdateUser(long userId) public void UpdateUser(long userId)
{ {

View File

@@ -1,4 +1,5 @@
using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.SkillAgg.Entities;
namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities;
@@ -21,6 +22,7 @@ public class ProjectSection : EntityBase<Guid>
public Guid SkillId { get; private set; } public Guid SkillId { get; private set; }
public Project Project { get; private set; } = null!; public Project Project { get; private set; } = null!;
public Skill? Skill { get; set; }
public void UpdateUser(long userId) public void UpdateUser(long userId)
{ {

View File

@@ -104,13 +104,8 @@ public class TaskSection : EntityBase<Guid>
UpdateStatus(TaskSectionStatus.NotAssigned); UpdateStatus(TaskSectionStatus.NotAssigned);
} }
public void StartWork(long userId, string? notes = null) public void StartWork(string? notes = null)
{ {
if (CurrentAssignedUserId != userId)
{
throw new BadRequestException("کاربر مجاز به شروع این بخش نیست");
}
// if (Status == TaskSectionStatus.Completed) // if (Status == TaskSectionStatus.Completed)
// { // {
// throw new BadRequestException("این بخش قبلاً تکمیل شده است"); // throw new BadRequestException("این بخش قبلاً تکمیل شده است");
@@ -121,14 +116,14 @@ public class TaskSection : EntityBase<Guid>
throw new BadRequestException("یک فعالیت در حال انجام وجود دارد"); throw new BadRequestException("یک فعالیت در حال انجام وجود دارد");
} }
var activity = new TaskSectionActivity(Id, userId, notes); var activity = new TaskSectionActivity(Id, CurrentAssignedUserId, notes);
_activities.Add(activity); _activities.Add(activity);
UpdateStatus(TaskSectionStatus.InProgress); UpdateStatus(TaskSectionStatus.InProgress);
} }
public void StopWork(long userId, TaskSectionStatus taskSectionStatus, string? endNotes = null) public void StopWork(TaskSectionStatus taskSectionStatus, string? endNotes = null)
{ {
var activeActivity = _activities.FirstOrDefault(a => a.IsActive); var activeActivity = _activities.FirstOrDefault(a => a.IsActive);
if (activeActivity == null) if (activeActivity == null)
@@ -136,11 +131,6 @@ public class TaskSection : EntityBase<Guid>
throw new BadRequestException("هیچ فعالیت فعالی یافت نشد"); throw new BadRequestException("هیچ فعالیت فعالی یافت نشد");
} }
if (activeActivity.UserId != userId)
{
throw new BadRequestException("کاربر مجاز به توقف این فعالیت نیست");
}
UpdateStatus(taskSectionStatus); UpdateStatus(taskSectionStatus);
activeActivity.StopWork(endNotes); activeActivity.StopWork(endNotes);
} }
@@ -220,4 +210,11 @@ public class TaskSection : EntityBase<Guid>
{ {
_additionalTimes.Clear(); _additionalTimes.Clear();
} }
public bool HasRemainingTime()
{
var totalSpent = GetTotalTimeSpent();
var finalEstimate = FinalEstimatedHours;
return totalSpent < finalEstimate;
}
} }

View File

@@ -9,4 +9,6 @@ public interface ITaskSectionRepository: IRepository<Guid,TaskSection>
Task<TaskSection?> GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default); Task<TaskSection?> GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default);
Task<List<TaskSection>> GetAssignedToUserAsync(long userId);
} }

View File

@@ -1,5 +1,7 @@
using System.Globalization; using System.Globalization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using PersianTools.Core; using PersianTools.Core;
@@ -1704,25 +1706,25 @@ public static class Tools
// return Convert.ToBase64String(bsonData); // return Convert.ToBase64String(bsonData);
//} //}
////بیسان هایی که بصورت لیست بودند استخراج میشود ////بیسان هایی که بصورت لیست بودند استخراج میشود
//public static List<T> DeserializeFromBsonList<T>(string base64Data) public static List<T> DeserializeFromBsonList<T>(string base64Data)
//{ {
// byte[] data = Convert.FromBase64String(base64Data); byte[] data = Convert.FromBase64String(base64Data);
// using MemoryStream memoryStream = new MemoryStream(data); using MemoryStream memoryStream = new MemoryStream(data);
// using BsonDataReader reader = new BsonDataReader(memoryStream); using BsonDataReader reader = new BsonDataReader(memoryStream);
// reader.ReadRootValueAsArray = true; reader.ReadRootValueAsArray = true;
// JsonSerializer serializer = new JsonSerializer(); JsonSerializer serializer = new JsonSerializer();
// return serializer.Deserialize<List<T>>(reader); return serializer.Deserialize<List<T>>(reader);
//} }
////بیسان هایی که بصورت تکی بودند استخراج میشود //بیسان هایی که بصورت تکی بودند استخراج میشود
//public static T DeserializeFromBson<T>(string base64Data) public static T DeserializeFromBson<T>(string base64Data)
//{ {
// byte[] bsonData = Convert.FromBase64String(base64Data); byte[] bsonData = Convert.FromBase64String(base64Data);
// using MemoryStream memoryStream = new MemoryStream(bsonData); using MemoryStream memoryStream = new MemoryStream(bsonData);
// using BsonDataReader bsonReader = new BsonDataReader(memoryStream); using BsonDataReader bsonReader = new BsonDataReader(memoryStream);
// JsonSerializer serializer = new JsonSerializer(); JsonSerializer serializer = new JsonSerializer();
// return serializer.Deserialize<T>(bsonReader); return serializer.Deserialize<T>(bsonReader);
//} }
//public static TimeOnly CalculateOffset(ICollection<CustomizeSifts> shiftDetailsRegularShifts) //public static TimeOnly CalculateOffset(ICollection<CustomizeSifts> shiftDetailsRegularShifts)
//{ //{

View File

@@ -0,0 +1,857 @@
// <auto-generated />
using System;
using GozareshgirProgramManager.Infrastructure.Persistence.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GozareshgirProgramManager.Infrastructure.Migrations
{
[DbContext(typeof(ProgramManagerDbContext))]
[Migration("20251215155149_add relation to phase section and projectsection to skill")]
partial class addrelationtophasesectionandprojectsectiontoskill
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CheckoutEndDate")
.HasColumnType("datetime2");
b.Property<DateTime>("CheckoutStartDate")
.HasColumnType("datetime2");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<double>("DeductionFromSalary")
.HasColumnType("float");
b.Property<string>("FullName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("MandatoryHours")
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<double>("MonthlySalaryDefined")
.HasColumnType("float");
b.Property<double>("MonthlySalaryPay")
.HasColumnType("float");
b.Property<int>("RemainingHours")
.HasColumnType("int");
b.Property<int>("TotalDaysWorked")
.HasColumnType("int");
b.Property<int>("TotalHoursWorked")
.HasColumnType("int");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Checkouts", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.HasKey("Id");
b.ToTable("Customers", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<Guid>("PhaseId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("PhaseId");
b.HasIndex("SkillId");
b.ToTable("PhaseSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<DateTime?>("PlannedEndDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("PlannedStartDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Projects", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("OrderIndex")
.HasColumnType("int");
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.ToTable("ProjectPhases", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.HasIndex("SkillId");
b.ToTable("ProjectSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("AllocatedTime")
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("DueDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<bool>("HasTimeOverride")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("OrderIndex")
.HasColumnType("int");
b.Property<Guid>("PhaseId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Priority")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.HasIndex("PhaseId");
b.ToTable("ProjectTasks", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long>("CurrentAssignedUserId")
.HasColumnType("bigint");
b.Property<string>("InitialDescription")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("InitialEstimatedHours")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<long>("OriginalAssignedUserId")
.HasColumnType("bigint");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<Guid>("TaskId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("SkillId");
b.HasIndex("TaskId");
b.ToTable("TaskSections", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<string>("EndNotes")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Notes")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<Guid>("SectionId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("StartDate")
.HasColumnType("datetime2");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("SectionId");
b.ToTable("TaskSectionActivities", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime2");
b.Property<long?>("AddedByUserId")
.HasColumnType("bigint");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Hours")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<string>("Reason")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<Guid?>("TaskSectionId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("TaskSectionId");
b.ToTable("TaskSectionAdditionalTimes", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long?>("GozareshgirRoleId")
.HasColumnType("bigint");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.HasKey("Id");
b.ToTable("PmRoles", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndSettingDate")
.HasColumnType("datetime2");
b.Property<bool>("HolidayWorking")
.HasColumnType("bit");
b.Property<double>("MonthlySalary")
.HasColumnType("float");
b.Property<DateTime?>("StartSettingDate")
.HasColumnType("datetime2");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("SalaryPaymentSetting", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.HasKey("Id");
b.ToTable("Skills", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<long?>("AccountId")
.HasColumnType("bigint");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Email")
.HasMaxLength(150)
.HasColumnType("nvarchar(150)");
b.Property<string>("FullName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Mobile")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<string>("Password")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("ProfilePhotoPath")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("VerifyCode")
.HasMaxLength(10)
.HasColumnType("nvarchar(10)");
b.HasKey("Id");
b.ToTable("Users", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime>("ExpiresAt")
.HasColumnType("datetime2");
b.Property<string>("IpAddress")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime?>("RevokedAt")
.HasColumnType("datetime2");
b.Property<string>("Token")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("UserAgent")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("ExpiresAt");
b.HasIndex("Token")
.IsUnique();
b.HasIndex("UserId");
b.ToTable("UserRefreshTokens", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
.WithMany("PhaseSections")
.HasForeignKey("PhaseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Phase");
b.Navigation("Skill");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project")
.WithMany("Phases")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project")
.WithMany("ProjectSections")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Project");
b.Navigation("Skill");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
.WithMany("Tasks")
.HasForeignKey("PhaseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Phase");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany("Sections")
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task")
.WithMany("Sections")
.HasForeignKey("TaskId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Skill");
b.Navigation("Task");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section")
.WithMany("Activities")
.HasForeignKey("SectionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Section");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null)
.WithMany("AdditionalTimes")
.HasForeignKey("TaskSectionId");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<int>("Code")
.HasColumnType("int");
b1.Property<long>("RoleId")
.HasColumnType("bigint");
b1.HasKey("Id");
b1.HasIndex("RoleId");
b1.ToTable("PmRolePermissions", (string)null);
b1.WithOwner("Role")
.HasForeignKey("RoleId");
b1.Navigation("Role");
});
b.Navigation("Permissions");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<TimeSpan>("EndShiftOne")
.HasColumnType("time(0)");
b1.Property<TimeSpan>("EndShiftTwo")
.HasColumnType("time(0)");
b1.Property<bool>("HasRestTime")
.HasColumnType("bit");
b1.Property<bool>("HasShiftOne")
.HasColumnType("bit");
b1.Property<bool>("HasShiftTow")
.HasColumnType("bit");
b1.Property<bool>("IsActiveDay")
.HasColumnType("bit");
b1.Property<int>("PersianDayOfWeek")
.HasColumnType("int");
b1.Property<TimeSpan>("RestTime")
.HasColumnType("time(0)");
b1.Property<long>("SalaryPaymentSettingId")
.HasColumnType("bigint");
b1.Property<int>("ShiftDurationInMinutes")
.HasColumnType("int");
b1.Property<TimeSpan>("StartShiftOne")
.HasColumnType("time(0)");
b1.Property<TimeSpan>("StartShiftTwo")
.HasColumnType("time(0)");
b1.HasKey("Id");
b1.HasIndex("SalaryPaymentSettingId");
b1.ToTable("WorkingHours", (string)null);
b1.WithOwner("SalaryPaymentSetting")
.HasForeignKey("SalaryPaymentSettingId");
b1.Navigation("SalaryPaymentSetting");
});
b.Navigation("WorkingHoursList");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<long>("RoleId")
.HasColumnType("bigint");
b1.Property<long>("UserId")
.HasColumnType("bigint");
b1.HasKey("Id");
b1.HasIndex("UserId");
b1.ToTable("RoleUsers", (string)null);
b1.WithOwner("User")
.HasForeignKey("UserId");
b1.Navigation("User");
});
b.Navigation("RoleUser");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User")
.WithMany("RefreshTokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{
b.Navigation("Phases");
b.Navigation("ProjectSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.Navigation("PhaseSections");
b.Navigation("Tasks");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.Navigation("Sections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.Navigation("Activities");
b.Navigation("AdditionalTimes");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b =>
{
b.Navigation("Sections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.Navigation("RefreshTokens");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GozareshgirProgramManager.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class addrelationtophasesectionandprojectsectiontoskill : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_ProjectSections_SkillId",
table: "ProjectSections",
column: "SkillId");
migrationBuilder.CreateIndex(
name: "IX_PhaseSections_SkillId",
table: "PhaseSections",
column: "SkillId");
migrationBuilder.AddForeignKey(
name: "FK_PhaseSections_Skills_SkillId",
table: "PhaseSections",
column: "SkillId",
principalTable: "Skills",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_ProjectSections_Skills_SkillId",
table: "ProjectSections",
column: "SkillId",
principalTable: "Skills",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_PhaseSections_Skills_SkillId",
table: "PhaseSections");
migrationBuilder.DropForeignKey(
name: "FK_ProjectSections_Skills_SkillId",
table: "ProjectSections");
migrationBuilder.DropIndex(
name: "IX_ProjectSections_SkillId",
table: "ProjectSections");
migrationBuilder.DropIndex(
name: "IX_PhaseSections_SkillId",
table: "PhaseSections");
}
}
}

View File

@@ -17,7 +17,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "10.0.0") .HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@@ -102,56 +102,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.ToTable("Customers", (string)null); b.ToTable("Customers", (string)null);
}); });
modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Year")
.IsRequired()
.HasMaxLength(4)
.HasColumnType("nvarchar(4)");
b.HasKey("Id");
b.ToTable("Holidays", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long>("HolidayId")
.HasColumnType("bigint");
b.Property<string>("HolidayYear")
.IsRequired()
.HasMaxLength(4)
.HasColumnType("nvarchar(4)");
b.Property<DateTime>("Holidaydate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.HasIndex("HolidayId");
b.ToTable("Holidayitems", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@@ -174,6 +124,8 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.HasIndex("PhaseId"); b.HasIndex("PhaseId");
b.HasIndex("SkillId");
b.ToTable("PhaseSections"); b.ToTable("PhaseSections");
}); });
@@ -284,6 +236,8 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.HasIndex("ProjectId"); b.HasIndex("ProjectId");
b.HasIndex("SkillId");
b.ToTable("ProjectSections"); b.ToTable("ProjectSections");
}); });
@@ -630,17 +584,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.ToTable("UserRefreshTokens", (string)null); b.ToTable("UserRefreshTokens", (string)null);
}); });
modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", "Holidayss")
.WithMany("HolidayItems")
.HasForeignKey("HolidayId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Holidayss");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{ {
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
@@ -649,7 +592,14 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Phase"); b.Navigation("Phase");
b.Navigation("Skill");
}); });
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
@@ -671,7 +621,14 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Project"); b.Navigation("Project");
b.Navigation("Skill");
}); });
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
@@ -856,11 +813,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.Navigation("User"); b.Navigation("User");
}); });
modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b =>
{
b.Navigation("HolidayItems");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{ {
b.Navigation("Phases"); b.Navigation("Phases");

View File

@@ -1,20 +0,0 @@
using GozareshgirProgramManager.Domain.HolidayItemAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings;
public class HolidayItemMapping : IEntityTypeConfiguration<HolidayItem>
{
public void Configure(EntityTypeBuilder<HolidayItem> builder)
{
builder.ToTable("Holidayitems");
builder.HasKey(x => x.Id);
builder.Property(x => x.HolidayYear).HasMaxLength(4);
builder.HasOne(x => x.Holidayss)
.WithMany(x => x.HolidayItems)
.HasForeignKey(x => x.HolidayId);
}
}

View File

@@ -1,20 +0,0 @@
using GozareshgirProgramManager.Domain.HolidayAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings;
public class HolidayMapping : IEntityTypeConfiguration<Holiday>
{
public void Configure(EntityTypeBuilder<Holiday> builder)
{
builder.ToTable("Holidays");
builder.HasKey(x => x.Id);
builder.Property(x => x.Year).HasMaxLength(4);
builder.HasMany(x => x.HolidayItems)
.WithOne(x => x.Holidayss)
.HasForeignKey(x => x.HolidayId);
}
}

View File

@@ -17,5 +17,11 @@ public class PhaseSectionMapping:IEntityTypeConfiguration<PhaseSection>
.WithMany(p => p.PhaseSections) .WithMany(p => p.PhaseSections)
.HasForeignKey(ps => ps.PhaseId) .HasForeignKey(ps => ps.PhaseId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
builder.HasOne(ps => ps.Skill)
.WithMany()
.HasForeignKey(ps => ps.SkillId)
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
} }
} }

View File

@@ -16,5 +16,11 @@ public class ProjectSectionMapping:IEntityTypeConfiguration<ProjectSection>
.WithMany(x => x.ProjectSections) .WithMany(x => x.ProjectSections)
.HasForeignKey(x => x.ProjectId) .HasForeignKey(x => x.ProjectId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
builder.HasOne(x => x.Skill)
.WithMany()
.HasForeignKey(x => x.SkillId)
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
} }
} }

View File

@@ -28,4 +28,11 @@ public class TaskSectionRepository:RepositoryBase<Guid,TaskSection>,ITaskSection
.Include(x => x.AdditionalTimes) .Include(x => x.AdditionalTimes)
.FirstOrDefaultAsync(x => x.Id == id, cancellationToken); .FirstOrDefaultAsync(x => x.Id == id, cancellationToken);
} }
public async Task<List<TaskSection>> GetAssignedToUserAsync(long userId)
{
return await _context.TaskSections
.Where(x => x.CurrentAssignedUserId == userId)
.ToListAsync();
}
} }

View File

@@ -1,5 +1,6 @@
using System.Security.Claims; using System.Security.Claims;
using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Domain._Common;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace GozareshgirProgramManager.Infrastructure.Services.Authentication; namespace GozareshgirProgramManager.Infrastructure.Services.Authentication;
@@ -106,6 +107,21 @@ public class AuthHelper : IAuthHelper
return _httpContextAccessor.HttpContext?.User?.FindFirst("FullName")?.Value; return _httpContextAccessor.HttpContext?.User?.FindFirst("FullName")?.Value;
} }
public bool HasPermission(int permission)
{
return GetPermissions().Any(x => x == permission);
}
public List<int> GetPermissions()
{
if (!IsAuthenticated())
return new List<int>();
var permissions = _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "permissions")
?.Value;
return Tools.DeserializeFromBsonList<int>(permissions); //Mahan
}
// /// <summary> // /// <summary>
// /// دریافت AccountId کاربر جاری از Claims // /// دریافت AccountId کاربر جاری از Claims
// /// </summary> // /// </summary>

View File

@@ -1,4 +1,5 @@
using GozareshgirProgramManager.Application._Common.Models; using System.Runtime.InteropServices;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject;
@@ -8,6 +9,7 @@ using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimePro
using GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; using GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectAssignDetails; using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectAssignDetails;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails;
using MediatR; using MediatR;
@@ -99,4 +101,11 @@ public class ProjectController : ProgramManagerBaseController
var res = await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }
[HttpGet("board/details")]
public async Task<ActionResult<OperationResult<ProjectBoardDetailResponse>>> GetProjectBoardDetails(Guid id)
{
var query = new ProjectBoardDetailQuery(id);
var res = await _mediator.Send(query);
return res;
}
} }

View File

@@ -129,7 +129,7 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="row"></div> <div class="row"></div>
<div class="form-group" style="margin: 29px 7px 0px;"> <div class="form-group" style="margin: 29px 7px 0px;">
<span> فعالیت کاربر در پروگرام منیجر </span> <span> فعالیت کاربر در مدیریت پروژه </span>
<span>&nbsp;</span> <span>&nbsp;</span>
<label class="switch"> <label class="switch">
<input id="checkAll" asp-for="IsProgramManagerUser" type="checkbox"/> <input id="checkAll" asp-for="IsProgramManagerUser" type="checkbox"/>
@@ -143,7 +143,7 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label asp-for="UserRoles" > نقش در پروگرام منیجر </label> <label asp-for="UserRoles" > انتخاب نقش در مدیریت پروژه </label>
<select disabled="disabled" class="form-control select-city" multiple="multiple" asp-for="UserRoles" asp-items="Model.RoleList"> <select disabled="disabled" class="form-control select-city" multiple="multiple" asp-for="UserRoles" asp-items="Model.RoleList">
<option value="0"></option> <option value="0"></option>
</select> </select>

View File

@@ -1,6 +1,10 @@
@model AccountManagement.Application.Contracts.Role.CreateRole @model AccountManagement.Application.Contracts.Role.CreateRole
@{ @{
<style> <style>
.modal .modal-dialog .modal-content{
width: 645px;
}
.child-check { .child-check {
margin-left: 15px; margin-left: 15px;
display: none; display: none;
@@ -224,9 +228,18 @@
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10323" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور قرارداد </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10323" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور قرارداد </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10324" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور بیمه ای </span> </label> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
</div> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="10324" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور بیمه ای </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="1032401" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه اضافه کار و حق عائله مندی در بیمه </span> </label>
</div>
</div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10327" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور مالیاتی </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10327" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور مالیاتی </span> </label>
</div> </div>
@@ -1014,7 +1027,7 @@
<!-- پروگرام منیجر --> <!-- پروگرام منیجر -->
<div class="parent-check"> @* <div class="parent-check">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
@@ -1024,111 +1037,281 @@
</div> </div> *@
<!-- مدیریت برنامه نویسان --> <!--### مدیریت پروژه ###-->
<div class="parent-check"> <div class="parent-check">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parent"> <input type="checkbox" value="99" class="check-btn" data-pm="" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت برنامه نویسان </span>&nbsp;</label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parent"> <input type="checkbox" value="99" class="check-btn" data-pm="" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت پروژه </span>&nbsp;</label>
<!-- مدیریت پروژه -->
<div class="child-check level2"> <!--=================================================-->
<!--#### تب کاربران برنامه نویسی ####-->
<div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="991" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت پروژه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9900" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب کاربران برنامه نویسی </span> </label>
<!-----------------------Sub Menu------------------->
<!-- تعیین حقوق -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="99101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد پروژه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990001" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب تعیین حقوق </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99000101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین زمان </span> </label>
</div>
</div>
<!-- وضعیت کارکرد -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990002" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب وضعیت کارکرد </span> </label>
</div>
<!-- فیش حقوقی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990003" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب فیش حقوقی </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000301" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد فیش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000302" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف تکی فیش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000303" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف گروهی فیش ها </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000304" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه مجدد گروهی فیش ها </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000305" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه مجدد تکی فیش</span> </label>
</div>
</div>
</div>
<!--=================================================-->
<!--#### تب مدیریت پروژه ####-->
<div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9901" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب مدیریت پروژه </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد پروژه </span> </label>
</div> </div>
<!-- ستون لیست پروژه -->
<!-- همه پروژه ها -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9911" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون لیست پروژه ها </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990102" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه پروژه ها </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99111" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99112" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات</span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99113" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش</span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99114" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف</span> </label>
</div>
</div> </div>
<!--ستون بخش اصلی --> <!-- پروژه های آماده برنامه ریزی -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9912" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون بخش اصلی </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990103" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های آماده برنامه ریزی </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99121" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99122" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99124" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99124" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف </span> </label>
</div>
</div> </div>
<!--ستون بخش فرعی --> <!-- پروژه های در حال اجرا -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9913" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون بخش اصلی </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990104" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های در حال اجرا </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99131" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99132" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99134" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99134" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف </span> </label>
</div>
</div> </div>
</div>
<!--اجرا--> <!-- پروژه های به اتمام رسیده -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990105" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های به اتمام رسیده </span> </label>
</div>
<!-- تعیین کاربر -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990106" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<!-- تعیین زمان پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990107" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین زمان پروژه </span> </label>
</div>
<!-- ویرایش پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990108" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش پروژه </span> </label>
</div>
<!-- حذف پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990109" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف پروژه </span> </label>
</div>
<!-- ایجاد بخش اصلی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990110" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد بخش اصلی </span> </label>
</div>
<!-- ایجاد بخش فرعی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990111" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد بخش فرعی </span> </label>
</div>
</div>
<!--=================================================-->
<!--#### تب اجرا ####-->
<div class="child-check level2"> <div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="992" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9902" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب اجرا </span> </label>
<!-- همه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990201" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه </span> </label>
</div>
<!-- آماده اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990202" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> آماده اجرا </span> </label>
</div>
<!-- در حال اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990203" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> در حال اجرا </span> </label>
</div>
<!-- نیمه کاره -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990204" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label>
</div>
<!-- اتمام اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990205" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label>
</div>
<!-- دیدن پروژه همه کاربران -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990206" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> دیدن پروژه همه کاربران </span> </label>
</div>
<!-- ارجاع به دیگران -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990207" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ارجاع به دیگران </span> </label>
</div>
<!-- چت -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990208" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> چت </span> </label>
</div>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="9921" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> آماده اجرا </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="9922" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> در حال اجرا </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="9023" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="9024" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> اتمام اجرا </span> </label>
</div>
</div>
</div> </div>
@@ -1324,6 +1507,13 @@
name="PmPermissions[${pmIndex}]" name="PmPermissions[${pmIndex}]"
value="${chk.checked ? chk.value : 0}"> value="${chk.checked ? chk.value : 0}">
`); `);
if(chk.checked && chk.value == 99){
$("#hiddenInput").append(`
<input class="item1" type="hidden"
name="Permissions[${normalIndex}]"
value="${chk.checked ? chk.value : 0}">`);
normalIndex++;
}
pmIndex++; pmIndex++;
} else { } else {
$("#hiddenInput").append(` $("#hiddenInput").append(`

View File

@@ -133,7 +133,7 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="row"></div> <div class="row"></div>
<div class="form-group" style="margin: 29px 7px 0px;"> <div class="form-group" style="margin: 29px 7px 0px;">
<span> فعالیت کاربر در پروگرام منیجر </span> <span> فعالیت کاربر درمدیریت پروژه </span>
<span>&nbsp;</span> <span>&nbsp;</span>
<label class="switch"> <label class="switch">
<input id="editcheckAll" asp-for="IsProgramManagerUser" type="checkbox"/> <input id="editcheckAll" asp-for="IsProgramManagerUser" type="checkbox"/>
@@ -148,7 +148,7 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label asp-for="UserRoles"> نقش در پروگرام منیجر </label> <label asp-for="UserRoles"> انتخاب نقش در مدیریت پروژه </label>
@if (Model.IsProgramManagerUser) @if (Model.IsProgramManagerUser)
{ {
<select class="form-control select-city editSelect" multiple="multiple" asp-for="UserRoles" asp-items="Model.RoleList"> <select class="form-control select-city editSelect" multiple="multiple" asp-for="UserRoles" asp-items="Model.RoleList">

View File

@@ -1,6 +1,10 @@
@model AccountManagement.Application.Contracts.Role.EditRole @model AccountManagement.Application.Contracts.Role.EditRole
@{ @{
<style> <style>
.modal .modal-dialog .modal-content {
width: 645px;
}
.child-check { .child-check {
margin-left: 15px; margin-left: 15px;
display: none; display: none;
@@ -224,9 +228,17 @@
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10323" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور قرارداد </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10323" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور قرارداد </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10324" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور بیمه ای </span> </label> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
</div> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="10324" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور بیمه ای </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="1032401" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه اضافه کار و حق عائله مندی در بیمه </span> </label>
</div>
</div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10327" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور مالیاتی </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="10327" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> تب امور مالیاتی </span> </label>
</div> </div>
@@ -1017,124 +1029,282 @@
</div> </div>
<!-- پروگرام منیجر --> <!--### مدیریت پروژه ###-->
<div class="parent-check"> <div class="parent-check">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parent"> <input type="checkbox" value="99" class="check-btn"> &nbsp;<span style="bottom: 2px;position: relative"> پروگرام منیجر </span>&nbsp;</label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parent"> <input type="checkbox" value="99" class="check-btn" data-pm="" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت پروژه </span>&nbsp;</label>
<!--=================================================-->
<!--#### تب کاربران برنامه نویسی ####-->
</div>
<!-- مدیریت برنامه نویسان -->
<div class="parent-check">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parent"> <input type="checkbox" value="99" class="check-btn" data-pm="" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت برنامه نویسان </span>&nbsp;</label>
<!-- مدیریت پروژه -->
<div class="child-check level2"> <div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="991" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> مدیریت پروژه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9900" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب کاربران برنامه نویسی </span> </label>
<!-----------------------Sub Menu------------------->
<!-- تعیین حقوق -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="99101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد پروژه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990001" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب تعیین حقوق </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99000101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین زمان </span> </label>
</div>
</div>
<!-- وضعیت کارکرد -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990002" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب وضعیت کارکرد </span> </label>
</div> </div>
<!-- ستون لیست پروژه --> <!-- فیش حقوقی -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9911" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون لیست پروژه ها </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990003" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب فیش حقوقی </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99111" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000301" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد فیش </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99112" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات</span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000302" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف تکی فیش </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99113" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش</span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000303" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف گروهی فیش ها </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99114" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف</span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000304" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه مجدد گروهی فیش ها </span> </label>
</div>
</div>
<!--ستون بخش اصلی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9912" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون بخش اصلی </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99121" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div> </div>
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99122" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99000305" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> محاسبه مجدد تکی فیش</span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99124" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99124" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف </span> </label>
</div>
</div>
<!--ستون بخش فرعی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9913" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ستون بخش اصلی </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99131" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="99132" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> توضیحات </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99134" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش </span> </label>
</div>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="99134" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف </span> </label>
</div> </div>
</div> </div>
</div> </div>
<!--اجرا-->
<!--=================================================-->
<!--#### تب مدیریت پروژه ####-->
<div class="child-check level2"> <div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close"> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" /> <i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label> </label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="992" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه </span> </label> <label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9901" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب مدیریت پروژه </span> </label>
<!-----------------------Sub Menu------------------->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990101" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد پروژه </span> </label>
<div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="9921" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> آماده اجرا </span> </label>
</div> </div>
<!-- همه پروژه ها -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children "><input type="checkbox" disabled="disabled" value="9922" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> در حال اجرا </span> </label> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990102" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه پروژه ها </span> </label>
</div> </div>
<!-- پروژه های آماده برنامه ریزی -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="9023" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990103" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های آماده برنامه ریزی </span> </label>
</div> </div>
<!-- پروژه های در حال اجرا -->
<div class="child-check level3"> <div class="child-check level3">
<label class="btn btn-inverse waves-effect waves-light m-b-5 children"><input type="checkbox" disabled="disabled" value="9024" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> اتمام اجرا </span> </label> <label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990104" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های در حال اجرا </span> </label>
</div>
<!-- پروژه های به اتمام رسیده -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990105" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> پروژه های به اتمام رسیده </span> </label>
</div>
<!-- تعیین کاربر -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990106" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین کاربر </span> </label>
</div>
<!-- تعیین زمان پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990107" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تعیین زمان پروژه </span> </label>
</div>
<!-- ویرایش پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990108" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ویرایش پروژه </span> </label>
</div>
<!-- حذف پروژه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990109" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> حذف پروژه </span> </label>
</div>
<!-- ایجاد بخش اصلی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990110" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد بخش اصلی </span> </label>
</div>
<!-- ایجاد بخش فرعی -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990111" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ایجاد بخش فرعی </span> </label>
</div> </div>
</div> </div>
<!--=================================================-->
<!--#### تب اجرا ####-->
<div class="child-check level2">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="9902" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> تب اجرا </span> </label>
<!-- همه -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990201" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> همه </span> </label>
</div>
<!-- آماده اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990202" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> آماده اجرا </span> </label>
</div>
<!-- در حال اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990203" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> در حال اجرا </span> </label>
</div>
<!-- نیمه کاره -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990204" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label>
</div>
<!-- اتمام اجرا -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990205" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> نیمه کاره </span> </label>
</div>
<!-- دیدن پروژه همه کاربران -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990206" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> دیدن پروژه همه کاربران </span> </label>
</div>
<!-- ارجاع به دیگران -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990207" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> ارجاع به دیگران </span> </label>
</div>
<!-- چت -->
<div class="child-check level3">
<label class="btn btn-icon waves-effect btn-default m-b-5 open-close">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
<label class="btn btn-inverse waves-effect waves-light m-b-5 parentLevel2"> <input type="checkbox" disabled="disabled" value="990208" class="check-btn" data-pm=""> &nbsp;<span style="bottom: 2px;position: relative"> چت </span> </label>
</div>
</div>
</div> </div>
</fieldset> </fieldset>
<div id="hiddenInput" @*style="display: none"*@> <div id="hiddenInput" @*style="display: none"*@>
@@ -1378,6 +1548,13 @@
name="PmPermissions[${pmIndex}]" name="PmPermissions[${pmIndex}]"
value="${chk.checked ? chk.value : 0}"> value="${chk.checked ? chk.value : 0}">
`); `);
if(chk.checked && chk.value == 99){
$("#hiddenInput").append(`
<input class="item1" type="hidden"
name="Permissions[${normalIndex}]"
value="${chk.checked ? chk.value : 0}">`);
normalIndex++;
}
pmIndex++; pmIndex++;
} else { } else {
$("#hiddenInput").append(` $("#hiddenInput").append(`

View File

@@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json; using Newtonsoft.Json;
using ServiceHost.Hubs; using ServiceHost.Hubs;
using Shared.Contracts.PmUser.Queries;
namespace ServiceHost.Areas.Admin.Pages.Accounts.Account; namespace ServiceHost.Areas.Admin.Pages.Accounts.Account;
@@ -30,6 +31,7 @@ public class IndexModel : PageModel
public List<RoleViewModel> Roless; public List<RoleViewModel> Roless;
public AccountSearchModel SearchModel; public AccountSearchModel SearchModel;
public IndexModel(IAccountApplication accountApplication, IRoleApplication roleApplication, IAuthHelper authHelper, public IndexModel(IAccountApplication accountApplication, IRoleApplication roleApplication, IAuthHelper authHelper,
ISmsService smsService, IHubContext<SendAccountMessage> hubContext) ISmsService smsService, IHubContext<SendAccountMessage> hubContext)
@@ -121,11 +123,11 @@ public class IndexModel : PageModel
//); //);
var result = _accountApplication.GetPmUserByAccountId(account.Id).GetAwaiter().GetResult(); var result = _accountApplication.GetPmUserAsync(account.Id).GetAwaiter().GetResult();
// مثل قبل: // مثل قبل:
if (result != null) if (result.AccountId > 0)
{ {
account.IsProgramManagerUser = (result.AccountId== account.Id && result.IsActive); account.IsProgramManagerUser = (result.AccountId== account.Id && result.IsActive);
account.UserRoles = result.Roles; account.UserRoles = result.Roles;
@@ -136,6 +138,7 @@ public class IndexModel : PageModel
} }
var pmRolseSelectList = _roleApplication.GetPmRoleList(null).GetAwaiter().GetResult(); var pmRolseSelectList = _roleApplication.GetPmRoleList(null).GetAwaiter().GetResult();
//سلکت لیست تمام رول های پروگرام منیجر
account.RoleList = pmRolseSelectList; account.RoleList = pmRolseSelectList;
//var response = InternalApiCaller.GetAsync<RoleResponse>( //var response = InternalApiCaller.GetAsync<RoleResponse>(

View File

@@ -358,6 +358,7 @@
<option value="هشدار دوم"> هشدار دوم </option> <option value="هشدار دوم"> هشدار دوم </option>
<option value="اقدام قضایی"> اقدام قضایی </option> <option value="اقدام قضایی"> اقدام قضایی </option>
<option value="یادآور وظایف"> یادآور وظایف </option> <option value="یادآور وظایف"> یادآور وظایف </option>
<option value="یادآور تایید قرارداد مالی"> یادآور تایید قرارداد مالی</option>
</select> </select>
</div> </div>
</div> </div>

View File

@@ -2642,8 +2642,9 @@ public class AutoExtensionModel : PageModel
case "شنبه": case "شنبه":
w1 = 7; w1 = 7;
w2 = 14; w2 = 14;
w3 = 28; w3 = 21;
w4 = 31; w4 = 28;
w5 = 31;
break; break;
case "یکشنبه": case "یکشنبه":
w1 = 6; w1 = 6;

View File

@@ -515,7 +515,7 @@
@if (Model.Command.PermissionIds != null && Model.Command.PermissionIds.Contains(10324)) @if (Model.Command.PermissionIds != null && Model.Command.PermissionIds.Contains(10324))
{ {
<div class="col-md-12 col-xs-12"> <div class="col-md-12 col-xs-12">
<div class="row card m-b-10"> <div class="row card m-b-10 @(Model.Command.PermissionIds.Contains(1032401) ? "" : "disabled")">
<div class="col-md-6 col-xs-12"> <div class="col-md-6 col-xs-12">
<h4>محاسبه اضافه کار و حق عائله مندی در لیست بیمه کارگاه</h4> <h4>محاسبه اضافه کار و حق عائله مندی در لیست بیمه کارگاه</h4>
<div> <div>

Some files were not shown because too many files have changed in this diff Show More