Compare commits

..

42 Commits

Author SHA1 Message Date
83b045c2b1 add employer controller 2025-06-17 14:17:26 +03:30
SamSys
9ca041ac18 add Authorization setting for next - subdomain 2025-06-11 15:32:40 +03:30
SamSys
031fb05f8c Menue Change for Next test 2025-06-08 17:09:09 +03:30
SamSys
4aed0ddd68 API ContractingParty Controller Merged 2025-06-07 17:25:27 +03:30
SamSys
9b455d4a2e Fix Conflict 2025-06-03 21:44:00 +03:30
SamSys
0c0e955800 new-Insurance-Opration Merged 2025-06-03 21:43:19 +03:30
SamSys
5f7f63689c build tailwind 2025-06-03 16:51:34 +03:30
SamSys
7db754af56 Merge branch 'Feature/Register/Init' into Upload/dad-mehr 2025-06-03 16:49:18 +03:30
SamSys
42ea521e0b set Salary in create employee by Client merged 2025-05-27 21:38:14 +03:30
SamSys
c608e22062 AMO merged 2025-05-25 21:40:54 +03:30
MahanCh
bb80da6e3b add set salary tab in create employee 2025-05-25 19:24:29 +03:30
SamSys
4c734e0513 Camera icon Task merged 2025-05-21 21:39:17 +03:30
SamSys
cc3812ebee Static merged 2025-05-20 22:41:55 +03:30
SamSys
17e390d840 ReCalculateValues Merged 2025-05-19 21:32:09 +03:30
SamSys
f4a16b8c69 Rgister Merge 2025-05-19 21:30:36 +03:30
SamSys
c2fa992369 Employer Confirm Insurance 2025-05-18 21:18:23 +03:30
SamSys
922ab6f32b RotatingShifrtReport Merged 2025-05-18 21:17:21 +03:30
SamSys
0eee2a53c3 register merged 2025-05-18 21:13:52 +03:30
SamSys
b0f5ec6bbd change 2025-05-14 21:37:12 +03:30
SamSys
9ef48b982d Mearge RecalCulate Valuse group 2025-05-14 21:33:38 +03:30
SamSys
2a306dedac merge New Version of RegisterFinancial 2025-05-14 21:31:56 +03:30
SamSys
400790a53b RotatingShiftReport BackEnd Changed 2025-05-14 18:53:34 +03:30
SamSys
6a2ff178d3 push 2025-05-13 22:15:06 +03:30
SamSys
5f64b945d1 RotatingShiftReport client 2025-05-13 21:37:41 +03:30
SamSys
280a475455 sepration contract index js on client 2025-05-13 13:06:56 +03:30
SamSys
a7b91fac18 merged loan and SalaryAid to OfficialCheckout 2025-05-12 21:26:07 +03:30
MahanCh
fcea7eed21 merge 2025-05-10 16:41:14 +03:30
MahanCh
0a293dfa8c fix application 2025-05-10 16:18:18 +03:30
MahanCh
5825c7b8e2 fix bug 2025-05-10 16:01:09 +03:30
ebdf26d93c merge from edit checkout on change salary aid and .... 2025-05-09 13:45:25 +03:30
SamSys
67ec735778 Register changes 2025-05-07 22:53:41 +03:30
MahanCh
1ebbd2d7a9 Merge branch 'Feature/EmployeeDocuments/V2' into Upload/dad-mehr 2025-05-06 14:17:32 +03:30
SamSys
a40a9643f4 employee document workflow V2 2025-05-05 22:08:00 +03:30
SamSys
55c139578d add workshopSetting page in client 2025-05-05 22:07:01 +03:30
MahanCh
e9588125c0 merge from register financial 2025-05-04 20:59:42 +03:30
SamSys
bf9c317565 uid autorize for create employee in admin side 2025-05-03 15:42:46 +03:30
SamSys
22bd435627 ReCalculate rollcall values in CWEs "PersonnelShiftChange" 2025-04-30 21:27:41 +03:30
MahanCh
423d6ada9b Merge branch 'Feature/Register/Init' into Upload/dad-mehr 2025-04-28 15:50:51 +03:30
SamSys
8bdfd44bba fix bug 2025-04-27 21:57:28 +03:30
SamSys
104534ed96 CalculationDate for SalaryAid 2025-04-27 21:43:00 +03:30
MahanCh
c00a9c0864 fix task size validation 2025-04-27 20:52:04 +03:30
MahanCh
cdb29a80e1 Add Calculation date to salaryAid 2025-04-27 19:37:50 +03:30
1389 changed files with 45959 additions and 1235917 deletions

View File

@@ -1,64 +0,0 @@
name: Deploy Dev (Branch Trigger)
on:
push:
branches:
- Feature/general/docker
env:
IMAGE_NAME: gozareshgir-api
# مسیری که فایل docker-compose.yml مخصوص تست در سرور قرار دارد
SERVER_PATH: ~/apps/test-dev/backend-api
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# 1. لاگین به داکر هاب/رجیستری شخصی
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ secrets.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# 2. بیلد و پوش کردن ایمیج با تگ :dev
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ secrets.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:dev
# 3. اتصال به سرور و آپدیت سرویس
- name: Update Service on Test Server
uses: appleboy/ssh-action@v1.0.3
env:
DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
APP_VERSION: dev # ورژن تست همیشه dev است
with:
host: ${{ secrets.SSH_HOST_TEST }}
username: ${{ secrets.SSH_USERNAME_TEST }}
key: ${{ secrets.SSH_KEY_TEST }}
port: 22
envs: DOCKER_REGISTRY,DOCKER_USERNAME,DOCKER_PASSWORD,APP_VERSION
script: |
cd ${{ env.SERVER_PATH }}
# لاگین مجدد در سرور برای اطمینان
echo "$DOCKER_PASSWORD" | docker login $DOCKER_REGISTRY -u $DOCKER_USERNAME --password-stdin
# اکسپورت کردن ورژن برای اینکه فایل داکر-کمپوز سرور آن را بشناسد
export APP_VERSION=$APP_VERSION
# دانلود ایمیج جدید و آپدیت کانتینر
docker compose pull
docker compose up -d --remove-orphans
# پاک کردن ایمیج‌های قدیمی برای پر نشدن فضای سرور
docker image prune -f

View File

@@ -1,45 +0,0 @@
name: Deploy Development ASP.NET Core App to IIS
on:
push:
branches:
- Main
jobs:
build-and-deploy:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x' # یا نسخه پروژه‌ت
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release
- name: Publish
run: dotnet publish --configuration Release --output ./publish /p:EnvironmentName=Development --no-build
- name: Deploy to IIS via Web Deploy
shell: powershell
run: |
$publishFolder = Resolve-Path ./publish
& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
-verb:sync `
-source:contentPath="$publishFolder" `
-dest:contentPath="dadmehrg",computerName="https://$env:SERVER_HOST:8172/msdeploy.axd?site=gozareshgir",userName="$env:DEPLOY_USER",password="$env:DEPLOY_PASSWORD",authType="Basic" `
-allowUntrusted `
-enableRule:AppOffline
env:
SERVER_HOST: 171.22.24.15
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PASSWORD: ${{ secrets.DEPLOY_PASSWORD }}

24
.gitignore vendored
View File

