Merge branch 'master' into Feature/InstitutionContract/upgrade

# Conflicts:
#	Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs
#	Company.Domain/InstitutionContractAgg/InstitutionContract.cs
#	ServiceHost/Areas/Admin/Controllers/institutionContractController.cs
This commit is contained in:
2025-10-21 14:45:22 +03:30
54 changed files with 24121 additions and 513 deletions

View File

@@ -1,5 +1,6 @@
using Company.Domain.AdminMonthlyOverviewAgg;
using Company.Domain.AndroidApkVersionAgg;
using Company.Domain.AuthorizedBankDetailsAgg;
using Company.Domain.BankAgg;
using Company.Domain.BillAgg;
using Company.Domain.Board;
@@ -201,6 +202,9 @@ public class CompanyContext : DbContext
public DbSet<InstitutionContractContactInfoTemp> InstitutionContractContactInfoTemps { get; set; }
public DbSet<AuthorizedBankDetails> AuthorizedBankDetails { get; set; }
#endregion
#region Pooya
@@ -309,7 +313,6 @@ public class CompanyContext : DbContext
public DbSet<Employer> Employers { get; set; }
public CompanyContext(DbContextOptions<CompanyContext> options) :base(options)
{

View File

@@ -0,0 +1,34 @@
using Company.Domain.AuthorizedBankDetailsAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace CompanyManagment.EFCore.Mapping
{
public class AuthorizedBankDetailsMapping : IEntityTypeConfiguration<AuthorizedBankDetails>
{
public void Configure(EntityTypeBuilder<AuthorizedBankDetails> builder)
{
builder.ToTable("AuthorizedBankDetails");
builder.HasKey(x => x.id);
builder.Property(x => x.CardNumber).HasMaxLength(50);
builder.Property(x => x.AccountNumber).HasMaxLength(50);
builder.Property(x => x.IBan).HasMaxLength(50);
builder.Property(x => x.BankName).HasMaxLength(100);
// Configure owners as owned entities (value objects)
builder.OwnsMany(x => x.OwnersList, ownersBuilder =>
{
ownersBuilder.ToTable("AuthorizedBankDetailsOwners");
ownersBuilder.WithOwner().HasForeignKey("AuthorizedBankDetailsId");
ownersBuilder.Property<int>("Id").ValueGeneratedOnAdd();
ownersBuilder.HasKey("Id");
ownersBuilder.Property(x => x.FName).HasMaxLength(100);
ownersBuilder.Property(x => x.LName).HasMaxLength(100);
ownersBuilder.Property(x => x.NationalIdentifier).HasMaxLength(20);
ownersBuilder.Property(x => x.CustomerType).HasMaxLength(50);
});
}
}
}

View File

@@ -0,0 +1,49 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace CompanyManagment.EFCore.Migrations
{
/// <inheritdoc />
public partial class addauthenticatecolumnstoemployer : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "IdNumberSeri",
table: "Employers",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "IdNumberSerial",
table: "Employers",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsAuth",
table: "Employers",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IdNumberSeri",
table: "Employers");
migrationBuilder.DropColumn(
name: "IdNumberSerial",
table: "Employers");
migrationBuilder.DropColumn(
name: "IsAuth",
table: "Employers");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace CompanyManagment.EFCore.Migrations
{
/// <inheritdoc />
public partial class addauthorizedbankdetails : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AuthorizedBankDetails",
columns: table => new
{
id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CardNumber = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
AccountNumber = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
IBan = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
BankName = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table => { table.PrimaryKey("PK_AuthorizedBankDetails", x => x.id); });
migrationBuilder.CreateTable(
name: "AuthorizedBankDetailsOwners",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FName = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
LName = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
NationalIdentifier = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true),
CustomerType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
AuthorizedBankDetailsId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AuthorizedBankDetailsOwners", x => x.Id);
table.ForeignKey(
name: "FK_AuthorizedBankDetailsOwners_AuthorizedBankDetails_AuthorizedBankDetailsId",
column: x => x.AuthorizedBankDetailsId,
principalTable: "AuthorizedBankDetails",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AuthorizedBankDetailsOwners_AuthorizedBankDetailsId",
table: "AuthorizedBankDetailsOwners",
column: "AuthorizedBankDetailsId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AuthorizedBankDetailsOwners");
migrationBuilder.DropTable(
name: "AuthorizedBankDetails");
}
}
}

