Compare commits

..

34 Commits

Author SHA1 Message Date
56e79d2099 fix: correct ContractAmountWithTax calculation for old contracts 2025-12-20 19:38:32 +03:30
93891f3837 add one month more details for InstitutionContract.cs print 2025-12-20 19:18:27 +03:30
SamSys
5bdfbc572b add next deploy and contractingParty add to workshop on AndroidApk page 2025-12-20 18:42:53 +03:30
SamSys
07113353c4 add uploadFrontEnd btn to AndroidApk page 2025-12-20 16:01:07 +03:30
8c6336b9bd fix: correct IsOldContract logic to properly identify old contracts 2025-12-20 14:35:02 +03:30
20e3d454cf feat: add ContractAmountWithTax calculation and update related references 2025-12-20 13:35:52 +03:30
2bf31db6b2 fix: enhance parameter binding logic for route parameters 2025-12-20 12:05:34 +03:30
7a4a6de84f feat: add OneMonthPrice to institution contract details 2025-12-20 10:56:36 +03:30
4f16d7680c feat: add insurance client list retrieval with pagination and filtering 2025-12-18 10:59:06 +03:30
SamSys
7a10d5ce59 changes 2025-12-18 10:40:11 +03:30
SamSys
3d88feeee7 Clent Add Employee Change to authorizedCanceled 2025-12-17 19:13:47 +03:30
SamSys
f408624463 Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-17 13:25:38 +03:30
SamSys
8296292e49 checkout week finder switch fixed bug 2025-12-17 13:25:24 +03:30
be8deef167 fix: update license context setting for Excel packages 2025-12-17 11:33:40 +03:30
84fb29c8c8 feat: enhance project creation validation and add operation result filter 2025-12-16 20:18:54 +03:30
0969e8a5fd Merge remote-tracking branch 'origin/master' 2025-12-16 19:14:28 +03:30
92e2282381 refactor: change GetAllCodes to return a dictionary for improved structure 2025-12-16 19:13:30 +03:30
SamSys
3b71b7d707 add pmPermission to claim 2025-12-16 18:24:18 +03:30
6123a53f01 fix: update permission check for project board visibility 2025-12-16 17:15:22 +03:30
ec74db17eb Merge branch 'master' into Feature/program-manager/set-permission-board 2025-12-16 17:10:41 +03:30
dc118cf18b Merge branch 'master' of https://github.com/syntax24/OriginalGozareshgir 2025-12-16 17:09:54 +03:30
a11e54c333 Add project board detail endpoint & validation improvements
- Added GET /board/{id:guid} endpoint to ProjectController for detailed project board info.
- Enforced max length of 15 characters for project names in CreateProjectCommandValidator.
- Improved SetTimeProjectCommandHandler: skip zero/negative initial times, removed duplicate error message, and cleaned up formatting.
- Enhanced RollCallApplication to use employee-specific workshop shift settings when available.
2025-12-16 17:09:28 +03:30
SamSys
2383e7a54f Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-16 17:03:02 +03:30
SamSys
2ef1ea3d1a add new permission for workshop 2025-12-16 17:02:40 +03:30
SamSys
ebdc9b1e55 ProgramManager PermissionCodes set 2025-12-16 16:26:15 +03:30
9e5a494881 feat: enhance project board query with skill and user details 2025-12-16 14:18:00 +03:30
2972807c9f feat: add permission handling methods and project board detail query 2025-12-16 12:56:49 +03:30
f7351454f3 feat: implement method to update face embedding names for employees with changed names 2025-12-16 11:05:22 +03:30
b64d0e5ffd feat: add method to update employee full name in FaceEmbeddingService and integrate with RollCallEmployeeApplication 2025-12-16 10:39:51 +03:30
35b7a3a3dd remove documentation file generation from project settings 2025-12-16 09:32:42 +03:30
fe93ef60c9 Merge branch 'master' of https://github.com/syntax24/OriginalGozareshgir 2025-12-15 21:14:06 +03:30
ef865d9c68 Add Skill navigation to Phase/ProjectSection, refactor logic
- Add Skill navigation properties to PhaseSection and ProjectSection, with EF Core mappings and migration for foreign keys and indexes.
- Refactor SetSkillFlags in GetProjectsListQueryHandler for clarity and efficiency; use eager loading for Skill.
- Add HasRemainingTime() to TaskSection and enforce time check in ChangeStatusSectionCommandHandler.
- Optimize EmployeeDocumentsRepository queries; add EmployeeId to WorkshopWithEmployeeDocumentsViewModel.
- Improve CustomExceptionHandler to handle FluentValidation exceptions and return proper status codes.
- Add FluentValidation package reference and perform minor code cleanups.
2025-12-15 20:56:32 +03:30
SamSys
61e35100f9 Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-15 18:49:35 +03:30
SamSys
01d33ff340 add InstitutionContract Confirm Reminder Sms completed 2025-12-15 18:49:13 +03:30
94 changed files with 3392 additions and 1080 deletions

View File

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

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> DeleteEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId, string newFullName);
}
public class FaceEmbeddingResponse

View File

@@ -27,7 +27,7 @@ public interface ISmsService
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> SendInstitutionVerificationCode(string number, string code, string contractingPartyFullName,
long contractingPartyId, long institutionContractId);

View File

@@ -17,7 +17,7 @@ public class 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
{

View File

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

View File

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

@@ -155,6 +155,8 @@ public class AccountApplication : IAccountApplication
if (command.IsProgramManagerUser)
{
if (command.UserRoles == null)
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, account.Password, command.Mobile,
null, account.id, pmUserRoles));
@@ -252,6 +254,8 @@ public class AccountApplication : IAccountApplication
//);
var userResult =await _pmUserQueryService.GetPmUserDataByAccountId(account.id);
if (command.UserRoles == null)
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
//اگر کاربر در پروگرام منیجر قبلا ایجاد شده
@@ -396,6 +400,23 @@ public class AccountApplication : IAccountApplication
.Permissions
.Select(x => x.Code)
.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;
if (account.PositionId != null)
{
@@ -405,7 +426,7 @@ public class AccountApplication : IAccountApplication
{
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
, account.Username, account.Mobile, account.ProfilePhoto,
permissions, account.RoleName, account.AdminAreaPermission,

View File

@@ -12,6 +12,7 @@
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.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="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" />
</ItemGroup>

View File

@@ -47,6 +47,11 @@ public class JobSchedulerRegistrator
() => SendBlockSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendInstitutionContractConfirmSms",
() => SendInstitutionContractConfirmSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
}
@@ -146,4 +151,15 @@ public class JobSchedulerRegistrator
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 CompanyManagment.App.Contracts.Hubs;
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 Microsoft.AspNetCore.Identity;
using MongoDB.Driver;
using PersonalContractingParty.Config;
using Query.Bootstrapper;
using Shared.Contracts.PmUser.Queries;
using WorkFlow.Infrastructure.Config;
var builder = WebApplication.CreateBuilder(args);
@@ -38,10 +43,15 @@ builder.Services.AddSingleton<IMongoDatabase>(mongoDatabase);
#endregion
builder.Services.AddProgramManagerApplication();
builder.Services.AddProgramManagerInfrastructure(builder.Configuration);
PersonalBootstrapper.Configure(builder.Services, connectionString);
TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb);
AccountManagementBootstrapper.Configure(builder.Services, connectionString);
WorkFlowBootstrapper.Configure(builder.Services, connectionString);
QueryBootstrapper.Configure(builder.Services);
JobsBootstrapper.Configure(builder.Services);
builder.Services.AddHttpClient();

View File

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

View File