@@ -1,21 +1,3 @@
.env*
.env
certs/*.pfx
certs/*.pem
certs/*.key
certs/*.crt
Storage/
Logs/
*.user
*.suo
bin/
obj/
certs/*.pfx
certs/*.pem
certs/*.key
certs/*.crt
Storage/
Logs/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
@@ -379,10 +361,4 @@ MigrationBackup/
# # Fody - auto-generated XML schema
# FodyWeavers.xsd
.idea
/ServiceHost/appsettings.Development.json
/ServiceHost/appsettings.json
# Storage folder - ignore all uploaded files, thumbnails, and temporary files
ServiceHost/Storage

View File

@@ -1,44 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>_0_Framework</RootNamespace>
</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" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3" />
<PackageReference Include="IPE.SmsIR" Version="1.0.5" />
<PackageReference Include="EPPlus" Version="7.5.2" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.34" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="PersianTools.Core" Version="2.0.4" />
<PackageReference Include="System.Drawing.Common" Version="10.0.1" />
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.6.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="10.0.1" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Application\UID\UidService.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Application\AuthorizedPerson\AuthorizedPersonApplication.cs" />
<Compile Remove="Application\AuthorizedPerson\IAuthorizedPersonApplication.cs" />
<Compile Remove="Domain\AuthorizedPersonAgg\IAuthorizedPersonRepository.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Domain\AuthorizedPersonAgg\" />
<Folder Include="InfraStructure\AuthorizedPerson\" />
</ItemGroup>
</Project>

View File

@@ -1,8 +0,0 @@
namespace _0_Framework.Application;
public class AppSettingConfiguration
{
public string Domain { get; set; }
public string ClientDomain =>"client"+Domain;
public string AdminDomain =>"admin"+Domain;
}

View File

@@ -40,10 +40,7 @@ public class AuthHelper : IAuthHelper
result.Mobile = claims.FirstOrDefault(x => x is { Type: "Mobile" }).Value;
result.SubAccountId = long.Parse(claims.FirstOrDefault(x => x.Type == "SubAccountId").Value);
result.WorkshopName = claims.FirstOrDefault(x => x is { Type: "WorkshopName" })?.Value;
result.Permissions = Tools.DeserializeFromBsonList<int>(claims.FirstOrDefault(x => x is { Type: "permissions" })?.Value);
result.RoleName = claims.FirstOrDefault(x => x is { Type: "RoleName" })?.Value;
result.WorkshopId = long.Parse(claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value??"0");
return result;
return result;
}
public List<int> GetPermissions()
@@ -56,11 +53,6 @@ public class AuthHelper : IAuthHelper
return Tools.DeserializeFromBsonList<int>(permissions); //Mahan
}
public bool HasPermission(int permission)
{
return GetPermissions().Any(x => x == permission);
}
public long CurrentAccountId()
{
return IsAuthenticated()
@@ -82,7 +74,7 @@ public class AuthHelper : IAuthHelper
#region Vafa
public void UpdateWorkshopSlugClaim(string newWorkshopSlug, string newWorkshopName,long newWorkshopId)
public void UpdateWorkshopSlugClaim(string newWorkshopSlug, string newWorkshopName)
{
var user = _contextAccessor.HttpContext.User;
@@ -91,7 +83,6 @@ public class AuthHelper : IAuthHelper
var claimsIdentity = (ClaimsIdentity)user.Identity;
var existingClaimSlug = claimsIdentity.FindFirst("WorkshopSlug");
var existingClaimName = claimsIdentity.FindFirst("WorkshopName");
var existingWorkshopId = claimsIdentity.FindFirst("WorkshopId");
if (existingClaimSlug != null)
{
@@ -103,14 +94,9 @@ public class AuthHelper : IAuthHelper
claimsIdentity.RemoveClaim(existingClaimName);
}
if (existingWorkshopId != null)
{
claimsIdentity.RemoveClaim(existingWorkshopId);
}
claimsIdentity.AddClaim(new Claim("WorkshopSlug", newWorkshopSlug));
claimsIdentity.AddClaim(new Claim("WorkshopName", newWorkshopName));
claimsIdentity.AddClaim(new Claim("WorkshopId",newWorkshopId.ToString()));
var authProperties = new AuthenticationProperties
@@ -140,16 +126,8 @@ public class AuthHelper : IAuthHelper
return "";
}
#endregion
public long GetWorkshopId()
{
return long.Parse(_contextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type == "WorkshopId")?.Value ?? "0");
}
public string CurrentAccountRole()
{
@@ -202,9 +180,7 @@ public class AuthHelper : IAuthHelper
//mahanChanges
new("workshopList",workshopBson),
new("WorkshopSlug",slug),
new("WorkshopId", account.WorkshopId.ToString()),
new("WorkshopName",account.WorkshopName??""),
new("pm.userId", account.PmUserId.ToString()),
new("WorkshopName",account.WorkshopName??"")
};

View File

@@ -20,19 +20,16 @@ public class AuthViewModel
public int? PositionValue { get; set; }
public string WorkshopSlug { get; set; }
public long WorkshopId { get; set; }
public string WorkshopName { get; set; }
public List<WorkshopClaim> WorkshopList { get; set; }
#endregion
public long SubAccountId { get; set; }
public long? PmUserId { get; set; }
public AuthViewModel(long id, long roleId, string fullname, string username, string mobile,string profilePhoto,
List<int> permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue,
long subAccountId = 0,long? pmUserId = null)
List<int> permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue, long subAccountId = 0)
{
Id = id;
RoleId = roleId;
@@ -46,7 +43,6 @@ public class AuthViewModel
ClientAriaPermission = clientAriaPermission;
PositionValue = positionValue;
SubAccountId = subAccountId;
PmUserId = pmUserId;
}
public AuthViewModel()

View File

@@ -1,22 +0,0 @@
namespace _0_Framework.Application.Enums;
/// <summary>
/// وضعیت تایید قرادا مالی
/// </summary>
public enum InstitutionContractVerificationStatus
{
/// <summary>
/// در انتظار تایید
/// </summary>
PendingForVerify = 0,
/// <summary>
/// در انتظار کارپوشه
/// </summary>
PendingWorkflow = 1,
/// <summary>
/// تایید شده
/// </summary>
Verified = 2
}

View File

@@ -1,15 +0,0 @@
namespace _0_Framework.Application.Enums;
public enum TypeOfCheckoutWarning
{
/// <summary>
/// هشدار های متفرقه
/// </summary>
OthersWarning,
/// <summary>
/// هشدار سهم بیمه کارگر
/// </summary>
InsuranceEmployeeShare,
}

View File

@@ -1,53 +0,0 @@
namespace _0_Framework.Application.Enums;
public enum TypeOfSmsSetting
{
//همه انواع پیامک
All = 0,
/// <summary>
/// پیامک
/// یادآور بدهی ماهیانه قرارداد مالی
/// </summary>
InstitutionContractDebtReminder,
/// <summary>
/// پیامک
/// صورت حساب ماهانه قرارداد مالی
/// </summary>
MonthlyInstitutionContract,
/// <summary>
/// پیامک
/// اعلام مسدودی طرف حساب
/// </summary>
BlockContractingParty,
/// <summary>
/// پیامک
/// هشدار بدهی
/// </summary>
Warning,
/// <summary>
///پیامک اقدام قضائی
/// </summary>
LegalAction,
/// <summary>
/// پیامک تایید قراداد
/// </summary>
InstitutionContractConfirm,
/// <summary>
/// ارسال کد تاییدیه قرارداد مالی
/// </summary>
SendInstitutionContractConfirmationCode,
/// <summary>
/// یادآور وظایف
/// </summary>
TaskReminder,
}

View File

@@ -1,25 +0,0 @@
using System.Threading.Tasks;
namespace _0_Framework.Application.FaceEmbedding;
/// <summary>
/// سرویس اطلاع‌رسانی تغییرات Face Embedding
/// </summary>
public interface IFaceEmbeddingNotificationService
{
/// <summary>
/// اطلاع‌رسانی ایجاد یا به‌روزرسانی Embedding
/// </summary>
Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName);
/// <summary>
/// اطلاع‌رسانی حذف Embedding
/// </summary>
Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId);
/// <summary>
/// اطلاع‌رسانی بهبود Embedding
/// </summary>
Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId);
}

View File

@@ -1,25 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace _0_Framework.Application.FaceEmbedding;
public interface IFaceEmbeddingService
{
Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId, string employeeFullName, string picture1Path, string picture2Path);
Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId, string employeeFullName, Stream picture1Stream, Stream picture2Stream);
Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding, float confidence, Dictionary<string, object> metadata = null);
Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId);
Task<OperationResult> UpdateEmbeddingFullNameAsync(long employeeId, long workshopId, string newFullName);
}
public class FaceEmbeddingResponse
{
public long EmployeeId { get; set; }
public long WorkshopId { get; set; }
public string EmployeeFullName { get; set; }
public float[] Embedding { get; set; }
public float Confidence { get; set; }
public Dictionary<string, object> Metadata { get; set; }
}

View File

@@ -12,18 +12,16 @@ public interface IAuthHelper
string CurrentAccountRole();
AuthViewModel CurrentAccountInfo();
List<int> GetPermissions();
bool HasPermission(int permission);
long CurrentAccountId();
string CurrentAccountMobile();
#region Vafa
void UpdateWorkshopSlugClaim(string workshopSlug, string workshopName, long workshopId);
void UpdateWorkshopSlugClaim(string workshopSlug, string workshopName);
#endregion
long CurrentSubAccountId();
string GetWorkshopSlug();
string GetWorkshopName();
long GetWorkshopId();
(long Id, UserType userType, long roleId) GetUserTypeWithId();
}

View File

@@ -1,15 +0,0 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace _0_Framework.Application;
public class PagedResult<T> where T : class
{
public int TotalCount { get; set; }
public List<T> List { get; set; }
}
public class PagedResult<T,TMeta>:PagedResult<T> where T : class
{
public TMeta? Meta { get; set; }
}

View File

@@ -1,7 +0,0 @@
namespace _0_Framework.Application;
public class PaginationRequest
{
public int PageIndex { get; set; } = 1;
public int PageSize { get; set; } = 30;
}

View File

@@ -1,100 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Security.Policy;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace _0_Framework.Application.PaymentGateway;
public class AqayePardakhtPaymentGateway:IPaymentGateway
{
private static string _pin = "86EAF2C4D052F7D8759F";
private const string AccountNumber = "AP.1042276242";
private const string EncryptedKey = "130D2@D2923";
private readonly HttpClient _httpClient;
public AqayePardakhtPaymentGateway(IHttpClientFactory httpClientFactory,IOptions<AppSettingConfiguration> appSetting)
{
_httpClient = httpClientFactory.CreateClient();
if (appSetting.Value.Domain == ".dadmehrg.ir")
{
_pin = "7349F84E81AB584862D9";
}
}
public async Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command,CancellationToken cancellationToken =default)
{
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new
{
pin = _pin,
amount = command.Amount,
callback = command.CallBackUrl,
card_number = command.CardNumber,
invoice_id = command.TransactionId,
mobile = command.Mobile,
email = command.Email??"",
description = command.Description,
}, cancellationToken: cancellationToken);
var resStr = await response.Content.ReadAsStringAsync(cancellationToken);
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
return result;
}
public string GetStartPayUrl(string transactionId) =>
$"https://panel.aqayepardakht.ir/startpay/{transactionId}";
public async Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken = default)
{
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/verify", new
{
pin = _pin,
amount = command.Amount,
transid = command.TransactionId,
}, cancellationToken: cancellationToken);
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
return result;
}
public async Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
{
var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new
{
pin = "sandbox",
amount = command.Amount,
callback = command.CallBackUrl,
card_number = command.Amount,
invoice_id = command.TransactionId,
mobile = command.Mobile,
email = command.Email,
description = command.Email,
}, cancellationToken: cancellationToken);
var result = await response.Content.ReadFromJsonAsync<PaymentGatewayResponse>(cancellationToken: cancellationToken);
return result;
}
public string GetStartPaySandBoxUrl(string transactionId) =>
$"https://panel.aqayepardakht.ir/startpay/sandbox/{transactionId}";
public async Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken)
{
var response =await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/getmoney", new
{
account=AccountNumber,
code = EncryptedKey
}, cancellationToken: cancellationToken);
var jsonString = await response.Content.ReadAsStringAsync(cancellationToken);
var result = await response.Content.ReadFromJsonAsync<WalletAmountResponse>(cancellationToken);
return result;
}
}

View File

@@ -1,67 +0,0 @@
using Microsoft.AspNetCore.Server.HttpSys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace _0_Framework.Application.PaymentGateway;
public interface IPaymentGateway
{
Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command, CancellationToken cancellationToken =default);
string GetStartPayUrl(string transactionId);
Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken=default);
Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken=default);
string GetStartPaySandBoxUrl(string transactionId);
Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken);
}
public class PaymentGatewayResponse
{
[JsonPropertyName("status")]
public string Status { get; set; }
[JsonPropertyName("code")]
public int? ErrorCode { get; set; }
[JsonPropertyName("transid")]
public string Token { get; set; }
public bool IsSuccess { get; set; }
public string Message { get; set; }
}
public class WalletAmountResponse
{
[JsonPropertyName("status")]
public string Status { get; set; }
[JsonPropertyName("money")]
public double Amount { get; set; }
[JsonPropertyName("code")]
public int Code { get; set; }
}
public class CreatePaymentGatewayRequest
{
public double Amount { get; set; }
public string TransactionId { get; set; }
public string CallBackUrl { get; set; }
public string CardNumber { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public string Description { get; set; }
public long FinancialInvoiceId { get; set; }
public IDictionary<string, object> ExtraData { get; set; }
}
public class VerifyPaymentGateWayRequest
{
public string DigitalReceipt { get; set; }
public string TransactionId { get; set; }
public double Amount { get; set; }
}

View File

@@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace _0_Framework.Application.PaymentGateway;
public class SepehrPaymentGateway:IPaymentGateway
{
private readonly HttpClient _httpClient;
private const long TerminalId = 99213700;
private readonly ILogger<SepehrPaymentGateway> _logger;
public SepehrPaymentGateway(IHttpClientFactory httpClient, ILogger<SepehrPaymentGateway> logger)
{
_logger = logger;
_httpClient = httpClient.CreateClient();
_httpClient.BaseAddress = new Uri("https://sepehr.shaparak.ir/Rest/V1/PeymentApi/");
}
public async Task<PaymentGatewayResponse> Create(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
{
_logger.LogInformation("Create payment started. TransactionId: {TransactionId}, Amount: {Amount}", command.TransactionId, command.Amount);
command.ExtraData ??= new Dictionary<string, object>();
_logger.LogInformation("Initializing extra data with FinancialInvoiceId: {FinancialInvoiceId}", command.FinancialInvoiceId);
command.ExtraData.Add("financialInvoiceId", command.FinancialInvoiceId);
var extraData = JsonConvert.SerializeObject(command.ExtraData);
_logger.LogInformation("Serialized extra data payload: {Payload}", extraData);
var res = await _httpClient.PostAsJsonAsync("GetToken", new
{
TerminalID = TerminalId,
Amount = command.Amount,
InvoiceID = command.TransactionId,
callbackURL = command.CallBackUrl,
payload = extraData
}, cancellationToken: cancellationToken);
_logger.LogInformation("Create payment request sent. StatusCode: {StatusCode}", res.StatusCode);
// خواندن محتوای پاسخ
var content = await res.Content.ReadAsStringAsync(cancellationToken);
_logger.LogInformation("Create payment response content: {Content}", content);
// تبدیل پاسخ JSON به آبجکت دات‌نت
var json = System.Text.Json.JsonDocument.Parse(content);
_logger.LogInformation("Create payment JSON parsed successfully.");
// گرفتن مقدار AccessToken
var accessToken = json.RootElement.GetProperty("Accesstoken").ToString();
var status = json.RootElement.GetProperty("Status").ToString();
_logger.LogInformation("Create payment parsed values. Status: {Status}, AccessToken: {AccessToken}", status, accessToken);
return new PaymentGatewayResponse
{
Status = status,
IsSuccess = status == "0",
Token = accessToken,
};
}
public string GetStartPayUrl(string token)=>
$"https://sepehr.shaparak.ir/Payment/Pay?token={token}&terminalId={TerminalId}";
public async Task<PaymentGatewayResponse> Verify(VerifyPaymentGateWayRequest command, CancellationToken cancellationToken = default)
{
_logger.LogInformation("Verify payment started. DigitalReceipt: {DigitalReceipt}", command.DigitalReceipt);
var res = await _httpClient.PostAsJsonAsync("Advice", new
{
digitalreceipt = command.DigitalReceipt,
Tid = TerminalId,
}, cancellationToken: cancellationToken);
_logger.LogInformation("Verify payment request sent. StatusCode: {StatusCode}", res.StatusCode);
// خواندن محتوای پاسخ
var content = await res.Content.ReadAsStringAsync(cancellationToken);
_logger.LogInformation("Verify payment response content: {Content}", content);
// تبدیل پاسخ JSON به آبجکت دات‌نت
var json = System.Text.Json.JsonDocument.Parse(content);
_logger.LogInformation("Verify payment JSON parsed successfully.");
var message = json.RootElement.GetProperty("Message").GetString();
var status = json.RootElement.GetProperty("Status").GetString();
_logger.LogInformation("Verify payment parsed values. Status: {Status}, Message: {Message}", status, message);
return new PaymentGatewayResponse
{
Status = status,
IsSuccess = status.ToLower() == "ok",
Message = message
};
}
public Task<PaymentGatewayResponse> CreateSandBox(CreatePaymentGatewayRequest command, CancellationToken cancellationToken = default)
{
throw new System.NotImplementedException();
}
public string GetStartPaySandBoxUrl(string transactionId)
{
throw new System.NotImplementedException();
}
public Task<WalletAmountResponse> GetWalletAmount(CancellationToken cancellationToken)
{
throw new System.NotImplementedException();
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _0_Framework.Application;
public static class SecretKeys
{
public static string ProgramManagerInternalApi => "JOb09$Ic3NJd0siLCJtYWMiOiI2%dmODJmNDV";
}

View File

@@ -17,18 +17,4 @@ public class ApiResultViewModel
public string DeliveryUnixTime { get; set; }
public string DeliveryColor { get; set; }
public string FullName { get; set; }
}
public class ApiReportDto
{
public int MessageId { get; set; }
public long Mobile { get; set; }
public string SendUnixTime { get; set; }
public string DeliveryState { get; set; }
public string DeliveryUnixTime { get; set; }
public string DeliveryColor { get; set; }
}

View File

@@ -19,13 +19,6 @@ public interface ISmsService
bool SendAccountsInfo(string number,string fullName, string userName);
Task<ApiResultViewModel> GetByMessageId(int messId);
Task<List<ApiResultViewModel>> GetApiResult(string startDate, string endDate);
#region ForApi
Task<List<ApiReportDto>> GetApiReport(string startDate, string endDate);
#endregion
string DeliveryStatus(byte? dv);
string DeliveryColorStatus(byte? dv);
string UnixTimeStampToDateTime(int? unixTimeStamp);
@@ -33,79 +26,6 @@ public interface ISmsService
#region Mahan
Task<double> GetCreditAmount();
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);
SmsResult TaskReminderSms(string number, string taskCount);
#endregion
#region InstitutionContractSMS
/// <summary>
/// پیامک اهانه جدید
/// </summary>
/// <param name="number"></param>
/// <param name="tamplateId"></param>
/// <param name="fullname"></param>
/// <param name="amount"></param>
/// <param name="code1"></param>
/// <param name="code2"></param>
/// <returns></returns>
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBillNew(string number, int tamplateId, string fullname, string amount, string code1,
string code2);
/// <summary>
/// پیامک ماهانه قدیم
/// </summary>
/// <param name="number"></param>
/// <param name="tamplateId"></param>
/// <param name="fullname"></param>
/// <param name="amount"></param>
/// <param name="id"></param>
/// <param name="aprove"></param>
/// <returns></returns>
Task<(byte status, string message, int messaeId, bool isSucceded)> MonthlyBill(string number, int tamplateId, string fullname, string amount, string id, string aprove);
/// <summary>
/// پیامک مسدودی طرف حساب
/// قراردادهای قدیم
/// </summary>
/// <param name="number"></param>
/// <param name="fullname"></param>
/// <param name="amount"></param>
/// <param name="accountType"></param>
/// <param name="id"></param>
/// <param name="aprove"></param>
/// <returns></returns>
Task<(byte status, string message, int messaeId, bool isSucceded)> BlockMessage(string number, string fullname, string amount, string accountType, string id, string aprove);
/// <summary>
/// پیامک مسدودی طرف حساب
/// قرارداد های جدید
/// </summary>
/// <param name="number"></param>
/// <param name="fullname"></param>
/// <param name="amount"></param>
/// <param name="code1"></param>
/// <param name="code2"></param>
/// <returns></returns>
Task<(byte status, string message, int messaeId, bool isSucceded)> BlockMessageForElectronicContract(string number,
string fullname,
string amount, string code1, string code2);
#endregion
#region AlarmMessage
/// <summary>
/// ارسال پیامک های خطا یا اعمال ارسال
/// </summary>
/// <param name="number"></param>
/// <param name="message"></param>
/// <returns></returns>
Task<bool> Alarm(string number, string message);
#endregion

View File

@@ -1,7 +0,0 @@
namespace _0_Framework.Application.Sms;
public class OtpResultViewModel
{
public int ExpireTimeSec { get; set; }
public int ReSendTimeSec { get; set; }
}

View File

@@ -1,32 +0,0 @@
namespace _0_Framework.Application.Sms;
public class SmsResult
{
public SmsResult()
{
IsSuccedded = false;
}
public bool IsSuccedded { get; set; }
public string Message { get; set; }
public byte StatusCode { get; set; }
public int MessageId { get; set; }
public SmsResult Succedded(byte statusCode, string message, int messageId)
{
IsSuccedded = true;
Message = message;
StatusCode = statusCode;
MessageId = messageId;
return this;
}
public SmsResult Failed(byte statusCode, string message, int messageId)
{
IsSuccedded = false;
Message = message;
StatusCode = statusCode;
MessageId = messageId;
return this;
}
}

View File

@@ -0,0 +1,337 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Security.AccessControl;
using System.Threading;
using System.Threading.Tasks;
using IPE.SmsIrClient;
using IPE.SmsIrClient.Models.Requests;
using IPE.SmsIrClient.Models.Results;
using Microsoft.Extensions.Configuration;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace _0_Framework.Application.Sms;
public class SmsService : ISmsService
{
private readonly IConfiguration _configuration;
public SmsIr SmsIr { get; set; }
public SmsService(IConfiguration configuration)
{
_configuration = configuration;
SmsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
}
public void Send(string number, string message)
{
//var token = GetToken();
//var lines = new SmsLine().GetSmsLines(token);
//if (lines == null) return;
//var line = lines.SMSLines.Last().LineNumber.ToString();
//var data = new MessageSendObject
//{
// Messages = new List<string>
// {message}.ToArray(),
// MobileNumbers = new List<string> {number}.ToArray(),
// LineNumber = line,
// SendDateTime = DateTime.Now,
// CanContinueInCaseOfError = true
//};
//var messageSendResponseObject =
// new MessageSend().Send(token, data);
//if (messageSendResponseObject.IsSuccessful) return;
//line = lines.SMSLines.First().LineNumber.ToString();
//data.LineNumber = line;
//new MessageSend().Send(token, data);
}
public bool VerifySend(string number, string message)
{
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
var verificationSendResult = smsIr.VerifySendAsync(number, 768382, new VerifySendParameter[] { new VerifySendParameter("VerificationCode", message) });
Thread.Sleep(2000);
if (verificationSendResult.IsCompletedSuccessfully)
{
var resStartStatus = verificationSendResult.Result;
var b = resStartStatus.Status;
var resResult = verificationSendResult.Status;
var a = verificationSendResult.IsCompleted;
var reseExceptiont = verificationSendResult.Exception;
return true;
}
else
{
var resStartStatus = verificationSendResult.Status;
var resResult = verificationSendResult.Status;
var reseExceptiont = verificationSendResult.Exception;
return false;
}
}
public bool LoginSend(string number, string message)
{
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
var verificationSendResult = smsIr.VerifySendAsync(number, 635330, new VerifySendParameter[] { new VerifySendParameter("LOGINCODE", message) });
Thread.Sleep(2000);
if (verificationSendResult.IsCompletedSuccessfully)
{
var resStartStatus = verificationSendResult.Result;
var b = resStartStatus.Status;
var resResult = verificationSendResult.Status;
var a = verificationSendResult.IsCompleted;
var reseExceptiont = verificationSendResult.Exception;
return true;
}
else
{
var resStartStatus = verificationSendResult.Status;
var resResult = verificationSendResult.Status;
var reseExceptiont = verificationSendResult.Exception;
return false;
}
}
public async Task<SentSmsViewModel> SendVerifyCodeToClient(string number, string code)
{
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
var result = new SentSmsViewModel();
//var bulkSendResult = smsIr.BulkSendAsync(95007079000006, "your text message", new string[] { "9120000000" });
var sendResult = await smsIr.VerifySendAsync(number, 768382, new VerifySendParameter[] { new VerifySendParameter("VerificationCode", code) });
Thread.Sleep(2000);
if (sendResult.Message == "موفق")
{
var status = sendResult.Status;
var message = sendResult.Message;
var messaeId = sendResult.Data.MessageId;
return result.Succedded(status, message, messaeId);
}
else
{
var status = sendResult.Status;
var message = sendResult.Message;
var messaeId = sendResult.Data.MessageId;
return result.Failed(status, message, messaeId);
}
}
public bool SendAccountsInfo(string number, string fullName, string userName)
{
var checkLength = fullName.Length;
if (checkLength > 25)
fullName = fullName.Substring(0, 24);
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
var sendResult = smsIr.VerifySendAsync(number, 725814, new VerifySendParameter[] { new VerifySendParameter("FULLNAME", fullName), new VerifySendParameter("USERNAME", userName), new VerifySendParameter("PASSWORD", userName) });
Console.WriteLine(userName + " - " + sendResult.Result.Status);
if (sendResult.IsCompletedSuccessfully)
{
return true;
}
else
{
return false;
}
}
public async Task<ApiResultViewModel> GetByMessageId(int messId)
{
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
var response = await smsIr.GetReportAsync(messId);
MessageReportResult messages = response.Data;
var appendData = new ApiResultViewModel()
{
MessageId = messages.MessageId,
LineNumber = messages.LineNumber,
Mobile = messages.Mobile,
MessageText = messages.MessageText,
SendUnixTime = UnixTimeStampToDateTime(messages.SendDateTime),
DeliveryState = DeliveryStatus(messages.DeliveryState),
DeliveryUnixTime = UnixTimeStampToDateTime(messages.DeliveryDateTime),
DeliveryColor = DeliveryColorStatus(messages.DeliveryState),
};
return appendData;
}
public async Task<List<ApiResultViewModel>> GetApiResult(string startDate, string endDate)
{
var st = new DateTime(2024, 6, 2);
var ed = new DateTime(2024, 7, 1);
if (!string.IsNullOrWhiteSpace(startDate) && startDate.Length == 10)
{
st = startDate.ToGeorgianDateTime();
}
if (!string.IsNullOrWhiteSpace(endDate) && endDate.Length == 10)
{
ed = endDate.ToGeorgianDateTime();
}
var res = new List<ApiResultViewModel>();
Int32 unixTimestamp = (int)st.Subtract(new DateTime(1970,1,1)).TotalSeconds;
Int32 unixTimestamp2 = (int)ed.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
// int? fromDateUnixTime = null; // unix time - for instance: 1700598600
//int? toDateUnixTime = null; // unix time - for instance: 1703190600
int pageNumber = 2;
int pageSize = 100; // max: 100
SmsIr smsIr = new SmsIr("Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
var response = await smsIr.GetArchivedReportAsync(pageNumber, pageSize, unixTimestamp, unixTimestamp2);
MessageReportResult[] messages = response.Data;
foreach (var message in messages)
{
var appendData = new ApiResultViewModel()
{
MessageId = message.MessageId,
LineNumber = message.LineNumber,
Mobile = message.Mobile,
MessageText = message.MessageText,
SendUnixTime = UnixTimeStampToDateTime(message.SendDateTime),
DeliveryState = DeliveryStatus(message.DeliveryState),
DeliveryUnixTime = UnixTimeStampToDateTime(message.DeliveryDateTime),
DeliveryColor = DeliveryColorStatus(message.DeliveryState),
};
res.Add(appendData);
}
return res;
}
public string DeliveryStatus(byte? dv)
{
string mess = "";
switch (dv)
{
case 1:
mess = "رسیده به گوشی";
break;
case 2:
mess = "نرسیده به گوشی";
break;
case 3:
mess = "پردازش در مخابرات";
break;
case 4:
mess = "نرسیده به مخابرات";
break;
case 5:
mess = "سیده به مخابرات";
break;
case 6:
mess = "خطا";
break;
case 7:
mess = "لیست سیاه";
break;
default:
mess="";
break;
}
return mess;
}
public string DeliveryColorStatus(byte? dv)
{
string mess = "";
switch (dv)
{
case 1:
mess = "successSend";
break;
case 2:
mess = "errSend";
break;
case 3:
mess = "pSend";
break;
case 4:
mess = "noSend";
break;
case 5:
mess = "itcSend";
break;
case 6:
mess = "redSend";
break;
case 7:
mess = "blockSend";
break;
default:
mess = "";
break;
}
return mess;
}
public string UnixTimeStampToDateTime(int? unixTimeStamp)
{
if (unixTimeStamp != null)
{
// Unix timestamp is seconds past epoch
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dateTime = dateTime.AddSeconds(Convert.ToDouble(unixTimeStamp)).ToLocalTime();
var time = dateTime.ToFarsiFull();
return time;
}
return "";
}
private string GetToken()
{
return "";
//var smsSecrets = _configuration.GetSection("SmsSecrets");
//var tokenService = new Token();
//return tokenService.GetToken("x-api-key", "Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa");
}
#region Mahan
public async Task<double> GetCreditAmount()
{
try
{
var credit = await SmsIr.GetCreditAsync();
return (double)credit.Data;
}
catch
{
return -1;
}
}
#endregion
}

View File

@@ -30,24 +30,12 @@ public static class StaticWorkshopAccounts
/// 380 - افروز نظری
/// 381 - مهدی قربانی
/// 392 - عمار حسن دوست
/// 20 - سمیرا الهی نیا
/// </summary>
public static List<long> StaticAccountIds = [2, 3, 380, 381, 392, 20, 476];
public static List<long> StaticAccountIds = [2, 3, 380, 381, 392];
/// <summary>
/// این تاریخ در جدول اکانت لفت ورک به این معنیست
/// که کاربر همچنان به کارگاه دسترسی دارد
/// </summary>
public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1);
/// <summary>
/// لیستی آی دی نقش هایی که مسئول بیمه کارگاه هستند
/// 7 : بیمه ارشد
/// 8 : بیمه ساده
/// </summary>
public static List<long> InsuranceAccountsRoleIds = [7, 8];
}

View File

@@ -477,42 +477,26 @@ public static class Tools
string bb = string.Empty;
bool isNegative = false;
try
for (int x = 0; x < myMoney.Length; x++)
{
if (!string.IsNullOrWhiteSpace(myMoney))
if (char.IsDigit(myMoney[x]))
{
for (int x = 0; x < myMoney.Length; x++)
{
if (char.IsDigit(myMoney[x]))
{
bb += myMoney[x];
}
else if (myMoney[x] == '-' && bb.Length == 0)
{
// اگر علامت منفی قبل از اولین عدد آمد، در نظر بگیر
isNegative = true;
}
}
if (bb.Length > 0)
{
double res = double.Parse(bb);
return isNegative ? -res : res;
}
else
{
return 0;
}
bb += myMoney[x];
}
else
else if (myMoney[x] == '-' && bb.Length == 0)
{
return 0;
// اگر علامت منفی قبل از اولین عدد آمد، در نظر بگیر
isNegative = true;
}
}
catch (Exception)
{
if (bb.Length > 0)
{
double res = double.Parse(bb);
return isNegative ? -res : res;
}
else
{
return 0;
}
}
@@ -913,15 +897,7 @@ public static class Tools
}
}
try
{
numbers = Convert.ToInt32(num);
}
catch (Exception e)
{
return 0;
}
numbers = Convert.ToInt32(num);
return numbers;
}
public static string ToFarsiMonthByNumber(this string value)
@@ -1437,73 +1413,6 @@ public static class Tools
return false;
return true;
}
/// <summary>
/// چک میکند که در دو شیفت استاتیک تداخل زمانی وجود دارد یا خیر
/// چک میکند که آیا ساعات وارد شده ولید هستند یا خیر
/// </summary>
/// <param name="start1"></param>
/// <param name="end1"></param>
/// <param name="start2"></param>
/// <param name="end2"></param>
/// <returns></returns>
public static bool InterferenceTime(string start1, string end1, string start2, string end2)
{
if (!CheckValidHm(start1))
return true;
if (!CheckValidHm(end1))
return true;
if (!CheckValidHm(start2))
return true;
if (!CheckValidHm(end2))
return true;
//اگه دو شیفت نبود
if (string.IsNullOrWhiteSpace(start1) || string.IsNullOrWhiteSpace(start2))
return false;
try
{
var start1Gr = Convert.ToDateTime(start1);
var end1Gr = Convert.ToDateTime(end1);
if (end1Gr < start1Gr)
end1Gr = end1Gr.AddDays(1);
var start2Gr = Convert.ToDateTime(start2);
var end2Gr = Convert.ToDateTime(end2);
start2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, start2Gr.Hour, start2Gr.Minute,
start2Gr.Second);
end2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, end2Gr.Hour, end2Gr.Minute,
end2Gr.Second);
if (end2Gr < start2Gr)
end2Gr = end2Gr.AddDays(1);
var diff = (end1Gr - start1Gr).Add((end2Gr - start2Gr));
if (diff > new TimeSpan(24,0,0))
return true;
if (start2Gr <= end1Gr)
return true;
return false;
}
catch (Exception)
{
return true;
}
}
public static DateTime FindFirstDayOfMonthGr(this DateTime date)
{
var pc = new PersianCalendar();
@@ -1512,14 +1421,6 @@ public static class Tools
#region Mahan
public static bool IsvalidIban(this string iban)
{
return Regex.IsMatch(iban, @"^IR[0-9]{24}$");
}
public static bool IsValidCardNumber(this string cardNumber)
{
return Regex.IsMatch(cardNumber, @"^[0-9]{16}$");
}
/// <summary>
/// این متد حروف عربی را به فارسی در میاورد. مثال: علي را به علی تبدیل میکند
/// </summary>

View File

@@ -38,7 +38,7 @@ public class UidBasicInformation
{
"GENDER_MALE" => Application.Gender.Male,
"GENDER_FEMALE" => Application.Gender.Female,
_ => Application.Gender.None
_ => throw new ArgumentOutOfRangeException()
};
}
public record IdentificationInformation(string NationalId, string BirthDate, string ShenasnameSeri, string ShenasnameSerial, string ShenasnamehNumber);
@@ -110,53 +110,6 @@ public interface IUidService
{
Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode , string birthDate);
Task<MatchMobileWithNationalCodeResponse> IsMachPhoneWithNationalCode(string nationalCode , string phoneNumber);
Task<IbanInquiryResponse> IbanInquiry (string iban);
Task<AccountToIbanResponse> AccountToIban(string accountNumber, UidBanks bank);
Task<CardToNumberResponse> CardToIban(string cardNumber);
}
public class CardToNumberResponse:UidBaseResponse
{
public string Iban { get; set; }
public string CardNumber { get; set; }
}
public class AccountToIbanResponse:UidBaseResponse
{
public string Iban { get; set; }
}
public class IbanInquiryResponse:UidBaseResponse
{
public IbanInquiryAccountBasicInformation AccountBasicInformation { get; set; }
[JsonProperty("owners")]
public List<IbanInquiryOwner> Owners { get; set; }
}
public class IbanInquiryAccountBasicInformation
{
public string Iban { get; set; }
public string AccountNumber { get; set; }
public IbanInquiryBankInformation BankInformation { get; set; }
public string AccountStatus { get; set; }
}
public class IbanInquiryBankInformation
{
public string BankName { get; set; }
}
public class IbanInquiryOwner
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
[JsonProperty("nationalIdentifier")]
public string NationalIdentifier { get; set; }
[JsonProperty("customerType")]
public string CustomerType { get; set; }
}
public class MatchMobileWithNationalCodeResponse
@@ -165,7 +118,4 @@ public class MatchMobileWithNationalCodeResponse
public ResponseContext ResponseContext { get; set; }
}
public class UidBaseResponse
{
public ResponseContext ResponseContext { get; set; }
}

View File

@@ -1,117 +0,0 @@
using System.ComponentModel;
namespace _0_Framework.Application.UID;
public enum UidBanks
{
[Description("بانک دی")]
BANK_DEY = 66,
[Description("بانک سپه")]
BANK_SEPAH = 15,
[Description("بانک شهر")]
BANK_SHAHR = 61,
[Description("بانک ملت")]
BANK_MELAT = 12,
[Description("بانک ملی")]
BANK_MELLI = 17,
[Description("بانک رفاه کارگران")]
BANK_REFAH = 13,
[Description("بانک سینا")]
BANK_SINA = 59,
[Description("بانک مسکن")]
BANK_MASKAN = 14,
[Description("بانک آینده")]
BANK_AYANDEH = 62,
[Description("بانک انصار")]
BANK_ANSAR = 63,
[Description("بانک تجارت")]
BANK_TEJARAT = 18,
[Description("بانک رسالت")]
BANK_RESALAT = 70,
[Description("بانک سامان")]
BANK_SAMAN = 56,
[Description("بانک مرکزی")]
BANK_MARKAZI = 10,
[Description("بانک سرمایه")]
BANK_SARMAYEH = 58,
[Description("بانک صادرات")]
BANK_SADERAT = 19,
[Description("بانک قوامین")]
BANK_GHAVAMIN = 52,
[Description("بانک پارسیان")]
BANK_PARSIAN = 54,
[Description("بانک کشاورزی")]
BANK_KESHAVARZI = 16,
[Description("بانک گردشگری")]
BANK_GARDESHGARI = 64,
[Description("پست بانک")]
BANK_POST_BANK = 21,
[Description("بانک پاسارگاد")]
BANK_PASARGAD = 57,
[Description("بانک کارآفرین")]
BANK_KARAFARIN = 53,
[Description("بانک خاورمیانه")]
BANK_KHAVARMIANEH = 78,
[Description("بانک ایران زمین")]
BANK_IRAN_ZAMIN = 69,
[Description("بانک مهر اقتصاد")]
BANK_MEHR_EQTESAD = 79,
[Description("بانک صنعت و معدن")]
BANK_SANAT_MADAN = 11,
[Description("بانک اقتصاد نوین")]
BANK_EGHTESAD_NOVIN = 55,
[Description("بانک توسعه تعاون")]
BANK_TOSSE_TAAVON = 22,
[Description("بانک توسعه صادرات")]
BANK_TOSSE_SADERAT = 20,
[Description("بانک ایران و ونزوئلا")]
BANK_IRAN_VENEZUELA = 95,
[Description("بانک حکمت ایرانیان")]
BANK_HEKMAT_IRANIAN = 65,
[Description("بانک قرض الحسنه مهر")]
BANK_GHARZOLHASANEH_MEHR = 60,
[Description("موسسه مالی و اعتباری ملل")]
BANK_MOASSASE_MELLAL = 75,
[Description("موسسه مالی و اعتباری نور")]
BANK_MOASSASE_NOOR = 80,
[Description("موسسه مالی و اعتباری کوثر")]
BANK_MOASSASE_KOSAR = 73,
[Description("موسسه مالی و اعتباری توسعه")]
BANK_MOASSASE_TOSSE = 51
}

View File

@@ -1,27 +0,0 @@
using System;
using System.ComponentModel;
using System.Reflection;
namespace _0_Framework.Application.UID
{
public static class UidBanksExtension
{
/// <summary>
/// دریافت نام فارسی بانک
/// </summary>
/// <param name="bank">بانک</param>
/// <returns>نام فارسی بانک</returns>
public static string GetPersianName(this UidBanks bank)
{
var fieldInfo = bank.GetType().GetField(bank.ToString());
if (fieldInfo == null)
return string.Empty;
var attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(
fieldInfo, typeof(DescriptionAttribute));
return attribute?.Description ?? bank.ToString();
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace _0_Framework.Application.UID;
public class UidService : IUidService
{
private readonly HttpClient _httpClient;
private const string BaseUrl= "https://json-api.uid.ir/api/inquiry/";
public UidService()
{
_httpClient = new HttpClient()
{
BaseAddress = new Uri(BaseUrl)
};
}
public async Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode, string birthDate)
{
var request = new PersonalInfoRequest
{
BirthDate = birthDate ,
NationalId = nationalCode,
RequestContext = new UidRequestContext()
};
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
var requestResult = await _httpClient.PostAsync("person/v2", contentType);
try
{
if (!requestResult.IsSuccessStatusCode)
return null;
var responseResult = await requestResult.Content.ReadFromJsonAsync<PersonalInfoResponse>();
if (responseResult.BasicInformation != null)
{
responseResult.BasicInformation.FirstName = responseResult.BasicInformation.FirstName?.ToPersian();
responseResult.BasicInformation.LastName = responseResult.BasicInformation.LastName?.ToPersian();
responseResult.BasicInformation.FatherName = responseResult.BasicInformation.FatherName?.ToPersian();
}
return responseResult;
}
catch
{
return null;
}
}
public async Task<MatchMobileWithNationalCodeResponse> IsMachPhoneWithNationalCode(string nationalCode, string phoneNumber)
{
var request = new PersonalInfoRequest
{
MobileNumber = phoneNumber,
NationalId = nationalCode,
RequestContext = new UidRequestContext()
};
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
var requestResult = await _httpClient.PostAsync("mobile/owner/v2", contentType);
if (!requestResult.IsSuccessStatusCode)
return null;
var responseResult = await requestResult.Content.ReadFromJsonAsync<MatchMobileWithNationalCodeResponse>();
return responseResult;
}
}

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
using Microsoft.EntityFrameworkCore.Design.Internal;
@@ -14,7 +12,8 @@ public class BaseCustomizeEntity : EntityBase
}
public BaseCustomizeEntity(FridayPay fridayPay, OverTimePay overTimePay,
BaseYearsPay baseYearsPay, BonusesPay bonusesPay, NightWorkPay nightWorkPay, MarriedAllowance marriedAllowance, ShiftPay shiftPay,
FamilyAllowance familyAllowance, LeavePay leavePay, InsuranceDeduction insuranceDeduction, FineAbsenceDeduction fineAbsenceDeduction, LateToWork lateToWork, EarlyExit earlyExit, HolidayWork holidayWork, BreakTime breakTime,int leavePermittedDays,List<WeeklyOffDay> weeklyOffDays)
FamilyAllowance familyAllowance, LeavePay leavePay, InsuranceDeduction insuranceDeduction, FineAbsenceDeduction fineAbsenceDeduction, LateToWork lateToWork, EarlyExit earlyExit,
FridayWork fridayWork, HolidayWork holidayWork, BreakTime breakTime,int leavePermittedDays)
{
FridayPay = fridayPay;
@@ -30,10 +29,10 @@ public class BaseCustomizeEntity : EntityBase
FineAbsenceDeduction = fineAbsenceDeduction;
LateToWork = lateToWork;
EarlyExit = earlyExit;
FridayWork = fridayWork;
HolidayWork = holidayWork;
BreakTime = breakTime;
LeavePermittedDays = leavePermittedDays;
WeeklyOffDays = weeklyOffDays.Select(x=> new WeeklyOffDay(x.DayOfWeek)).ToList();
}
/// <summary>
@@ -118,28 +117,4 @@ public class BaseCustomizeEntity : EntityBase
public BreakTime BreakTime { get; protected set; }
public List<WeeklyOffDay> WeeklyOffDays { get; set; } = [];
public void FridayWorkToWeeklyDayOfWeek()
{
if (FridayWork == FridayWork.Default && !WeeklyOffDays.Any(x => x.DayOfWeek == DayOfWeek.Friday))
{
WeeklyOffDays.Add(new WeeklyOffDay(DayOfWeek.Friday));
}
}
}
public class WeeklyOffDay
{
public WeeklyOffDay(DayOfWeek dayOfWeek)
{
DayOfWeek = dayOfWeek;
}
public long Id { get; set; }
public DayOfWeek DayOfWeek { get; set; }
public long ParentId { get; set; }
}

View File

@@ -1,9 +0,0 @@
namespace _0_Framework.Application.Enums
{
public class CheckoutDynamicDeductionItem
{
public string Name { get; set; }
public int Count { get; set; }
public string Amount { get; set; }
}
}

View File

@@ -4,7 +4,6 @@ using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Storage;
namespace _0_Framework.Domain;
@@ -18,6 +17,4 @@ public interface IRepository<TKey, T> where T:class
bool Exists(Expression<Func<T, bool>> expression);
void SaveChanges();
Task SaveChangesAsync();
Task<IDbContextTransaction> BeginTransactionAsync();
}

View File

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

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
namespace _0_Framework.Exceptions;
@@ -15,13 +14,5 @@ public class BadRequestException:Exception
Details = details;
}
public BadRequestException(string message, Dictionary<string, object?> extra) :
base(message)
{
Extra = extra;
}
public string Details { get; }
public Dictionary<string,object> Extra { get; set; }
}

View File

@@ -1,101 +0,0 @@
#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;
using Microsoft.Extensions.Logging;
namespace _0_Framework.Exceptions.Handler;
public class CustomExceptionHandler : IExceptionHandler
{
private readonly ILogger<CustomExceptionHandler> _logger;
public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
{
_logger = logger;
}
public async ValueTask<bool> TryHandleAsync(HttpContext context, Exception exception, CancellationToken cancellationToken)
{
_logger.LogError(exception,
"Error Message: {exceptionMessage}, Type: {exceptionType}, Time: {time}, Path: {path}, TraceId: {traceId}",
exception.Message,
exception.GetType().FullName,
DateTime.UtcNow,
context.Request.Path,
context.TraceIdentifier);
(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,
exception.GetType().Name,
context.Response.StatusCode = StatusCodes.Status500InternalServerError,
null
),
BadRequestException bre =>
(
exception.Message,
exception.GetType().Name,
context.Response.StatusCode = StatusCodes.Status400BadRequest,
bre.Extra
),
NotFoundException =>
(
exception.Message,
exception.GetType().Name,
context.Response.StatusCode = StatusCodes.Status404NotFound,
null
),
UnAuthorizeException =>
(
exception.Message,
exception.GetType().Name,
context.Response.StatusCode = StatusCodes.Status401Unauthorized,
null
),
_ =>
(
exception.Message,
exception.GetType().Name,
context.Response.StatusCode = StatusCodes.Status500InternalServerError,
null
)
};
var problemDetails = new ProblemDetails
{
Title = details.Title,
Detail = details.Detail,
Status = details.StatusCode,
Instance = context.Request.Path,
Extensions = details.Extra ?? new Dictionary<string, object>()
};
problemDetails.Extensions.Add("traceId", context.TraceIdentifier);
await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);
return true;
}
}

View File

@@ -1,10 +0,0 @@
using System;
namespace _0_Framework.Exceptions;
public class UnAuthorizeException:Exception
{
public UnAuthorizeException(string message) : base(message)
{
}
}

View File

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

View File

@@ -1,8 +0,0 @@
namespace _0_Framework.InfraStructure.Mongo;
public class MongoDbConfig
{
public string ConnectionString { get; set; } = null!;
public string DatabaseName { get; set; } = null!;
}

View File

@@ -1,29 +0,0 @@
using System.Threading.Tasks;
using _0_Framework.Application.FaceEmbedding;
namespace _0_Framework.InfraStructure;
/// <summary>
/// پیاده‌سازی پیش‌فرض (بدون عملیات) برای IFaceEmbeddingNotificationService
/// این کلاس زمانی استفاده می‌شود که SignalR در دسترس نباشد
/// </summary>
public class NullFaceEmbeddingNotificationService : IFaceEmbeddingNotificationService
{
public Task NotifyEmbeddingCreatedAsync(long workshopId, long employeeId, string employeeFullName)
{
// هیچ عملیاتی انجام نمی‌دهد
return Task.CompletedTask;
}
public Task NotifyEmbeddingDeletedAsync(long workshopId, long employeeId)
{
// هیچ عملیاتی انجام نمی‌دهد
return Task.CompletedTask;
}
public Task NotifyEmbeddingRefinedAsync(long workshopId, long employeeId)
{
// هیچ عملیاتی انجام نمی‌دهد
return Task.CompletedTask;
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace _0_Framework.InfraStructure;
public static class QueryableExtensions
{
public static IQueryable<T> ApplyPagination<T>(this IQueryable<T> query, int page, int pageSize = 30)
{
if (page <= 0) page = 1;
if (pageSize <= 0) pageSize = 10;
return query.Skip((page - 1) * pageSize).Take(pageSize);
}
public static IEnumerable<T> ApplyPagination<T>(this IEnumerable<T> source, int page, int pageSize = 30)
{
if (page <= 0) page = 1;
if (pageSize <= 0) pageSize = 10;
return source.Skip((page - 1) * pageSize).Take(pageSize);
}
}

View File

@@ -6,7 +6,6 @@ using System.Text;
using System.Threading.Tasks;
using _0_Framework.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
namespace _0_Framework.InfraStructure
{
@@ -71,10 +70,5 @@ namespace _0_Framework.InfraStructure
{
await _context.SaveChangesAsync();
}
public async Task<IDbContextTransaction> BeginTransactionAsync()
{
return await _context.Database.BeginTransactionAsync();
}
}
}

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using AccountManagement.Application.Contracts.Role;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace AccountManagement.Application.Contracts.Account;
@@ -36,20 +35,4 @@ public class CreateAccount
public string Email { get; set; }
public string VerifyCode { get; set; }
public string IsActiveString { get; set; }
/// <summary>
/// آیا کاربر در پروگرام منیجر فعالیت مبکند؟
/// </summary>
public bool IsProgramManagerUser { get; set; }
/// <summary>
/// لیست نقش های پروگرام منیجر
/// </summary>
public List<long> UserRoles { get; set; }
/// <summary>
/// لیست نقشهای موجود در پروگرام منیجر
/// </summary>
public SelectList RoleList { get; set; }
}

View File

@@ -3,5 +3,4 @@
public class EditAccount : CreateAccount
{
public long Id { get; set; }
}

View File

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

View File

@@ -2,21 +2,15 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Shared.Contracts.PmUser.Queries;
namespace AccountManagement.Application.Contracts.Account;
public interface IAccountApplication
{
AccountViewModel GetAccountBy(long id);
/// <summary>
/// ایجاد کاربر گزارشگیر و پروگرام منیجر
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
Task<OperationResult> Create(CreateAccount command);
OperationResult Create(CreateAccount command);
OperationResult RegisterClient(RegisterAccount command);
Task<OperationResult> Edit(EditAccount command);
OperationResult Edit(EditAccount command);
OperationResult EditClient(EditClientAccount command);
OperationResult ChangePassword(ChangePassword command);
OperationResult Login(Login command);
@@ -34,7 +28,7 @@ public interface IAccountApplication
OperationResult DeActive(long id);
OperationResult DirectLogin(long id);
// AccountLeftWorkViewModel WorkshopList(long accountId);
AccountLeftWorkViewModel WorkshopList(long accountId);
OperationResult SaveWorkshopAccount(
List<WorkshopAccountlistViewModel> workshopAccountList,
string startDate,
@@ -70,15 +64,4 @@ public interface IAccountApplication
/// <param name="userName"></param>
/// <returns></returns>
public bool CheckExistClientAccount(string userName);
List<AccountViewModel> GetAdminAccountsNew();
void CameraLogin(CameraLoginRequest request);
Task<GetPmUserDto> GetPmUserAsync(long accountId);
}
public class CameraLoginRequest
{
public string UserName { get; set; }
public string Password { get; set; }
}

View File

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

View File

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

View File

@@ -1,21 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<NuGetAudit>false</NuGetAudit>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\Shared.Contracts\Shared.Contracts.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,11 +0,0 @@
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
public record ApiResponse
{
public bool isSuccess { get; set; }
public string errorMessage { get; set; }
public ErrorType ErrorType { get; set; }
}

View File

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

View File

@@ -1,7 +0,0 @@
using System.Collections.Generic;
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
public record CreateProgramManagerUser(string FullName, string UserName, string Password, string Mobile, string Email, long? AccountId, List<long> Roles);
public record EditUserCommand(string FullName, string UserName, string Mobile, long AccountId, List<long> Roles, bool IsActive);

View File

@@ -1,11 +0,0 @@
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
public enum ErrorType
{
None,
BadRequest,
NotFound,
Unauthorized,
Validation,
InternalServerError
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
public class RoleResponse
{
public bool isSuccess { get; set; }
public RolesData data { get; set; }
}
public class RolesData
{
public List<RoleList> role { get; set; }
}
public class RoleList
{
public int id { get; set; }
public string roleName { get; set; }
public int gozareshgirRoleId { get; set; }
public List<int> permissions { get; set; }
}

View File

@@ -1,55 +0,0 @@
using System.Collections.Generic;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace AccountManagement.Application.Contracts.ProgramManagerApiResult;
public record SingleUserResponseResult
{
public bool isSuccess { get; set; }
public SingleUserData Data { get; set; }
};
public record SingleUserData
{
public long id { get; set; }
/// <summary>
/// نام و نام خانوادگی
/// </summary>
public string fullName { get; set; }
/// <summary>
/// نام کاربری
/// </summary>
public string userName { get; set; }
/// <summary>
/// مسیر عکس پروفایل
/// </summary>
public string profilePhotoPath { get; set; }
/// <summary>
/// شماره موبایل
/// </summary>
public string mobile { get; set; }
/// <summary>
/// فعال/غیر فعال بودن یوزر
/// </summary>
public bool isActive { get; set; }
/// <summary>
/// گذرواژه
/// </summary>
public string password { get; set; }
/// <summary>
/// ای دی اکانت کاربر در گزارشگیر
/// </summary>
public long? accountId { get; set; }
public List<long> Roles { get; set; }
}

View File

@@ -9,10 +9,6 @@ namespace AccountManagement.Application.Contracts.Role
[Required(ErrorMessage = ValidationMessages.IsRequired)]
public string Name { get; set; }
public List<int> Permissions { get; set; }
/// <summary>
/// لیست پرمیشن های پروگرام منیجر
/// </summary>
public List<int> PmPermissions { get; set; }
}
}

View File

@@ -1,26 +1,13 @@
using _0_Framework.Application;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
using System.Threading.Tasks;
using Shared.Contracts.PmRole.Queries;
namespace AccountManagement.Application.Contracts.Role
{
public interface IRoleApplication
{
Task<OperationResult> Create(CreateRole command);
Task<OperationResult> Edit(EditRole command);
OperationResult Create(CreateRole command);
OperationResult Edit(EditRole command);
List<RoleViewModel> List();
EditRole GetDetails(long id);
#region ProgramManager
Task<SelectList> GetPmRoleList(long? gozareshgirRoleId);
Task<List<GetPmRolesDto>> GetPmRoleListToEdit(long? gozareshgirRoleId);
#endregion
}
}

View File

@@ -1,25 +1,28 @@
using _0_Framework.Application;
using _0_Framework.Application.Sms;
using _0_Framework.Exceptions;
using System;
using System.Collections;
using _0_Framework.Application;
using AccountManagement.Application.Contracts.Account;
using AccountManagement.Domain.AccountAgg;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using _0_Framework.Application.Sms;
using AccountManagement.Domain.AccountLeftWorkAgg;
using AccountManagement.Domain.CameraAccountAgg;
using AccountManagement.Domain.PositionAgg;
using AccountManagement.Domain.RoleAgg;
using CompanyManagment.App.Contracts.Workshop;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
using Company.Domain.WorkshopAgg;
using System.Security.Claims;
using AccountManagement.Domain.PositionAgg;
using AccountManagement.Domain.SubAccountAgg;
using AccountManagement.Domain.SubAccountPermissionSubtitle1Agg;
using AccountManagement.Domain.SubAccountRoleAgg;
using Company.Domain._common;
using Company.Domain.WorkshopAgg;
using Company.Domain.WorkshopSubAccountAgg;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Shared.Contracts.PmUser.Commands;
using Shared.Contracts.PmUser.Queries;
//using AccountManagement.Domain.RoleAgg;
@@ -35,25 +38,15 @@ public class AccountApplication : IAccountApplication
private readonly ISmsService _smsService;
private readonly ICameraAccountRepository _cameraAccountRepository;
private readonly IPositionRepository _positionRepository;
private readonly IAccountLeftworkRepository _accountLeftworkRepository;
private readonly IAccountLeftworkRepository _accountLeftworkRepository;
private readonly IWorkshopRepository _workshopRepository;
private readonly ISubAccountRepository _subAccountRepository;
private readonly ISubAccountRoleRepository _subAccountRoleRepository;
private readonly IWorkshopSubAccountRepository _workshopSubAccountRepository;
private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository;
private readonly IUnitOfWork _unitOfWork;
private readonly IPmUserQueryService _pmUserQueryService;
private readonly IPmUserCommandService _pmUserCommandService;
public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher,
IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker,
ISmsService smsService, ICameraAccountRepository cameraAccountRepository,
IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository,
IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository,
ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository,
ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork,
IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService)
public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher,
IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository)
{
_authHelper = authHelper;
_roleRepository = roleRepository;
@@ -66,13 +59,10 @@ public class AccountApplication : IAccountApplication
_subAccountRoleRepository = subAccountRoleRepository;
_workshopSubAccountRepository = workshopSubAccountRepository;
_accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository;
_unitOfWork = unitOfWork;
_pmUserQueryService = pmUserQueryService;
_pmUserCommandService = pmUserCommandService;
_fileUploader = fileUploader;
_passwordHasher = passwordHasher;
_accountRepository = accountRepository;
}
public OperationResult EditClient(EditClientAccount command)
@@ -93,8 +83,7 @@ public class AccountApplication : IAccountApplication
(x.Mobile == command.Mobile && x.id != command.Id)))
return opreation.Failed("شماره موبایل تکراری است");
if (_accountRepository.Exists(x =>
(x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) &&
x.id != command.Id)))
(x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) && x.id != command.Id)))
return opreation.Failed("کد ملی تکراری است");
if (_accountRepository.Exists(x =>
(x.Email == command.Email && !string.IsNullOrWhiteSpace(x.Email) && x.id != command.Id)))
@@ -102,8 +91,7 @@ public class AccountApplication : IAccountApplication
var path = $"profilePhotos";
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
editAccount.EditClient(command.Fullname, command.Username, command.Mobile, picturePath, command.Email,
command.NationalCode);
editAccount.EditClient(command.Fullname,command.Username,command.Mobile,picturePath,command.Email,command.NationalCode);
_accountRepository.SaveChanges();
return opreation.Succcedded();
}
@@ -134,7 +122,7 @@ public class AccountApplication : IAccountApplication
};
}
public async Task<OperationResult> Create(CreateAccount command)
public OperationResult Create(CreateAccount command)
{
var operation = new OperationResult();
@@ -144,59 +132,15 @@ public class AccountApplication : IAccountApplication
var password = _passwordHasher.Hash(command.Password);
var roleName = _roleRepository.GetDetails(command.RoleId);
var path = $"profilePhotos";
var picturePath = "";
if (_fileUploader != null)
{
picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
var account = new Account(command.Fullname, command.Username, password, command.Mobile, command.RoleId,
picturePath, roleName.Name,"true","false");
_accountRepository.Create(account);
}
var account = new Account(command.Fullname, command.Username, password, command.Mobile, command.RoleId,
picturePath, roleName.Name, "true", "false");
_unitOfWork.BeginAccountContext();
_accountRepository.Create(account);
_accountRepository.SaveChanges();
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));
if (!createPm.isSuccess)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
}
//var url = "api/user/create";
//var key = SecretKeys.ProgramManagerInternalApi;
//var response = InternalApiCaller.PostAsync<CreateProgramManagerUser, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Error);
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Result.errorMessage);
//}
}
_unitOfWork.CommitAccountContext();
return operation.Succcedded();
}
@@ -210,8 +154,8 @@ public class AccountApplication : IAccountApplication
return opreation.Failed("پر کردن تمامی فیلدها الزامی است");
if (_accountRepository.Exists(x => x.Username == command.Username))
return opreation.Failed("نام کاربری تکراری است");
if (_accountRepository.Exists(x => x.Mobile == command.Mobile && x.IsActiveString == "true"))
if (_accountRepository.Exists(x => x.Mobile == command.Mobile && x.IsActiveString =="true"))
return opreation.Failed("مقادیر وارد شده تکراری است");
//var nationalCodeValidation = command.NationalCode.NationalCodeValid();
@@ -228,14 +172,14 @@ public class AccountApplication : IAccountApplication
// break;
//}
var password = _passwordHasher.Hash(command.Password);
var register = new Account(command.Fullname, command.Username, password, command.Mobile, command.NationalCode);
var register =new Account(command.Fullname,command.Username, password, command.Mobile, command.NationalCode);
_accountRepository.Create(register);
_accountRepository.SaveChanges();
return opreation.Succcedded(register.id, message: "ثبت نام شما با موفقیت انجام شد");
return opreation.Succcedded(register.id,message: "ثبت نام شما با موفقیت انجام شد");
}
public async Task<OperationResult> Edit(EditAccount command)
public OperationResult Edit(EditAccount command)
{
var operation = new OperationResult();
var account = _accountRepository.Get(command.Id);
@@ -249,124 +193,8 @@ public class AccountApplication : IAccountApplication
var roleName = _roleRepository.GetDetails(command.RoleId);
var path = $"profilePhotos";
var picturePath = _fileUploader.Upload(command.ProfilePhoto, path);
_unitOfWork.BeginAccountContext();
account.Edit(command.Fullname, command.Username, command.Mobile, command.RoleId, picturePath, roleName.Name);
_accountRepository.SaveChanges();
var key = SecretKeys.ProgramManagerInternalApi;
//var apiResult = InternalApiCaller.GetAsync<SingleUserResponseResult>(
// $"api/user/{account.id}",
// key
//);
var userResult = await _pmUserQueryService.GetPmUserDataByAccountId(account.id);
if (command.UserRoles == null)
return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است");
var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList();
//اگر کاربر در پروگرام منیجر قبلا ایجاد شده
if (userResult.Id > 0)
{
if (!command.UserRoles.Any())
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("حداقل یک نقش باید انتخاب شود");
}
var editPm = await _pmUserCommandService.Edit(new EditPmUserDto(command.Fullname, command.Username,
command.Mobile, account.id, pmUserRoles,
command.IsProgramManagerUser));
if (!editPm.isSuccess)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
}
//var parameters = new EditUserCommand(
// command.Fullname,
// command.Username,
// command.Mobile,
// account.id,
// command.UserRoles,
// command.IsProgramManagerUser
//);
//var url = "api/user/edit";
//var response = InternalApiCaller.PostAsync<EditUserCommand, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Error);
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Error);
//}
}
else //اگر کاربر قبلا ایجاد نشده
{
//اگر تیک فعالیت در پروگرام منیجر روشن بود
if (command.IsProgramManagerUser)
{
if (!command.UserRoles.Any())
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("حداقل یک نقش باید انتخاب شود");
}
var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname,
command.Username, account.Password, command.Mobile,
null, account.id, pmUserRoles));
if (!createPm.isSuccess)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر");
}
//var parameters = new CreateProgramManagerUser(
// command.Fullname,
// command.Username,
// account.Password,
// command.Mobile,
// command.Email,
// account.id,
// command.UserRoles
//);
//var url = "api/user/Create";
//var response = InternalApiCaller.PostAsync<CreateProgramManagerUser, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Error);
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Error);
//}
}
}
_unitOfWork.CommitAccountContext();
return operation.Succcedded();
}
@@ -377,21 +205,22 @@ public class AccountApplication : IAccountApplication
public OperationResult Login(Login command)
{
long idAutoriz = 0;
var operation = new OperationResult();
if (string.IsNullOrWhiteSpace(command.Password))
return operation.Failed(ApplicationMessages.EmptyPassword);
return operation.Failed(ApplicationMessages.EmptyPassword);
if (string.IsNullOrWhiteSpace(command.Username))
return operation.Failed(ApplicationMessages.EmptyUsername);
return operation.Failed(ApplicationMessages.EmptyUsername);
var account = _accountRepository.GetBy(command.Username);
var account = _accountRepository.GetBy(command.Username);
var cameraAccount = _cameraAccountRepository.GetBy(command.Username);
SubAccount subAccount = _subAccountRepository.GetBy(command.Username);
if (account == null && cameraAccount == null && subAccount == null)
return operation.Failed(ApplicationMessages.WrongUserPass);
SubAccount subAccount = _subAccountRepository.GetBy(command.Username);
if (account == null && cameraAccount == null && subAccount == null)
return operation.Failed(ApplicationMessages.WrongUserPass);
if (account != null)
if (account != null)
{
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(account.Password, command.Password);
if (!result.Verified)
@@ -400,29 +229,6 @@ public class AccountApplication : IAccountApplication
.Permissions
.Select(x => x.Code)
.ToList();
//PmPermission
var PmUserData = _pmUserQueryService.GetPmUserDataByAccountId(account.id)
.GetAwaiter().GetResult();
long? pmUserId = null;
if (PmUserData != null)
{
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);
}
pmUserId = PmUserData.Id > 0 ? PmUserData.Id : null;
}
int? positionValue;
if (account.PositionId != null)
{
@@ -432,45 +238,36 @@ public class AccountApplication : IAccountApplication
{
positionValue = null;
}
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
, account.Username, account.Mobile, account.ProfilePhoto,
permissions, account.RoleName, account.AdminAreaPermission,
account.ClientAriaPermission, positionValue, 0, pmUserId);
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
account.IsActiveString == "true")
{
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
authViewModel.Permissions = clientPermissions;
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x =>
new WorkshopClaim
{
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
authViewModel.WorkshopList = workshopList;
if (workshopList.Any())
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
authViewModel.Permissions = clientPermissions;
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.Name;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
authViewModel.WorkshopId = workshop.Id;
}
}
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
authViewModel.WorkshopList = workshopList;
if (workshopList.Any())
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.Name;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
}
}
_authHelper.Signin(authViewModel);
if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" &&
account.IsActiveString == "true") || (account.AdminAreaPermission == "true" &&
account.ClientAriaPermission == "false" &&
account.IsActiveString == "true"))
if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" && account.IsActiveString == "true") || (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false" && account.IsActiveString == "true"))
idAutoriz = 1;
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
account.IsActiveString == "true")
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true")
idAutoriz = 2;
}
@@ -482,8 +279,7 @@ public class AccountApplication : IAccountApplication
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
cameraAccount.IsActiveSting);
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,cameraAccount.IsActiveSting);
if (cameraAccount.IsActiveSting == "true")
{
_authHelper.CameraSignIn(authViewModel);
@@ -493,43 +289,41 @@ public class AccountApplication : IAccountApplication
{
idAutoriz = 0;
}
}
if (subAccount != null)
{
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(subAccount.Password, command.Password);
if (!result.Verified)
return operation.Failed(ApplicationMessages.WrongUserPass);
var role = _subAccountRoleRepository.Get(subAccount.SubAccountRoleId);
if (subAccount != null)
{
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(subAccount.Password, command.Password);
if (!result.Verified)
return operation.Failed(ApplicationMessages.WrongUserPass);
var role = _subAccountRoleRepository.Get(subAccount.SubAccountRoleId);
var permissions = role.RolePermissions.Select(x => x.PermissionCode).ToList();
var authViewModel = new AuthViewModel(subAccount.AccountId, subAccount.SubAccountRoleId, subAccount.FullName
, subAccount.Username, subAccount.PhoneNumber, "", permissions, role.Title, "false",
"true", 0, subAccount.id);
var workshopList = _workshopSubAccountRepository.GetWorkshopsBySubAccountId(subAccount.id);
authViewModel.WorkshopList = workshopList.Select(x => new WorkshopClaim()
{
Slug = _passwordHasher.SlugHasher(x.WorkshopId),
Name = x.WorkshopName,
PersonnelCount = x.PersonnelCount,
Id = x.WorkshopId
}).ToList();
var permissions = role.RolePermissions.Select(x => x.PermissionCode).ToList();
var authViewModel = new AuthViewModel(subAccount.AccountId, subAccount.SubAccountRoleId, subAccount.FullName
, subAccount.Username, subAccount.PhoneNumber, "", permissions, role.Title, "false",
"true", 0, subAccount.id);
var workshopList = _workshopSubAccountRepository.GetWorkshopsBySubAccountId(subAccount.id);
authViewModel.WorkshopList = workshopList.Select(x => new WorkshopClaim()
{
Slug = _passwordHasher.SlugHasher(x.WorkshopId),
Name = x.WorkshopName,
PersonnelCount = x.PersonnelCount,
Id = x.WorkshopId
}).ToList();
if (workshopList.Any())
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.WorkshopName;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.WorkshopId);
authViewModel.WorkshopId = workshop.WorkshopId;
}
if (workshopList.Any())
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.WorkshopName;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.WorkshopId);
}
_authHelper.Signin(authViewModel);
idAutoriz = 2;
}
_authHelper.Signin(authViewModel);
idAutoriz = 2;
}
return operation.Succcedded(idAutoriz);
return operation.Succcedded(idAutoriz);
}
public OperationResult LoginWithMobile(long id)
{
var operation = new OperationResult();
@@ -538,6 +332,7 @@ public class AccountApplication : IAccountApplication
return operation.Failed(ApplicationMessages.WrongUserPass);
var permissions = _roleRepository.Get(account.RoleId)
.Permissions
.Select(x => x.Code)
@@ -553,43 +348,38 @@ public class AccountApplication : IAccountApplication
}
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName,
account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue);
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" &&
account.IsActiveString == "true")
{
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
authViewModel.Permissions = clientPermissions;
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x =>
new WorkshopClaim
{
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
authViewModel.WorkshopList = workshopList;
if (workshopList.Any())
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.Name;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
authViewModel.WorkshopId = workshop.Id;
}
}
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
authViewModel.Permissions = clientPermissions;
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
{
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
authViewModel.WorkshopList = workshopList;
if (workshopList.Any())
{
var workshop = workshopList.First();
authViewModel.WorkshopName = workshop.Name;
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
}
}
_authHelper.Signin(authViewModel);
long idAutoriz = 0;
if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" ||
account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false")
if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" || account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false")
idAutoriz = 1;
if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false")
idAutoriz = 2;
return operation.Succcedded(idAutoriz);
}
public void Logout()
{
_authHelper.SignOut();
@@ -625,7 +415,6 @@ public class AccountApplication : IAccountApplication
_accountRepository.SaveChanges();
return operation.Succcedded();
}
public EditAccount GetByVerifyCode(string code, string phone)
{
return _accountRepository.GetByVerifyCode(code, phone);
@@ -636,7 +425,7 @@ public class AccountApplication : IAccountApplication
return _accountRepository.GetByUserNameAndId(id, username);
}
public async Task<OperationResult> SetVerifyCode(string phone, long id)
public async Task <OperationResult> SetVerifyCode(string phone, long id)
{
var operation = new OperationResult();
var account = _accountRepository.Get(id);
@@ -650,10 +439,11 @@ public class AccountApplication : IAccountApplication
_smsService.LoginSend(phone, r);
//TimeSpan delay = TimeSpan.FromSeconds(30);
await _accountRepository.RemoveCode(id);
return operation.Succcedded();
}
@@ -698,88 +488,87 @@ public class AccountApplication : IAccountApplication
return operation.Failed("این اکانت وجود ندارد");
var permissions = _roleRepository.Get(account.RoleId)
.Permissions
.Select(x => x.Code)
.ToList();
_authHelper.SignOut();
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true",
null);
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
{
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true",null);
var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim
{
PersonnelCount = x.PersonnelCount,
Id = x.Id,
Name = x.WorkshopFullName,
Slug = _passwordHasher.SlugHasher(x.Id)
}).OrderByDescending(x => x.PersonnelCount).ToList();
authViewModel.WorkshopList = workshopList;
authViewModel.WorkshopList = workshopList;
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes();
authViewModel.Permissions = clientPermissions;
if (authViewModel.WorkshopList.Any())
{
var workshop = authViewModel.WorkshopList.First();
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
authViewModel.WorkshopName = workshop.Name;
authViewModel.WorkshopId = workshop.Id;
}
_authHelper.Signin(authViewModel);
if (authViewModel.WorkshopList.Any())
{
var workshop = authViewModel.WorkshopList.First();
authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.Id);
authViewModel.WorkshopName = workshop.Name;
}
_authHelper.Signin(authViewModel);
return operation.Succcedded(2);
}
public OperationResult DirectCameraLogin(long cameraAccountId)
{
var prAcc = _authHelper.CurrentAccountInfo();
var operation = new OperationResult();
var cameraAccount = _cameraAccountRepository.GetById(cameraAccountId);
if (cameraAccount == null)
return operation.Failed("این اکانت وجود ندارد");
var prAcc = _authHelper.CurrentAccountInfo();
var operation = new OperationResult();
var cameraAccount = _cameraAccountRepository.GetById(cameraAccountId);
if (cameraAccount == null)
return operation.Failed("این اکانت وجود ندارد");
_authHelper.SignOut();
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
cameraAccount.IsActiveSting);
if (cameraAccount.IsActiveSting == "true")
{
_authHelper.CameraSignIn(authViewModel);
}
else
{
return operation.Failed("این اکانت غیر فعال شده است");
}
return operation.Succcedded(2);
_authHelper.SignOut();
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, cameraAccount.IsActiveSting);
if (cameraAccount.IsActiveSting == "true")
{
_authHelper.CameraSignIn(authViewModel);
}
else
{
return operation.Failed("این اکانت غیر فعال شده است");
}
return operation.Succcedded(2);
}
// public AccountLeftWorkViewModel WorkshopList(long accountId)
// {
// string fullname = this._accountRepository.GetById(accountId).Fullname;
// List<WorkshopAccountlistViewModel> source = _accountLeftworkRepository.WorkshopList(accountId);
// List<long> userWorkshopIds = source.Select(x => x.WorkshopId).ToList();
// List<WorkshopSelectList> allWorkshops = this._accountLeftworkRepository.GetAllWorkshops();
// List<AccountViewModel> accountSelectList = this._accountRepository.GetAdminAccountSelectList();
// (string StartWorkFa, string LeftWorkFa) byAccountId = this._accountLeftworkRepository.GetByAccountId(accountId);
// return new AccountLeftWorkViewModel()
// {
// AccountId = accountId,
// AccountFullName = fullname,
// StartDateFa = byAccountId.StartWorkFa,
// LeftDateFa = byAccountId.LeftWorkFa,
// WorkshopAccountlist = source,
// WorkshopSelectList = new SelectList(allWorkshops.Where(x => !userWorkshopIds.Contains(x.Id)), "Id", "WorkshopFullName"),
// AccountSelectList = new SelectList(accountSelectList, "Id", "Fullname")
// };
// }
public AccountLeftWorkViewModel WorkshopList(long accountId)
{
string fullname = this._accountRepository.GetById(accountId).Fullname;
List<WorkshopAccountlistViewModel> source =_accountLeftworkRepository.WorkshopList(accountId);
List<long> userWorkshopIds = source.Select(x => x.WorkshopId).ToList();
List<WorkshopSelectList> allWorkshops = this._accountLeftworkRepository.GetAllWorkshops();
List<AccountViewModel> accountSelectList = this._accountRepository.GetAdminAccountSelectList();
(string StartWorkFa, string LeftWorkFa) byAccountId = this._accountLeftworkRepository.GetByAccountId(accountId);
return new AccountLeftWorkViewModel()
{
AccountId = accountId,
AccountFullName = fullname,
StartDateFa = byAccountId.StartWorkFa,
LeftDateFa = byAccountId.LeftWorkFa,
WorkshopAccountlist = source,
WorkshopSelectList = new SelectList(allWorkshops.Where(x => !userWorkshopIds.Contains(x.Id)), "Id", "WorkshopFullName"),
AccountSelectList = new SelectList(accountSelectList, "Id", "Fullname")
};
}
public OperationResult SaveWorkshopAccount(
List<WorkshopAccountlistViewModel> workshopAccountList,
@@ -789,12 +578,10 @@ public class AccountApplication : IAccountApplication
{
return this._accountLeftworkRepository.SaveWorkshopAccount(workshopAccountList, startDate, leftDate, accountId);
}
public OperationResult CreateNewWorkshopAccount(long currentAccountId, long newAccountId)
{
return this._accountLeftworkRepository.CopyWorkshopToNewAccount(currentAccountId, newAccountId);
}
#region Mahan
public List<AccountViewModel> AccountsForAssign(long taskId)
@@ -808,7 +595,6 @@ public class AccountApplication : IAccountApplication
{
return new List<AccountViewModel>();
}
return _accountRepository.GetAccountsByPositionId(positionId);
}
@@ -826,6 +612,7 @@ public class AccountApplication : IAccountApplication
return operation.Failed("این اکانت وجود ندارد");
var permissions = _roleRepository.Get(account.RoleId)
.Permissions
.Select(x => x.Code)
@@ -834,10 +621,10 @@ public class AccountApplication : IAccountApplication
_authHelper.SignOut();
var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName,
account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue);
, account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue);
_authHelper.Signin(authViewModel);
return operation.Succcedded(2);
}
public async Task<List<AccountSelectListViewModel>> GetAdminSelectList()
@@ -846,74 +633,68 @@ public class AccountApplication : IAccountApplication
}
#endregion
#region Pooya
public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password,
string rePassword)
public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password, string rePassword)
{
OperationResult op = new();
OperationResult op = new();
var entity = _accountRepository.Get(accountId);
var entity = _accountRepository.Get(accountId);
if (entity == null)
return op.Failed(ApplicationMessages.RecordNotFound);
if (entity == null)
return op.Failed(ApplicationMessages.RecordNotFound);
if (!string.IsNullOrWhiteSpace(rePassword) || !string.IsNullOrWhiteSpace(password))
{
if (rePassword != password)
return op.Failed("تکرار رمز عبور با رمز عبور مطابقت ندارد");
if (!string.IsNullOrWhiteSpace(rePassword) || !string.IsNullOrWhiteSpace(password))
{
if (rePassword != password)
return op.Failed("تکرار رمز عبور با رمز عبور مطابقت ندارد");
if (password.Length < 8)
return op.Failed("رمز عبور نمی تواند کمتر از 8 کاراکتر باشد");
}
if (password.Length < 8)
return op.Failed("رمز عبور نمی تواند کمتر از 8 کاراکتر باشد");
}
if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) &&
string.IsNullOrWhiteSpace(rePassword))
return op.Failed("چیزی برای تغییر وجود ندارد");
if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) && string.IsNullOrWhiteSpace(rePassword))
return op.Failed("چیزی برای تغییر وجود ندارد");
if (!string.IsNullOrWhiteSpace(phoneNumber) && entity.Mobile != phoneNumber)
{
phoneNumber = phoneNumber.Trim();
if (phoneNumber.Length != 11)
return op.Failed("شماره تلفن همراه به درستی وارد نشده است");
if (_accountRepository.Exists(x => x.Mobile == phoneNumber && x.id != accountId) ||
_subAccountRepository.Exists(x => x.PhoneNumber == phoneNumber) ||
_cameraAccountRepository.Exists(x => x.Mobile == phoneNumber))
return op.Failed("قبلا یک حساب با این شماره ثبت شده است");
}
if (!string.IsNullOrWhiteSpace(phoneNumber) && entity.Mobile != phoneNumber)
{
phoneNumber = phoneNumber.Trim();
if (phoneNumber.Length != 11)
return op.Failed("شماره تلفن همراه به درستی وارد نشده است");
if (_accountRepository.Exists(x => x.Mobile == phoneNumber && x.id != accountId) ||
_subAccountRepository.Exists(x => x.PhoneNumber == phoneNumber) ||
_cameraAccountRepository.Exists(x => x.Mobile == phoneNumber))
return op.Failed("قبلا یک حساب با این شماره ثبت شده است");
}
return op.Succcedded();
}
return op.Succcedded();
}
public OperationResult ChangePasswordAndPhoneNumber(AccountChangePasswordAndPhoneNumber command)
{
OperationResult op = new();
command.PhoneNumber = command.PhoneNumber.Trim();
var entity = _accountRepository.Get(command.AccountId);
if (entity == null)
return op.Failed(ApplicationMessages.RecordNotFound);
var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password,
command.RePassword);
if (validationResult.IsSuccedded == false)
return validationResult;
OperationResult op = new();
command.PhoneNumber = command.PhoneNumber.Trim();
var entity = _accountRepository.Get(command.AccountId);
if (entity == null)
return op.Failed(ApplicationMessages.RecordNotFound);
var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password, command.RePassword);
if (validationResult.IsSuccedded == false)
return validationResult;
if (!string.IsNullOrWhiteSpace(command.RePassword))
{
entity.ChangePassword(_passwordHasher.Hash(command.Password));
}
if (!string.IsNullOrWhiteSpace(command.RePassword))
{
if (!string.IsNullOrWhiteSpace(command.PhoneNumber))
{
entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto,
entity.RoleName);
}
entity.ChangePassword(_passwordHasher.Hash(command.Password));
}
_accountRepository.SaveChanges();
return op.Succcedded();
}
if (!string.IsNullOrWhiteSpace(command.PhoneNumber))
{
entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto, entity.RoleName);
}
_accountRepository.SaveChanges();
return op.Succcedded();
}
//public UserClaimsResponseDTO GetClaimsForSignIn(Login command)
//{
// var operation = new OperationResult();
@@ -1006,7 +787,6 @@ public class AccountApplication : IAccountApplication
// return claimsResponse.Failed(ApplicationMessages.WrongUserPass);
//}
#endregion
@@ -1015,38 +795,4 @@ public class AccountApplication : IAccountApplication
return _accountRepository.CheckExistClientAccount(userName);
}
public List<AccountViewModel> GetAdminAccountsNew()
{
return _accountRepository.GetAdminAccountsNew();
}
public void CameraLogin(CameraLoginRequest request)
{
var cameraAccount = _cameraAccountRepository.GetBy(request.UserName);
if (cameraAccount == null)
{
throw new BadRequestException(ApplicationMessages.WrongUserPass);
}
(bool Verified, bool NeedUpgrade) result = _passwordHasher.Check(cameraAccount.Password, request.Password);
if (!result.Verified)
throw new BadRequestException(ApplicationMessages.WrongUserPass);
var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile;
var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId,
cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId,
cameraAccount.IsActiveSting);
if (cameraAccount.IsActiveSting != "true")
throw new BadRequestException(ApplicationMessages.WrongUserPass);
_authHelper.CameraSignIn(authViewModel);
}
public async Task<GetPmUserDto> GetPmUserAsync(long accountId)
{
return await _pmUserQueryService.GetPmUserDataByAccountId(accountId);
}
}

View File

@@ -1,14 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />
<ProjectReference Include="..\AccountManagement.Domain\AccountManagement.Domain.csproj" />
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
<ProjectReference Include="..\Shared.Contracts\Shared.Contracts.csproj" />
</ItemGroup>

View File

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

View File

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

View File

@@ -2,14 +2,6 @@
using AccountManagement.Application.Contracts.Role;
using AccountManagement.Domain.RoleAgg;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Company.Domain._common;
using Microsoft.AspNetCore.Mvc.Rendering;
using Shared.Contracts.PmRole.Commands;
using GetPmRolesDto = Shared.Contracts.PmRole.Queries.GetPmRolesDto;
using Role = AccountManagement.Domain.RoleAgg.Role;
using Shared.Contracts.PmRole.Queries;
namespace AccountManagement.Application;
@@ -17,82 +9,32 @@ public class RoleApplication : IRoleApplication
{
private readonly IRoleRepository _roleRepository;
private readonly IPmRoleQueryService _pmRoleQueryService;
private readonly IPmRoleCommandService _pmRoleCommandService;
private readonly IUnitOfWork _unitOfWork;
public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleQueryService pmRoleQueryService, IPmRoleCommandService pmRoleCommandService)
public RoleApplication(IRoleRepository roleRepository)
{
_roleRepository = roleRepository;
_unitOfWork = unitOfWork;
_pmRoleQueryService = pmRoleQueryService;
_pmRoleCommandService = pmRoleCommandService;
}
public async Task<OperationResult> Create(CreateRole command)
public OperationResult Create(CreateRole command)
{
var operation = new OperationResult();
if (_roleRepository.Exists(x => x.Name == command.Name))
return operation.Failed(ApplicationMessages.DuplicatedRecord);
var permissions = command.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList();
var permissions = new List<Permission>();
foreach (var code in command.Permissions)
{
if (code > 0)
{
permissions.Add(new Permission(code));
}
}
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
var role = new Role(command.Name, permissions);
_unitOfWork.BeginAccountContext();
_roleRepository.Create(role);
_roleRepository.SaveChanges();
var pmPermissions = command.PmPermissions.Where(x => x > 0).ToList();
if (pmPermissions.Any())
{
var pmRole = new CreatePmRoleDto{ RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id};
var res =await _pmRoleCommandService.Create(pmRole);
if (!res.Item1)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
}
//var parameters = new CreateProgramManagerRole
//{
// RoleName = command.Name,
// Permissions = pmPermissions,
// GozareshgirRoleId = role.id
//};
//var url = "api/role";
//var key = SecretKeys.ProgramManagerInternalApi;
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Result.errorMessage);
//}
}
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
_unitOfWork.CommitAccountContext();
return operation.Succcedded();
}
public async Task<OperationResult> Edit(EditRole command)
public OperationResult Edit(EditRole command)
{
var operation = new OperationResult();
var role = _roleRepository.Get(command.Id);
@@ -105,134 +47,17 @@ public class RoleApplication : IRoleApplication
//var permissions = new List<Permission>();
//command.Permissions.ForEach(code => permissions.Add(new Permission(code)));
var permissions = command.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList();
var permissions = new List<Permission>();
foreach (var code in command.Permissions)
{
if (code > 0)
{
permissions.Add(new Permission(code));
}
}
_unitOfWork.BeginAccountContext();
role.Edit(command.Name, permissions);
_roleRepository.SaveChanges();
var key = SecretKeys.ProgramManagerInternalApi;
var pmPermissions = command.PmPermissions.Where(x => x > 0).ToList();
//یافتن نقش در پروگرام منیجر
//var apiResult = InternalApiCaller.GetAsync<RoleResponse>(
// "api/role",
// key,
// new Dictionary<string, object>
// {
// { "RoleName", "" },
// { "GozareshgirRoleId", command.Id}
// }
//);
var pmRoleListResult = await _pmRoleQueryService.GetPmRoleList(command.Id);
var pmRoleResult = pmRoleListResult.FirstOrDefault();
//اگر این نقش در پروگرام منیجر وجود داشت ویرایش کن
if (pmRoleResult != null)
{
var edit = new CreatePmRoleDto { RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id };
var res = await _pmRoleCommandService.Edit(edit);
if (!res.Item1)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
}
//var parameters = new CreateProgramManagerRole
//{
// RoleName = command.Name,
// Permissions = pmPermissions,
// GozareshgirRoleId = role.id
//};
//var url = "api/role/edit";
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Result.errorMessage);
//}
}
else //اگر نقش در پروگرام منیجر وجود نداشت
{
//اگر تیک پرمیشن های پروگرام منیجر زده شده
//این نقش را سمت پروگرام منیجر بساز
if (pmPermissions.Any())
{
var pmRole = new CreatePmRoleDto { RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id };
var res = await _pmRoleCommandService.Create(pmRole);
if (!res.Item1)
{
_unitOfWork.RollbackAccountContext();
return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
}
//try
//{
// var pmPermissionsData = pmPermissions.Where(x => x > 0).Select(x => new PmPermission(x)).ToList();
// var pmRole = new PmRole(command.Name, command.Id, pmPermissionsData);
// await _pmRoleRepository.CreateAsync(pmRole);
// await _pmRoleRepository.SaveChangesAsync();
//}
//catch (System.Exception)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر");
//}
//var parameters = new CreateProgramManagerRole
//{
// RoleName = command.Name,
// Permissions = pmPermissions,
// GozareshgirRoleId = role.id
//};
//var url = "api/role";
//var response = InternalApiCaller.PostAsync<CreateProgramManagerRole, ApiResponse>(
// url,
// key,
// parameters
//);
//if (!response.Success)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed("ارتباط با اپلیکیش پروگرام منیجر برقرار نشد");
//}
//if (!response.Result.isSuccess)
//{
// _unitOfWork.RollbackAccountContext();
// return operation.Failed(response.Result.errorMessage);
//}
}
}
_unitOfWork.CommitAccountContext();
return operation.Succcedded();
}
@@ -245,23 +70,4 @@ public class RoleApplication : IRoleApplication
{
return _roleRepository.List();
}
public async Task<SelectList> GetPmRoleList(long? gozareshgirRoleId)
{
var rolse = await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId);
return new SelectList(rolse, "Id", "RoleName");
}
public async Task<List<GetPmRolesDto>> GetPmRoleListToEdit(long? gozareshgirRoleId)
{
return await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId);
}
}

View File

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

View File

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

View File

@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -10,7 +10,7 @@ public interface IAccountLeftworkRepository : IRepository<long, AccountLeftWork>
{
(string StartWorkFa, string LeftWorkFa) GetByAccountId(long accountId);
List<WorkshopAccountlistViewModel> WorkshopList(long accountId);
// List<WorkshopSelectList> GetAllWorkshops();
List<WorkshopSelectList> GetAllWorkshops();
OperationResult CopyWorkshopToNewAccount(long currentAccountId, long newAccountId);

View File

@@ -1,16 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\AccountManagement.Application.Contracts\AccountManagement.Application.Contracts.csproj" />

View File

@@ -2,7 +2,6 @@
using AccountManagement.Domain.TaskAgg;
using System;
using System.Collections.Generic;
using System.Linq;
using AccountManagement.Domain.TaskMessageAgg;
namespace AccountManagement.Domain.AssignAgg;
@@ -159,24 +158,4 @@ public class Assign : EntityBase
IsDoneRequest=isDoneRequest;
DoneDescription=doneDescription;
}
public void ChangeAssignedId(long assignedId)
{
AssignedId = assignedId;
}
public void SetAssignerId(long assignerId)
{
AssignerId = assignerId;
}
public void ChangeSender(long senderId)
{
Task.SetSender(senderId);
var taskMessageItemsEnumerable =TaskMessageList.SelectMany(m => m.TaskMessageItemsList);
foreach (var taskMessageItems in taskMessageItemsEnumerable)
{
taskMessageItems.SetSenderId(senderId);
}
}
}

View File

@@ -1,155 +0,0 @@
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Configuration;
namespace AccountManagement.Domain.InternalApiCaller;
public class ApiResult<T>
{
public bool Success { get; set; }
public T Result { get; set; }
public string Error { get; set; }
}
public static class InternalApiCaller
{
private static string _baseUrl = "";
public static void SetBaseUrl(string baseUrl)
{
_baseUrl = baseUrl.TrimEnd('/'); // حذف / اضافی
}
/// <summary>
///api post متد
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TResponse"></typeparam>
/// <param name="url"></param>
/// <param name="internalKey"></param>
/// <param name="body"></param>
/// <returns></returns>
public static ApiResult<TResponse> PostAsync<TRequest, TResponse>(
string url,
string internalKey,
TRequest body
)
{
try
{
var client = new HttpClient();
// ساخت URL نهایی
var finalUrl = $"{_baseUrl}/{url.TrimStart('/')}";
var request = new HttpRequestMessage(HttpMethod.Post, finalUrl);
request.Headers.Add("X-INTERNAL-KEY", internalKey);
var json = JsonConvert.SerializeObject(body);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = client.SendAsync(request).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
return new ApiResult<TResponse>
{
Success = false,
Error = $"HTTP Error: {response.StatusCode}"
};
}
var text = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var deserialized = JsonConvert.DeserializeObject<TResponse>(text);
return new ApiResult<TResponse>
{
Success = true,
Result = deserialized
};
}
catch (Exception ex)
{
return new ApiResult<TResponse>
{
Success = false,
Error = ex.Message
};
}
}
/// <summary>
/// Api Get متد
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="url"></param>
/// <param name="internalKey"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public static ApiResult<TResponse> GetAsync<TResponse>(
string url,
string internalKey,
Dictionary<string, object> parameters = null
)
{
try
{
if (parameters != null && parameters.Any())
{
var query = string.Join("&",
parameters
.Where(p => p.Value != null)
.Select(p => $"{p.Key}={p.Value}")
);
url += url.Contains("?") ? "&" + query : "?" + query;
}
// ساخت URL نهایی
var finalUrl = $"{_baseUrl}/{url.TrimStart('/')}";
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, finalUrl);
request.Headers.Add("X-INTERNAL-KEY", internalKey);
var response = client.SendAsync(request).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
return new ApiResult<TResponse>
{
Success = false,
Error = $"HTTP Error: {response.StatusCode}"
};
}
var text = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var deserialized = JsonConvert.DeserializeObject<TResponse>(text);
return new ApiResult<TResponse>
{
Success = true,
Result = deserialized
};
}
catch (Exception ex)
{
return new ApiResult<TResponse>
{
Success = false,
Error = ex.Message
};
}
}
}

View File

@@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using _0_Framework.Domain;
using AccountManagement.Domain.AssignAgg;
using AccountManagement.Domain.TaskMediaAgg;
using AccountManagement.Domain.TaskScheduleAgg;
using OfficeOpenXml.Style;
namespace AccountManagement.Domain.TaskAgg;
@@ -82,40 +80,4 @@ public class Tasks : EntityBase
TaskScheduleId = taskScheduleId;
}
public void ChangeSender(long senderId)
{
var prevSender = SenderId;
var assigners = Assigns.Where(x => x.AssignerId == prevSender).ToList();
foreach (var assigner in assigners)
{
assigner.SetAssignerId(senderId);
}
var senderMessageItem = Assigns
.SelectMany(x=>x.TaskMessageList
.SelectMany(m=>m.TaskMessageItemsList)).Where(x=>x.SenderAccountId == prevSender).ToList();
var receiverMessageItem = Assigns.SelectMany(x=>x.TaskMessageList
.SelectMany(m=>m.TaskMessageItemsList)).Where(x=>x.ReceiverAccountId == prevSender).ToList();
SenderId = senderId;
foreach (var taskMessageItems in senderMessageItem)
{
taskMessageItems.SetSenderId(senderId);
}
foreach (var taskMessageItems in receiverMessageItem)
{
taskMessageItems.SetReceiver(senderId);
}
}
public void SetSender(long senderId)
{
SenderId = senderId;
}
}

View File

@@ -19,13 +19,4 @@ public class TaskMessageItems:EntityBase
public TaskMessage TaskMessage { get; set; }
public void SetSenderId(long senderId)
{
SenderAccountId = senderId;
}
public void SetReceiver(long receiverId)
{
ReceiverAccountId = receiverId;
}
}

View File

@@ -1,4 +1,4 @@
using AccountManagement.Domain.AccountAgg;
using AccountManagement.Domain.AccountAgg;
using AccountMangement.Infrastructure.EFCore.Mappings;
using Microsoft.EntityFrameworkCore;
using System;
@@ -26,6 +26,7 @@ using AccountManagement.Domain.SubAccountPermissionSubtitle2Agg;
using AccountManagement.Domain.SubAccountPermissionSubtitle3Agg;
using AccountManagement.Domain.SubAccountPermissionSubtitle4Agg;
using AccountManagement.Domain.SubAccountRoleAgg;
using AccountMangement.Infrastructure.EFCore.Seed;
using AccountManagement.Domain.TaskScheduleAgg;
namespace AccountMangement.Infrastructure.EFCore
@@ -59,10 +60,9 @@ namespace AccountMangement.Infrastructure.EFCore
public DbSet<TaskSchedule> TaskSchedules { get; set; }
#endregion
#region Pooya
public DbSet<SubAccount> SubAccounts { get; set; }
public DbSet<SubAccountRole> SubAccountRoles { get; set; }

View File

@@ -1,15 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.17.1" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@@ -20,12 +18,4 @@
<ProjectReference Include="..\Company.Domain\Company.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Mappings\BugReportMapping.cs" />
</ItemGroup>
</Project>

View File

@@ -1,31 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AccountMangement.Infrastructure.EFCore.Migrations
{
/// <inheritdoc />
public partial class addprogrammangerbooinaccount : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsProgramManagerUser",
table: "Accounts",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsProgramManagerUser",
table: "Accounts");
}
}
}

View File

@@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AccountMangement.Infrastructure.EFCore.Migrations
{
/// <inheritdoc />
public partial class romoveIsProgramManagerUserFromAccount : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsProgramManagerUser",
table: "Accounts");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsProgramManagerUser",
table: "Accounts",
type: "bit",
nullable: false,
defaultValue: false);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@@ -377,87 +377,6 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations
b.ToTable("Medias", (string)null);
});
modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", 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", null, t =>
{
t.ExcludeFromMigrations();
});
});
modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", 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("AccountManagement.Domain.PositionAgg.Position", b =>
{
b.Property<long>("id")
@@ -1082,71 +1001,6 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations
b.Navigation("Media");
});
modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b =>
{
b.OwnsMany("AccountManagement.Domain.PmDomains.PmPermissionAgg.PmPermission", "PmPermission", 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", null, t =>
{
t.ExcludeFromMigrations();
});
b1.WithOwner("Role")
.HasForeignKey("Roleid");
b1.Navigation("Role");
});
b.Navigation("PmPermission");
});
modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b =>
{
b.OwnsMany("AccountManagement.Domain.PmDomains.PmRoleUserAgg.PmRoleUser", "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("AccountManagement.Domain.RoleAgg.Role", b =>
{
b.OwnsMany("AccountManagement.Domain.RoleAgg.Permission", "Permissions", b1 =>

View File

@@ -18,13 +18,14 @@ public class AccountLeftworkRepository : RepositoryBase<long, AccountLeftWork>,
{
private readonly AccountContext _accountContext;
private readonly IWorkshopAccountRepository _workshopAccountRepository;
private readonly IWorkshopApplication _workshopApplication;
public AccountLeftworkRepository(AccountContext accountContext,
IWorkshopAccountRepository workshopAccountRepository) : base(accountContext)
public AccountLeftworkRepository(AccountContext accountContext, IWorkshopAccountRepository workshopAccountRepository, IWorkshopApplication workshopApplication) : base(accountContext)
{
_accountContext = accountContext;
_workshopAccountRepository = workshopAccountRepository;
}
_workshopApplication = workshopApplication;
}
public (string StartWorkFa, string LeftWorkFa) GetByAccountId(long accountId)
{
@@ -57,14 +58,14 @@ public class AccountLeftworkRepository : RepositoryBase<long, AccountLeftWork>,
}).ToList();
}
// public List<WorkshopSelectList> GetAllWorkshops()
// {
// return this._workshopApplication.GetWorkshopAll().Select(x => new WorkshopSelectList()
// {
// Id = x.Id,
// WorkshopFullName = x.WorkshopFullName
// }).ToList();
// }
public List<WorkshopSelectList> GetAllWorkshops()
{
return this._workshopApplication.GetWorkshopAll().Select(x => new WorkshopSelectList()
{
Id = x.Id,
WorkshopFullName = x.WorkshopFullName
}).ToList();
}
public OperationResult CopyWorkshopToNewAccount(long currentAccountId, long newAccountId)
{

View File

@@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>BackgroundInstitutionContract.Task</AssemblyName>
<RootNamespace>BackgroundInstitutionContract.Task</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" />
<ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" />
<ProjectReference Include="..\..\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>
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,32 +0,0 @@
using _0_Framework.Application;
namespace BackgroundInstitutionContract.Task
{
public class FileUploader : IFileUploader
{
private readonly IWebHostEnvironment _webHostEnvironment;
public FileUploader(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment = webHostEnvironment;
}
public string Upload(IFormFile file, string path)
{
if (file == null) return "";
var directoryPath = $"{_webHostEnvironment.WebRootPath}\\ProductPictures\\{path}";
if (!Directory.Exists(directoryPath))
Directory.CreateDirectory(directoryPath);
var fileName = $"{DateTime.Now.ToFileName()}-{file.FileName}";
var filePath = $"{directoryPath}\\{fileName}";
var output = System.IO.File.Create(filePath);
file.CopyTo(output);
return $"{path}/{fileName}";
}
}
}

View File

@@ -1,304 +0,0 @@
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Application.Sms;
using Company.Domain.ContarctingPartyAgg;
using Company.Domain.InstitutionContractAgg;
using Hangfire;
namespace BackgroundInstitutionContract.Task.Jobs;
public class JobSchedulerRegistrator
{
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly SmsReminder _smsReminder;
private readonly IInstitutionContractRepository _institutionContractRepository;
private readonly IInstitutionContractSmsServiceRepository _institutionContractSmsServiceRepository;
private static DateTime? _lastRunCreateTransaction;
private static DateTime? _lastRunSendMonthlySms;
private readonly ISmsService _smsService;
private readonly ILogger<JobSchedulerRegistrator> _logger;
public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient, IInstitutionContractRepository institutionContractRepository, ISmsService smsService, ILogger<JobSchedulerRegistrator> logger, IInstitutionContractSmsServiceRepository institutionContractSmsServiceRepository)
{
_smsReminder = smsReminder;
_backgroundJobClient = backgroundJobClient;
_institutionContractRepository = institutionContractRepository;
_smsService = smsService;
_logger = logger;
_institutionContractSmsServiceRepository = institutionContractSmsServiceRepository;
}
public void Register()
{
_logger.LogInformation("hangfire Started");
RecurringJob.AddOrUpdate(
"InstitutionContract.CreateFinancialTransaction",
() => CreateFinancialTransaction(),
"*/30 * * * *" // هر 30 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendMonthlySms",
() => SendFirstDayOfMonthSms(),
"*/20 * * * *" // هر 30 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendReminderSms",
() => SendReminderSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendBlockSms",
() => SendBlockSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendInstitutionContractConfirmSms",
() => SendInstitutionContractConfirmSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendWarningSms",
() => SendWarningSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.SendLegalActionSms",
() => SendLegalActionSms(),
"*/1 * * * *" // هر 1 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.Block",
() => Block(),
"*/30 * * * *" // هر 30 دقیقه یکبار چک کن
);
RecurringJob.AddOrUpdate(
"InstitutionContract.UnBlock",
() => UnBlock(),
"*/10 * * * *"
);
RecurringJob.AddOrUpdate(
"InstitutionContract.DeActiveInstitutionEndOfContract",
() => DeActiveInstitutionEndOfContract(),
"*/30 * * * *"
);
RecurringJob.AddOrUpdate(
"InstitutionContract.BlueDeActiveAfterZeroDebt",
() => BlueDeActiveAfterZeroDebt(),
"*/10 * * * *"
);
}
/// <summary>
/// ایجاد سند بدهی ماهیانه برای قراداد مالی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 1200)]
public async System.Threading.Tasks.Task CreateFinancialTransaction()
{
var now = DateTime.Now;
var endOfMonth = now.ToFarsi().FindeEndOfMonth();
var endOfMonthGr = endOfMonth.ToGeorgianDateTime();
_logger.LogInformation("CreateFinancialTransaction job run");
if (now.Date == endOfMonthGr.Date && now.Hour >= 2 && now.Hour < 4 &&
now.Date != _lastRunCreateTransaction?.Date)
{
var month = endOfMonth.Substring(5, 2);
var year = endOfMonth.Substring(0, 4);
var monthName = month.ToFarsiMonthByNumber();
var description = $"{monthName} {year}";
var endnew = ($"{endOfMonth.Substring(0, 8)}01").FindeEndOfMonth();
var endNewGr = endnew.ToGeorgianDateTime();
var endNewFa = endNewGr.ToFarsi();
try
{
await _institutionContractRepository.CreateTransactionForInstitutionContracts(endNewGr, endNewFa, description);
_lastRunCreateTransaction = now;
Console.WriteLine("CreateTransAction executed");
}
catch (Exception e)
{
await _smsService.Alarm("09114221321", "خطا-ایجاد سند مالی");
}
}
}
/// <summary>
/// ارسال پیامک صورت حساب ماهانه
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 600)]
public async System.Threading.Tasks.Task SendFirstDayOfMonthSms()
{
//var now = new DateTime(2025,11,21, 10,30,0);
var now = DateTime.Now;
var endOfMonth = now.ToFarsi().FindeEndOfMonth();
var endOfMonthGr = endOfMonth.ToGeorgianDateTime();
_logger.LogInformation("SendFirstDayOfMonthSms job run");
if (now.Date == endOfMonthGr.Date && now.Hour >= 10 && now.Hour < 11 &&
now.Date != _lastRunSendMonthlySms?.Date)
{
try
{
await _institutionContractSmsServiceRepository.SendMonthlySms(now);
_lastRunSendMonthlySms = now;
Console.WriteLine("Send Monthly sms executed");
}
catch (Exception e)
{
//_smsService.Alarm("09114221321", "خطا-ایجاد سند مالی");
}
}
}
/// <summary>
/// ارسال پیامک یاد آور بدهی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 1200)]
public async System.Threading.Tasks.Task SendReminderSms()
{
_logger.LogInformation("SendReminderSms job run");
await _institutionContractSmsServiceRepository.SendReminderSmsForBackgroundTask();
}
/// <summary>
/// ارسال پیامک مسدودی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task SendBlockSms()
{
_logger.LogInformation("SendBlockSms job run");
await _institutionContractSmsServiceRepository.SendBlockSmsForBackgroundTask();
}
/// <summary>
/// ارسال پیامک یادآور تایید قراداد مالی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task SendInstitutionContractConfirmSms()
{
_logger.LogInformation("SendInstitutionContractConfirmSms job run");
await _institutionContractSmsServiceRepository.SendInstitutionContractConfirmSmsTask();
}
/// <summary>
/// ارسال پیامک هشدار
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task SendWarningSms()
{
_logger.LogInformation("SendWarningSms job run");
await _institutionContractSmsServiceRepository.SendWarningOrLegalActionSmsTask(TypeOfSmsSetting.Warning);
}
/// <summary>
/// پیامک اقدام قضایی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task SendLegalActionSms()
{
_logger.LogInformation("SendWarningSms job run");
await _institutionContractSmsServiceRepository.SendWarningOrLegalActionSmsTask(TypeOfSmsSetting.LegalAction);
}
/// <summary>
/// بلاگ سازی
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task Block()
{
_logger.LogInformation("block job run");
var now = DateTime.Now;
var executeDate = now.ToFarsi().Substring(8, 2);
if (executeDate == "20")
{
if (now.Hour >= 9 && now.Hour < 10)
{
await _institutionContractSmsServiceRepository.Block(now);
}
}
}
/// <summary>
/// آنبلاک
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task UnBlock()
{
_logger.LogInformation("UnBlock job run");
await _institutionContractSmsServiceRepository.UnBlock();
}
/// <summary>
/// غیر فعال سازی قراداد های پایان یافته
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 100)]
public async System.Threading.Tasks.Task DeActiveInstitutionEndOfContract()
{
_logger.LogInformation("DeActiveInstitutionEndOfContract job run");
var now = DateTime.Now;
var executeDate = now.ToFarsi().Substring(8, 2);
if (executeDate == "01")
{
if (now.Hour >= 9 && now.Hour < 10)
{
await _institutionContractSmsServiceRepository.DeActiveInstitutionEndOfContract(now);
}
}
}
/// <summary>
/// غیرفعال سازس قرارداد های آبی که بدهی ندارند
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 800)]
public async System.Threading.Tasks.Task BlueDeActiveAfterZeroDebt()
{
_logger.LogInformation("BlueDeActiveAfterZeroDebt job run");
await _institutionContractSmsServiceRepository.BlueDeActiveAfterZeroDebt();
}
}