View File

@@ -90,6 +90,38 @@ namespace CompanyManagment.EFCore.Migrations
b.ToTable("AndroidApkVersions", (string)null);
});
modelBuilder.Entity("Company.Domain.AuthorizedBankDetailsAgg.AuthorizedBankDetails", b =>
{
b.Property<long>("id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("id"));
b.Property<string>("AccountNumber")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("BankName")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("CardNumber")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("IBan")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("id");
b.ToTable("AuthorizedBankDetails", (string)null);
});
modelBuilder.Entity("Company.Domain.AuthorizedPersonAgg.AuthorizedPerson", b =>
{
b.Property<long>("id")
@@ -3209,6 +3241,9 @@ namespace CompanyManagment.EFCore.Migrations
b.Property<long>("InstitutionContractId")
.HasColumnType("bigint");
b.Property<long>("LawId")
.HasColumnType("bigint");
b.Property<DateTime>("VerificationCreation")
.HasColumnType("datetime2");
@@ -6779,9 +6814,18 @@ namespace CompanyManagment.EFCore.Migrations
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<string>("IdNumberSeri")
.HasColumnType("nvarchar(max)");
b.Property<string>("IdNumberSerial")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<bool>("IsAuth")
.HasColumnType("bit");
b.Property<string>("IsLegal")
.HasMaxLength(10)
.HasColumnType("nvarchar(10)");
@@ -6861,6 +6905,48 @@ namespace CompanyManagment.EFCore.Migrations
b.ToTable("EmployerWorkshop");
});
modelBuilder.Entity("Company.Domain.AuthorizedBankDetailsAgg.AuthorizedBankDetails", b =>
{
b.OwnsMany("Company.Domain.AuthorizedBankDetailsAgg.AuthorizedBankDetailsOwner", "OwnersList", b1 =>
{
b1.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<int>("Id"));
b1.Property<long>("AuthorizedBankDetailsId")
.HasColumnType("bigint");
b1.Property<string>("CustomerType")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b1.Property<string>("FName")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b1.Property<string>("LName")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b1.Property<string>("NationalIdentifier")
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b1.HasKey("Id");
b1.HasIndex("AuthorizedBankDetailsId");
b1.ToTable("AuthorizedBankDetailsOwners", (string)null);
b1.WithOwner()
.HasForeignKey("AuthorizedBankDetailsId");
});
b.Navigation("OwnersList");
});
modelBuilder.Entity("Company.Domain.Board.Board", b =>
{
b.HasOne("Company.Domain.BoardType.BoardType", "BoardType")

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using _0_Framework.Application;
using _0_Framework_b.InfraStructure;
using Company.Application.Contracts.AuthorizedBankDetails;
using Company.Domain.AuthorizedBankDetailsAgg;
using Microsoft.EntityFrameworkCore;
namespace CompanyManagment.EFCore.Repository
{
public class AuthorizedBankDetailsRepository : RepositoryBase<long, AuthorizedBankDetails>, IAuthorizedBankDetailsRepository
{
private readonly CompanyContext _context;
public AuthorizedBankDetailsRepository(CompanyContext context) : base(context)
{
_context = context;
}
public EditAuthorizedBankDetails GetDetails(long id)
{
var authorizedBankDetails = _context.AuthorizedBankDetails
.Include(x => x.OwnersList)
.FirstOrDefault(x => x.id == id);
if (authorizedBankDetails == null)
return new EditAuthorizedBankDetails();
var result = new EditAuthorizedBankDetails
{
Id = authorizedBankDetails.id,
CardNumber = authorizedBankDetails.CardNumber,
AccountNumber = authorizedBankDetails.AccountNumber,
IBan = authorizedBankDetails.IBan,
BankName = authorizedBankDetails.BankName,
OwnersList = authorizedBankDetails.OwnersList.Select(o => new AuthorizedBankDetailsOwnerViewModel
{
FName = o.FName,
LName = o.LName,
NationalIdentifier = o.NationalIdentifier,
CustomerType = o.CustomerType
}).ToList()
};
return result;
}
public List<AuthorizedBankDetailsViewModel> Search(AuthorizedBankDetailsSearchModel searchModel)
{
var query = _context.AuthorizedBankDetails
.Include(x => x.OwnersList)
.Select(x => new AuthorizedBankDetailsViewModel
{
Id = x.id,
CardNumber = x.CardNumber,
AccountNumber = x.AccountNumber,
IBan = x.IBan,
});
if (!string.IsNullOrWhiteSpace(searchModel.CardNumber))
query = query.Where(x => x.CardNumber.Contains(searchModel.CardNumber));
if (!string.IsNullOrWhiteSpace(searchModel.AccountNumber))
query = query.Where(x => x.AccountNumber.Contains(searchModel.AccountNumber));
if (!string.IsNullOrWhiteSpace(searchModel.IBan))
query = query.Where(x => x.IBan.Contains(searchModel.IBan));
// if (!string.IsNullOrWhiteSpace(searchModel.BankName))
// query = query.Where(x => x.BankName.Contains(searchModel.BankName));
if (!string.IsNullOrWhiteSpace(searchModel.NationalIdentifier))
query = query.Where(x =>
_context.AuthorizedBankDetails
.Include(a => a.OwnersList)
.Any(a => a.id == x.Id &&
a.OwnersList.Any(o => o.NationalIdentifier.Contains(searchModel.NationalIdentifier))));
return query.OrderByDescending(x => x.Id).ToList();
}
public AuthorizedBankDetailsViewModel GetByIban(string iban)
{
return _context.AuthorizedBankDetails
.Include(x => x.OwnersList)
.Where(x => x.IBan == iban)
.Select(x => new AuthorizedBankDetailsViewModel
{
Id = x.id,
CardNumber = x.CardNumber,
AccountNumber = x.AccountNumber,
IBan = x.IBan,
BankName = x.BankName,
NationalIdentifier = x.OwnersList.FirstOrDefault().NationalIdentifier,
Owners = x.OwnersList.Select(o=> new AuthorizedBankDetailsOwnerViewModel()
{
FName = o.FName,
LName = o.LName,
NationalIdentifier = o.NationalIdentifier,
CustomerType = o.CustomerType
}).ToList()
})
.FirstOrDefault();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AccountManagement.Application.Contracts.SubAccount;
using ZstdSharp.Unsafe;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace CompanyManagment.EFCore.Repository;
@@ -266,16 +267,26 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
public async Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel)
{
var contractingParty = await _context.PersonalContractingParties
.FirstOrDefaultAsync(x=>x.id == contractingPartyId);
if (contractingParty == null)
throw new NotFoundException("طرف حساب یافت نشد");
var financialStatement = await _context.FinancialStatments
.Include(x=>x.FinancialTransactionList)
.FirstOrDefaultAsync(x=>x.ContractingPartyId == contractingPartyId);
if (financialStatement == null)
{
throw new NotFoundException("وضعیت مالی مورد نظر یافت نشد");
financialStatement = new FinancialStatment(contractingPartyId,contractingParty.FName+" "+contractingParty.LName);
await _context.AddAsync(financialStatement);
await _context.SaveChangesAsync();
}
bool searched = false;
#region Search
@@ -323,6 +334,71 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
}
#endregion
double balance = 0;
// var list = financialStatement.FinancialTransactionList.Select(t =>
// {
// if (!searched)
// {
// if (t.TypeOfTransaction == "debt")
// {
// balance += t.Deptor;
// }
// else
// {
// balance -= t.Creditor;
// }
// }
// return new FinancialTransactionDetailViewModel()
// {
// Id = t.id,
// DateTimeGr = t.TdateGr,
// DateFa = t.TdateGr.ToFarsi(),
// TimeFa = $"{t.TdateGr:HH:mm}",
// Description = t.DescriptionOption + " " + t.Description,
// Debtor = t.Deptor,
// Creditor = t.Creditor,
// Balance = balance,
// Type = t.TypeOfTransaction == "debt"
// ? FinancialTransactionType.Debt
// : FinancialTransactionType.Credit,
// TypeStr = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد"
// };
// }).OrderByDescending(t => t.DateTimeGr).ToList();
var list = new List<FinancialTransactionDetailViewModel>();
foreach (var financialTransaction in financialStatement.FinancialTransactionList.OrderBy(t=>t.TdateGr))
{
if (!searched)
{
if (financialTransaction.TypeOfTransaction == "debt")
{
balance += financialTransaction.Deptor;
}
else
{
balance -= financialTransaction.Creditor;
}
}
var item = new FinancialTransactionDetailViewModel()
{
Id = financialTransaction.id,
DateTimeGr = financialTransaction.TdateGr,
DateFa = financialTransaction.TdateGr.ToFarsi(),
TimeFa = $"{financialTransaction.TdateGr:HH:mm}",
Description = financialTransaction.DescriptionOption + " " + financialTransaction.Description,
Debtor = financialTransaction.Deptor,
Creditor = financialTransaction.Creditor,
Balance = balance,
Type = financialTransaction.TypeOfTransaction == "debt"
? FinancialTransactionType.Debt
: FinancialTransactionType.Credit,
TypeStr = financialTransaction.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد"
};
list.Add(item);
}
list.Reverse();
var res = new FinancialStatmentDetailsByContractingPartyViewModel()
{
Id = financialStatement.id,
@@ -330,35 +406,7 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
TotalCredit = financialStatement.FinancialTransactionList.Sum(x => x.Creditor),
TotalDebt = financialStatement.FinancialTransactionList.Sum(x => x.Deptor),
ContractingPartyName = financialStatement.ContractingPartyName,
List = financialStatement.FinancialTransactionList.Select(t =>
{
if (!searched)
{
if (t.TypeOfTransaction == "debt")
{
balance += t.Deptor;
}
else
{
balance -= t.Creditor;
}
}
return new FinancialTransactionDetailViewModel()
{
Id = t.id,
DateTimeGr = t.TdateGr,
DateFa = t.TdateGr.ToFarsi(),
TimeFa = $"{t.TdateGr:HH:mm}",
Description = t.DescriptionOption + " " + t.Description,
Debtor = t.Deptor,
Creditor = t.Creditor,
Balance = balance,
Type = t.TypeOfTransaction == "debt"
? FinancialTransactionType.Debt
: FinancialTransactionType.Credit,
TypeStr = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد"
};
}).OrderByDescending(t => t.DateTimeGr).ToList(),
List = list,
};
return res;
}

View File

@@ -1088,6 +1088,11 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
joinedQuery = joinedQuery.Where(x =>
x.contractingParty.RepresentativeFullName.Contains(keyword) ||
(x.contractingParty.FName + " " + x.contractingParty.LName).Contains(keyword) ||
(x.contractingParty.IsLegal == "حقیقی" ? x.contractingParty.SureName == null
? x.contractingParty.FName + " " + x.contractingParty.LName
: x.contractingParty.FName + " " + x.contractingParty.LName + " " + x.contractingParty.SureName
: x.contractingParty.SureName == null ? x.contractingParty.LName
: x.contractingParty.LName + " " + x.contractingParty.SureName).Contains(keyword)||
x.contractingParty.Employers.Any(e =>
e.FullName.Contains(keyword) ||
e.WorkshopEmployers.Any(we =>
@@ -1825,7 +1830,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
public async Task<InstitutionContract> GetByPublicIdAsync(Guid id)
{
return await _context.InstitutionContractSet.FirstOrDefaultAsync(x => x.PublicId == id);
return await _context.InstitutionContractSet.Include(x=>x.ContactInfoList).FirstOrDefaultAsync(x => x.PublicId == id);
}
#region Extension
@@ -2213,7 +2218,6 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
{
res.SetWorkshopId(x.WorkshopId);
}
return res;
}).ToList();
@@ -2592,6 +2596,60 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp);
}
public async Task<List<InstitutionContractSelectListViewModel>> GetInstitutionContractSelectList(string search,
string selected)
{
var contractingParties = _context.PersonalContractingParties.Select(x => new InstitutionContractSelectListViewModel()
{
Id = x.id,
Text = x.IsLegal == "حقیقی" ? x.SureName == null
? x.FName + " " + x.LName
: x.FName + " " + x.LName + " " + x.SureName
: x.SureName == null ? x.LName
: x.LName + " " + x.SureName
});
var workshops = _context.Workshops.Select(x => new InstitutionContractSelectListViewModel()
{
Id = x.id,
Text = x.WorkshopFullName
});
var employers = _context.Employers.Select(x => new InstitutionContractSelectListViewModel()
{
Id = x.id,
Text = x.FName + " " + x.LName
});
var representatives = _context.RepresentativeSet.Select(x => new InstitutionContractSelectListViewModel()
{
Id = x.id,
Text = x.FName + " " + x.LName
});
var res = contractingParties
.Union(workshops)
.Union(employers)
.Union(representatives);
InstitutionContractSelectListViewModel idSelected = null;
if (!string.IsNullOrWhiteSpace(selected))
{
idSelected = await res.FirstOrDefaultAsync(x => x.Text == selected);
}
if (!string.IsNullOrWhiteSpace(search))
{
res = res.Where(x => x.Text.Contains(search));
}
var list = await res.Take(100).ToListAsync();
if (idSelected != null)
list.Add(idSelected);
return list.DistinctBy(x => x.Id).ToList();
}
private InstitutionContractExtensionPaymentResponse CalculateInPersonPayment(
InstitutionContractExtensionPlanDetail selectedPlan, double baseAmount, double tenPercent,

View File

@@ -1517,7 +1517,9 @@ public class RollCallRepository : RepositoryBase<long, RollCall>, IRollCallRepos
StartDate = y.StartDate.Value.ToString("HH:mm"),
EndDate = y.EndDate!.Value.ToString("HH:mm"),
StartDateGr = y.StartDate.Value,
EndDateGr = y.EndDate.Value
EndDateGr = y.EndDate.Value,
EntryTimeDifferences = CalculateEntryTimeDifferences( y.EarlyEntryDuration, y.LateEntryDuration),
ExitTimeDifferences = CalculateExitTimeDifferences(y.EarlyExitDuration, y.LateExitDuration)
}),
TotalWorkingHoursSpan = new TimeSpan(rollCallsList.Where(y => x.Date == y.ShiftDate.Date)
.Sum(y => (y.EndDate!.Value - y.StartDate.Value).Ticks)),

View File

@@ -1181,6 +1181,33 @@ public class WorkshopRepository : RepositoryBase<long, Company.Domain.WorkshopAg
return list.DistinctBy(x => x.Id).ToList();
}
public int GetLastArchiveCode()
{
var archiveCodes = _context.Workshops
.Where(x => !string.IsNullOrEmpty(x.ArchiveCode))
.Select(x => x.ArchiveCode)
.ToList();
int maxArchiveCode = 0;
foreach (var code in archiveCodes)
{
// Remove "b-" prefix if exists
string cleanCode = code.StartsWith("b-") ? code.Substring(2) : code;
// Try to parse the clean code to an integer
if (int.TryParse(cleanCode, out int codeValue))
{
if (codeValue > maxArchiveCode)
{
maxArchiveCode = codeValue;
}
}
}
return maxArchiveCode;
}
#endregion
#region NewByHeydari
//public List<WorkshopViewModel> GetWorkshopByWorkshopIds(List<long> workshopIds)

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
@@ -7,6 +9,7 @@ using Newtonsoft.Json;
using CompanyManagment.App.Contracts.AuthorizedPerson;
using _0_Framework.Application;
using _0_Framework.Application.UID;
using Company.Application.Contracts.AuthorizedBankDetails;
namespace CompanyManagment.EFCore.Services;
@@ -14,15 +17,21 @@ public class UidService : IUidService
{
private readonly HttpClient _httpClient;
private readonly IAuthorizedPersonApplication _authorizedPersonApplication;
private const string BaseUrl = "https://json-api.uid.ir/api/inquiry/";
private readonly IAuthorizedBankDetailsApplication _authorizedBankDetailsApplication;
private const string BaseUrl = "https://json-api.uid.ir/api/";
public const string BusinessToken = "5e03dd4e-999d-466f-92d8-7c0b1f66a8e9";
public const string BusinessId = "98ed67ca-d441-4978-a748-e8bebce010eb";
public UidService(IAuthorizedPersonApplication authorizedPersonApplication)
public UidService(IAuthorizedPersonApplication authorizedPersonApplication, IAuthorizedBankDetailsApplication authorizedBankDetailsApplication)
{
_httpClient = new HttpClient()
{
BaseAddress = new Uri(BaseUrl)
};
_authorizedPersonApplication = authorizedPersonApplication;
_authorizedBankDetailsApplication = authorizedBankDetailsApplication;
}
public async Task<PersonalInfoResponse> GetPersonalInfo(string nationalCode, string birthDate)
@@ -53,7 +62,7 @@ public class UidService : IUidService
try
{
var requestResult = await _httpClient.PostAsync("person/v2", contentType);
var requestResult = await _httpClient.PostAsync("inquiry/person/v2", contentType);
if (!requestResult.IsSuccessStatusCode)
return null;
var responseResult = await requestResult.Content.ReadFromJsonAsync<PersonalInfoResponse>();
@@ -138,11 +147,134 @@ public class UidService : IUidService
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
var requestResult = await _httpClient.PostAsync("mobile/owner/v2", contentType);
var requestResult = await _httpClient.PostAsync("inquiry/mobile/owner/v2", contentType);
if (!requestResult.IsSuccessStatusCode)
return null;
var responseResult = await requestResult.Content.ReadFromJsonAsync<MatchMobileWithNationalCodeResponse>();
return responseResult;
}
public async Task<IbanInquiryResponse> IbanInquiry(string iban)
{
// First check if bank details exist in database
var existingBankDetails = _authorizedBankDetailsApplication.GetByIban(iban);
if (existingBankDetails != null)
{
// Return data from database instead of calling API
return CreateIbanInquiryResponseFromDatabase(existingBankDetails);
}
// If not found in database, call UID API
var request = new
{
iban,
requestContext = new UidRequestContext()
};
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
try
{
var requestResult = await _httpClient.PostAsync("inquiry/iban/v2", contentType);
requestResult.EnsureSuccessStatusCode();
var responseResult = await requestResult.Content.ReadFromJsonAsync<IbanInquiryResponse>();
if (responseResult.ResponseContext.Status.Code == 0)
{
var entity = new CreateAuthorizedBankDetails
{
IBan = iban,
AccountNumber = responseResult?.AccountBasicInformation?.AccountNumber ?? "",
BankName = responseResult?.AccountBasicInformation?.BankInformation?.BankName ?? "",
OwnersList = responseResult?.Owners.Select(x=> new CreateAuthorizedBankDetailsOwner()
{
FName = x.FirstName,
LName = x.LastName,
NationalIdentifier = x.NationalIdentifier,
CustomerType = x.CustomerType
}).ToList() ?? []
};
_authorizedBankDetailsApplication.Create(entity);
}
return responseResult;
}
catch
{
return new IbanInquiryResponse
{
ResponseContext = new ResponseContext(new UidStatus(14, "خطا در دریافت اطلاعات از سرویس"))
};
}
}
private IbanInquiryResponse CreateIbanInquiryResponseFromDatabase(AuthorizedBankDetailsViewModel bankDetails)
{
var accountBasicInfo = new IbanInquiryAccountBasicInformation
{
Iban = bankDetails.IBan,
AccountNumber = bankDetails.AccountNumber,
BankInformation = new IbanInquiryBankInformation
{
BankName = bankDetails.BankName
},
AccountStatus = "Active"
};
var owners = new List<IbanInquiryOwner>();
// Add owner information if available
if (bankDetails.Owners.Any())
{
var owner = bankDetails.Owners.First();
owners.Add(new IbanInquiryOwner
{
NationalIdentifier = owner.NationalIdentifier,
FirstName = owner.FName,
LastName = owner.LName,
CustomerType = owner.CustomerType
});
}
var responseContext = new ResponseContext(new UidStatus(0, "Success - از دیتابیس"));
return new IbanInquiryResponse
{
AccountBasicInformation = accountBasicInfo,
Owners = owners,
ResponseContext = responseContext
};
}
public async Task<AccountToIbanResponse> AccountToIban(string accountNumber, UidBanks bank)
{
var request = new
{
accountNumber,
bank,
requestContext = new UidRequestContext()
};
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
var requestResult = await _httpClient.PostAsync("account-to-iban", contentType);
requestResult.EnsureSuccessStatusCode();
var responseResult = await requestResult.Content.ReadFromJsonAsync<AccountToIbanResponse>();
return responseResult;
}
public async Task<CardToNumberResponse> CardToIban(string cardNumber)
{
var request = new
{
cardNumber,
requestContext = new UidRequestContext()
};
var json = JsonConvert.SerializeObject(request);
var contentType = new StringContent(json, Encoding.UTF8, "application/json");
var requestResult = await _httpClient.PostAsync("inquiry/card", contentType);
requestResult.EnsureSuccessStatusCode();
var responseResult = await requestResult.Content.ReadFromJsonAsync<CardToNumberResponse>();
return responseResult;
}
}