@@ -98,6 +98,11 @@ public class InstitutionContract : EntityBase
// مبلغ قرارداد
public double ContractAmount { get; private set; }
public double ContractAmountWithTax => !IsOldContract ? ContractAmount + ContractAmountTax
: ContractAmount;
public double ContractAmountTax => ContractAmount*0.10;
//خسارت روزانه
public double DailyCompenseation { get; private set; }
@@ -159,6 +164,8 @@ public class InstitutionContract : EntityBase
public List<InstitutionContractAmendment> Amendments { get; private set; }
public bool IsOldContract => LawId== 0;
public InstitutionContract()
{
ContactInfoList = [];

View File

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

View File

@@ -316,7 +316,10 @@ public class Workshop : EntityBase
IsStaticCheckout = isStaticCheckout;
}
public void AddContractingPartyId(long contractingPartyId)
{
ContractingPartyId = contractingPartyId;
}
public void Active(string archiveCode)
{
this.IsActive = true;

View File

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

View File

@@ -24,7 +24,7 @@ public class CaseManagementExcelGenerator
};
public static byte[] GenerateCheckoutTempExcelInfo(List<FileExcelViewModel> data)
{
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage();
CreateSheet(data, 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)
{
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -344,6 +344,9 @@ public class InstitutionContractPrintViewModel
public string TotalPrice { get; set; }
public string TaxPrice { get; set; }
public string PaymentPrice { get; set; }
public string OneMonthPrice { get; set; }
public string OneMonthWithoutTax { get; set; }
public string OneMonthTax { get; set; }
public string VerifyCode { get; set; }
public string VerifyDate { get; set; }
public string VerifyTime { 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<InsuranceListTabsCountViewModel> GetTabCounts(InsuranceListSearchModel searchModel);
Task<PagedResult<InsuranceClientListViewModel>> GetInsuranceClientList(InsuranceClientSearchModel searchModel);
#endregion
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 System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CompanyManagment.App.Contracts.RollCallEmployee;

View File

@@ -1263,7 +1263,7 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
System.IO.File.WriteAllBytes(filePath, bytes);
}
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>();
@@ -1279,65 +1279,25 @@ public class EmployeeAplication : RepositoryBase<long, Employee>, IEmployeeAppli
var employee = _EmployeeRepository.GetByNationalCodeIgnoreQueryFilter(nationalCode);
if (employee == null)
if (employee == null && !authorizedCanceled)
{
var personalInfo = await _uidService.GetPersonalInfo(nationalCode, birthDate);
if (personalInfo.ResponseContext.Status.Code == 14)
if (personalInfo != null)
{
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeByNationalCodeInWorkshopViewModel() { AuthorizedCanceled = true });
}
if (personalInfo.ResponseContext.Status.Code != 0)
{
return op.Failed("کد ملی و تاریخ تولد با هم همخانی ندارند");
}
if (personalInfo.ResponseContext.Status.Code == 14)
{
return op.Failed("سامانه احراز هویت در دسترس نمیباشد لطفا اطلاعات پرسنل را به صورت دستی وارد کنید", new EmployeeByNationalCodeInWorkshopViewModel() { AuthorizedCanceled = true });
}
if (personalInfo.ResponseContext.Status.Code != 0)
{
return op.Failed("کد ملی و تاریخ تولد با هم همخانی ندارند");
}
var basicInfo = personalInfo.BasicInformation;
var identityInfo = personalInfo.IdentificationInformation;
DateTime apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime();
var basicInfo = personalInfo.BasicInformation;
var identityInfo = personalInfo.IdentificationInformation;
DateTime apiBirthDate = identityInfo.BirthDate.ToGeorgianDateTime();
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 dateOfIssue = new DateTime(1922, 1, 1);
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;
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();
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
});
}
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("کد ملی با تاریخ تولد وارد شده مطابقت ندارد");
}
}
else if (employee.DateOfBirth.ToFarsi() != birthDate || employee.NationalCode != nationalCode)
{
return op.Failed("کد ملی با تاریخ تولد وارد شده مطابقت ندارد");
}
var leftWorkViewModel = _leftWorkRepository.GetLastLeftWorkByEmployeeIdAndWorkshopId(workshopId, employee.id);
if (leftWorkViewModel == null)

View File

@@ -2371,6 +2371,11 @@ public class InsuranceListApplication : IInsuranceListApplication
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)
{
return await _insuranceListRepositpry.GetNotCreatedWorkshop(searchModel);

View File

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

View File

@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Transactions;
using _0_Framework.Application.FaceEmbedding;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace CompanyManagment.Application;
@@ -23,7 +24,9 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
private readonly ILeftWorkRepository _leftWorkRepository;
private readonly IRollCallEmployeeStatusRepository _rollCallEmployeeStatusRepository;
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;
_employeeRepository = employeeRepository;
@@ -31,6 +34,7 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
_leftWorkRepository = leftWorkRepository;
_rollCallEmployeeStatusRepository = rollCallEmployeeStatusRepository;
_webHostEnvironment = webHostEnvironment;
_faceEmbeddingService = faceEmbeddingService;
}
public OperationResult Create(CreateRollCallEmployee command)
@@ -213,9 +217,18 @@ public class RollCallEmployeeApplication : IRollCallEmployeeApplication
if (entity.IsActiveString != "true")
return result.Failed("امکان تغییر نام برای کارمند غیر فعال وجود ندارد");
var transaction = _rollCallEmployeeRepository.BeginTransactionAsync().GetAwaiter().GetResult();
entity.ChangeName(fName, lName);
_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();
}
#endregion

View File

@@ -45,5 +45,10 @@ public class InstitutionContractMapping : IEntityTypeConfiguration<InstitutionCo
builder.HasMany(x => x.Amendments).WithOne(x => x.InstitutionContract)
.HasForeignKey(x => x.InstitutionContractId);
builder.Ignore(x => x.ContractAmountWithTax);
builder.Ignore(x => x.ContractAmountTax);
builder.Ignore(x => x.ContractAmountTax);
}
}

View File