View File

@@ -1,116 +0,0 @@
using _0_Framework.Application.Sms;
using AccountManagement.Application.Contracts.Account;
using AccountMangement.Infrastructure.EFCore;
using Company.Domain.SmsResultAgg;
using Microsoft.EntityFrameworkCore;
using SmsResult = Company.Domain.SmsResultAgg.SmsResult;
namespace BackgroundInstitutionContract.Task.Jobs;
public class SmsReminder
{
private readonly AccountContext _accountContext;
private readonly ISmsService _smsService;
private readonly ISmsResultRepository _smsResultRepository;
public SmsReminder(ISmsService smsService, AccountContext accountContext, ISmsResultRepository smsResultRepository)
{
_smsService = smsService;
_accountContext = accountContext;
_smsResultRepository = smsResultRepository;
}
public void Execute()
{
//var accounts = _accountContext.Accounts.Where(x => x.PositionId > 0 && x.IsActiveString == "true").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList();
//Thread.Sleep(300);
//var accounts = new List<AccountViewModel>() { new AccountViewModel() { Mobile = "09114221321", Id = 2 } };
var accounts= _accountContext.Accounts.Where(x => x.Username.ToLower()=="mahan").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList();
var smsVM = accounts.Select(x => new AccountSmsTaskViewModel()
{
Mobile = x.Mobile,
AccountId = x.Id,
FullName = x.Fullname,
TaskCount = GetLateTasksCount(x.Id)
}).Where(x => x.TaskCount > 0 && !string.IsNullOrEmpty(x.Mobile) && x.Mobile.Length == 11).ToList();
Thread.Sleep(300);
foreach (var viewmodel in smsVM)
{
var smsResult = _smsService.TaskReminderSms(viewmodel.Mobile, $"{viewmodel.TaskCount}");
Thread.Sleep(1000);
var createSmsResult = new SmsResult(smsResult.MessageId, smsResult.Message, "یادآور وظایف",
viewmodel.FullName, viewmodel.Mobile, viewmodel.AccountId, viewmodel.AccountId);
_smsResultRepository.Create(createSmsResult);
_smsResultRepository.SaveChanges();
Thread.Sleep(1000);
}
}
private int GetLateTasksCount(long accountId)
{
var positionValue = _accountContext.Accounts
.Where(x => x.id == accountId)
.Include(p => p.Position)
.Select(x => x.Position.PositionValue)
.FirstOrDefault();
if (positionValue == 0)
return 0;
DateTime now = DateTime.Now;
int overdueTasksCount;
if (positionValue == 1)
{
overdueTasksCount = _accountContext.Assigns.Include(x => x.Task).Where(x => x.AssignedId == accountId &&
x.AssignerId == accountId && x.Task.Assigns.Count == 1 &&
!x.IsCancel && !x.IsCanceledRequest &&
!x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true")
.GroupBy(x => x.TaskId).Select(x => x.First()).Count();
//overdueTasksCount = _accountContext.Tasks.Include(x =>
// x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) &&
// !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) &&
// !x.Assigns.Any(a => a.TimeRequest)
// && x.Assigns.Any(a => a.AssignedId == accountId && a.AssignerId == accountId) &&
// (x.Assigns.First(a => a.AssignedId == accountId && a.AssignerId == accountId)
// .EndTaskDate.Date <= DateTime.Now.Date) && x.Assigns.Count == 1);
}
else
{
overdueTasksCount = _accountContext.Assigns
.Include(x => x.Task)
.Where(x => x.AssignedId == accountId &&
!x.IsCancel && !x.IsCanceledRequest &&
!x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true")
.GroupBy(x => x.TaskId).Select(x => x.First()).Count();
}
//overdueTasksCount = _accountContext.Tasks.Include(x =>
// x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) &&
// !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) &&
// !x.Assigns.Any(a => a.TimeRequest)
// && x.Assigns.Any(a => a.AssignedId == accountId) &&
// (x.Assigns.First(a => a.AssignedId == accountId).EndTaskDate.Date <= DateTime.Now.Date));
var overdueRequestsCount = _accountContext.Assigns.Include(x => x.Task)
.Where(x => (x.IsCanceledRequest
|| x.IsDoneRequest || x.TimeRequest) && !x.IsCancel && !x.IsDone &&
x.Task.IsActiveString == "true" &&
x.Task.SenderId == accountId).GroupBy(x => x.TaskId).Select(x => x.First()).Count();
return overdueTasksCount + overdueRequestsCount;
}
}
public class AccountSmsTaskViewModel
{
public int TaskCount { get; set; }
public long AccountId { get; set; }
public string Mobile { get; set; }
public string FullName { get; set; }
}

View File

@@ -1,25 +0,0 @@
using BackgroundInstitutionContract.Task.Jobs;
namespace BackgroundInstitutionContract.Task;
public class JobsBootstrapper
{
public static void Configure(IServiceCollection services)
{
var currentNamespace = typeof(JobSchedulerRegistrator).Namespace; // همون namespace کلاس
var assembly = typeof(JobSchedulerRegistrator).Assembly;
var jobTypes = assembly.GetTypes()
.Where(t =>
t is { IsClass: true, IsAbstract: false, Namespace: not null } &&
t.Namespace.StartsWith(currentNamespace, StringComparison.Ordinal))
.ToList();
foreach (var jobType in jobTypes)
{
services.AddTransient(jobType);
}
}
}

View File

@@ -1,10 +0,0 @@
using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
public class NullBoardNotificationPublisher:IBoardNotificationPublisher
{
public Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus, TaskSectionStatus newStatus, Guid sectionId)
{
throw new NotImplementedException();
}
}

View File

@@ -1,108 +0,0 @@
using _0_Framework.Application;
using _0_Framework.Application.Sms;
using _0_Framework.Application.UID;
using _0_Framework.InfraStructure.Mongo;
using AccountManagement.Configuration;
using BackgroundInstitutionContract.Task;
using BackgroundInstitutionContract.Task.Jobs;
using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.EFCore.Services;
using GozareshgirProgramManager.Application._Bootstrapper;
using GozareshgirProgramManager.Application.Interfaces;
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 Serilog;
using Serilog.Events;
using Shared.Contracts.PmUser.Queries;
using WorkFlow.Infrastructure.Config;
var logDirectory = @"C:\Logs\Hangfire\BackgroundInstitutionContract\";
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
Log.Logger = new LoggerConfiguration()
//NO EF Core log
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
//NO DbCommand log
.MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
//NO Microsoft Public log
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
//.MinimumLevel.Information()
.WriteTo.File(
path: Path.Combine(logDirectory, "institution-contract-log-.txt"),
rollingInterval: RollingInterval.Day,
retainedFileCountLimit: 30,
shared: true,
outputTemplate:
"{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
).CreateLogger();
var builder = WebApplication.CreateBuilder(args);
var hangfireConnectionString = builder.Configuration.GetConnectionString("HangfireDb");
builder.Services.AddHangfire(x => x.UseSqlServerStorage(hangfireConnectionString));
builder.Services.AddHangfireServer();
var connectionString = builder.Configuration.GetConnectionString("MesbahDb");
var connectionStringTestDb = builder.Configuration.GetConnectionString("TestDb");
builder.Services.AddSingleton<IPasswordHasher, PasswordHasher>();
builder.Services.AddTransient<IAuthHelper, AuthHelper>();
builder.Services.AddTransient<ISmsService, SmsService>();
builder.Services.AddTransient<IUidService, UidService>();
builder.Services.AddTransient<IFileUploader, FileUploader>();
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
builder.Services.AddScoped<IBoardNotificationPublisher, NullBoardNotificationPublisher>();
#region MongoDb
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");
var mongoDbSettings = mongoConnectionSection.Get<MongoDbConfig>();
var mongoClient = new MongoClient(mongoDbSettings.ConnectionString);
var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName);
builder.Services.AddSingleton<IMongoDatabase>(mongoDatabase);
#endregion
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();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSignalR();
builder.Host.UseSerilog();
Log.Information("SERILOG STARTED SUCCESSFULLY");
var app = builder.Build();
app.MapHub<SendSmsHub>("/sendSmsHub");
app.MapHangfireDashboard();
app.MapGet("/", () => "Hello World!");
using (var scope = app.Services.CreateScope())
{
var jobScheduler = scope.ServiceProvider.GetRequiredService<JobSchedulerRegistrator>();
jobScheduler.Register();
}
app.Run();