@@ -1194,41 +1194,99 @@ public class EmployeeDocumentsRepository : RepositoryBase<long, EmployeeDocument
{
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
.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()
});
// Step 5: Get workshop employers for the filtered workshops
var workshopIds = groupedByWorkshop.Select(x => x.WorkshopId).ToList();
var workshopEmployers = await _companyContext.WorkshopEmployers
.Where(x => workshopIds.Contains(x.WorkshopId))
.Include(x => x.Employer)
.GroupBy(x => x.WorkshopId)
.Select(g => g.FirstOrDefault())
.ToListAsync();
// 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)
.Where(x => query.Any(y => y.WorkshopId == x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync();
// var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer)
// .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId))
// .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync();
var result = await query.ToListAsync();
// var result = await query.ToListAsync();
result.ForEach(x =>
{
var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer;
x.EmployerName = employer?.FullName;
// result.ForEach(x =>
// {
// var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer;
// 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)
@@ -1347,33 +1405,37 @@ public class EmployeeDocumentsRepository : RepositoryBase<long, EmployeeDocument
// ترکیب کل لیست‌ها در حافظه
var allActiveEmployees = activeEmployees
.Concat(clientTemp)
.Concat(leftWorkTemp);
.Concat(leftWorkTemp).ToList();
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
.Where(x => contractingPartyIds.Contains(x.PersonalContractingPartyId)).Select(x => x.AccountId)
.ToListAsync();
var query = _companyContext.EmployeeDocuments
.Where(x => workshops.Contains(x.WorkshopId) &&
(allActiveEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId)))
var query =await _companyContext.EmployeeDocuments
.Where(x => workshops.Contains(x.WorkshopId))
.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)))
.GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel()
{
WorkshopId = x.Key,
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)
.Where(x => query.Any(y => y.WorkshopId == x.WorkshopId))
.Where(x => resWorkshopIds.Contains(x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync();
var result = await query.ToListAsync();
var result = query;
result.ForEach(x =>

View File

@@ -1,15 +1,4 @@
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 _0_Framework.Application;
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Application.Sms;
using _0_Framework.Exceptions;
@@ -38,6 +27,7 @@ using CompanyManagment.App.Contracts.Law;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop;
using CompanyManagment.App.Contracts.WorkshopPlan;
using CompanyManagment.EFCore.Migrations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
@@ -47,10 +37,23 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MongoDB.Driver;
using OfficeOpenXml.Packaging.Ionic.Zip;
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 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 Workshop = Company.Domain.WorkshopAgg.Workshop;
namespace CompanyManagment.EFCore.Repository;
@@ -102,69 +105,69 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
public EditInstitutionContract GetDetails(long id)
{
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
ContractAmount = x.ContractAmount,
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
HasValueAddedTax = x.HasValueAddedTax,
ValueAddedTax = x.ValueAddedTax,
})
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
ContractAmount = x.ContractAmount,
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
HasValueAddedTax = x.HasValueAddedTax,
ValueAddedTax = x.ValueAddedTax,
})
.FirstOrDefault(x => x.Id == id);
}
public EditInstitutionContract GetFirstContract(long contractingPartyId, string typeOfContract)
{
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature
})
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature
})
.Where(x => x.ContractingPartyId == contractingPartyId && x.TypeOfContract == typeOfContract)
.OrderBy(x => x.ExtensionNo).FirstOrDefault();
}
@@ -582,40 +585,40 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
}).ToList(),
}).ToList();
listQuery = listQuery.Select(x => new InstitutionContractViewModel()
{
Id = x.Id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount,
TotalAmount = x.TotalAmount,
SearchAmount = x.SearchAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
ExpireColor = x.ExpireColor,
IsExpier = x.IsExpier,
BalanceDouble = x.BalanceDouble,
BalanceStr = x.BalanceStr,
EmployerViewModels = x.EmployerViewModels,
EmployerNo = x.EmployerNo,
EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(),
WorkshopViewModels = x.WorkshopViewModels,
WorkshopCount = x.WorkshopCount,
IsContractingPartyBlock = x.IsContractingPartyBlock,
BlockTimes = x.BlockTimes,
EmployeeCount =
{
Id = x.Id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount,
TotalAmount = x.TotalAmount,
SearchAmount = x.SearchAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
ExpireColor = x.ExpireColor,
IsExpier = x.IsExpier,
BalanceDouble = x.BalanceDouble,
BalanceStr = x.BalanceStr,
EmployerViewModels = x.EmployerViewModels,
EmployerNo = x.EmployerNo,
EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(),
WorkshopViewModels = x.WorkshopViewModels,
WorkshopCount = x.WorkshopCount,
IsContractingPartyBlock = x.IsContractingPartyBlock,
BlockTimes = x.BlockTimes,
EmployeeCount =
((x.WorkshopViewModels.Sum(w => w.LeftWorkIds.Count)) + (x.WorkshopViewModels.Sum(w =>
w.InsuranceLeftWorkIds.Count(c => !w.LeftWorkIds.Contains(c))))).ToString(),
ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0,
}).OrderBy(x => x.WorkshopCount != "0" && string.IsNullOrWhiteSpace(x.ExpireColor))
ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0,
}).OrderBy(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.ExpireColor == "purple")
@@ -640,17 +643,17 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var op = new OperationResult();
var institutionContarct = _context.InstitutionContractSet
.FirstOrDefault(x => x.id == id);
var prevInstitutionContracts = _context.InstitutionContractSet
.Where(x => x.ContractingPartyId == institutionContarct.ContractingPartyId)
.OrderByDescending(x => x.ContractEndGr).Skip(1).FirstOrDefault();
var transaction = _context.Database.BeginTransaction();
var contactInfo = _context.InstitutionContractContactInfos
.Where(x => x.InstitutionContractId == id)
.ToList();
if (contactInfo.Count > 0)
{
foreach (var item in contactInfo)
@@ -673,20 +676,20 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var financialStatement =
_context.FinancialStatments
.Include(x => x.FinancialTransactionList)
.FirstOrDefault(x=>x.ContractingPartyId == institutionContarct.ContractingPartyId);
.FirstOrDefault(x => x.ContractingPartyId == institutionContarct.ContractingPartyId);
if (financialStatement != null)
{
var sumDebtor = financialStatement.FinancialTransactionList
.Sum(x => x.Deptor);
var sumDebtor = financialStatement.FinancialTransactionList
.Sum(x => x.Deptor);
var sumCreditor = financialStatement.FinancialTransactionList
.Sum(x => x.Creditor);
var balance = sumDebtor - sumCreditor;
if (balance>0 && prevInstitutionContracts.ContractEndGr<now)
{
prevInstitutionContracts.DeActiveBlue();
_context.SaveChanges();
}
if (balance > 0 && prevInstitutionContracts.ContractEndGr < now)
{
prevInstitutionContracts.DeActiveBlue();
_context.SaveChanges();
}
}
}
@@ -1372,7 +1375,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now);
return new GetInstitutionContractListItemsViewModel()
{
ContractAmount = x.contract.ContractAmount,
ContractAmount = x.contract.ContractAmountWithTax,
Balance = statement?.FinancialTransactionList.Sum(ft => ft.Deptor - ft.Creditor) ?? 0,
WorkshopsCount = workshops.Count(),
ContractStartFa = x.contract.ContractStartGr.ToFarsi(),
@@ -1392,9 +1395,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
Workshops = workshopDetails,
IsInPersonContract = x.contract.WorkshopGroup?.CurrentWorkshops
.Any(y => y.Services.ContractInPerson) ?? true,
IsOldContract = x.contract.WorkshopGroup?.CurrentWorkshops == null
|| x.contract.WorkshopGroup.CurrentWorkshops.Count == 0
|| x.contract.WorkshopGroup.CurrentWorkshops.Any(y => y.Price == 0)
IsOldContract = x.contract.IsOldContract
};
}).ToList()
};
@@ -3213,6 +3214,9 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
PaymentPrice = institution.TotalAmount.ToMoney(),
TotalPrice = (institution.TotalAmount - institution.ValueAddedTax).ToMoney(),
TaxPrice = institution.ValueAddedTax.ToMoney(),
OneMonthPrice = institution.ContractAmountWithTax.ToMoney(),
OneMonthWithoutTax = institution.ContractAmount.ToMoney(),
OneMonthTax = institution.ContractAmountTax.ToMoney(),
VerifierFullName = institution.VerifierFullName,
VerifierPhoneNumber = institution.VerifierPhoneNumber,
VerifyCode = institution.VerifyCode,
@@ -3573,19 +3577,19 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
var smsList = new List<BlockSmsListData>();
var institutionContracts = await _context.InstitutionContractSet.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
OfficialCompany = x.OfficialCompany
}).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate &&
x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First())
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
OfficialCompany = x.OfficialCompany
}).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate &&
x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First())
.ToListAsync();
@@ -3679,9 +3683,12 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
{
smsList.Add(new BlockSmsListData()
{
PhoneNumber = number.PhoneNumber, PartyName = partyName,
AccountType = accountType, Amount = amount,
ContractingPartyId = contractingParty.id, InstitutionContractId = item.Id,
PhoneNumber = number.PhoneNumber,
PartyName = partyName,
AccountType = accountType,
Amount = amount,
ContractingPartyId = contractingParty.id,
InstitutionContractId = item.Id,
AproveId = aprove
});
}
@@ -3869,11 +3876,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1,
Code2 = code2, InstitutionContractId = item.Id
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
@@ -3887,10 +3899,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "",
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
@@ -3922,11 +3939,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1,
Code2 = code2, InstitutionContractId = item.Id
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
@@ -3940,10 +3962,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "",
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
@@ -3979,11 +4006,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1,
Code2 = code2, InstitutionContractId = item.Id
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
@@ -3997,10 +4029,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "",
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
@@ -4035,11 +4072,16 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
string code2 = publicId.Substring(25);
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew", Code1 = code1,
Code2 = code2, InstitutionContractId = item.Id
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
@@ -4053,10 +4095,15 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber, TemplateId = templateId,
PartyName = partyName, Amount = balanceToMoney,
ContractingPartyId = contractingParty.id, AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill", Code1 = "", Code2 = "",
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
@@ -4217,6 +4264,9 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
#endregion
}
#region PrivateMetods
/// <summary>
@@ -4258,6 +4308,88 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.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
@@ -4301,7 +4433,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
VerificationStatus = x.VerificationStatus,
InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).Where(x =>
x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0)
@@ -4345,7 +4477,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
VerificationStatus = x.VerificationStatus,
InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).ToListAsync();

View File

@@ -1777,6 +1777,49 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
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)
{
if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year))

View File

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

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;
if (fullName.Length >= 25)
{
@@ -377,8 +380,9 @@ public class SmsService : ISmsService
new("CODE1",firstPart),
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);
await _smsResultRepository.CreateAsync(smsResult);
await _smsResultRepository.SaveChangesAsync();

View File

@@ -4,23 +4,20 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
using Microsoft.Extensions.Logging;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
public class ProjectSectionAddedHandler:INotificationHandler<DomainEventNotification<TaskSectionAddedEvent>>
public class ProjectSectionAddedHandler:INotificationHandler<DomainEventNotification<ProjectSectionAddedEvent>>
{
private readonly ILogger<CustomerRegisteredHandler> _logger;
private readonly IBoardNotificationPublisher _boardNotificationPublisher;
public ProjectSectionAddedHandler(ILogger<CustomerRegisteredHandler> logger, IBoardNotificationPublisher boardNotificationPublisher)
public ProjectSectionAddedHandler(ILogger<CustomerRegisteredHandler> logger)
{
_logger = logger;
_boardNotificationPublisher = boardNotificationPublisher;
}
public Task Handle(DomainEventNotification<TaskSectionAddedEvent> notification, CancellationToken cancellationToken)
public Task Handle(DomainEventNotification<ProjectSectionAddedEvent> notification, CancellationToken cancellationToken)
{
var domainEvent = notification.DomainEvent;
//_boardNotificationPublisher.NotifyTaskCreated()
return Task.CompletedTask;
}
}

View File

@@ -2,7 +2,7 @@ using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
public class ProjectSectionAssignedHandler:INotificationHandler<DomainEventNotification<ProjectSectionAssignedEvent>>
{

View File

@@ -3,7 +3,7 @@ using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
public class TaskSectionStatusChangedHandler:INotificationHandler<DomainEventNotification<TaskSectionStatusChangedEvent>>
{
@@ -17,7 +17,7 @@ public class TaskSectionStatusChangedHandler:INotificationHandler<DomainEventNot
public Task Handle(DomainEventNotification<TaskSectionStatusChangedEvent> notification, CancellationToken cancellationToken)
{
var domainEvent = notification.DomainEvent;
_boardNotificationPublisher.NotifyTaskStatusChanged(domainEvent.UserId,domainEvent.OldStatus,domainEvent.NewStatus,domainEvent.SectionId);
_boardNotificationPublisher.SendProjectStatusChanged(domainEvent.UserId,domainEvent.OldStatus,domainEvent.NewStatus,domainEvent.SectionId);
return Task.CompletedTask;
}
}

View File

@@ -1,19 +1,9 @@
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
namespace GozareshgirProgramManager.Application.Interfaces;
public interface IBoardNotificationPublisher
{
Task NotifyTaskStatusChanged(long userId, TaskSectionStatus oldStatus,
Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus,
TaskSectionStatus newStatus, Guid sectionId);
Task NotifyTaskCreated(TaskSection taskSection);
Task NotifyTaskAssigned(long userId, Guid sectionId);
Task NotifyTaskRemoved(long userId, Guid sectionId);
}

View File

@@ -49,8 +49,11 @@ public class ChangeStatusSectionCommandHandler : IBaseCommandHandler<ChangeStatu
}
else if (request.Status == TaskSectionStatus.InProgress)
{
// Going TO InProgress: Start work and create activity
section.StartWork();
// Going TO InProgress: Check if section has remaining time, then start work
if (!section.HasRemainingTime())
return OperationResult.ValidationError("زمان این بخش به پایان رسیده است");
section.StartWork();
}
else
{

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
using FluentValidation;
using FluentValidation.Validators;
using GozareshgirProgramManager.Application.Modules.Projects.DTOs;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject;
@@ -15,6 +16,9 @@ public class SetTimeProjectCommandValidator:AbstractValidator<SetTimeProjectComm
RuleForEach(x => x.SectionItems)
.SetValidator(command => new SetTimeProjectSectionItemValidator());
RuleFor(x => x.SectionItems)
.Must(sectionItems => sectionItems.Any(si => si.InitData?.Hours > 0))
.WithMessage("حداقل یکی از بخش‌ها باید مقدار ساعت معتبری داشته باشد.");
}
}
public class SetTimeProjectSectionItemValidator:AbstractValidator<SetTimeProjectSectionItem>
@@ -30,13 +34,14 @@ public class SetTimeProjectSectionItemValidator:AbstractValidator<SetTimeProject
.SetValidator(new TimeDataValidator());
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)
.GreaterThanOrEqualTo(0)
@@ -45,6 +50,13 @@ public class TimeDataValidator : AbstractValidator<SetTimeSectionTime>
RuleFor(x=>x.Description)
.MaximumLength(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)
{
if (!projects.Any())
return;
var projectIds = projects.Select(x => x.Id).ToList();
// تنها تسک‌ها sections دارند، بنابراین برای سطوح مختلف باید متفاوت عمل کنیم
List<Guid> taskIds;
switch (projects.FirstOrDefault()?.Level)
var hierarchyLevel = projects.First().Level;
switch (hierarchyLevel)
{
case ProjectHierarchyLevel.Project:
// برای پروژه‌ها، باید تمام تسک‌های زیرمجموعه را پیدا کنیم
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);
await SetSkillFlagsForProjects(projects, projectIds, cancellationToken);
break;
case ProjectHierarchyLevel.Phase:
// برای فازها، تمام تسک‌های آن فازها را پیدا کنیم
taskIds = await _context.ProjectTasks
.Where(t => projectIds.Contains(t.PhaseId))
.Select(t => t.Id)
.ToListAsync(cancellationToken);
await SetSkillFlagsForPhases(projects, projectIds, cancellationToken);
break;
case ProjectHierarchyLevel.Task:
// برای تسک‌ها، خود آنها taskIds هستند
taskIds = projectIds;
await SetSkillFlagsForTasks(projects, projectIds, cancellationToken);
break;
default:
return;
}
}
if (!taskIds.Any())
return;
var sections = await _context.TaskSections
private async Task SetSkillFlagsForProjects(List<GetProjectListDto> projects, List<Guid> projectIds, CancellationToken cancellationToken)
{
var projectSections = await _context.ProjectSections
.Include(x => x.Skill)
.Where(x => taskIds.Contains(x.TaskId))
.Where(s => projectIds.Contains(s.ProjectId))
.ToListAsync(cancellationToken);
if (!projectSections.Any())
return;
foreach (var project in projects)
{
List<Guid> relevantTaskIds;
switch (project.Level)
{
case ProjectHierarchyLevel.Project:
// برای پروژه، تمام تسک‌های زیرمجموعه
var projectPhaseIds = await _context.ProjectPhases
.Where(ph => ph.ProjectId == project.Id)
.Select(ph => ph.Id)
.ToListAsync(cancellationToken);
relevantTaskIds = await _context.ProjectTasks
.Where(t => projectPhaseIds.Contains(t.PhaseId))
.Select(t => t.Id)
.ToListAsync(cancellationToken);
break;
case ProjectHierarchyLevel.Phase:
// برای فاز، تمام تسک‌های آن فاز
relevantTaskIds = await _context.ProjectTasks
.Where(t => t.PhaseId == project.Id)
.Select(t => t.Id)
.ToListAsync(cancellationToken);
break;
case ProjectHierarchyLevel.Task:
// برای تسک، خود آن
relevantTaskIds = new List<Guid> { project.Id };
break;
default:
continue;
}
var projectSections = sections.Where(x => relevantTaskIds.Contains(x.TaskId)).ToList();
project.HasBackend = projectSections.Any(x => x.Skill.Name == "Backend");
project.HasFront = projectSections.Any(x => x.Skill.Name == "Frontend");
project.HasDesign = projectSections.Any(x => x.Skill.Name == "UI/UX Design");
var sections = projectSections.Where(s => s.ProjectId == project.Id).ToList();
project.HasBackend = sections.Any(x => x.Skill?.Name == "Backend");
project.HasFront = sections.Any(x => x.Skill?.Name == "Frontend");
project.HasDesign = sections.Any(x => x.Skill?.Name == "UI/UX Design");
}
}
private async Task SetSkillFlagsForPhases(List<GetProjectListDto> projects, List<Guid> phaseIds, CancellationToken cancellationToken)
{
var phaseSections = await _context.PhaseSections
.Include(x => x.Skill)
.Where(s => phaseIds.Contains(s.PhaseId))
.ToListAsync(cancellationToken);
if (!phaseSections.Any())
return;
foreach (var phase in projects)
{
var sections = phaseSections.Where(s => s.PhaseId == phase.Id).ToList();
phase.HasBackend = sections.Any(x => x.Skill?.Name == "Backend");
phase.HasFront = sections.Any(x => x.Skill?.Name == "Frontend");
phase.HasDesign = sections.Any(x => x.Skill?.Name == "UI/UX Design");
}
}
private async Task SetSkillFlagsForTasks(List<GetProjectListDto> projects, List<Guid> taskIds, CancellationToken cancellationToken)
{
var taskSections = await _context.TaskSections
.Include(x => x.Skill)
.Where(s => taskIds.Contains(s.TaskId))
.ToListAsync(cancellationToken);
if (!taskSections.Any())
return;
foreach (var task in projects)
{
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 TaskSectionStatus? Status { get; set; }
}

View File

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

View File

@@ -10,6 +10,10 @@ public class ProjectBoardListResponse
public string TaskName { get; set; }
public ProjectProgressDto Progress { 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
{

View File

@@ -4,35 +4,238 @@ 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 = 991;
public const int Code = 9902;
/// <summary>
/// تب همه
/// </summary>
public static class All
{
public const int Code = 99101;
public const int Code = 990201;
}
/// <summary>
/// دیدن همه تسک ها
/// </summary>
public const int ViewAll = 9910101;
/// <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;
}
}
public static List<int> GetAllCodes()
{
var result = new List<int>();
void Collect(Type type)
#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);
@@ -43,7 +246,7 @@ public static class ProgramManagerPermissionCode
var raw = f.GetRawConstantValue();
if (raw is int value)
{
result.Add(value);
dict[f.Name] = value;
}
}
}
@@ -52,11 +255,16 @@ public static class ProgramManagerPermissionCode
var nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
foreach (var nt in nestedTypes)
{
Collect(nt);
var nestedDict = new Dictionary<string, object>();
Collect(nt, nestedDict);
if (nestedDict.Count > 0)
{
dict[nt.Name] = nestedDict;
}
}
}
Collect(typeof(ProgramManagerPermissionCode));
Collect(typeof(ProgramManagerPermissionCode), result);
return result;
}
}