View File

@@ -1,38 +0,0 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:56492",
"sslPort": 44378
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7223;http://localhost:5217",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -1,47 +0,0 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
//تست
//"MesbahDb": "Data Source=DESKTOP-NUE119G\\MSNEW;Initial Catalog=Mesbah_db;Integrated Security=True"
//server
//"MesbahDb": "Data Source=171.22.24.15;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;",
//local
"MesbahDb": "Data Source=.;Initial Catalog=mesbah_db;Integrated Security=True;TrustServerCertificate=true;",
//dad-mehr
//"MesbahDb": "Data Source=.;Initial Catalog=teamWork;Integrated Security=True;TrustServerCertificate=true;",
"TestDb": "Data Source=.;Initial Catalog=TestDb;Integrated Security=True;TrustServerCertificate=true;",
//mahan Docker
//"MesbahDb": "Data Source=localhost,5069;Initial Catalog=mesbah_db;User ID=sa;Password=YourPassword123;TrustServerCertificate=True;",
"HangfireDb": "Data Source=.;Initial Catalog=hangfire_db;Integrated Security=True;TrustServerCertificate=true;",
//"HangfireDb": "Data Source=185.208.175.186;Initial Catalog=hangfire_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
},
"GoogleRecaptchaV3": {
"SiteKey": "6Lfhp_AnAAAAAB79WkrMoHd1k8ir4m8VvfjE7FTH",
"SecretKey": "6Lfhp_AnAAAAANjDDY6DPrbbUQS7k6ZCRmrVP5Lb"
},
"SmsSecrets": {
"ApiKey": "Og5M562igmzJRhQPnq0GdtieYdLgtfikjzxOmeQBPxJjZtyge5Klc046Lfw1mxSa",
"SecretKey": "dadmehr"
},
"Domain": ".gozareshgir.ir",
"MongoDb": {
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "Gozareshgir"
}
}