View File

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

View File

@@ -8,6 +8,7 @@
<ItemGroup>
<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" />
</ItemGroup>

View File

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

View File

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

View File

@@ -210,4 +210,11 @@ public class TaskSection : EntityBase<Guid>
{
_additionalTimes.Clear();
}
public bool HasRemainingTime()
{
var totalSpent = GetTotalTimeSpent();
var finalEstimate = FinalEstimatedHours;
return totalSpent < finalEstimate;
}
}

View File

@@ -1,5 +1,7 @@
using System.Globalization;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using PersianTools.Core;
@@ -1704,25 +1706,25 @@ public static class Tools
// return Convert.ToBase64String(bsonData);
//}
////بیسان هایی که بصورت لیست بودند استخراج میشود
//public static List<T> DeserializeFromBsonList<T>(string base64Data)
//{
// byte[] data = Convert.FromBase64String(base64Data);
public static List<T> DeserializeFromBsonList<T>(string base64Data)
{
byte[] data = Convert.FromBase64String(base64Data);
// using MemoryStream memoryStream = new MemoryStream(data);
// using BsonDataReader reader = new BsonDataReader(memoryStream);
// reader.ReadRootValueAsArray = true;
// JsonSerializer serializer = new JsonSerializer();
// return serializer.Deserialize<List<T>>(reader);
//}
////بیسان هایی که بصورت تکی بودند استخراج میشود
//public static T DeserializeFromBson<T>(string base64Data)
//{
// byte[] bsonData = Convert.FromBase64String(base64Data);
// using MemoryStream memoryStream = new MemoryStream(bsonData);
// using BsonDataReader bsonReader = new BsonDataReader(memoryStream);
// JsonSerializer serializer = new JsonSerializer();
// return serializer.Deserialize<T>(bsonReader);
//}
using MemoryStream memoryStream = new MemoryStream(data);
using BsonDataReader reader = new BsonDataReader(memoryStream);
reader.ReadRootValueAsArray = true;
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize<List<T>>(reader);
}
//بیسان هایی که بصورت تکی بودند استخراج میشود
public static T DeserializeFromBson<T>(string base64Data)
{
byte[] bsonData = Convert.FromBase64String(base64Data);
using MemoryStream memoryStream = new MemoryStream(bsonData);
using BsonDataReader bsonReader = new BsonDataReader(memoryStream);
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize<T>(bsonReader);
}
//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
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@@ -102,56 +102,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
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 =>
{
b.Property<Guid>("Id")
@@ -174,6 +124,8 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.HasIndex("PhaseId");
b.HasIndex("SkillId");
b.ToTable("PhaseSections");
});
@@ -284,6 +236,8 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.HasIndex("ProjectId");
b.HasIndex("SkillId");
b.ToTable("ProjectSections");
});
@@ -630,17 +584,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
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 =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
@@ -649,7 +592,14 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
.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 =>
@@ -671,7 +621,14 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
.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 =>
@@ -856,11 +813,6 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.Navigation("User");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b =>
{
b.Navigation("HolidayItems");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{
b.Navigation("Phases");

View File

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

View File

@@ -1,5 +1,6 @@
using System.Security.Claims;
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Domain._Common;
using Microsoft.AspNetCore.Http;
namespace GozareshgirProgramManager.Infrastructure.Services.Authentication;
@@ -106,6 +107,21 @@ public class AuthHelper : IAuthHelper
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>
// /// دریافت AccountId کاربر جاری از Claims
// /// </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.ChangeStatusSection;
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.Queries.GetProjectAssignDetails;
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.ProjectSetTimeDetails;
using MediatR;
@@ -99,4 +101,11 @@ public class ProjectController : ProgramManagerBaseController
var res = await _mediator.Send(query);
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="row"></div>
<div class="form-group" style="margin: 29px 7px 0px;">
<span> فعالیت کاربر در پروگرام منیجر </span>
<span> فعالیت کاربر در مدیریت پروژه </span>
<span>&nbsp;</span>
<label class="switch">
<input id="checkAll" asp-for="IsProgramManagerUser" type="checkbox"/>
@@ -143,7 +143,7 @@
<div class="col-md-6">
<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">
<option value="0"></option>
</select>

View File

@@ -1,6 +1,10 @@
@model AccountManagement.Application.Contracts.Role.CreateRole
@{
<style>
.modal .modal-dialog .modal-content{
width: 645px;
}
.child-check {
margin-left: 15px;
display: none;
@@ -224,9 +228,18 @@
<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>
</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="10324" class="check-btn"> &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="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">
<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>
@@ -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">
<i class="ion-plus"></i> <i class="ion-minus" style="display: none;"></i><input type="checkbox" style="display: none" class="open-btn" />
</label>
@@ -1024,111 +1037,281 @@
</div>
</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">
<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">
<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="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">
<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="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 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="9911" 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>
<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 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>
<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 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>
<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 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">
<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="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>
@@ -1324,6 +1507,13 @@
name="PmPermissions[${pmIndex}]"
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++;
} else {
$("#hiddenInput").append(`

View File

@@ -133,7 +133,7 @@
<div class="col-md-6">
<div class="row"></div>
<div class="form-group" style="margin: 29px 7px 0px;">
<span> فعالیت کاربر در پروگرام منیجر </span>
<span> فعالیت کاربر درمدیریت پروژه </span>
<span>&nbsp;</span>
<label class="switch">
<input id="editcheckAll" asp-for="IsProgramManagerUser" type="checkbox"/>
@@ -148,7 +148,7 @@
<div class="col-md-6">
<div class="form-group">
<label asp-for="UserRoles"> نقش در پروگرام منیجر </label>
<label asp-for="UserRoles"> انتخاب نقش در مدیریت پروژه </label>
@if (Model.IsProgramManagerUser)
{
<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
@{
<style>
.modal .modal-dialog .modal-content {
width: 645px;
}
.child-check {
margin-left: 15px;
display: none;
@@ -224,9 +228,17 @@
<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>
</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="10324" class="check-btn"> &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="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">
<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>
@@ -1017,124 +1029,282 @@
</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"> &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">
<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="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">
<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="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="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">
<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 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 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 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 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>
<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="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 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>
<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="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 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 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 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 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>
</fieldset>
<div id="hiddenInput" @*style="display: none"*@>
@@ -1378,6 +1548,13 @@
name="PmPermissions[${pmIndex}]"
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++;
} else {
$("#hiddenInput").append(`

View File

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

View File

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

View File

@@ -515,7 +515,7 @@
@if (Model.Command.PermissionIds != null && Model.Command.PermissionIds.Contains(10324))
{
<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">
<h4>محاسبه اضافه کار و حق عائله مندی در لیست بیمه کارگاه</h4>
<div>

View File

@@ -523,7 +523,7 @@
<input type="hidden" id="PermissionInsurance" asp-for="@Model.HasPermissionInsurance" value="@Model.HasPermissionInsurance" />
<div style="@(Model.HasPermissionInsurance ? "" : "display: none;")">
<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">
<h4>محاسبه اضافه کار و حق عائله مندی در لیست بیمه کارگاه</h4>
<div>

View File

@@ -518,7 +518,7 @@
<a href="https://admin@(AppSetting.Value.Domain)/program-manager" class="waves-effect btnCustom">
<div class="menuTitle">
<i class="md md-home"></i>
<span> پروگرام منیجر </span>
<span> مدیریت پروژه </span>
</div>
</a>
</li>

View File

@@ -0,0 +1,15 @@
@page
<h4>Deploy Log</h4>
<pre style="
background:#111;
color:#0f0;
padding:15px;
max-height:600px;
overflow:auto;
font-size:13px;
border-radius:6px;">
</pre>

View File

@@ -2,6 +2,14 @@
@model ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel
@{
ViewData["Title"] = "File Upload";
<style>
.lineDiv {
width: 100%;
height: 2px;
background-image: linear-gradient(to right, #ffffff, #e5e5e5, #cbcbcb, #b2b2b2, #9a9a9a, #9a9a9a, #9a9a9a, #9a9a9a, #b2b2b2, #cbcbcb, #e5e5e5, #ffffff);
margin: 10px;
}
</style>
}
<h1>Upload APK File</h1>
@@ -60,16 +68,85 @@
</form>
<form style="margin:50px" asp-page-handler="PaymentGateWay" id="11" method="post">
<form style="margin:30px" asp-page-handler="PaymentGateWay" id="11" method="post">
<button type="submit">درگاه پرداخت تستی </button>
</form>
<div class="lineDiv"></div>
<div class="row m-t-20">
<div class="col-4"></div>
<div class="col-2">
<form asp-page-handler="UploadFrontEnd" id="12" method="post">
<button type="submit"
class="btn btn-danger"
onclick="return confirm('آیا از انتشار نسخه جدید فرانت مطمئن هستید؟');">
🚀 Deploy Next UI
</button>
</form>
</div>
<div class="col-2">
<button type="button" class="btn btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#logModal">
مشاهده لاگ Deploy
</button>
</div>
<div class="col-4"></div>
</div>
<div class="lineDiv"></div>
<div class="modal fade" id="logModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Deploy Log</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<pre id="logContent"
style="background: #111;
color: #0f0;
padding: 15px;
font-size: 13px;
text-align: left;
direction: ltr;">
</pre>
</div>
</div>
</div>
</div>
<form style="margin:20px" asp-page-handler="ContractingPartyToWorkshop" id="13" method="post">
<button class="btn btn-outline-secondary" type="submit"> افزودن آی دی طرف حساب به کارگاه </button>
</form>
@if (ViewData["message"] != null)
{
<p>@ViewData["message"]</p>
}
<script>
document.getElementById('logModal')
.addEventListener('show.bs.modal', function () {
fetch('?handler=Log')
.then(r => r.text())
.then(t => {
document.getElementById('logContent').textContent = t;
});
});
</script>
@* <script>

View File

@@ -1,35 +1,40 @@
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Application.FaceEmbedding;
using _0_Framework.Application.PaymentGateway;
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
using AccountManagement.Domain.AccountLeftWorkAgg;
using AccountMangement.Infrastructure.EFCore;
using Company.Domain.AndroidApkVersionAgg;
using Company.Domain.CustomizeCheckoutAgg.ValueObjects;
using Company.Domain.CustomizeCheckoutTempAgg.ValueObjects;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.InstitutionPlanAgg;
using Company.Domain.PaymentTransactionAgg;
using Company.Domain.RewardAgg;
using Company.Domain.RollCallAgg.DomainService;
using CompanyManagement.Infrastructure.Excel.WorkshopsRollCall;
using CompanyManagment.App.Contracts.AndroidApkVersion;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.PaymentTransaction;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.EFCore;
using Hangfire;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Net.Http;
using System.Security.Cryptography.Xml;
using System.Text.Json.Serialization;
using _0_Framework.Application.PaymentGateway;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.InstitutionPlanAgg;
using Company.Domain.PaymentTransactionAgg;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.PaymentTransaction;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using Microsoft.Extensions.Options;
using Parbad;
using Parbad.AspNetCore;
using Parbad.Gateway.Sepehr;
using System.ComponentModel.DataAnnotations;
using _0_Framework.Application.Enums;
using CompanyManagement.Infrastructure.Excel.WorkshopsRollCall;
using System.Diagnostics;
using System.Net.Http;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Authentication;
using static ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel2;
namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
@@ -45,6 +50,8 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
private readonly ITemporaryClientRegistrationApplication _clientRegistrationApplication;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IOnlinePayment _onlinePayment;
private readonly IFaceEmbeddingService _faceEmbeddingService;
private readonly IAuthHelper _authHelper;
[BindProperty] public IFormFile File { get; set; }
@@ -59,13 +66,18 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
[Display(Name = "کد ورژن")]
public string VersionCode { get; set; }
/// <summary>
/// لاگ آپلود فرانت
/// </summary>
public string LogContent { get; set; }
[BindProperty] public ApkType SelectedApkType { get; set; }
[BindProperty] public bool IsForce { get; set; }
public IndexModel(IAndroidApkVersionApplication application, IRollCallDomainService rollCallDomainService,
CompanyContext context, AccountContext accountContext, IHttpClientFactory httpClientFactory,
IOptions<AppSettingConfiguration> appSetting,
ITemporaryClientRegistrationApplication clientRegistrationApplication, IOnlinePayment onlinePayment)
ITemporaryClientRegistrationApplication clientRegistrationApplication, IOnlinePayment onlinePayment, IFaceEmbeddingService faceEmbeddingService, IAuthHelper authHelper)
{
_application = application;
_rollCallDomainService = rollCallDomainService;
@@ -74,6 +86,8 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
_httpClientFactory = httpClientFactory;
_clientRegistrationApplication = clientRegistrationApplication;
_onlinePayment = onlinePayment;
_faceEmbeddingService = faceEmbeddingService;
_authHelper = authHelper;
_paymentGateway = new SepehrPaymentGateway(httpClientFactory);
}
@@ -136,7 +150,8 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
public async Task<IActionResult> OnPostShiftDateNew()
{
await UpdateInstitutionContract();
//await UpdateInstitutionContract();
await UpdateFaceEmbeddingNames();
ViewData["message"] = "تومام یک";
return Page();
}
@@ -256,6 +271,18 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
}
}
private async System.Threading.Tasks.Task UpdateFaceEmbeddingNames()
{
var rollCallEmployees = await _context.RollCallEmployees
.Where(x => x.HasChangedName)
.ToListAsync();
foreach (var rollCallEmployee in rollCallEmployees)
{
await _faceEmbeddingService.UpdateEmbeddingFullNameAsync(rollCallEmployee.EmployeeId,
rollCallEmployee.WorkshopId, rollCallEmployee.EmployeeFullName);
}
}
public async Task<IActionResult> OnPostPaymentGateWay(CancellationToken cancellationToken)
{
var command = new CreatePaymentGatewayRequest()
@@ -276,6 +303,105 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
//TranslateCode(result?.ErrorCode);
return Page();
}
[DisableConcurrentExecution(timeoutInSeconds: 120)]
public async Task<IActionResult> OnPostUploadFrontEnd(CancellationToken cancellationToken)
{
var validAccountId = _authHelper.CurrentAccountId();
if (validAccountId == 2 || validAccountId == 322)
{
var batPath = @"C:\next-ui\deploy-next-ui.bat";
var psi = new ProcessStartInfo
{
FileName = batPath,
UseShellExecute = true, // خیلی مهم
Verb = "runas", // اجرای Administrator
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(psi);
TempData["Message"] = "فرآیند Deploy شروع شد. لاگ را بررسی کنید.";
return RedirectToPage();
}
return Forbid();
}
/// <summary>
/// افزودن آی دی طرف حساب به کارگاه
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 120)]
public async Task<IActionResult> OnPostContractingPartyToWorkshop()
{
var workshops = await _context.Workshops.Where(x => x.ContractingPartyId == 0).ToListAsync();
var worskhopEmployeer = await _context.WorkshopEmployers.Include(x => x.Employer).ToListAsync();
var contractingParties = await _context.PersonalContractingParties.ToListAsync();
foreach (var workshop in workshops)
{
var employers = worskhopEmployeer.Where(x => x.WorkshopId == workshop.id);
var contractingPartyIdList = new List<long>();
foreach (var employer in employers)
{
if (contractingParties.Any(x => x.id == employer.Employer.ContractingPartyId))
{
contractingPartyIdList.Add(employer.Employer.ContractingPartyId);
}
}
if (contractingPartyIdList.Count > 0)
{
if (contractingPartyIdList.Count == 1)
{
workshop.AddContractingPartyId(contractingPartyIdList[0]);
await _context.SaveChangesAsync();
}
else
{
var idDistinct = contractingPartyIdList.Distinct().ToList();
if (idDistinct.Count == 1)
{
workshop.AddContractingPartyId(contractingPartyIdList[0]);
await _context.SaveChangesAsync();
}
}
}
}
ViewData["message"] = "آی دی های طرف حساب اضافه شد";
return Page();
}
/// <summary>
/// دریافت لاگ آپلود فرانت
/// </summary>
/// <returns></returns>
public IActionResult OnGetLog()
{
var validAccountId = _authHelper.CurrentAccountId();
if (validAccountId == 2 || validAccountId == 322)
{
var logPath = @"C:\next-ui\log.txt";
if (!System.IO.File.Exists(logPath))
return Content("Log file not found.");
var content = System.IO.File.ReadAllText(logPath, Encoding.UTF8);
return Content(content);
}
return Content("شما مجاز به دیدن لاگ نیستید");
}
public async System.Threading.Tasks.Task OnGetCallback(string? transid, string? cardnumber,
string? tracking_number, string status)
@@ -824,8 +950,8 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
contract => contract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, contractingParty) => new { contract, contractingParty });
var remoteContractsQuery = query
.Where(x => x.contractingParty.Employers
.Any(e => e.WorkshopEmployers

View File

@@ -671,7 +671,7 @@
<a href="https://admin@(AppSetting.Value.Domain)/program-manager" class="waves-effect btnCustom">
<div class="menuTitle">
<i class="md md-home"></i>
<span> پروگرام منیجر </span>
<span> مدیریت پروژه </span>
</div>
</a>
</li>

View File

@@ -0,0 +1,22 @@
using _0_Framework.Application;
using CompanyManagment.App.Contracts.InsuranceList;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
namespace ServiceHost.Areas.Client.Controllers;
public class InsuranceController:ClientBaseController
{
private readonly IInsuranceListApplication _insuranceListApplication;
public InsuranceController(IInsuranceListApplication insuranceListApplication)
{
_insuranceListApplication = insuranceListApplication;
}
[HttpGet]
public async Task<ActionResult<PagedResult<InsuranceClientListViewModel>>> GetInsurances(InsuranceClientSearchModel searchModel)
{
var insurances =await _insuranceListApplication.GetInsuranceClientList(searchModel);
return Ok(insurances);
}
}

View File

@@ -157,9 +157,10 @@ namespace ServiceHost.Areas.Client.Pages.Company.Employees
});
}
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode,string birthDate)
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode,string birthDate, bool authorizedCanceled)
{
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, _workshopId);
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, authorizedCanceled, _workshopId);
return new JsonResult(result);
}

View File

@@ -47,7 +47,7 @@
</div>
</div>
<div id="AuthorizedCanceled" class="col-12 p-2 disable">
<div id="AuthorizedCanceled" class="col-12 p-2 disable">
<input id="authorizedCheckboxInput" type="checkbox"/>
<label>ثبت مشخصات پرسنل بدون احراز هویت</label>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -39,7 +39,7 @@ namespace ServiceHost.Areas.Client.Pages.Company.InsuranceList
public string WorkshopName;
public List<string> YearlyList;
public string Year;
public string Month;
public string Month;
public string Sorting;
public int PageIndex;
public string TypeOfInsurance;
@@ -163,6 +163,7 @@ namespace ServiceHost.Areas.Client.Pages.Company.InsuranceList
}
#endregion
#region OldClientByHeydari
//public IActionResult OnGetSearch(InsuranceListSearchModel searchModel)

View File

@@ -777,9 +777,9 @@ namespace ServiceHost.Areas.Client.Pages.Company.RollCall
});
}
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode, string birthDate)
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode, string birthDate, bool? authorizedCanceled = null)
{
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, _workshopId);
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate,false, _workshopId);
return new JsonResult(result);
}

View File

@@ -546,11 +546,11 @@ namespace ServiceHost.Areas.Client.Pages
return new JsonResult(jobViewModels);
}
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode, string birthDate)
public async Task<IActionResult> OnGetEmployeeDetailsWithNationalCode(string nationalCode, string birthDate, bool? authorizedCanceled = null)
{
var workshopSlug = User.FindFirst("WorkshopSlug")?.Value;
long workshopIDecrypt = _passwordHasher.SlugDecrypt(workshopSlug);
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate, workshopIDecrypt);
var result = await _employeeApplication.ValidateCreateEmployeeClientByNationalCodeAndWorkshopId(nationalCode, birthDate,false, workshopIDecrypt);
return new JsonResult(result);
}