View File

@@ -1,28 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
//local
//"MesbahDb": "Data Source=.;Initial Catalog=mesbah_db;Integrated Security=True;TrustServerCertificate=true;",
"MesbahDb": "Data Source=185.208.175.186;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;",
//dad-mehr
//"MesbahDb": "Data Source=.;Initial Catalog=teamWork;Integrated Security=True;TrustServerCertificate=true;",
//"TestDb": "Data Source=.;Initial Catalog=TestDb;Integrated Security=True;TrustServerCertificate=true;",
"TestDb": "Data Source=185.208.175.186;Initial Catalog=TestDb;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;",
//"MesbahDb": "Data Source=.\\MSSQLSERVER2019;Initial Catalog=mesbah_db;Persist Security Info=False;User ID=mesbah_db;Password=sa142857$@;"
//"HangfireDb": "Data Source=.;Initial Catalog=hangfire_db;Integrated Security=True;TrustServerCertificate=true;",
"HangfireDb": "Data Source=185.208.175.186;Initial Catalog=hangfire_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;"
},
"MongoDb": {
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "Gozareshgir"
}
}

View File

@@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\0_Framework\0_Framework.csproj" />
<ProjectReference Include="..\..\AccountManagement.Configuration\AccountManagement.Configuration.csproj" />
<ProjectReference Include="..\..\PersonalContractingParty.Config\PersonalContractingParty.Config.csproj" />
<ProjectReference Include="..\..\Query.Bootstrapper\Query.Bootstrapper.csproj" />
<ProjectReference Include="..\..\WorkFlow\Infrastructure\WorkFlow.Infrastructure.Config\WorkFlow.Infrastructure.Config.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,32 +0,0 @@
using _0_Framework.Application;
namespace BackgroundJobs.Task
{
public class FileUploader : IFileUploader
{
private readonly IWebHostEnvironment _webHostEnvironment;
public FileUploader(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment = webHostEnvironment;
}
public string Upload(IFormFile file, string path)
{
if (file == null) return "";
var directoryPath = $"{_webHostEnvironment.WebRootPath}\\ProductPictures\\{path}";
if (!Directory.Exists(directoryPath))
Directory.CreateDirectory(directoryPath);
var fileName = $"{DateTime.Now.ToFileName()}-{file.FileName}";
var filePath = $"{directoryPath}\\{fileName}";
var output = System.IO.File.Create(filePath);
file.CopyTo(output);
return $"{path}/{fileName}";
}
}
}

View File

@@ -1,62 +0,0 @@
using Hangfire;
namespace BackgroundJobs.Task.Jobs;
public class JobSchedulerRegistrator
{
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly SmsReminder _smsReminder;
private static DateTime? _lastRunDateMorning;
private static DateTime? _lastRunDateEvening;
public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient)
{
_smsReminder = smsReminder;
_backgroundJobClient = backgroundJobClient;
}
public void Register()
{
RecurringJob.AddOrUpdate(
"Task.SmsReminderChecker",
() => SmsReminderCheckAndSchedule(),
"*/5 * * * *" // هر 5 دقیقه یکبار چک کن
);
}
public void SmsReminderCheckAndSchedule()
{
var now = DateTime.Now;
var startMorning = new TimeSpan(9, 0, 0);
var endMorning = new TimeSpan(9, 40, 0);
var startEvening = new TimeSpan(15, 30, 0);
var endEvening = new TimeSpan(15, 40, 0);
// صبح
if (now.DayOfWeek != DayOfWeek.Friday &&
now.TimeOfDay >= startMorning &&
now.TimeOfDay < endMorning)
{
if (_lastRunDateMorning?.Date != now.Date)
{
_backgroundJobClient.Enqueue(() => _smsReminder.Execute());
_lastRunDateMorning = now;
}
}
// عصر - پنجشنبه و جمعه تعطیل است
if (now.DayOfWeek != DayOfWeek.Friday &&
now.DayOfWeek != DayOfWeek.Thursday &&
now.TimeOfDay >= startEvening &&
now.TimeOfDay < endEvening)
{
if (_lastRunDateEvening?.Date != now.Date)
{
_backgroundJobClient.Enqueue(() => _smsReminder.Execute());
_lastRunDateEvening = now;
}
}
}
}