View File

@@ -21,6 +21,8 @@ using System.Security.Cryptography;
using System.Threading;
using CompanyManagment.App.Contracts.FinancialInvoice;
using CompanyManagment.App.Contracts.InstitutionContract;
using GozareshgirProgramManager.Application._Common.Constants;
using GozareshgirProgramManager.Infrastructure.Persistence.Context;
namespace ServiceHost.Controllers;
@@ -65,6 +67,12 @@ public class GeneralController : GeneralBaseController
});
}
[HttpGet("pm-permissions")]
public IActionResult GetPMPermissions()
{
var permissions = ProgramManagerPermissionCode.GetAllCodes();
return new JsonResult(permissions);
}
[HttpGet("/api/callback"), HttpPost("/api/callback")]
public async Task<IActionResult> Verify(SepehrGatewayPayResponse payResponse)

View File

@@ -0,0 +1,38 @@
using GozareshgirProgramManager.Application._Common.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace ServiceHost.Filters;
public class OperationResultFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
// بررسی کنید که درخواست برای مسیر /api/programmanager/ است
var path = context.HttpContext.Request.Path.Value ?? string.Empty;
if (!path.StartsWith("/api/programmanager/", StringComparison.OrdinalIgnoreCase))
{
return; // اگر مسیر مطابقت ندارد، فیلتر را اعمال نکنید
}
if (context.Result is ObjectResult objectResult)
{
if (objectResult.Value is OperationResult operationResult && !operationResult.IsSuccess)
{
int statusCode = GetStatusCode(operationResult.ErrorType);
objectResult.StatusCode = statusCode;
context.HttpContext.Response.StatusCode = statusCode;
}
}
}
private static int GetStatusCode(ErrorType errorType) => errorType switch
{
ErrorType.NotFound => StatusCodes.Status404NotFound,
ErrorType.Unauthorized => StatusCodes.Status401Unauthorized,
ErrorType.Validation => StatusCodes.Status400BadRequest,
ErrorType.BadRequest => StatusCodes.Status400BadRequest,
ErrorType.InternalServerError => StatusCodes.Status500InternalServerError,
_ => StatusCodes.Status400BadRequest
};
}

View File