View File

@@ -1,116 +0,0 @@
using _0_Framework.Application.Sms;
using AccountManagement.Application.Contracts.Account;
using AccountMangement.Infrastructure.EFCore;
using Company.Domain.SmsResultAgg;
using Microsoft.EntityFrameworkCore;
using SmsResult = Company.Domain.SmsResultAgg.SmsResult;
namespace BackgroundJobs.Task.Jobs;
public class SmsReminder
{
private readonly AccountContext _accountContext;
private readonly ISmsService _smsService;
private readonly ISmsResultRepository _smsResultRepository;
public SmsReminder(ISmsService smsService, AccountContext accountContext, ISmsResultRepository smsResultRepository)
{
_smsService = smsService;
_accountContext = accountContext;
_smsResultRepository = smsResultRepository;
}
public void Execute()
{
//var accounts = _accountContext.Accounts.Where(x => x.PositionId > 0 && x.IsActiveString == "true").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList();
//Thread.Sleep(300);
//var accounts = new List<AccountViewModel>() { new AccountViewModel() { Mobile = "09114221321", Id = 2 } };
var accounts= _accountContext.Accounts.Where(x => x.Username.ToLower()=="mahan").Select(x => new AccountViewModel() { Id = x.id, Mobile = x.Mobile, Fullname = x.Fullname }).ToList();
var smsVM = accounts.Select(x => new AccountSmsTaskViewModel()
{
Mobile = x.Mobile,
AccountId = x.Id,
FullName = x.Fullname,
TaskCount = GetLateTasksCount(x.Id)
}).Where(x => x.TaskCount > 0 && !string.IsNullOrEmpty(x.Mobile) && x.Mobile.Length == 11).ToList();
Thread.Sleep(300);
foreach (var viewmodel in smsVM)
{
var smsResult = _smsService.TaskReminderSms(viewmodel.Mobile, $"{viewmodel.TaskCount}");
Thread.Sleep(1000);
var createSmsResult = new SmsResult(smsResult.MessageId, smsResult.Message, "یادآور وظایف",
viewmodel.FullName, viewmodel.Mobile, viewmodel.AccountId, viewmodel.AccountId);
_smsResultRepository.Create(createSmsResult);
_smsResultRepository.SaveChanges();
Thread.Sleep(1000);
}
}
private int GetLateTasksCount(long accountId)
{
var positionValue = _accountContext.Accounts
.Where(x => x.id == accountId)
.Include(p => p.Position)
.Select(x => x.Position.PositionValue)
.FirstOrDefault();
if (positionValue == 0)
return 0;
DateTime now = DateTime.Now;
int overdueTasksCount;
if (positionValue == 1)
{
overdueTasksCount = _accountContext.Assigns.Include(x => x.Task).Where(x => x.AssignedId == accountId &&
x.AssignerId == accountId && x.Task.Assigns.Count == 1 &&
!x.IsCancel && !x.IsCanceledRequest &&
!x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true")
.GroupBy(x => x.TaskId).Select(x => x.First()).Count();
//overdueTasksCount = _accountContext.Tasks.Include(x =>
// x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) &&
// !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) &&
// !x.Assigns.Any(a => a.TimeRequest)
// && x.Assigns.Any(a => a.AssignedId == accountId && a.AssignerId == accountId) &&
// (x.Assigns.First(a => a.AssignedId == accountId && a.AssignerId == accountId)
// .EndTaskDate.Date <= DateTime.Now.Date) && x.Assigns.Count == 1);
}
else
{
overdueTasksCount = _accountContext.Assigns
.Include(x => x.Task)
.Where(x => x.AssignedId == accountId &&
!x.IsCancel && !x.IsCanceledRequest &&
!x.IsDone && !x.TimeRequest && !x.IsDoneRequest && x.EndTaskDate.Date <= DateTime.Now.Date && x.Task.IsActiveString == "true")
.GroupBy(x => x.TaskId).Select(x => x.First()).Count();
}
//overdueTasksCount = _accountContext.Tasks.Include(x =>
// x.Assigns).Count(x => !x.Assigns.Any(a => a.IsCancel) && !x.Assigns.Any(a => a.IsCanceledRequest) &&
// !x.Assigns.Any(a => a.IsDone) && !x.Assigns.Any(a => a.IsDoneRequest) &&
// !x.Assigns.Any(a => a.TimeRequest)
// && x.Assigns.Any(a => a.AssignedId == accountId) &&
// (x.Assigns.First(a => a.AssignedId == accountId).EndTaskDate.Date <= DateTime.Now.Date));
var overdueRequestsCount = _accountContext.Assigns.Include(x => x.Task)
.Where(x => (x.IsCanceledRequest
|| x.IsDoneRequest || x.TimeRequest) && !x.IsCancel && !x.IsDone &&
x.Task.IsActiveString == "true" &&
x.Task.SenderId == accountId).GroupBy(x => x.TaskId).Select(x => x.First()).Count();
return overdueTasksCount + overdueRequestsCount;
}
}
public class AccountSmsTaskViewModel
{
public int TaskCount { get; set; }
public long AccountId { get; set; }
public string Mobile { get; set; }
public string FullName { get; set; }
}

View File

@@ -1,24 +0,0 @@
using BackgroundJobs.Task.Jobs;
namespace BackgroundJobs.Task;
public class JobsBootstrapper
{
public static void Configure(IServiceCollection services)
{
var currentNamespace = typeof(JobSchedulerRegistrator).Namespace; // همون namespace کلاس
var assembly = typeof(JobSchedulerRegistrator).Assembly;
var jobTypes = assembly.GetTypes()
.Where(t =>
t is { IsClass: true, IsAbstract: false, Namespace: not null } &&
t.Namespace.StartsWith(currentNamespace, StringComparison.Ordinal))
.ToList();
foreach (var jobType in jobTypes)
{
services.AddTransient(jobType);
}
}
}

View File

@@ -1,59 +0,0 @@
using _0_Framework.Application;
using _0_Framework.Application.Sms;
using _0_Framework.Application.UID;
using _0_Framework.InfraStructure.Mongo;
using AccountManagement.Configuration;
using BackgroundJobs.Task;
using BackgroundJobs.Task.Jobs;
using CompanyManagment.EFCore.Services;
using Hangfire;
using Microsoft.AspNetCore.Identity;
using MongoDB.Driver;
using PersonalContractingParty.Config;
using Query.Bootstrapper;
using WorkFlow.Infrastructure.Config;
var builder = WebApplication.CreateBuilder(args);
var hangfireConnectionString = builder.Configuration.GetConnectionString("HangfireDb");
builder.Services.AddHangfire(x => x.UseSqlServerStorage(hangfireConnectionString));
builder.Services.AddHangfireServer();
var connectionString = builder.Configuration.GetConnectionString("MesbahDb");
var connectionStringTestDb = builder.Configuration.GetConnectionString("TestDb");
builder.Services.AddSingleton<IPasswordHasher, PasswordHasher>();
builder.Services.AddTransient<IAuthHelper, AuthHelper>();
builder.Services.AddTransient<ISmsService, SmsService>();
builder.Services.AddTransient<IUidService, UidService>();
builder.Services.AddTransient<IFileUploader, FileUploader>();
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
#region MongoDb
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");
var mongoDbSettings = mongoConnectionSection.Get<MongoDbConfig>();
var mongoClient = new MongoClient(mongoDbSettings.ConnectionString);
var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName);
builder.Services.AddSingleton<IMongoDatabase>(mongoDatabase);
#endregion
PersonalBootstrapper.Configure(builder.Services, connectionString);
TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb);
AccountManagementBootstrapper.Configure(builder.Services, connectionString);
WorkFlowBootstrapper.Configure(builder.Services, connectionString);
QueryBootstrapper.Configure(builder.Services);
JobsBootstrapper.Configure(builder.Services);
builder.Services.AddHttpClient();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
app.MapHangfireDashboard();
app.MapGet("/", () => "Hello World!");
using (var scope = app.Services.CreateScope())
{
var jobScheduler = scope.ServiceProvider.GetRequiredService<JobSchedulerRegistrator>();
jobScheduler.Register();
}
app.Run();