@@ -1,14 +1,12 @@
using System.Collections.Concurrent;
using GozareshgirProgramManager.Application._Common.Constants;
using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using Microsoft.AspNetCore.SignalR;
using ServiceHost.Hubs.ProgramManager;
namespace ServiceHost.Notifications.ProgramManager;
public class SignalRBoardNotificationPublisher : IBoardNotificationPublisher
public class SignalRBoardNotificationPublisher:IBoardNotificationPublisher
{
private readonly IHubContext<ProjectBoardHub> _hubContext;
@@ -17,12 +15,12 @@ public class SignalRBoardNotificationPublisher : IBoardNotificationPublisher
_hubContext = hubContext;
}
public Task NotifyTaskStatusChanged(long userId, TaskSectionStatus oldStatus,
public Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus,
TaskSectionStatus newStatus, Guid sectionId)
{
var payload = new
{
UserId = userId,
UserId= userId,
OldStatus = oldStatus,
NewStatus = newStatus,
SectionId = sectionId
@@ -32,85 +30,10 @@ public class SignalRBoardNotificationPublisher : IBoardNotificationPublisher
var taskGroup = $"pm.task:{sectionId}";
// گروه permission-based (مثلاً برای Admin ها)
var permissionGroup = $"pm.perm:{ProgramManagerPermissionCode.Board.All.ViewAll}";
var permissionGroup = $"pm.perm:{ProgramManagerPermissionCode.Board.ViewAllUsersProjects.Code}";
// ارسال به هر دو گروه؛ SignalR خودش duplicate connection رو هندل می‌کنه
return _hubContext.Clients.Groups(taskGroup, permissionGroup)
.SendAsync("ReceiveProjectStatusChanged", payload);
}
public async Task NotifyTaskCreated(TaskSection taskSection)
{
var sectionId = taskSection.Id;
var userId = taskSection.CurrentAssignedUserId;
var taskGroup = $"pm.task:{taskSection.Id}";
var adminGroup = $"pm.perm:{ProgramManagerPermissionCode.Board.All.ViewAll}";
// Add assignee connections to task group automatically
await AddAssigneeConnectionsToTaskGroup(userId, sectionId);
var payload = new
{
TaskId = sectionId,
AssignedTo = userId,
};
await _hubContext.Clients.Groups(taskGroup, adminGroup)
.SendAsync("TaskCreated", payload);
}
public Task NotifyTaskAssigned(long userId, Guid sectionId)
{
throw new NotImplementedException();
}
public Task NotifyTaskRemoved(long userId, Guid sectionId)
{
throw new NotImplementedException();
}
private async Task AddAssigneeConnectionsToTaskGroup(long userId, Guid taskId)
{
// Retrieve all connectionIds that have this claim
var connections = ConnectionMapping.GetConnectionsByClaim("pm.userId", userId.ToString());
var taskGroup = $"pm.task:{taskId}";
var joinTasks = connections
.Select(connId => _hubContext.Groups.AddToGroupAsync(connId, taskGroup));
await Task.WhenAll(joinTasks);
}
}
public static class ConnectionMapping
{
private static readonly ConcurrentDictionary<string, HashSet<string>> _map = new();
public static void Add(string claimType, string claimValue, string connectionId)
{
var key = $"{claimType}:{claimValue}";
_map.AddOrUpdate(key,
_ => new HashSet<string> { connectionId },
(_, set) => { set.Add(connectionId); return set; });
}
public static void Remove(string claimType, string claimValue, string connectionId)
{
var key = $"{claimType}:{claimValue}";
if (_map.TryGetValue(key, out var set))
{
set.Remove(connectionId);
if (!set.Any()) _map.TryRemove(key, out _);
}
}
public static IEnumerable<string> GetConnectionsByClaim(string claimType, string claimValue)
{
var key = $"{claimType}:{claimValue}";
return _map.TryGetValue(key, out var set) ? set : Enumerable.Empty<string>();
}
}

View File

@@ -35,6 +35,7 @@ using Microsoft.OpenApi;
using ServiceHost.Hubs.ProgramManager;
using ServiceHost.Notifications.ProgramManager;
using ServiceHost.Conventions;
using ServiceHost.Filters;
var builder = WebApplication.CreateBuilder(args);
@@ -178,6 +179,7 @@ builder.Services.AddAuthorization(options =>
builder.Services.AddControllers(options =>
{
options.Conventions.Add(new ParameterBindingConvention());
options.Filters.Add(new OperationResultFilter());
})
.AddJsonOptions(options =>
{

View File

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

View File

@@ -3,8 +3,8 @@
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
<!--<StartupObject>ServiceHost.Program</StartupObject>-->
</PropertyGroup>

View File

@@ -28,7 +28,7 @@
//program_manager_db
"ProgramManagerDb": "Data Source=.;Initial Catalog=program_manager_db;Integrated Security=True;TrustServerCertificate=true;",
//"ProgramManagerDb": "Data Source=185.208.175.186;Initial Catalog=program_manager_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
//"ProgramManagerDbServer": "Data Source=171.22.24.15;Initial Catalog=program_manager_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
"ProgramManagerDbServer": "Data Source=171.22.24.15;Initial Catalog=program_manager_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
//mahan Docker
//"MesbahDb": "Data Source=localhost,5069;Initial Catalog=mesbah_db;User ID=sa;Password=YourPassword123;TrustServerCertificate=True;"
},

View File

@@ -69,14 +69,14 @@ $(document).ready(function () {
function checkInputs() {
const genderSelected = $(".genderStatus:checked").length > 0;
const maritalStatusSelected = $(".maritalStatus:checked").length > 0;
const nationality = $("#NationalitySelect").val();
;
const nationality = $('#NationalitySelect option:selected').length > 0;
const fName = $("#firstName").val();
const lName = $("#lastName").val();
const startWork = $("#startWork").val().trim();
const startWorkIsValidDate = /^\d{4}[-\/]\d{2}[-\/]\d{2}$/.test(startWork);
const semat = $("#sematSelect").val();
debugger;
let isEmpty = false;
if (!genderSelected || !maritalStatusSelected || !nationality || !fName || !lName || !startWork || !startWorkIsValidDate || semat === "0") {
@@ -88,6 +88,11 @@ function checkInputs() {
validateField(".validMariage", "لطفا وضعیت تاهل را مشخص کنید.");
return false;
}
debugger;
if (!nationality) {
validateField("#NationalitySelect", "لطفا ملیت را مشخص نمایید.");
return false;
}
if (!$("input[name='Command.Gender']:checked").val()) {
validateField(".validGender", "لطفا جنسیت را مشخص کنید.");
return false;

View File

@@ -186,6 +186,14 @@ $(document).ready(function () {
next() {
if (goToStep2) {
if ($('#authorizedCheckboxInput').is(':checked')) {
$('#nationalCodeS2Section').removeClass('disable');
$('#birthDateS2Section').removeClass('disable');
$('#nameS2Section').removeClass('disable');
$('#fNameS2Section').removeClass('disable');
$('.disablemightBeNullDB1').removeClass('disable');
}
this.modal.setState(this.modal.step2);
}
}
@@ -454,7 +462,17 @@ function saveFullData() {
formData.append("Command.CreateCustomizeEmployeeSettings.FridayWork", $('#Friday1').prop('checked') ? "Default" : "WorkInFriday");
formData.append("Command.CreateCustomizeEmployeeSettings.HolidayWork", $('#HolidayWork1').prop('checked') ? "Default" : "WorkInHolidays");
var authorizedCanceled = false;
if ($('#authorizedCheckboxInput').is(':checked')) {
//$('#nationalCodeS2Section').removeClass('disable');
//$('#birthDateS2Section').removeClass('disable');
//$('#nameS2Section').removeClass('disable');
//$('#fNameS2Section').removeClass('disable');
//$('.disablemightBeNullDB1').removeClass('disable');
formData.append("Command.CanceledAuthorize", true)
}
let pic1 = $("#pic1").attr('src');
let pic2 = $("#pic2").attr('src');
if (pic1) formData.append("Command.RollCallUploadEmployeePicture.Picture1", pic1);

View File

@@ -82,12 +82,24 @@ function checkNationalCode(nationalCode, birthDate) {
checkNationalUrl = getEmployeeDataByNationalCodeUrl;
}
var authorizedCanceled = false;
if ($('#authorizedCheckboxInput').is(':checked')) {
//$('#nationalCodeS2Section').removeClass('disable');
//$('#birthDateS2Section').removeClass('disable');
//$('#nameS2Section').removeClass('disable');
//$('#fNameS2Section').removeClass('disable');
//$('.disablemightBeNullDB1').removeClass('disable');
authorizedCanceled = true;
}
$("#IdentityLoading").show();
$.ajax({
async: false,
url: checkNationalUrl,
method: "GET",
data: { nationalCode: nationalCode, birthDate: birthDate },
data: { nationalCode: nationalCode, birthDate: birthDate, authorizedCanceled: authorizedCanceled },
success: (response) => {
if (response.isSuccedded) {
if (response.data) {