View File

@@ -1,38 +0,0 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:56492",
"sslPort": 44378
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7222;http://localhost:5216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -1,248 +0,0 @@
# ✅ Docker Bind Mounts Configuration - Summary
## What Was Changed
### 1. docker-compose.yml
**Before:**
```yaml
volumes:
- ./ServiceHost/certs:/app/certs:ro
- app_storage:/app/Storage # ❌ Docker volume
- app_logs:/app/Logs # ❌ Docker volume
volumes:
app_storage:
driver: local
app_logs:
driver: local
```
**After:**
```yaml
volumes:
# ✅ Bind mounts for production-critical data on Windows host
- ./ServiceHost/certs:/app/certs:ro
- D:/AppData/Faces:/app/Faces
- D:/AppData/Storage:/app/Storage
- D:/AppData/Logs:/app/Logs
# ✅ No volumes section needed
```
### 2. New Files Created
- `DOCKER_BIND_MOUNTS_SETUP.md` - Complete documentation
- `setup-bind-mounts.ps1` - Automated setup script
- `QUICK_REFERENCE.md` - Quick command reference
## Path Mapping
| Container (Linux paths) | Windows Host (forward slash) | Actual Windows Path |
|-------------------------|------------------------------|---------------------|
| `/app/Faces` | `D:/AppData/Faces` | `D:\AppData\Faces` |
| `/app/Storage` | `D:/AppData/Storage` | `D:\AppData\Storage`|
| `/app/Logs` | `D:/AppData/Logs` | `D:\AppData\Logs` |
**Note:** Docker Compose on Windows accepts both `D:/` and `D:\` but prefers forward slashes.
## Application Code Compatibility
Your application uses:
```csharp
Path.Combine(env.ContentRootPath, "Faces"); // → /app/Faces
Path.Combine(env.ContentRootPath, "Storage"); // → /app/Storage
```
Where `env.ContentRootPath` = `/app` in the container.
**No code changes required!** The bind mounts map directly to these paths.
## Setup Instructions
### Option 1: Automated Setup (Recommended)
```powershell
# Navigate to project directory
cd D:\GozareshgirOrginal\OriginalGozareshgir
# Run setup script with permissions
.\setup-bind-mounts.ps1 -GrantFullPermissions
# Start the application
docker-compose up -d
```
### Option 2: Manual Setup
```powershell
# 1. Create directories
New-Item -ItemType Directory -Force -Path "D:\AppData\Faces"
New-Item -ItemType Directory -Force -Path "D:\AppData\Storage"
New-Item -ItemType Directory -Force -Path "D:\AppData\Logs"
# 2. Grant permissions
icacls "D:\AppData\Faces" /grant Everyone:F /T
icacls "D:\AppData\Storage" /grant Everyone:F /T
icacls "D:\AppData\Logs" /grant Everyone:F /T
# 3. Start the application
docker-compose up -d
```
## Verification Checklist
After starting the container:
1. **Check if directories are mounted:**
```powershell
docker exec gozareshgir-servicehost ls -la /app
```
Should show: `Faces/`, `Storage/`, `Logs/`
2. **Test write access from container:**
```powershell
docker exec gozareshgir-servicehost sh -c "echo 'test' > /app/Storage/test.txt"
Get-Content D:\AppData\Storage\test.txt # Should display: test
Remove-Item D:\AppData\Storage\test.txt
```
3. **Test write access from host:**
```powershell
"test from host" | Out-File "D:\AppData\Storage\host-test.txt"
docker exec gozareshgir-servicehost cat /app/Storage/host-test.txt
Remove-Item D:\AppData\Storage\host-test.txt
```
4. **Check application logs:**
```powershell
docker logs gozareshgir-servicehost --tail 50
# Or directly on host:
Get-Content D:\AppData\Logs\gozareshgir_log.txt -Tail 50
```
## Data Persistence Guarantees
✅ **Files persist through:**
- `docker-compose down`
- `docker-compose restart`
- Container removal (`docker rm`)
- Image rebuilds (`docker-compose build`)
- Server reboots (with `restart: unless-stopped`)
✅ **Direct access:**
- Files can be accessed from Windows Explorer at `D:\AppData\*`
- Can be backed up using Windows Backup, robocopy, or any backup software
- Can be edited directly on the host (changes visible in container immediately)
⚠️ **Data does NOT survive:**
- Deleting the host directories (`D:\AppData\*`)
- Formatting the D: drive
- Without regular backups, hardware failures
## Production Checklist
Before deploying to production:
- [ ] Run `setup-bind-mounts.ps1 -GrantFullPermissions`
- [ ] Verify disk space on D: drive (at least 50 GB recommended)
- [ ] Set up scheduled backups (see `DOCKER_BIND_MOUNTS_SETUP.md`)
- [ ] Replace `Everyone` with specific service account for permissions
- [ ] Enable NTFS encryption for sensitive data (optional)
- [ ] Test container restart: `docker-compose restart`
- [ ] Test data persistence: Create a test file, restart container, verify file exists
- [ ] Configure monitoring for disk space usage
## Security Recommendations
1. **Restrict permissions** (production):
```powershell
# Replace Everyone with specific account
icacls "D:\AppData\Faces" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
icacls "D:\AppData\Storage" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
icacls "D:\AppData\Logs" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
```
2. **Enable encryption** for sensitive data:
```powershell
cipher /e "D:\AppData\Faces"
cipher /e "D:\AppData\Storage"
```
3. **Set up audit logging:**
```powershell
auditpol /set /subcategory:"File System" /success:enable /failure:enable
```
## Backup Strategy
### Scheduled Backup (Recommended)
```powershell
# Create daily backup at 2 AM
$action = New-ScheduledTaskAction -Execute "robocopy" -Argument '"D:\AppData" "D:\Backups\AppData" /MIR /Z /LOG:"D:\Backups\backup.log"'
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "GozareshgirBackup" -Description "Daily backup of Gozareshgir data"
```
### Manual Backup
```powershell
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
robocopy "D:\AppData" "D:\Backups\AppData_$timestamp" /MIR /Z
```
## Troubleshooting
### Issue: Container starts but files not appearing
**Solution:**
```powershell
# Check mount points
docker inspect gozareshgir-servicehost --format='{{json .Mounts}}' | ConvertFrom-Json
# Verify directories exist
Test-Path D:\AppData\Faces
Test-Path D:\AppData\Storage
Test-Path D:\AppData\Logs
```
### Issue: Permission denied errors
**Solution:**
```powershell
# Re-grant permissions
icacls "D:\AppData\Faces" /grant Everyone:F /T
icacls "D:\AppData\Storage" /grant Everyone:F /T
icacls "D:\AppData\Logs" /grant Everyone:F /T
```
### Issue: Out of disk space
**Solution:**
```powershell
# Check disk usage
Get-ChildItem D:\AppData -Recurse | Measure-Object -Property Length -Sum
# Clean old log files (example: older than 30 days)
Get-ChildItem D:\AppData\Logs -Recurse -File | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | Remove-Item
```
## Support & Documentation
- **Full Documentation:** `DOCKER_BIND_MOUNTS_SETUP.md`
- **Quick Reference:** `QUICK_REFERENCE.md`
- **Setup Script:** `setup-bind-mounts.ps1`
## Migration from Docker Volumes (If applicable)
If you previously used Docker volumes, migrate the data:
```powershell
# 1. Stop the container
docker-compose down
# 2. Copy data from old volumes to host
docker run --rm -v old_volume_name:/source -v D:/AppData/Storage:/dest alpine cp -av /source/. /dest/
# 3. Start with new bind mounts
docker-compose up -d
```
---
**Configuration Date:** January 2026
**Tested On:** Windows Server 2019/2022 with Docker Desktop
**Status:** ✅ Production Ready

View File

@@ -1,7 +1,6 @@
using System;
using _0_Framework.Application;
using _0_Framework.Domain;
using CompanyManagment.App.Contracts.AndroidApkVersion;
namespace Company.Domain.AndroidApkVersionAgg;
@@ -9,17 +8,14 @@ public class AndroidApkVersion:EntityBase
{
private AndroidApkVersion () { }
public AndroidApkVersion( string versionName,string versionCode, IsActive isActive, string path, ApkType apkType, bool isForce = false)
public AndroidApkVersion( string versionName,string versionCode, IsActive isActive, string path)
{
VersionName = versionName;
VersionCode = versionCode;
IsActive = isActive;
Path = path;
ApkType = apkType;
IsForce = isForce;
var appName = apkType == ApkType.WebView ? "Gozareshgir-WebView" : "Gozareshgir-FaceDetection";
Title = $"{appName}-{versionName}-{CreationDate:g}";
Title = $"Gozareshgir-{versionName}-{CreationDate:g}";
}
public string Title { get; private set; }
@@ -27,9 +23,6 @@ public class AndroidApkVersion:EntityBase
public string VersionCode{ get; private set; }
public IsActive IsActive { get; private set; }
public string Path { get; set; }
public ApkType ApkType { get; private set; }
public bool IsForce { get; private set; }
public void Active()
{
@@ -40,4 +33,4 @@ public class AndroidApkVersion:EntityBase
{
IsActive = IsActive.False;
}
}
}

View File

@@ -1,14 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using _0_Framework_b.Domain;
using CompanyManagment.App.Contracts.AndroidApkVersion;
namespace Company.Domain.AndroidApkVersionAgg;
public interface IAndroidApkVersionRepository:IRepository<long,AndroidApkVersion>
{
IQueryable<AndroidApkVersion> GetActives(ApkType apkType);
AndroidApkVersion GetLatestActive(ApkType apkType);
IQueryable<AndroidApkVersion> GetActives();
void Remove(AndroidApkVersion entity);
System.Threading.Tasks.Task<string> GetLatestActiveVersionPath(ApkType apkType);
System.Threading.Tasks.Task<string> GetLatestActiveVersionPath();
}

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