Files
Backend-Api/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs
2025-12-23 15:14:15 +03:30

5038 lines
232 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Application.Sms;
using _0_Framework.Exceptions;
using _0_Framework.InfraStructure;
using Company.Domain.ContarctingPartyAgg;
using Company.Domain.empolyerAgg;
using Company.Domain.FinancialStatmentAgg;
using Company.Domain.FinancialTransactionAgg;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.InstitutionContractAmendmentTempAgg;
using Company.Domain.InstitutionContractContactInfoAgg;
using Company.Domain.InstitutionContractExtensionTempAgg;
using Company.Domain.InstitutionPlanAgg;
using Company.Domain.SmsResultAgg;
using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.Employer;
using CompanyManagment.App.Contracts.FinancialStatment;
using CompanyManagment.App.Contracts.FinancilTransaction;
using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.InstitutionContractContactinfo;
using CompanyManagment.App.Contracts.Law;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
using PersianTools.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ContractingPartyAccount = Company.Domain.ContractingPartyAccountAgg.ContractingPartyAccount;
using FinancialStatment = Company.Domain.FinancialStatmentAgg.FinancialStatment;
using String = System.String;
using Workshop = Company.Domain.WorkshopAgg.Workshop;
namespace CompanyManagment.EFCore.Repository;
public class InstitutionContractRepository : RepositoryBase<long, InstitutionContract>, IInstitutionContractRepository
{
private readonly CompanyContext _context;
private readonly IEmployerRepository _employerRepository;
private readonly IWorkshopRepository _workshopRepository;
private readonly IMongoCollection<InstitutionContractExtensionTemp> _institutionExtensionTemp;
private readonly IMongoCollection<InstitutionContractAmendmentTemp> _institutionAmendmentTemp;
private readonly IPlanPercentageRepository _planPercentageRepository;
private readonly ISmsService _smsService;
private readonly ISmsResultRepository _smsResultRepository;
private readonly IFinancialTransactionRepository _financialTransactionRepository;
private readonly IFinancialStatmentRepository _financialStatmentRepository;
private readonly IHubContext<SendSmsHub> _hubContext;
private readonly InstitutionContratVerificationParty _firstParty = new()
{
Address = "رشت - خیابان حاجی آیاد - کوچه سپهدار - ساختمان داماش - واحد 17",
PhoneNumber = "09111485044",
CeoName = "سید حسن مصباح",
CompanyNameOrFullName = "نور داد مهر گستر کاسپین",
NationalCodeOrNationalId = "14009970584",
LegalType = LegalType.Legal
};
public InstitutionContractRepository(CompanyContext context, IEmployerRepository employerRepository,
IWorkshopRepository workshopRepository, IMongoDatabase database,
IPlanPercentageRepository planPercentageRepository, ISmsService smsService,
ISmsResultRepository smsResultRepository, IFinancialTransactionRepository financialTransactionRepository,
IFinancialStatmentRepository financialStatmentRepository, IHubContext<SendSmsHub> hubContext) : base(context)
{
_context = context;
_employerRepository = employerRepository;
_workshopRepository = workshopRepository;
_planPercentageRepository = planPercentageRepository;
_smsService = smsService;
_smsResultRepository = smsResultRepository;
_financialTransactionRepository = financialTransactionRepository;
_financialStatmentRepository = financialStatmentRepository;
_hubContext = hubContext;
_institutionExtensionTemp =
database.GetCollection<InstitutionContractExtensionTemp>("InstitutionContractExtensionTemp");
_institutionAmendmentTemp =
database.GetCollection<InstitutionContractAmendmentTemp>("InstitutionContractAmendmentTemp");
}
public EditInstitutionContract GetDetails(long id)
{
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
ContractAmount = x.ContractAmount,
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
HasValueAddedTax = x.HasValueAddedTax,
ValueAddedTax = x.ValueAddedTax,
})
.FirstOrDefault(x => x.Id == id);
}
public EditInstitutionContract GetFirstContract(long contractingPartyId, string typeOfContract)
{
return _context.InstitutionContractSet.Select(x => new EditInstitutionContract()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
RepresentativeId = x.RepresentativeId,
ContractingPartyId = x.ContractingPartyId,
ContractDateFa = x.ContractDateFa,
State = x.State,
City = x.City,
Address = x.Address,
Description = x.Description,
WorkshopManualCount = x.WorkshopManualCount,
EmployeeManualCount = x.EmployeeManualCount,
ContractAmountString = x.ContractAmount.ToMoney(),
DailyCompenseationString = x.DailyCompenseation.ToMoney(),
ObligationString = x.Obligation.ToMoney(),
TotalAmountString = x.TotalAmount.ToMoney(),
ExtensionNo = x.ExtensionNo,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature
})
.Where(x => x.ContractingPartyId == contractingPartyId && x.TypeOfContract == typeOfContract)
.OrderBy(x => x.ExtensionNo).FirstOrDefault();
}
public List<InstitutionContractViewModel> InstitutionContractsWithoutAccount()
{
var now = DateTime.Now;
var contractHasClientAccountList = _context.InstitutionContractSet.AsSplitQuery().Where(x =>
x.IsActiveString == "true" && x.ContractStartGr <= now && x.ContractEndGr >= now)
.Join(_context.ContractingPartyAccounts,
contract => contract.ContractingPartyId,
acc => acc.PersonalContractingPartyId,
((contract, account) => new { contract, account })).Select(x => x.contract);
var allActiveContracts = _context.InstitutionContractSet.Where(x =>
x.IsActiveString == "true" && x.ContractStartGr <= now && x.ContractEndGr >= now);
var contractWithoutAccountList = allActiveContracts.Except(contractHasClientAccountList);
return contractWithoutAccountList.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount.ToMoney(),
TotalAmount = x.TotalAmount.ToMoney(),
SearchAmount = x.ContractAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
}).ToList();
}
public List<InstitutionContractViewModel> ContractWithoutValidContactInfo()
{
var now = DateTime.Now;
var contractHasContactInfo = _context.InstitutionContractSet.AsSplitQuery().Where(x =>
x.IsActiveString == "true" && x.ContractStartGr <= now && x.ContractEndGr >= now)
.Join(_context.InstitutionContractContactInfos,
contract => contract.id,
contactInfo => contactInfo.InstitutionContractId,
((contract, contactInfo) => new { contract, contactInfo }))
.Where(x => x.contactInfo.SendSms && x.contactInfo.Position == "طرف قرارداد" &&
x.contactInfo.PhoneType == "شماره همراه")
.Select(x => x.contract);
var allvalidCcntactInfoContracts = _context.InstitutionContractSet.Where(x =>
x.IsActiveString == "true" && x.ContractStartGr <= now && x.ContractEndGr >= now);
var contractWithoutAccountList = allvalidCcntactInfoContracts.Except(contractHasContactInfo);
return contractWithoutAccountList.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount.ToMoney(),
TotalAmount = x.TotalAmount.ToMoney(),
SearchAmount = x.ContractAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
}).ToList();
}
public List<InstitutionContractViewModel> Search(InstitutionContractSearchModel searchModel)
{
//var stored = _context.InstitutionContractSet.FromSqlInterpolated($"SelectQuery_InstitutionContract").AsNoTracking()
// .ToList();
var query = _context.InstitutionContractSet.Select(x => new InstitutionContractViewModel()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount.ToMoney(),
TotalAmount = x.TotalAmount.ToMoney(),
SearchAmount = x.ContractAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature
});
if (searchModel.Id != 0)
query = query.Where(x => x.Id == searchModel.Id);
if (searchModel.RepresentativeId != 0)
query = query.Where(x => x.RepresentativeId == searchModel.RepresentativeId);
if (searchModel.ContractingPartyId != 0)
query = query.Where(x => x.ContractingPartyId == searchModel.ContractingPartyId);
if (!string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
!string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start && x.SearchAmount <= end);
}
if (!string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start);
}
if (string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
!string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start);
query = query.Where(x =>
x.SearchAmount <= end);
}
if (searchModel.IsActiveString == null)
{
query = query.Where(x => x.IsActiveString == "true" || x.IsActiveString == "blue");
}
if (searchModel.IsActiveString == "false")
{
query = query.Where(x => x.IsActiveString == "false");
}
else if (searchModel.IsActiveString == "both")
{
query = query.Where(x =>
x.IsActiveString == "false" || x.IsActiveString == "true" || x.IsActiveString == "blue");
}
if (searchModel.OfficialCompany == "Official")
query = query.Where(x => x.OfficialCompany == "Official");
if (searchModel.OfficialCompany == "NotOfficial")
query = query.Where(x => x.OfficialCompany == "NotOfficial");
if (searchModel.TypeOfContract == "both")
{
query = query.Where(x => x.TypeOfContract == "JobRelation" || x.TypeOfContract == "JobRelation");
}
else if (searchModel.TypeOfContract == "JobRelation" || string.IsNullOrWhiteSpace(searchModel.TypeOfContract))
{
query = query.Where(x => x.TypeOfContract == "JobRelation");
}
else if (searchModel.TypeOfContract == "taxAndFinancial")
{
query = query.Where(x => x.TypeOfContract == "taxAndFinancial");
}
if (searchModel.Signature == "2")
{
query = query.Where(x => x.Signature == "0" || x.Signature == "1");
}
if (searchModel.Signature == "1")
{
query = query.Where(x => x.Signature == "1");
}
else if (searchModel.Signature == "0")
{
query = query.Where(x => x.Signature == "0");
}
//var sumList = query.Select(x => x.SearchAmount).ToList();
//double sum = 0;
//foreach (var amount in sumList)
//{
// sum += amount;
//}
//Console.WriteLine(sum);
return query.OrderByDescending(x => x.Id).ToList();
}
public List<InstitutionContractViewModel> NewSearch(InstitutionContractSearchModel searchModel)
{
var timer = Stopwatch.StartNew();
var query = _context.InstitutionContractSet.AsSplitQuery()
.Select(x => new InstitutionContractViewModel()
{
Id = x.id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount.ToMoney(),
TotalAmount = x.TotalAmount.ToMoney(),
SearchAmount = x.ContractAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
WorkshopCount = "",
//WorkshopViewModels = _context.Workshops.Include(w=>w.WorkshopEmployers).Include(w => w.LeftWorks).Include(w => w.LeftWorkInsurances).Select(w => new WorkshopViewModel()
//{
// Id = w.id,
// WorkshopName = w.WorkshopName,
// WorkshopFullName = w.WorkshopFullName,
// ArchiveCode = w.ArchiveCode,
// ContractingPartId = w.WorkshopEmployers.Select(e => e.Employer.ContractingPartyId).FirstOrDefault(),
// LeftWorkIds = w.LeftWorks.Where(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate > DateTime.Now).Select(l => l.EmployeeId).ToList(),
// InsuranceLeftWorkIds = w.LeftWorkInsurances.Where(l => (l.StartWorkDate <= DateTime.Now && l.LeftWorkDate > DateTime.Now) || (l.StartWorkDate <= DateTime.Now && l.LeftWorkDate == null)).Select(l => l.EmployeeId).ToList(),
//}).Where(w=>w.ContractingPartId == x.ContractingPartyId).ToList(),
WorkshopIds = _context.Workshops
.Include(w => w.WorkshopEmployers).Select(w => new WorkshopViewModel()
{
Id = w.id,
ContractingPartId = w.WorkshopEmployers.Select(e => e.Employer.ContractingPartyId)
.FirstOrDefault(),
}).Where(c => c.ContractingPartId == x.ContractingPartyId).Select(w => w.Id).ToList(),
EmployerViewModels = _context.Employers.Where(e => e.ContractingPartyId == x.ContractingPartyId)
.Select(e =>
new EmployerViewModel()
{
Id = e.id,
FullName = e.FName + " " + e.LName,
}).GroupBy(e => e.Id).Select(e => e.First()).ToList(),
EmployerIds = _context.Employers.AsSplitQuery().Where(e => e.ContractingPartyId == x.ContractingPartyId)
.Select(e => e.id).ToList(),
EmployerNo = "",
EmployerName = "",
IsContractingPartyBlock =
_context.PersonalContractingParties.AsSplitQuery()
.Any(p => p.id == x.ContractingPartyId && p.IsBlock == "true")
? "true"
: "false",
BlockTimes = _context.PersonalContractingParties.AsSplitQuery().Any(p => p.id == x.ContractingPartyId)
? _context.PersonalContractingParties.FirstOrDefault(p => p.id == x.ContractingPartyId).BlockTimes
: 0,
});
if (searchModel.Id != 0)
query = query.Where(x => x.Id == searchModel.Id);
if (searchModel.RepresentativeId != 0)
query = query.Where(x => x.RepresentativeId == searchModel.RepresentativeId);
if (searchModel.ContractingPartyId != 0)
query = query.Where(x => x.ContractingPartyId == searchModel.ContractingPartyId);
if (!string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
!string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start && x.SearchAmount <= end);
}
if (!string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start);
}
if (string.IsNullOrWhiteSpace(searchModel.StartAmount) &&
!string.IsNullOrWhiteSpace(searchModel.EndAmount))
{
var start = Convert.ToDouble(searchModel.StartAmount);
var end = Convert.ToDouble(searchModel.EndAmount);
query = query.Where(x =>
x.SearchAmount >= start);
query = query.Where(x =>
x.SearchAmount <= end);
}
if (searchModel.IsActiveString == null)
{
query = query.Where(x => x.IsActiveString == "true" || x.IsActiveString == "blue");
}
if (searchModel.IsActiveString == "false")
{
query = query.Where(x => x.IsActiveString == "false");
}
else if (searchModel.IsActiveString == "both")
{
query = query.Where(x =>
x.IsActiveString == "false" || x.IsActiveString == "true" || x.IsActiveString == "blue");
}
if (searchModel.OfficialCompany == "Official")
query = query.Where(x => x.OfficialCompany == "Official");
if (searchModel.OfficialCompany == "NotOfficial")
query = query.Where(x => x.OfficialCompany == "NotOfficial");
if (searchModel.TypeOfContract == "both")
{
query = query.Where(x => x.TypeOfContract == "JobRelation" || x.TypeOfContract == "taxAndFinancial");
}
else if (searchModel.TypeOfContract == "JobRelation" || string.IsNullOrWhiteSpace(searchModel.TypeOfContract))
{
query = query.Where(x => x.TypeOfContract == "JobRelation");
}
else if (searchModel.TypeOfContract == "taxAndFinancial")
{
query = query.Where(x => x.TypeOfContract == "taxAndFinancial");
}
if (searchModel.WorkshopId != 0)
{
query = query.Where(x => x.WorkshopIds.Count > 0 && x.WorkshopIds.Any(e => e == searchModel.WorkshopId));
}
if (searchModel.EmployerId != 0)
{
query = query.Where(x => x.EmployerIds.Count > 0 && x.EmployerIds.Any(e => e == searchModel.EmployerId));
}
if (searchModel.Signature == "2")
{
query = query.Where(x => x.Signature == "0" || x.Signature == "1");
}
if (searchModel.Signature == "1")
{
query = query.Where(x => x.Signature == "1");
}
else if (searchModel.Signature == "0")
{
query = query.Where(x => x.Signature == "0");
}
var listQuery = query.ToList();
listQuery = listQuery.Select(x => new InstitutionContractViewModel()
{
Id = x.Id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount,
TotalAmount = x.TotalAmount,
SearchAmount = x.SearchAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
ExpireColor = ExpColor(x.ContractEndGr, x.SearchAmount,
x.IsActiveString).result,
IsExpier = ExpColor(x.ContractEndGr, x.SearchAmount,
x.IsActiveString).isExpier,
BalanceDouble = TotalBalance(x.ContractingPartyId).TotalBalanceDbl,
BalanceStr = TotalBalance(x.ContractingPartyId).TotalBalanceStr,
EmployerViewModels = x.EmployerViewModels,
EmployerNo = x.EmployerNo,
// EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(),
// WorkshopViewModels = x.WorkshopViewModels,
WorkshopCount = Convert.ToString(x.WorkshopIds.Count),
IsContractingPartyBlock = x.IsContractingPartyBlock,
BlockTimes = x.BlockTimes,
// EmployeeCount = ((x.WorkshopViewModels.Sum(w => w.LeftWorkIds.Count)) + (x.WorkshopViewModels.Sum(w => w.InsuranceLeftWorkIds.Count(c => !w.LeftWorkIds.Contains(c))))).ToString(),
// ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0,
WorkshopViewModels = _context.Workshops.AsSplitQuery().Where(w => x.WorkshopIds.Contains(w.id))
.Include(w => w.LeftWorks).Include(w => w.LeftWorkInsurances).Select(w => new WorkshopViewModel()
{
Id = w.id,
WorkshopName = w.WorkshopName,
WorkshopFullName = w.WorkshopFullName,
ArchiveCode = w.ArchiveCode,
ContractingPartId = w.WorkshopEmployers.Select(e => e.Employer.ContractingPartyId).FirstOrDefault(),
LeftWorkIds = w.LeftWorks
.Where(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate > DateTime.Now)
.Select(l => l.EmployeeId).ToList(),
InsuranceLeftWorkIds = w.LeftWorkInsurances
.Where(l => (l.StartWorkDate <= DateTime.Now && l.LeftWorkDate > DateTime.Now) ||
(l.StartWorkDate <= DateTime.Now && l.LeftWorkDate == null))
.Select(l => l.EmployeeId).ToList(),
}).ToList(),
}).ToList();
listQuery = listQuery.Select(x => new InstitutionContractViewModel()
{
Id = x.Id,
ContractNo = x.ContractNo,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
RepresentativeId = x.RepresentativeId,
RepresentativeName = x.RepresentativeName,
ContractingPartyName = x.ContractingPartyName,
ContractingPartyId = x.ContractingPartyId,
ContractAmount = x.ContractAmount,
TotalAmount = x.TotalAmount,
SearchAmount = x.SearchAmount,
IsActiveString = x.IsActiveString,
OfficialCompany = x.OfficialCompany,
TypeOfContract = x.TypeOfContract,
Signature = x.Signature,
ExpireColor = x.ExpireColor,
IsExpier = x.IsExpier,
BalanceDouble = x.BalanceDouble,
BalanceStr = x.BalanceStr,
EmployerViewModels = x.EmployerViewModels,
EmployerNo = x.EmployerNo,
EmployerName = x.EmployerViewModels.Select(n => n.FullName).FirstOrDefault(),
WorkshopViewModels = x.WorkshopViewModels,
WorkshopCount = x.WorkshopCount,
IsContractingPartyBlock = x.IsContractingPartyBlock,
BlockTimes = x.BlockTimes,
EmployeeCount =
((x.WorkshopViewModels.Sum(w => w.LeftWorkIds.Count)) + (x.WorkshopViewModels.Sum(w =>
w.InsuranceLeftWorkIds.Count(c => !w.LeftWorkIds.Contains(c))))).ToString(),
ArchiveCode = x.WorkshopViewModels.Count > 0 ? ArchiveCodeFinder(x.WorkshopViewModels) : 0,
}).OrderBy(x => x.WorkshopCount != "0" && string.IsNullOrWhiteSpace(x.ExpireColor))
.ThenBy(x => x.WorkshopCount == "0" && string.IsNullOrWhiteSpace(x.ExpireColor))
.ThenBy(x => x.IsExpier == "true")
.ThenBy(x => x.ExpireColor == "purple")
.ThenBy(x => x.ExpireColor == "black").ToList();
Console.WriteLine("test >>> " + timer.Elapsed);
return listQuery;
}
public List<InstitutionContractViewModel> PrintAll(List<long> id)
{
throw new NotImplementedException();
}
public InstitutionContractViewModel PrintOne(long id)
{
throw new NotImplementedException();
}
public void RemoveContract(long id)
{
var op = new OperationResult();
var institutionContarct = _context.InstitutionContractSet
.FirstOrDefault(x => x.id == id);
var prevInstitutionContracts = _context.InstitutionContractSet
.Where(x => x.ContractingPartyId == institutionContarct.ContractingPartyId)
.OrderByDescending(x => x.ContractEndGr).Skip(1).FirstOrDefault();
var transaction = _context.Database.BeginTransaction();
var contactInfo = _context.InstitutionContractContactInfos
.Where(x => x.InstitutionContractId == id)
.ToList();
if (contactInfo.Count > 0)
{
foreach (var item in contactInfo)
{
_context.InstitutionContractContactInfos.Remove(item);
_context.SaveChanges();
}
}
if (institutionContarct != null)
{
_context.InstitutionContractSet.Remove(institutionContarct);
_context.SaveChanges();
}
if (prevInstitutionContracts != null)
{
var now = DateTime.Now;
var financialStatement =
_context.FinancialStatments
.Include(x => x.FinancialTransactionList)
.FirstOrDefault(x => x.ContractingPartyId == institutionContarct.ContractingPartyId);
if (financialStatement != null)
{
var sumDebtor = financialStatement.FinancialTransactionList
.Sum(x => x.Deptor);
var sumCreditor = financialStatement.FinancialTransactionList
.Sum(x => x.Creditor);
var balance = sumDebtor - sumCreditor;
if (balance > 0 && prevInstitutionContracts.ContractEndGr < now)
{
prevInstitutionContracts.DeActiveBlue();
_context.SaveChanges();
}
}
}
transaction.Commit();
}
public void CreateContractingPartyAccount(long contractingPartyid, long accountId)
{
var create = new ContractingPartyAccount(contractingPartyid, accountId);
_context.ContractingPartyAccounts.Add(create);
_context.SaveChanges();
}
public double GetcontractAmount(int countPerson)
{
var planPercentage = _context.PlanPercentages.FirstOrDefault();
int contarctAndCheckoutPercent = 100;
int insurancePercent = 50;
int rollCallPercent = 100;
int customizeCkeckoutPercen = 50;
int contarctAndCheckoutInPersonPercent = 900;
int insuranceInPersonPercent = 500;
if (planPercentage != null)
{
contarctAndCheckoutPercent = planPercentage.ContractAndCheckoutPercent;
insurancePercent = planPercentage.InsurancePercent;
rollCallPercent = planPercentage.RollCallPercent;
customizeCkeckoutPercen = planPercentage.CustomizeCheckoutPercent;
contarctAndCheckoutInPersonPercent = planPercentage.ContractAndCheckoutInPersonPercent;
insuranceInPersonPercent = planPercentage.InsuranceInPersonPercent;
}
var dailyWageYearlySalery = _context.YearlySalaries.Include(i => i.YearlySalaryItemsList).FirstOrDefault(x =>
x.StartDate.Date <= DateTime.Now.Date && x.EndDate >= DateTime.Now.Date);
double res = 0;
if (countPerson > 0 && dailyWageYearlySalery != null)
{
var dailyWage = dailyWageYearlySalery.YearlySalaryItemsList.Where(x => x.ItemName == "مزد روزانه")
.Select(x => x.ItemValue).FirstOrDefault();
var plan = _context.InstitutionPlans.FirstOrDefault(x => x.CountPerson == countPerson);
if (plan != null)
{
//مبلغ قرارداد و تصفیه
var contarctAndCheckout = ((dailyWage * contarctAndCheckoutPercent) / 100) * countPerson *
plan.IncreasePercentage;
//خدمات بیمه
var insurance = ((dailyWage * insurancePercent) / 100) * countPerson *
plan.IncreasePercentage;
////خدمات حضور غیاب
//var rollCall = ((dailyWage * rollCallPercent) / 100) * countPerson *
// plan.IncreasePercentage;
////خدمات فیش حقوقی غیر رسمی
//var customizeCkeckout = ((dailyWage * customizeCkeckoutPercen) / 100) * countPerson *
// plan.IncreasePercentage;
//خدمات حضوری قرارداد و تصفیه
var contarctAndCheckoutInPerson =
((dailyWage * contarctAndCheckoutInPersonPercent) / 100) * countPerson *
plan.IncreasePercentage;
//خدمات حضوری بیمه
var insuranceInPerson = ((dailyWage * insuranceInPersonPercent) / 100) * countPerson *
plan.IncreasePercentage;
//جمع کل
res = contarctAndCheckout + insurance + contarctAndCheckoutInPerson + insuranceInPerson;
}
}
return res;
}
public (string result, string isExpier) ExpColor(DateTime contractEndGr, double contractAmount,
string isActiveString)
{
var now = DateTime.Now;
var nowFa = now.ToFarsi();
var endFa = nowFa.FindeEndOfMonth();
var endThisMontGr = endFa.ToGeorgianDateTime();
string result = "";
string isExpier = "false";
if (contractEndGr < now)
{
result = "black";
isExpier = "true";
}
if (contractEndGr >= now && contractEndGr <= endThisMontGr)
{
result = "red";
isExpier = "true";
}
if (contractAmount == 0)
{
result = "purple";
if ((contractEndGr >= now && contractEndGr <= endThisMontGr) || (contractEndGr < now))
{
isExpier = "true";
}
}
if (isActiveString == "blue")
{
result = "blue";
isExpier = "false";
}
return (result, isExpier);
}
#region ExteraMetods
public TotalbalancViewModel TotalBalance(long contractingPartyId)
{
var result = new TotalbalancViewModel();
var firstGetStatement = _context.FinancialStatments.Include(x => x.FinancialTransactionList)
.FirstOrDefault(x => x.ContractingPartyId == contractingPartyId);
if (firstGetStatement != null)
{
if (firstGetStatement.FinancialTransactionList != null)
{
var allTransactions = firstGetStatement.FinancialTransactionList;
allTransactions = allTransactions.OrderBy(x => x.TdateGr).ToList();
var debt = allTransactions.Sum(x => x.Deptor);
var credit = allTransactions.Sum(x => x.Creditor);
result.TotalBalanceDbl = debt - credit;
result.TotalBalanceStr = result.TotalBalanceDbl.ToMoney();
}
}
return result;
}
public int ArchiveCodeFinder(List<WorkshopViewModel> workshopViewModels)
{
var workshop = workshopViewModels.OrderBy(x => x.Id)?.ToList();
var arc = workshop.Select(x => new ArchiveCodConvertoint
{
ArchiveCodeInt = x.ArchiveCode.Substring(0, 1) == "b" ? 10000000 : x.ArchiveCode.ConvertToInt(),
}).OrderBy(x => x.ArchiveCodeInt).ToList();
var minArchiveCode = arc.Min(x => x.ArchiveCodeInt);
return minArchiveCode == 10000000 ? 0 : minArchiveCode;
}
#endregion
public InstitutionContract InstitutionContractByEmployerId(long employerId)
{
long contractingPryId = _context.Employers.FirstOrDefault(x => x.id == employerId)!.ContractingPartyId;
if (_context.PersonalContractingParties.Any(x => x.id == contractingPryId && x.IsBlock == "true"))
return new();
var contracts = _context.InstitutionContractSet.Where(x =>
x.ContractingPartyId == contractingPryId).ToList();
var contract = contracts.FirstOrDefault(x => x.IsActiveString != "false" &&
x.ContractStartGr.Date <= DateTime.Now.Date &&
x.ContractEndGr >= DateTime.Now.Date);
if (contract != null)
{
return contract;
}
else
{
var future = contracts.FirstOrDefault(x => x.IsActiveString != "false" &&
x.ContractStartGr.Date >= DateTime.Now.Date &&
x.ContractEndGr >= DateTime.Now.Date);
if (future != null)
return future;
return new();
}
}
/// <summary>
/// ایجاد سند مالی حضور غیاب
/// </summary>
/// <param name="now"></param>
/// <param name="endOfMonthGr"></param>
/// <param name="endOfMonth"></param>
/// <param name="description"></param>
#region RollcallServicCreateTransaction
public async Task RollCallServiceCreateTransaction()
{
DateTime now = DateTime.Now;
var nowFa = now.ToFarsi();
var endOfMonth = nowFa.FindeEndOfMonth();
DateTime endOfMonthGr = endOfMonth.ToGeorgianDateTime();
#region FindeNextMonth 1th
var year = Convert.ToInt32(endOfMonth.Substring(0, 4));
var month = Convert.ToInt32(endOfMonth.Substring(5, 2));
var nextM = new PersianDateTime(year, month, 1).AddMonths(1);
var nextMonthGr = ($"{nextM}").ToGeorgianDateTime();
var endOfCurrentMonth = (($"{endOfMonth.Substring(0, 8)}/01").FindeEndOfMonth()).ToGeorgianDateTime();
#endregion
#region GetAvtiveContracts
var institutionContracts = _context.InstitutionContractSet.Where(x => x.IsActiveString == "true").Select(x =>
new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
SearchAmount = x.ContractAmount,
TypeOfContract = x.TypeOfContract
}).Where(x =>
x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.SearchAmount > 0)
.ToList();
#endregion
#region GetFutureContracts
List<InstitutionContractViewModel> futureContracts = _context.InstitutionContractSet
.Where(x => x.IsActiveString == "true" &&
x.ContractStartGr == nextMonthGr && x.ContractAmount > 0)
.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
TypeOfContract = x.TypeOfContract,
ExtensionNo = x.ExtensionNo,
}).ToList();
#endregion
#region GetDectivedContractOnCurrentMonth
if (futureContracts.Any())
{
List<long> futureContractIds = futureContracts.Select(x => x.ContractingPartyId).ToList();
List<InstitutionContractViewModel> deatcivedContract = _context.InstitutionContractSet
.Where(x => x.IsActiveString == "false" && futureContractIds.Contains(x.ContractingPartyId) &&
x.ContractEndGr == endOfCurrentMonth && x.ContractAmount > 0)
.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
SearchAmount = x.ContractAmount,
TypeOfContract = x.TypeOfContract
}).ToList();
if (deatcivedContract.Any())
institutionContracts.AddRange(deatcivedContract);
}
List<long> exceptionContractingPartyIds = [30520, 30739];
institutionContracts = institutionContracts
.Where(x => !exceptionContractingPartyIds.Contains(x.ContractingPartyId)).ToList();
int counter = 0;
var rollcallServiceList =
_context.RollCallServices.Where(x => x.IsActiveString == "true").ToList();
var activeStatusDate = new DateTime(2121, 03, 21);
foreach (var item in institutionContracts)
{
//var isblock = contractingParty.IsBlock == "true" ? true : false;
var employers = _context.Employers.Where(x => x.ContractingPartyId == item.ContractingPartyId)
.Select(x => x.id);
var workshops = _context.WorkshopEmployers.Where(x => employers.Contains(x.EmployerId))
.Select(x => x.WorkshopId).Distinct().ToList();
var srvices =
rollcallServiceList.Where(x => workshops.Contains(x.WorkshopId)).ToList();
if (rollcallServiceList.Count > 0)
{
foreach (var rollCallService in srvices)
{
//var spaning = (int)(endOfMonthGr - rollCallService.StartService).TotalDays + 1;
int monthCounter = 0;
var currentMonthStart = ($"{(endOfMonthGr.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
var prevMonthEnd = currentMonthStart.AddDays(-1);
var prevMonthStart = ($"{(prevMonthEnd.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
var monthCurrent = endOfMonth.Substring(5, 2);
var yearCurrent = endOfMonth.Substring(0, 4);
var currentMonthName = monthCurrent.ToFarsiMonthByNumber();
var workshop = _context.Workshops.FirstOrDefault(x => x.id == rollCallService.WorkshopId);
string description = "";
//if (rollCallService.StartService <= prevMonthStart)
//{
// var monthPrev = prevMonthEnd.ToFarsi().Substring(5, 2);
// var yearPrev = prevMonthEnd.ToFarsi().Substring(0, 4);
// var prevMonthName = monthPrev.ToFarsiMonthByNumber();
// description =
// $"{prevMonthName} و {currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
// monthCounter = 2;
//}
//else if (rollCallService.StartService <= currentMonthStart &&
// rollCallService.StartService > prevMonthStart)
//{
// monthCounter = 1;
// description = $"{currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
//}
if (rollCallService.StartService <= currentMonthStart)
{
monthCounter = 1;
description = $"{currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
}
var employees =
_context.RollCallEmployees.Where(x => x.WorkshopId == rollCallService.WorkshopId)
.Select(x => x.id);
var employeeCount = _context.RollCallEmployeesStatus
.Where(x => employees.Contains(x.RollCallEmployeeId))
.Count(x => x.EndDate.Date == activeStatusDate.Date);
if (employeeCount > 0 && monthCounter > 0)
{
counter++;
var dailyWageYearlySalery = _context.YearlySalaries.Include(i => i.YearlySalaryItemsList)
.FirstOrDefault(x =>
x.StartDate.Date <= DateTime.Now.Date && x.EndDate >= DateTime.Now.Date);
var dailyWage = dailyWageYearlySalery.YearlySalaryItemsList
.Where(x => x.ItemName == "مزد روزانه")
.Select(x => x.ItemValue).FirstOrDefault();
var planPercentage = _context.PlanPercentages.FirstOrDefault();
var countPersonnel = employeeCount;
var planByCountPerson = _context.InstitutionPlans
.FirstOrDefault(x => x.CountPerson == countPersonnel);
var amountForOneMonth = (((dailyWage * planPercentage.RollCallPercent) / 100) *
planByCountPerson.CountPerson *
planByCountPerson.IncreasePercentage);
var amountWithoutTax = amountForOneMonth * monthCounter;
var tenPercent = amountWithoutTax * 10 / 100;
var totalAmonut = amountWithoutTax + tenPercent;
double roundFloor = Math.Floor(totalAmonut);
double result = Math.Ceiling(roundFloor / 10000.0) * 10000;
Console.WriteLine(counter + " - " + rollCallService.StartService.ToFarsi() + " - " +
rollCallService.WorkshopId + " - " + employeeCount +
$" - {totalAmonut} - round {result}");
var financialStatment =
_context.FinancialStatments.FirstOrDefault(x =>
x.ContractingPartyId == item.ContractingPartyId);
long financialStatementId = 0;
if (financialStatment != null)
{
financialStatementId = financialStatment.id;
}
else
{
var statement = new FinancialStatment(item.ContractingPartyId, item.ContractingPartyName);
_context.FinancialStatments.Add(statement);
_context.SaveChanges();
financialStatementId = statement.id;
}
var transaction = new FinancialTransaction(financialStatementId, endOfMonthGr, endOfMonth,
description,
"debt", "بابت سرویس حضور غیاب", result, 0, 0);
_context.FinancialTransactions.Add(transaction);
_context.SaveChanges();
//Console.WriteLine(" number : " + counter + " - " + rollCallService.StartService.ToFarsi() + " - WorkshopId : " + rollCallService.WorkshopId + " - monthCount : " + monthCounter + " - employeeCount : " + employeeCount + $" - Amount : {amountWithoutTax.ToMoney()}" + $" - ten : {tenPercent.ToMoney()} total : {totalAmonut.ToMoney()}");
}
}
}
}
#endregion
}
public async Task<PagedResult<GetInstitutionContractListItemsViewModel>> GetList(
InstitutionContractListSearchModel searchModel)
{
var query = _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.InitialWorkshops)
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.CurrentWorkshops)
.Include(x => x.ContactInfoList).AsNoTracking();
var now = DateTime.Today;
var nowFa = now.ToFarsi();
var endFa = nowFa.FindeEndOfMonth();
var endThisMontGr = endFa.ToGeorgianDateTime();
var joinedQuery = query.Join(_context.PersonalContractingParties
.Include(x => x.Employers)
.ThenInclude(x => x.WorkshopEmployers)
.ThenInclude(x => x.Workshop),
contract => contract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, contractingParty) => new { contract, contractingParty })
.Select(x => new
{
x.contract,
x.contractingParty,
StatusPriority =
x.contract.VerificationStatus == InstitutionContractVerificationStatus.PendingForVerify
? (int)InstitutionContractListStatus.PendingForVerify
: x.contract.IsActiveString == "blue"
? (int)InstitutionContractListStatus.DeactiveWithDebt
: x.contract.ContractEndGr < now
? (int)InstitutionContractListStatus.Deactive
: (x.contract.ContractEndGr >= now && x.contract.ContractEndGr <= endThisMontGr &&
!_context.InstitutionContractSet.Any(i =>
i.ContractingPartyId == x.contract.ContractingPartyId &&
x.contract.ExtensionNo + 1 <= i.ExtensionNo && i.IsActiveString == "true"))
? (int)InstitutionContractListStatus.PendingForRenewal
: x.contractingParty.IsBlock == "true"
? (int)InstitutionContractListStatus.Block
: x.contract.ContractAmount == 0
? (int)InstitutionContractListStatus.Free
: !x.contractingParty.Employers
.SelectMany(e => e.WorkshopEmployers.Select(we => we.Workshop)).Any()
? (int)InstitutionContractListStatus.WithoutWorkshop
: (int)InstitutionContractListStatus.Active
});
#region Search
if (!string.IsNullOrWhiteSpace(searchModel.EmployerOrWorkshopOrContractingPartyOrRepresentativeName))
{
var keyword = searchModel.EmployerOrWorkshopOrContractingPartyOrRepresentativeName;
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 =>
we.Workshop.WorkshopFullName.Contains(keyword)))
);
}
if (!string.IsNullOrWhiteSpace(searchModel.City))
{
joinedQuery = joinedQuery.Where(x => x.contract.City == searchModel.City);
}
if (!string.IsNullOrWhiteSpace(searchModel.Province))
{
joinedQuery = joinedQuery.Where(x => x.contract.State == searchModel.Province);
}
if (searchModel.AmountFrom > 0)
{
joinedQuery = joinedQuery.Where(x => x.contract.ContractAmount >= searchModel.AmountFrom);
}
if (searchModel.AmountTo > 0)
{
joinedQuery = joinedQuery.Where(x => x.contract.ContractAmount <= searchModel.AmountTo);
}
if (!string.IsNullOrWhiteSpace(searchModel.ContractDateFrom) &&
!string.IsNullOrWhiteSpace(searchModel.ContractDateTo))
{
if (!searchModel.ContractDateFrom.TryToGeorgianDateTime(out var dateFrom))
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
if (!searchModel.ContractDateTo.TryToGeorgianDateTime(out var dateTo))
{
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
}
if (dateFrom > dateTo)
{
throw new BadRequestException("تاریخ شروع نمیتواند بزرگ تر از تاریخ پایان باشد");
}
joinedQuery = joinedQuery.Where(x =>
x.contract.ContractStartGr <= dateTo && x.contract.ContractEndGr <= dateFrom);
}
if (searchModel.HasSignature != null)
{
var hasSignature = searchModel.HasSignature == true ? "1" : "0";
joinedQuery = joinedQuery.Where(x => x.contract.Signature == hasSignature);
}
if (searchModel.IsActive != null)
{
var isActiveStr = searchModel.IsActive == true ? "true" : "false";
joinedQuery = joinedQuery.Where(x =>
x.contract.IsActiveString == isActiveStr || x.contract.IsActiveString == "blue");
}
if (searchModel.Type != null)
{
var typeStr = searchModel.Type switch
{
InstitutionContractType.JobRelation => "JobRelation",
InstitutionContractType.TaxAndFinancial => "taxAndFinancial",
_ => throw new ArgumentOutOfRangeException()
};
joinedQuery = joinedQuery.Where(x => x.contract.TypeOfContract == typeStr);
}
if (searchModel.IsOfficial != null)
{
var isOfficialStr = searchModel.IsOfficial == true ? "Official" : "NotOfficial";
joinedQuery = joinedQuery.Where(x => x.contract.OfficialCompany == isOfficialStr);
}
if (searchModel.Status != null)
{
switch (searchModel.Status)
{
case InstitutionContractListStatus.DeactiveWithDebt:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.DeactiveWithDebt);
break;
case InstitutionContractListStatus.PendingForRenewal:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.PendingForRenewal);
break;
case InstitutionContractListStatus.Block:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Block);
break;
case InstitutionContractListStatus.Free:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Free);
break;
case InstitutionContractListStatus.WithoutWorkshop:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.WithoutWorkshop);
break;
case InstitutionContractListStatus.Active:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Active);
break;
case InstitutionContractListStatus.Deactive:
joinedQuery = joinedQuery.Where(x => x.contract.ContractEndGr < now);
break;
case InstitutionContractListStatus.PendingForVerify:
joinedQuery = joinedQuery.Where(x =>
x.contract.VerificationStatus == InstitutionContractVerificationStatus.PendingForVerify);
break;
}
}
else
{
joinedQuery = joinedQuery.Where(x => x.contract.IsActiveString != "blue");
}
#endregion
var endOfMonth = new DateTime(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month));
var orderedQuery = joinedQuery
.OrderBy(x =>
x.StatusPriority == (int)InstitutionContractListStatus.DeactiveWithDebt
? 0
: // DeactiveWithoutDebt
(x.StatusPriority == (int)InstitutionContractListStatus.PendingForRenewal)
? 1
: // PendingToRenewal
x.StatusPriority == (int)InstitutionContractListStatus.Block
? 2
: // Block
x.StatusPriority == (int)InstitutionContractListStatus.Free
? 3
: // Free
x.StatusPriority == (int)InstitutionContractListStatus.WithoutWorkshop
? 4
: // WithoutWorkshop
5 // Active
);
var list = await orderedQuery.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
var contractingPartyIds = list.Select(x => x.contractingParty.id).ToList();
var financialStatements = _context.FinancialStatments.Include(x => x.FinancialTransactionList)
.Where(x => contractingPartyIds.Contains(x.ContractingPartyId)).ToList();
var res = new PagedResult<GetInstitutionContractListItemsViewModel>()
{
TotalCount = await joinedQuery.CountAsync(),
List = list.Select(x =>
{
var workshops = x.contractingParty.Employers
.SelectMany(e => e.WorkshopEmployers.Select(we => we.Workshop)).DistinctBy(w => w.id).ToList();
var employers = x.contractingParty.Employers.ToList();
var arc = workshops.Select(w =>
w.ArchiveCode.Substring(0, 1) == "b"
? 10000000
: w.ArchiveCode.ConvertToInt()
).OrderBy(w => w).ToList();
var minArchiveCode = arc.Count > 0 ? arc.Min(a => a) : 0;
var archiveCode = minArchiveCode == 10000000 ? 0 : minArchiveCode;
var status = Enum.Parse<InstitutionContractListStatus>(x.StatusPriority.ToString());
List<InstitutionContractWorkshopBase> currentStateWorkshops = x.contract.WorkshopGroup?.CurrentWorkshops
.Cast<InstitutionContractWorkshopBase>().ToList();
var statement = financialStatements.FirstOrDefault(f => f.ContractingPartyId == x.contractingParty.id);
currentStateWorkshops?.AddRange(
x.contract.WorkshopGroup?.InitialWorkshops.Where(w => !w.WorkshopCreated) ?? []);
var workshopDetails = currentStateWorkshops?.Select(w =>
{
Workshop workshopSelected = null;
if (w.WorkshopId != null && workshops.Select(ww => ww.id).Contains(w.WorkshopId.Value))
{
workshopSelected = workshops.First(ww => ww.id == w.WorkshopId.Value);
}
return new InstitutionContractListWorkshop()
{
EmployeeCount = w.PersonnelCount,
Price = w.Price.ToMoney(),
WorkshopName = workshopSelected?.WorkshopName ?? w.WorkshopName,
WorkshopServices = new WorkshopServicesViewModel()
{
Contract = w.Services.Contract,
ContractInPerson = w.Services.ContractInPerson,
CustomizeCheckout = w.Services.CustomizeCheckout,
Insurance = w.Services.Insurance,
InsuranceInPerson = w.Services.InsuranceInPerson,
RollCall = w.Services.RollCall,
RollCallInPerson = w.Services.RollCallInPerson,
}
};
}).ToList() ?? [];
var employeesCount = _context.LeftWorkList
.Where(l => workshops.Select(w => w.id).Contains(l.WorkshopId))
.Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now);
return new GetInstitutionContractListItemsViewModel()
{
ContractAmount = x.contract.ContractAmountWithTax,
Balance = statement?.FinancialTransactionList.Sum(ft => ft.Deptor - ft.Creditor) ?? 0,
WorkshopsCount = workshops.Count(),
ContractStartFa = x.contract.ContractStartGr.ToFarsi(),
ContractEndFa = x.contract.ContractEndGr.ToFarsi(),
ContractingPartyName = x.contract.ContractingPartyName,
WorkshopNames = workshops.Select(w => w.WorkshopFullName).ToList(),
RepresentativeName = x.contractingParty.RepresentativeFullName,
HasSigniture = x.contract.Signature == "1",
Id = x.contract.id,
ContractNo = x.contract.ContractNo,
ArchiveNo = archiveCode.ToString(),
EmployeesCount = employeesCount,
EmployerNames = employers.Select(e => e.FullName).ToList(),
ListStatus = status,
IsExpired = x.contract.ContractEndGr <= endThisMontGr,
ContractingPartyId = x.contractingParty.id,
Workshops = workshopDetails,
IsInPersonContract = x.contract.WorkshopGroup?.CurrentWorkshops
.Any(y => y.Services.ContractInPerson) ?? true,
IsOldContract = x.contract.SigningType == InstitutionContractSigningType.Legacy
};
}).ToList()
};
return res;
}
public async Task<GetInstitutionContractListStatsViewModel> GetListStats(
InstitutionContractListSearchModel searchModel)
{
var query = _context.InstitutionContractSet
.Include(x => x.ContactInfoList);
var now = DateTime.Today;
var nowFa = now.ToFarsi();
var endFa = nowFa.FindeEndOfMonth();
var endThisMontGr = endFa.ToGeorgianDateTime();
var joinedQuery = query.Join(_context.PersonalContractingParties
.Include(x => x.Employers)
.ThenInclude(x => x.WorkshopEmployers)
.ThenInclude(x => x.Workshop),
contract => contract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, contractingParty) => new { contract, contractingParty })
.Join(_context.FinancialStatments.Include(x => x.FinancialTransactionList),
x => x.contractingParty.id,
statement => statement.ContractingPartyId,
(x, statement) => new { x.contractingParty, x.contract, statement })
.Select(x => new
{
x.contract,
x.contractingParty,
x.statement,
StatusPriority =
x.contract.IsActiveString == "blue"
? (int)InstitutionContractListStatus.DeactiveWithDebt
: x.contract.ContractEndGr < now
? (int)InstitutionContractListStatus.Deactive
: (x.contract.ContractEndGr >= now && x.contract.ContractEndGr <= endThisMontGr)
? (int)InstitutionContractListStatus.PendingForRenewal
: x.contractingParty.IsBlock == "true"
? (int)InstitutionContractListStatus.Block
: x.contract.ContractAmount == 0
? (int)InstitutionContractListStatus.Free
: !x.contractingParty.Employers
.SelectMany(e => e.WorkshopEmployers.Select(we => we.Workshop)).Any()
? (int)InstitutionContractListStatus.WithoutWorkshop
: (int)InstitutionContractListStatus.Active
});
#region Search
if (!string.IsNullOrWhiteSpace(searchModel.EmployerOrWorkshopOrContractingPartyOrRepresentativeName))
{
var keyword = searchModel.EmployerOrWorkshopOrContractingPartyOrRepresentativeName;
joinedQuery = joinedQuery.Where(x =>
x.contractingParty.RepresentativeFullName.Contains(keyword) ||
(x.contractingParty.FName + " " + x.contractingParty.LName).Contains(keyword) ||
x.contractingParty.Employers.Any(e =>
e.FullName.Contains(keyword) ||
e.WorkshopEmployers.Any(we =>
we.Workshop.WorkshopFullName.Contains(keyword)))
);
}
if (!string.IsNullOrWhiteSpace(searchModel.City))
{
joinedQuery = joinedQuery.Where(x => x.contract.City == searchModel.City);
}
if (!string.IsNullOrWhiteSpace(searchModel.Province))
{
joinedQuery = joinedQuery.Where(x => x.contract.State == searchModel.Province);
}
if (searchModel.AmountFrom > 0)
{
joinedQuery = joinedQuery.Where(x => x.contract.ContractAmount >= searchModel.AmountFrom);
}
if (searchModel.AmountTo > 0)
{
joinedQuery = joinedQuery.Where(x => x.contract.ContractAmount <= searchModel.AmountTo);
}
if (!string.IsNullOrWhiteSpace(searchModel.ContractDateFrom) &&
!string.IsNullOrWhiteSpace(searchModel.ContractDateTo))
{
if (!searchModel.ContractDateFrom.TryToGeorgianDateTime(out var dateFrom))
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
if (!searchModel.ContractDateTo.TryToGeorgianDateTime(out var dateTo))
{
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
}
if (dateFrom > dateTo)
{
throw new BadRequestException("تاریخ شروع نمیتواند بزرگ تر از تاریخ پایان باشد");
}
joinedQuery = joinedQuery.Where(x =>
x.contract.ContractStartGr <= dateTo && x.contract.ContractEndGr <= dateFrom);
}
if (searchModel.HasSignature != null)
{
var hasSignature = searchModel.HasSignature == true ? "1" : "0";
joinedQuery = joinedQuery.Where(x => x.contract.Signature == hasSignature);
}
if (searchModel.IsActive != null)
{
var isActiveStr = searchModel.IsActive == true ? "true" : "false";
joinedQuery = joinedQuery.Where(x =>
x.contract.IsActiveString == isActiveStr || x.contract.IsActiveString == "blue");
}
if (searchModel.Type != null)
{
var typeStr = searchModel.Type switch
{
InstitutionContractType.JobRelation => "JobRelation",
InstitutionContractType.TaxAndFinancial => "taxAndFinancial",
_ => throw new ArgumentOutOfRangeException()
};
joinedQuery = joinedQuery.Where(x => x.contract.TypeOfContract == typeStr);
}
if (searchModel.IsOfficial != null)
{
var isOfficialStr = searchModel.IsOfficial == true ? "Official" : "NotOfficial";
joinedQuery = joinedQuery.Where(x => x.contract.OfficialCompany == isOfficialStr);
}
if (searchModel.Status != null)
{
switch (searchModel.Status)
{
case InstitutionContractListStatus.DeactiveWithDebt:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.DeactiveWithDebt);
break;
case InstitutionContractListStatus.PendingForRenewal:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.PendingForRenewal);
break;
case InstitutionContractListStatus.Block:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Block);
break;
case InstitutionContractListStatus.Free:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Free);
break;
case InstitutionContractListStatus.WithoutWorkshop:
joinedQuery = joinedQuery.Where(x =>
x.StatusPriority == (int)InstitutionContractListStatus.WithoutWorkshop);
break;
case InstitutionContractListStatus.Active:
joinedQuery = joinedQuery.Where(x => x.StatusPriority == (int)InstitutionContractListStatus.Active);
break;
case InstitutionContractListStatus.Deactive:
joinedQuery = joinedQuery.Where(x => x.contract.ContractEndGr < now);
break;
case InstitutionContractListStatus.PendingForVerify:
joinedQuery = joinedQuery.Where(x =>
x.contract.VerificationStatus == InstitutionContractVerificationStatus.PendingForVerify);
break;
}
}
else
{
joinedQuery = joinedQuery.Where(x => x.contract.IsActiveString != "blue");
}
#endregion
var totalAmount = await joinedQuery.SumAsync(x => x.contract.ContractAmount);
var totalDebt = await _context.FinancialStatments.Include(x => x.FinancialTransactionList)
.Where(x => joinedQuery.Select(i => i.contract.ContractingPartyId).Contains(x.ContractingPartyId))
.SelectMany(x => x.FinancialTransactionList)
.SumAsync(x => x.Deptor - x.Creditor);
var counts = new List<InstitutionContractStatusCount>();
foreach (var name in typeof(InstitutionContractListStatus).GetEnumNames())
{
var @enum = Enum.Parse<InstitutionContractListStatus>(name);
searchModel.Status = @enum;
searchModel.PageSize = 1;
var count = (await GetList(searchModel)).TotalCount;
counts.Add(new() { ListStatus = @enum, Count = count });
}
var res = new GetInstitutionContractListStatsViewModel()
{
TotalDebt = totalDebt,
TotalAmount = totalAmount,
Counts = counts
};
return res;
}
public async Task<List<RegistrationWorkflowMainListViewModel>> RegistrationWorkflowMainList()
{
return await _context.InstitutionContractSet
.Where(x => x.VerificationStatus == InstitutionContractVerificationStatus.PendingWorkflow)
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.InitialWorkshops)
.Join(_context.PersonalContractingParties,
institutionContract => institutionContract.ContractingPartyId,
contractingParty => contractingParty.id,
(institutionContract, contractingParty) => new { institutionContract, contractingParty }).Select(x =>
new RegistrationWorkflowMainListViewModel
{
InstitutionContractId = x.institutionContract.id,
ContractingPartyFullName = $"{x.contractingParty.FName} {x.contractingParty.LName}",
Phone = x.contractingParty.Phone,
Amount = x.institutionContract.TotalAmount,
DoneWorkshops = x.institutionContract.WorkshopGroup.InitialWorkshops.Count(w => w.WorkshopCreated),
TotalWorkshops =
x.institutionContract.WorkshopGroup.InitialWorkshops.Count,
UnDoneWorkshops =
x.institutionContract.WorkshopGroup.InitialWorkshops.Count(w => !w.WorkshopCreated),
ContractingPartyId = x.contractingParty.id
}).ToListAsync();
}
/// <summary>
/// دریافت لیست اقلام گردش کار ثبت نام
/// </summary>
/// <param name="institutionContractId">شناسه قرارداد نهاد</param>
/// <returns>لیست اقلام گردش کار ثبت نام</returns>
public async Task<List<RegistrationWorkflowItemsViewModel>> RegistrationWorkflowItems(long institutionContractId)
{
// دریافت قرارداد نهاد همراه با جزئیات کارگاه‌ها
var institutionContract = await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup).ThenInclude(institutionContractWorkshopGroup =>
institutionContractWorkshopGroup.InitialWorkshops).ThenInclude(institutionContractWorkshopDetail =>
institutionContractWorkshopDetail.Employers)
.FirstOrDefaultAsync(x => x.id == institutionContractId);
if (institutionContract == null)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
// استخراج شناسه‌های کارگاه‌هایی که ایجاد شده‌اند
var workshopIds = institutionContract.WorkshopGroup.InitialWorkshops
.Where(x => x.WorkshopId != null)
.Select(x => x.WorkshopId.Value)
.ToList();
// دریافت کارگاه‌ها همراه با کارفرمایان در یک کوئری
var workshops = await _context.Workshops
.Where(x => workshopIds.Contains(x.id))
.ToListAsync();
// استخراج تمامی شناسه‌های کارفرمایان از جزئیات کارگاه‌ها
var allEmployerIds = institutionContract.WorkshopGroup.InitialWorkshops
.SelectMany(x => x.Employers.Select(e => e.EmployerId))
.Distinct()
.ToList();
// دریافت اطلاعات کارفرمایان در یک کوئری واحد
var employersDict = (await _context.Employers
.Where(e => allEmployerIds.Contains(e.id))
.Select(e => new { e.id, e.FullName })
.ToListAsync())
.ToDictionary(e => e.id, e => e);
// ساخت نتیجه نهایی با استفاده از داده‌های از پیش بارگذاری شده
var items = institutionContract.WorkshopGroup
.InitialWorkshops.Select(workshopDetail =>
{
// پیدا کردن کارگاه مرتبط
var workshop = workshops.FirstOrDefault(w => w.id == workshopDetail.WorkshopId);
// ساخت لیست کارفرمایان این جزئیات کارگاه
var employers = workshopDetail.Employers
.Where(e => employersDict.ContainsKey(e.EmployerId))
.Select(e => new RegistrationWorkflowItemsEmployerViewModel
{
Id = e.EmployerId,
FullName = employersDict[e.EmployerId].FullName
})
.ToList();
return new RegistrationWorkflowItemsViewModel
{
Price = workshopDetail.Price,
IsDone = workshop != null,
PersonnelCount = workshopDetail.PersonnelCount,
WorkshopName = workshopDetail.WorkshopName,
Employers = employers,
WorkshopDetailsId = workshopDetail.id
};
}).ToList();
return items;
}
private (InstitutionContractListStatus status, bool isExpiered) SetContractStatus(InstitutionContract contract,
PersonalContractingParty contractingParty,
FinancialStatment financialStatment)
{
//if (contract.ContractEndGr <= endThisMontGr)
var now = DateTime.Now;
var nowFa = now.ToFarsi();
var endFa = nowFa.FindeEndOfMonth();
var endThisMontGr = endFa.ToGeorgianDateTime();
InstitutionContractListStatus listStatus = InstitutionContractListStatus.Active;
bool isExpier = false;
if (contract.ContractEndGr < now)
{
listStatus = InstitutionContractListStatus.Deactive;
isExpier = true;
}
if (contract.ContractEndGr >= now && contract.ContractEndGr <= endThisMontGr)
{
listStatus = InstitutionContractListStatus.PendingForRenewal;
isExpier = true;
}
if (contract.ContractAmount == 0)
{
listStatus = InstitutionContractListStatus.Free;
if ((contract.ContractEndGr >= now && contract.ContractEndGr <= endThisMontGr) ||
(contract.ContractEndGr < now))
{
isExpier = true;
}
}
if (contract.IsActiveString == "blue")
{
listStatus = InstitutionContractListStatus.DeactiveWithDebt;
isExpier = true;
}
var workshops = contractingParty.Employers
.SelectMany(e => e.WorkshopEmployers.Select(we => we.Workshop)).DistinctBy(w => w.id).ToList();
if (workshops.Count == 0)
{
listStatus = InstitutionContractListStatus.Free;
}
if (contractingParty.IsBlock == "true")
{
listStatus = InstitutionContractListStatus.Block;
}
return (listStatus, isExpier);
}
public async Task<InstitutionContractWorkshopInitial> GetInstitutionWorkshopInitialDetails(
long institutionWorkshopInitialId)
{
var result = await _context.InstitutionContractWorkshopInitials.Include(x => x.WorkshopGroup)
.Include(x => x.Employers)
.FirstOrDefaultAsync(x => x.id == institutionWorkshopInitialId);
return result;
}
public async Task<InstitutionContract> GetIncludeWorkshopDetailsAsync(long institutionContractId)
{
return await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.InitialWorkshops)
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.CurrentWorkshops)
.FirstOrDefaultAsync(x => x.id == institutionContractId);
}
public void UpdateStatusIfNeeded(long institutionContractId)
{
var institutionContract = _context.InstitutionContractSet
.Include(x => x.WorkshopGroup).ThenInclude(institutionContractWorkshopGroup =>
institutionContractWorkshopGroup.InitialWorkshops)
.FirstOrDefault(x => x.id == institutionContractId);
if (institutionContract == null)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
if (institutionContract.VerificationStatus == InstitutionContractVerificationStatus.Verified)
return;
if (institutionContract.WorkshopGroup.InitialWorkshops
.All(x => x.WorkshopCreated))
institutionContract.Verified();
_context.SaveChanges();
}
public async Task<GetInstitutionVerificationDetailsViewModel> GetVerificationDetails(Guid id)
{
var query = await _context.InstitutionContractSet.Where(x => x.PublicId == id)
.Include(x => x.WorkshopGroup).ThenInclude(institutionContractWorkshopGroup =>
institutionContractWorkshopGroup.InitialWorkshops)
.Include(institutionContract => institutionContract.Installments)
.Join(_context.PersonalContractingParties,
institutionContract => institutionContract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, party) => new { contract, party }).FirstOrDefaultAsync();
if (query == null)
{
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
}
if (query.contract.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
{
throw new BadRequestException(
"قرارداد وارد شده تایید شده میباشد",
new Dictionary<string, object>
{
{ "isVerified", true }
}
);
}
int installmentNumber = 1;
var res = new GetInstitutionVerificationDetailsViewModel()
{
ContractStart = query.contract.ContractStartFa,
ContractEnd = query.contract.ContractEndFa,
ContractNo = query.contract.ContractNo,
CreationDate = query.contract.CreationDate.ToFarsi(),
TaxPrice = query.contract.ValueAddedTax.ToMoney(),
TotalPrice = (query.contract.TotalAmount - query.contract.ValueAddedTax).ToMoney(),
PaymentPrice = query.contract.TotalAmount.ToMoney(),
IsInstallment = query.contract.IsInstallment,
Installments = query.contract.Installments.OrderBy(x => x.InstallmentDateGr)
.Select(x =>
{
var res = new InstitutionContractInstallmentViewModel()
{
Amount = x.Amount.ToMoney(),
InstallmentIndex = GetInstallmentPersianNumber(installmentNumber),
Id = x.Id,
InstallmentDateFa = x.InstallmentDateFa,
InstallmentDateGr = x.InstallmentDateGr,
InstitutionContractId = x.InstitutionContractId,
};
installmentNumber++;
return res;
}).ToList(),
Workshops = query.contract.WorkshopGroup.InitialWorkshops
.Select(x => new GetInstitutionVerificationDetailsWorkshopsViewModel
{
Services = new WorkshopServicesViewModel()
{
Contract = x.Services.Contract,
ContractInPerson = x.Services.ContractInPerson,
CustomizeCheckout = x.Services.CustomizeCheckout,
Insurance = x.Services.Insurance,
InsuranceInPerson = x.Services.InsuranceInPerson,
RollCall = x.Services.RollCall,
RollCallInPerson = x.Services.RollCallInPerson
},
Name = x.WorkshopName,
PersonnelCount = x.PersonnelCount,
Price = x.Price.ToMoney()
}).ToList(),
SecondParty = new InstitutionContratVerificationParty()
{
Address = query.contract.Address,
PhoneNumber = query.party.Phone,
CeoName = query.party.IsLegal == "حقیقی"
? $"{query.party.FName} {query.party.LName}"
: $"{query.party.CeoFName} {query.party.CeoLName}",
CompanyNameOrFullName = query.party.IsLegal == "حقیقی"
? $"{query.party.FName} {query.party.LName}"
: query.party.LName,
NationalCodeOrNationalId =
query.party.IsLegal == "حقیقی" ? query.party.Nationalcode : query.party.NationalId,
LegalType = query.party.IsLegal == "حقیقی" ? LegalType.Real : LegalType.Legal,
},
FirstParty = _firstParty
};
return res;
}
private string GetInstallmentPersianNumber(int number)
{
return number switch
{
1 => "اول",
2 => "دوم",
3 => "سوم",
4 => "چهارم",
5 => "پنجم",
6 => "ششم",
7 => "هفتم",
8 => "هشتم",
9 => "نهم",
10 => "دهم",
11 => "یازدهم",
12 => "دوازدهم",
_ => number.ToString()
};
}
public async Task<InstitutionContract> GetByPublicIdAsync(Guid id)
{
return await _context.InstitutionContractSet
.Include(x => x.ContactInfoList)
.Include(x => x.Installments)
.FirstOrDefaultAsync(x => x.PublicId == id);
}
public InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request,string contractStart=null)
{
var baseAmount = request.TotalAmount;
var discountAmount = (baseAmount * request.DiscountPercentage) / 100;
var discountOneMonthAmount = (request.OneMonthAmount * request.DiscountPercentage) / 100;
var discountedOneMonthAmount = request.OneMonthAmount - discountOneMonthAmount;
var totalAmount = baseAmount - discountAmount;
var taxAmount = totalAmount * 0.10;
var paymentAmount = totalAmount + taxAmount;
InstitutionContractDiscountMonthlyViewModel monthlyPayment = null;
InstitutionContractDiscountOneTimeViewModel oneTimePayment = null;
if (request.IsInstallment)
{
monthlyPayment = new InstitutionContractDiscountMonthlyViewModel()
{
TotalAmount = totalAmount.ToMoney(),
PaymentAmount = paymentAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
DiscountedAmount = discountAmount.ToMoney(),
DiscountPercetage = request.DiscountPercentage,
Installments = InstitutionMonthlyInstallmentCaculation((int)request.Duration,
totalAmount, DateTime.Now.ToFarsi()),
OneMonthAmount = discountedOneMonthAmount.ToMoney(),
Obligation = totalAmount.ToMoney()
};
}
else
{
oneTimePayment = new InstitutionContractDiscountOneTimeViewModel()
{
TotalAmount = totalAmount.ToMoney(),
PaymentAmount = paymentAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
DiscountedAmount = discountAmount.ToMoney(),
DiscountPercetage = request.DiscountPercentage,
OneMonthAmount = discountedOneMonthAmount.ToMoney(),
Obligation = totalAmount.ToMoney()
};
}
if (discountAmount > baseAmount)
throw new BadRequestException("مقدار تخفیف نمی‌تواند بیشتر از مبلغ کل باشد");
return new InstitutionContractDiscountResponse()
{
Monthly = monthlyPayment,
OneTime = oneTimePayment
};
}
public InstitutionContractDiscountResponse ResetDiscountCreate(
InstitutionContractResetDiscountForCreateRequest request)
{
InstitutionContractDiscountMonthlyViewModel monthlyPayment = null;
InstitutionContractDiscountOneTimeViewModel oneTimePayment = null;
if (request.IsInstallment)
{
var newTotalAmount = request.TotalAmount / (1 - (request.DiscountPercentage / 100.0));
var taxAmount = (newTotalAmount * 0.10);
var paymentAmount = (newTotalAmount + taxAmount);
var newOneMonthAmount = request.OneMonthAmount / (1 - (request.DiscountPercentage / 100.0));
monthlyPayment = new InstitutionContractDiscountMonthlyViewModel()
{
TotalAmount = newTotalAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
DiscountedAmount = "0",
DiscountPercetage = 0,
PaymentAmount = paymentAmount.ToMoney(),
Installments = InstitutionMonthlyInstallmentCaculation((int)request.Duration,
paymentAmount, DateTime.Now.ToFarsi()),
Obligation = newTotalAmount.ToMoney(),
OneMonthAmount = newOneMonthAmount.ToMoney()
};
}
else
{
var newTotalAmount = request.TotalAmount / (1 - ((double)request.DiscountPercentage / 100));
var taxAmount = (newTotalAmount * 0.10);
var paymentAmount = (newTotalAmount + taxAmount);
var newOneMonthAmount = request.OneMonthAmount / (1 - ((double)request.DiscountPercentage / 100));
oneTimePayment = new InstitutionContractDiscountOneTimeViewModel()
{
TotalAmount = newTotalAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
PaymentAmount = paymentAmount.ToMoney(),
DiscountedAmount = "0",
DiscountPercetage = 0,
Obligation = newTotalAmount.ToMoney(),
OneMonthAmount = newOneMonthAmount.ToMoney()
};
}
return new InstitutionContractDiscountResponse()
{
Monthly = monthlyPayment,
OneTime = oneTimePayment
};
}
#region Extension
public async Task<InstitutionContractExtensionInquiryResult> GetExtensionInquiry(long previousContractId)
{
var institutionContracts = await _context.InstitutionContractSet
.Include(institutionContract => institutionContract.ContactInfoList)
.FirstOrDefaultAsync(x => x.id == previousContractId);
var contractingParty = await
_context.PersonalContractingParties.FirstOrDefaultAsync(x =>
x.id == institutionContracts.ContractingPartyId);
var legalType = contractingParty.IsLegal == "حقیقی" ? LegalType.Real : LegalType.Legal;
CreateInstitutionContractLegalPartyRequest legalPartyRequest = null;
CreateInstitutionContractRealPartyRequest realPartyRequest = null;
if (legalType == LegalType.Legal)
{
legalPartyRequest = new CreateInstitutionContractLegalPartyRequest()
{
NationalCode = contractingParty.Nationalcode == "*" ? string.Empty : contractingParty.Nationalcode,
BirthDateFa = contractingParty.DateOfBirth.ToFarsi(),
PhoneNumber = contractingParty.Phone,
FatherName = contractingParty.FatherName,
FName = contractingParty.CeoFName,
LName = contractingParty.CeoLName,
CompanyName = contractingParty.LName,
Gender = contractingParty.Gender,
IdNumber = contractingParty.IdNumber,
RegisterId = contractingParty.RegisterId,
IsAuth = contractingParty.IsAuthenticated,
NationalId = contractingParty.NationalId,
Position = contractingParty.LegalPosition,
ContractingPartyTempId = 0
};
}
else
{
realPartyRequest = new CreateInstitutionContractRealPartyRequest()
{
NationalCode = contractingParty.Nationalcode,
BirthDateFa = contractingParty.DateOfBirth.ToFarsi(),
PhoneNumber = contractingParty.Phone,
FatherName = contractingParty.FatherName,
FName = contractingParty.FName,
Gender = contractingParty.Gender,
IdNumber = contractingParty.IdNumber,
IsAuth = contractingParty.IsAuthenticated,
LName = contractingParty.LName,
ContractingPartyTempId = 0
};
}
var previousContractTemp = await _institutionExtensionTemp
.Find(x => x.PreviousId == previousContractId)
.FirstOrDefaultAsync();
if (previousContractTemp != null)
{
await _institutionExtensionTemp.DeleteOneAsync(x => x.Id == previousContractTemp.Id);
}
var institutionContractTemp = new InstitutionContractExtensionTemp(previousContractId);
await _institutionExtensionTemp.InsertOneAsync(institutionContractTemp);
var res = new InstitutionContractExtensionInquiryResult()
{
LegalType = legalType,
Address = contractingParty.Address,
City = contractingParty.City,
ContactInfoViewModels = institutionContracts.ContactInfoList.Select(x => new EditContactInfo()
{
Id = x.id,
FnameLname = x.FnameLname,
InstitutionContractId = x.InstitutionContractId,
PhoneNumber = x.PhoneNumber,
PhoneType = x.PhoneType,
Position = x.Position,
SendSms = x.SendSms
}).ToList(),
Province = contractingParty.State,
LegalParty = legalPartyRequest,
RealParty = realPartyRequest,
TemporaryId = institutionContractTemp.Id,
RepresentativeId = institutionContracts.RepresentativeId
};
return res;
}
public async Task<InstitutionContractExtensionWorkshopsResponse> GetExtensionWorkshops(
InstitutionContractExtensionWorkshopsRequest request)
{
var transaction = await _context.Database.BeginTransactionAsync();
switch (request.LegalType)
{
case LegalType.Legal:
var legalCommand = request.LegalParty;
var legalPersonalContractingParty = _context.PersonalContractingParties
.FirstOrDefault(x => x.NationalId == legalCommand.NationalId);
if (!request.LegalParty.IsAuth)
{
if (legalPersonalContractingParty is { IsAuthenticated: false })
{
legalPersonalContractingParty.UnAuthenticateLegalEdit(legalCommand.FName, legalCommand.LName,
legalCommand.FatherName, legalCommand.IdNumber, legalPersonalContractingParty.IdNumberSeri,
legalPersonalContractingParty.IdNumberSerial, legalCommand.BirthDateFa, legalCommand.Gender,
legalCommand.PhoneNumber);
}
}
else
{
legalPersonalContractingParty?.LegalAuthentication(legalCommand.FName, legalCommand.LName,
legalCommand.FatherName, legalCommand.IdNumber, legalPersonalContractingParty.IdNumberSeri,
legalPersonalContractingParty.IdNumberSerial, legalCommand.BirthDateFa, legalCommand.Gender,
legalCommand.PhoneNumber);
}
legalPersonalContractingParty?.EditLegalPartyFromInstitution(legalCommand.Position,
legalCommand.CompanyName,
legalCommand.RegisterId, legalCommand.NationalId);
break;
case LegalType.Real:
if (!request.RealParty.IsAuth)
{
var realCommand = request.RealParty;
var personalContractingParty = _context.PersonalContractingParties
.FirstOrDefault(x => x.Nationalcode == realCommand.NationalCode);
if (personalContractingParty is { IsAuthenticated: false })
{
personalContractingParty.UnAuthenticateRealEdit(realCommand.FName, realCommand.LName,
realCommand.FatherName, realCommand.IdNumber, personalContractingParty.IdNumberSeri,
personalContractingParty.IdNumberSerial, realCommand.BirthDateFa, realCommand.Gender,
realCommand.PhoneNumber);
}
}
break;
}
await SaveChangesAsync();
await transaction.CommitAsync();
var extenstionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId)
.FirstOrDefaultAsync();
if (extenstionTemp == null)
{
throw new BadRequestException("دیتای درخواست شده نامعتبر است");
}
var prevInstitutionContracts = await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(institutionContractWorkshopGroup => institutionContractWorkshopGroup.CurrentWorkshops)
.FirstOrDefaultAsync(x => x.id == extenstionTemp.PreviousId);
if (prevInstitutionContracts == null)
{
throw new BadRequestException("قرارداد مالی قبلی یافت نشد");
}
extenstionTemp.SetContractingPartyInfos(request.Address, request.City, request.Province, request.ContactInfos);
await _institutionExtensionTemp.ReplaceOneAsync(
x => x.Id == extenstionTemp.Id,
extenstionTemp
);
var workshopIds = prevInstitutionContracts.WorkshopGroup.CurrentWorkshops.Select(x => x.WorkshopId.Value);
var workshops = await _context.Workshops.Where(x => workshopIds.Contains(x.id)).ToListAsync();
var workshopDetails = prevInstitutionContracts.WorkshopGroup.CurrentWorkshops
.Select(x =>
{
var workshop = workshops.FirstOrDefault(w => w.id == x.WorkshopId);
var service = x.Services;
var price = x.Price;
if (x.Price == 0)
{
var command = new WorkshopTempViewModel()
{
ContractAndCheckout = service.Contract,
ContractAndCheckoutInPerson = service.ContractInPerson,
CountPerson = x.PersonnelCount,
CustomizeCheckout = service.CustomizeCheckout,
Insurance = service.Insurance,
InsuranceInPerson = service.InsuranceInPerson,
RollCall = service.RollCall,
WorkshopName = x.WorkshopName,
RollCallInPerson = service.RollCallInPerson,
};
var institutionPlanForWorkshop = _planPercentageRepository.GetInstitutionPlanForWorkshop(command);
price = institutionPlanForWorkshop.OnlineAndInPersonSumAmountDouble;
}
return new WorkshopTempViewModel()
{
Id = x.id,
ContractAndCheckout = service.Contract,
ContractAndCheckoutInPerson = service.ContractInPerson,
CustomizeCheckout = service.CustomizeCheckout,
CountPerson = x.PersonnelCount,
Insurance = service.Insurance,
InsuranceInPerson = service.InsuranceInPerson,
RollCall = service.RollCall,
WorkshopName = workshop?.WorkshopName ?? "فاقد کارگاه",
WorkshopServicesAmount = price,
WorkshopServicesAmountStr = price.ToMoney(),
WorkshopId = workshop?.id ?? 0,
RollCallInPerson = service.RollCallInPerson
};
}).ToList();
var res = new InstitutionContractExtensionWorkshopsResponse()
{
TotalAmount = workshopDetails.Sum(x => x.WorkshopServicesAmount).ToMoney(),
WorkshopTemps = workshopDetails
};
return res;
}
public async Task<InstitutionContractExtensionPlanResponse> GetExtensionInstitutionPlan(
InstitutionContractExtensionPlanRequest request)
{
if (request.WorkshopTemps.Count == 0)
throw new BadRequestException("هیچ کارگاهی یافت نشد");
bool hasInPerson = request.WorkshopTemps.Any(x => x.ContractAndCheckoutInPerson);
double amount = request.TotalAmount.MoneyToDouble();
var institutionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId).FirstOrDefaultAsync();
var previousInstitution =
await _context.InstitutionContractSet.FirstOrDefaultAsync(x => x.id == institutionTemp.PreviousId);
var res = new InstitutionContractExtensionPlanResponse();
DateTime newContractStart;
if (previousInstitution.ContractEndGr <= DateTime.Now)
{
newContractStart = DateTime.Now;
}
else
{
newContractStart = previousInstitution.ContractEndGr.AddDays(1);
}
if (hasInPerson)
{
res.OneMonth = null;
res.ThreeMonths = null;
res.SixMonths = null;
res.TwelveMonths =
CalculateInstitutionPlan(InstitutionContractDuration.TwelveMonths, amount, true, newContractStart);
}
else
{
res.OneMonth =
CalculateInstitutionPlan(InstitutionContractDuration.OneMonth, amount, false, newContractStart);
res.ThreeMonths =
CalculateInstitutionPlan(InstitutionContractDuration.ThreeMonths, amount, false, newContractStart);
res.SixMonths =
CalculateInstitutionPlan(InstitutionContractDuration.SixMonths, amount, false, newContractStart);
res.TwelveMonths = CalculateInstitutionPlan(InstitutionContractDuration.TwelveMonths, amount, false,
newContractStart);
}
var workshops = request.WorkshopTemps
.Select(x => new InstitutionContractExtensionTempWorkshop(x.WorkshopName, x.CountPerson,
x.ContractAndCheckout, x.ContractAndCheckoutInPerson,
x.Insurance, x.InsuranceInPerson, x.RollCall, x.RollCall,
x.RollCallInPerson, x.WorkshopServicesAmount, x.WorkshopId)).ToList();
institutionTemp.SetWorkshopsAndPlanAmounts(workshops, res.OneMonth, res.ThreeMonths, res.SixMonths,
res.TwelveMonths, hasInPerson);
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id, institutionTemp);
return res;
}
public async Task<InstitutionContractExtensionPaymentResponse> GetExtensionPaymentMethod(
InstitutionContractExtensionPaymentRequest request)
{
var institutionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId).FirstOrDefaultAsync();
if (institutionTemp == null)
throw new BadRequestException("اطلاعات وارد شده نامعتبر است");
var duration = request.Duration;
var selectedPlan = duration switch
{
InstitutionContractDuration.OneMonth => institutionTemp.OneMonth,
InstitutionContractDuration.ThreeMonths => institutionTemp.ThreeMonths,
InstitutionContractDuration.SixMonths => institutionTemp.SixMonths,
InstitutionContractDuration.TwelveMonths => institutionTemp.TwelveMonths,
_ => throw new ArgumentOutOfRangeException()
};
var baseAmount = selectedPlan.TotalPayment.MoneyToDouble();
var vatOrDiscount = baseAmount * 0.10;
var res = institutionTemp.HasContractInPerson
? CalculateInPersonPayment(selectedPlan, baseAmount, vatOrDiscount, request.Duration)
: CalculateOnlinePayment(baseAmount, vatOrDiscount);
institutionTemp.SetAmountAndDuration(duration, res.Monthly, res.OneTime);
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id, institutionTemp);
return res;
}
public async Task<InstitutionContractDiscountResponse> SetDiscountForExtension(
InstitutionContractSetDiscountForExtensionRequest request)
{
if (request.DiscountPercentage <= 0)
throw new BadRequestException("مقدار تخفیف نمی‌تواند برابر یا کمتر از صفر باشد");
var institutionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId)
.FirstOrDefaultAsync();
if (institutionTemp == null)
{
throw new BadRequestException("اطلاعات وارد شده نامعتبر است");
}
if (request.IsInstallment)
{
if (institutionTemp.MonthlyPayment.DiscountPercetage > 0)
throw new BadRequestException("تخفیف قبلا برای این قرارداد اعمال شده است");
}
else
{
if (institutionTemp.OneTimePayment.DiscountPercetage > 0)
throw new BadRequestException("تخفیف قبلا برای این قرارداد اعمال شده است");
}
var selectedPlan = institutionTemp.Duration switch
{
InstitutionContractDuration.OneMonth => institutionTemp.OneMonth,
InstitutionContractDuration.ThreeMonths => institutionTemp.ThreeMonths,
InstitutionContractDuration.SixMonths => institutionTemp.SixMonths,
InstitutionContractDuration.TwelveMonths => institutionTemp.TwelveMonths,
_ => throw new ArgumentOutOfRangeException()
};
var calculateRequest = new InstitutionContractSetDiscountRequest()
{
Duration = institutionTemp.Duration.Value,
TotalAmount = request.TotalAmount,
DiscountPercentage = request.DiscountPercentage,
IsInstallment = request.IsInstallment,
OneMonthAmount = selectedPlan.OneMonthPaymentDiscounted.MoneyToDouble()
};
var res = CalculateDiscount(calculateRequest,selectedPlan.ContractStart);
//این به این دلیل هست که متد caclulate discount یکی از مقادیر رو پر میکنه و ما نیاز داریم هر دو مقدار رو داشته باشیم
if (request.IsInstallment)
{
var onetime = institutionTemp.OneTimePayment;
res.OneTime = new()
{
PaymentAmount = onetime.PaymentAmount,
Tax = onetime.Tax,
TotalAmount = onetime.TotalAmount,
DiscountedAmount = onetime.DiscountedAmount,
DiscountPercetage = onetime.DiscountPercetage,
};
institutionTemp.MonthlyPayment = new()
{
Installments = res.Monthly.Installments,
PaymentAmount = res.Monthly.PaymentAmount,
Tax = res.Monthly.Tax,
TotalAmount = res.Monthly.TotalAmount,
DiscountedAmount = res.Monthly.DiscountedAmount,
DiscountPercetage = res.Monthly.DiscountPercetage,
};
selectedPlan.TotalPayment = res.Monthly.TotalAmount;
selectedPlan.Obligation = res.Monthly.Obligation;
selectedPlan.OneMonthPaymentDiscounted = res.Monthly.OneMonthAmount;
selectedPlan.DailyCompenseation = (res.Monthly.OneMonthAmount.MoneyToDouble() * 0.10).ToMoney();
}
else
{
var monthly = institutionTemp.MonthlyPayment;
res.Monthly = new()
{
PaymentAmount = monthly.PaymentAmount,
Tax = monthly.Tax,
TotalAmount = monthly.TotalAmount,
DiscountedAmount = monthly.DiscountedAmount,
DiscountPercetage = monthly.DiscountPercetage,
Installments = monthly.Installments,
};
institutionTemp.OneTimePayment = new()
{
PaymentAmount = res.OneTime.PaymentAmount,
Tax = res.OneTime.Tax,
TotalAmount = res.OneTime.TotalAmount,
DiscountedAmount = res.OneTime.DiscountedAmount,
DiscountPercetage = res.OneTime.DiscountPercetage,
};
selectedPlan.TotalPayment = res.OneTime.TotalAmount;
selectedPlan.Obligation = res.OneTime.Obligation;
selectedPlan.OneMonthPaymentDiscounted = res.OneTime.OneMonthAmount;
selectedPlan.DailyCompenseation = (res.OneTime.OneMonthAmount.MoneyToDouble() * 0.10).ToMoney();
}
switch (institutionTemp.Duration)
{
case InstitutionContractDuration.OneMonth:
institutionTemp.OneMonth = selectedPlan;
break;
case InstitutionContractDuration.ThreeMonths:
institutionTemp.ThreeMonths = selectedPlan;
break;
case InstitutionContractDuration.SixMonths:
institutionTemp.SixMonths = selectedPlan;
break;
case InstitutionContractDuration.TwelveMonths:
institutionTemp.TwelveMonths = selectedPlan;
break;
default:
throw new ArgumentOutOfRangeException();
}
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id,
institutionTemp);
return new()
{
OneTime = res.OneTime,
Monthly = res.Monthly
};
}
public async Task<InstitutionContractDiscountResponse> ResetDiscountForExtension
(InstitutionContractResetDiscountForExtensionRequest request)
{
var institutionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId)
.FirstOrDefaultAsync();
if (institutionTemp == null)
{
throw new BadRequestException("اطلاعات وارد شده نامعتبر است");
}
InstitutionContractDiscountMonthlyViewModel monthlyPayment = null;
InstitutionContractDiscountOneTimeViewModel oneTimePayment = null;
var selectedPlan = institutionTemp.Duration switch
{
InstitutionContractDuration.OneMonth => institutionTemp.OneMonth,
InstitutionContractDuration.ThreeMonths => institutionTemp.ThreeMonths,
InstitutionContractDuration.SixMonths => institutionTemp.SixMonths,
InstitutionContractDuration.TwelveMonths => institutionTemp.TwelveMonths,
_ => throw new ArgumentOutOfRangeException()
};
if (request.IsInstallment)
{
var prevMonthlyPayment = institutionTemp.MonthlyPayment;
var resetTotalAmount = prevMonthlyPayment.TotalAmount.MoneyToDouble() /
(1 - (prevMonthlyPayment.DiscountPercetage / 100.0));
var resetTax = (resetTotalAmount * 0.10);
var paymentAmount = (resetTotalAmount + resetTax);
var newOneMonthAmount = selectedPlan.OneMonthPaymentDiscounted.MoneyToDouble() /
(1 - (prevMonthlyPayment.DiscountPercetage / 100));
monthlyPayment = new InstitutionContractDiscountMonthlyViewModel()
{
DiscountPercetage = 0,
DiscountedAmount = "0",
PaymentAmount = paymentAmount.ToMoney(),
Tax = resetTax.ToMoney(),
TotalAmount = resetTotalAmount.ToMoney(),
Installments = InstitutionMonthlyInstallmentCaculation((int)institutionTemp.Duration.Value,
paymentAmount,selectedPlan.ContractStart),
OneMonthAmount = newOneMonthAmount.ToMoney(),
Obligation = resetTotalAmount.ToMoney()
};
institutionTemp.MonthlyPayment = new InstitutionContractPaymentMonthlyViewModel()
{
Installments = monthlyPayment.Installments,
PaymentAmount = monthlyPayment.PaymentAmount,
Tax = monthlyPayment.Tax,
TotalAmount = monthlyPayment.TotalAmount,
DiscountedAmount = monthlyPayment.DiscountedAmount,
DiscountPercetage = monthlyPayment.DiscountPercetage,
};
selectedPlan.TotalPayment = monthlyPayment.TotalAmount;
selectedPlan.Obligation = monthlyPayment.Obligation;
selectedPlan.OneMonthPaymentDiscounted = monthlyPayment.OneMonthAmount;
selectedPlan.DailyCompenseation = (monthlyPayment.OneMonthAmount.MoneyToDouble() * 0.10).ToMoney();
switch (institutionTemp.Duration)
{
case InstitutionContractDuration.OneMonth:
institutionTemp.OneMonth = selectedPlan;
break;
case InstitutionContractDuration.ThreeMonths:
institutionTemp.ThreeMonths = selectedPlan;
break;
case InstitutionContractDuration.SixMonths:
institutionTemp.SixMonths = selectedPlan;
break;
case InstitutionContractDuration.TwelveMonths:
institutionTemp.TwelveMonths = selectedPlan;
break;
default:
throw new ArgumentOutOfRangeException();
}
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id,
institutionTemp);
}
else
{
var prevOneTimePayment = institutionTemp.OneTimePayment;
var resetTotalAmount = prevOneTimePayment.TotalAmount.MoneyToDouble() /
(1 - (prevOneTimePayment.DiscountPercetage / 100.0));
var resetTax = (resetTotalAmount * 0.10);
var newOneMonthAmount = selectedPlan.OneMonthPaymentDiscounted.MoneyToDouble() /
(1 - (prevOneTimePayment.DiscountPercetage / 100));
oneTimePayment = new InstitutionContractDiscountOneTimeViewModel()
{
DiscountPercetage = 0,
DiscountedAmount = "0",
TotalAmount = resetTotalAmount.ToMoney(),
Tax = resetTax.ToMoney(),
PaymentAmount = (resetTotalAmount + resetTax).ToMoney(),
OneMonthAmount = newOneMonthAmount.ToMoney(),
Obligation = resetTotalAmount.ToMoney()
};
institutionTemp.OneTimePayment = new InstitutionContractPaymentOneTimeViewModel()
{
PaymentAmount = oneTimePayment.PaymentAmount,
Tax = oneTimePayment.Tax,
TotalAmount = oneTimePayment.TotalAmount,
DiscountedAmount = oneTimePayment.DiscountedAmount,
DiscountPercetage = oneTimePayment.DiscountPercetage,
};
selectedPlan.TotalPayment = oneTimePayment.TotalAmount;
selectedPlan.Obligation = oneTimePayment.Obligation;
selectedPlan.OneMonthPaymentDiscounted = oneTimePayment.OneMonthAmount;
selectedPlan.DailyCompenseation = (oneTimePayment.OneMonthAmount.MoneyToDouble() * 0.10).ToMoney();
switch (institutionTemp.Duration)
{
case InstitutionContractDuration.OneMonth:
institutionTemp.OneMonth = selectedPlan;
break;
case InstitutionContractDuration.ThreeMonths:
institutionTemp.ThreeMonths = selectedPlan;
break;
case InstitutionContractDuration.SixMonths:
institutionTemp.SixMonths = selectedPlan;
break;
case InstitutionContractDuration.TwelveMonths:
institutionTemp.TwelveMonths = selectedPlan;
break;
default:
throw new ArgumentOutOfRangeException();
}
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id,
institutionTemp);
}
return new InstitutionContractDiscountResponse()
{
OneTime = oneTimePayment,
Monthly = monthlyPayment
};
}
public async Task<OperationResult> ExtensionComplete(InstitutionContractExtensionCompleteRequest request)
{
var institutionContractTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TemporaryId)
.FirstOrDefaultAsync();
if (institutionContractTemp == null)
throw new BadRequestException("اطلاعات وارد شده نامعتبر است");
var selectedDuration = institutionContractTemp.Duration switch
{
InstitutionContractDuration.OneMonth => institutionContractTemp.OneMonth,
InstitutionContractDuration.ThreeMonths => institutionContractTemp.ThreeMonths,
InstitutionContractDuration.SixMonths => institutionContractTemp.SixMonths,
InstitutionContractDuration.TwelveMonths => institutionContractTemp.TwelveMonths,
_ => throw new ArgumentOutOfRangeException()
};
var previousInstitutionContract = await _context.InstitutionContractSet
.FirstOrDefaultAsync(x => x.id == institutionContractTemp.PreviousId);
if (previousInstitutionContract == null)
throw new NotFoundException("قرارداد مالی مورد نظر یافت نشد");
var contractingParty = await _context.PersonalContractingParties
.FirstOrDefaultAsync(x => x.id == previousInstitutionContract.ContractingPartyId);
var payment = request.IsInstallment
? institutionContractTemp.MonthlyPayment
: institutionContractTemp.OneTimePayment;
bool dateMessages = false;
string dateMaessageResult = String.Empty;
var opration = new OperationResult();
var extensionNo = previousInstitutionContract.ExtensionNo + 1;
if (_context.InstitutionContractSet.Any(x =>
x.ExtensionNo == extensionNo &&
x.ContractingPartyId == previousInstitutionContract.ContractingPartyId &&
x.TypeOfContract == previousInstitutionContract.TypeOfContract))
return opration.Failed("برای این قرارداد قبلا تمدید ایجاد شده است");
var contractStart = selectedDuration.ContractStart;
if (string.IsNullOrWhiteSpace(contractStart))
{
dateMaessageResult = "تاریخ قراراداد اجباری است. ";
dateMessages = true;
}
if (string.IsNullOrWhiteSpace(contractStart))
{
dateMaessageResult += "تاریخ شروع قراراداد اجباری است. ";
dateMessages = true;
}
if (string.IsNullOrWhiteSpace(selectedDuration.ContractEnd))
{
dateMaessageResult += "تاریخ پایان قراراداد اجباری است. ";
dateMessages = true;
}
if (dateMessages)
return opration.Failed(dateMaessageResult);
var firstContract = GetFirstContract(previousInstitutionContract.ContractingPartyId,
previousInstitutionContract.TypeOfContract);
var syear = firstContract.ContractStartFa.Substring(0, 4);
var smonth = firstContract.ContractStartFa.Substring(5, 2);
var sday = firstContract.ContractStartFa.Substring(8, 2);
//شماره قرارداد
var contractNo = $"{syear}{smonth}{sday}/{contractingParty.ArchiveCode}/{extensionNo}";
var contractStartGr = contractStart.ToGeorgianDateTime();
var contractEndGr = selectedDuration.ContractEnd.ToGeorgianDateTime();
var contractDateGr = contractStart.ToGeorgianDateTime();
if (Exists(x =>
((contractStartGr >= x.ContractStartGr && contractStartGr <= x.ContractEndGr) ||
(contractEndGr >= x.ContractStartGr && contractEndGr <= x.ContractEndGr)) &&
x.TypeOfContract == previousInstitutionContract.TypeOfContract
&& x.ContractingPartyId == previousInstitutionContract.ContractingPartyId))
return opration.Failed("تاریخ شروع و پایان وارد شده با قرارداد دیگری تداخل دارد");
if (institutionContractTemp.Address != null && institutionContractTemp.Province == null)
{
return opration.Failed("لطفا استان و شهر را انتخاب کنید");
}
if ((institutionContractTemp.Address != null && institutionContractTemp.Province != null) &&
institutionContractTemp.City == "شهرستان")
{
return opration.Failed("لطفا شهر را انتخاب کنید");
}
if (institutionContractTemp.Address == null && institutionContractTemp.Province != null)
{
return opration.Failed("لطفا آدرس را وارد کنید");
}
var hasValueAddedTax = payment.Tax.MoneyToDouble() > 0 ? "true" : "false";
var workshopsCount = institutionContractTemp.Workshops.Count.ToString();
var workshopDetails = institutionContractTemp
.Workshops.Select(x =>
{
var res = new InstitutionContractWorkshopInitial(x.WorkshopName, x.RollCall, x.RollCallInPerson,
x.CustomizeCheckout,
x.ContractAndCheckout,
x.ContractAndCheckoutInPerson, x.Insurance, x.InsuranceInPerson, x.CountPerson, x.Price);
if (x.WorkshopId != 0)
{
res.SetWorkshopId(x.WorkshopId);
}
return res;
}).ToList();
var employeeCount = institutionContractTemp.Workshops.Sum(x => x.CountPerson).ToString();
var oneMonthPayment = selectedDuration.OneMonthPaymentDiscounted.MoneyToDouble();
var contractingPartyFullName = previousInstitutionContract.ContractingPartyName;
var totalAmount = payment.PaymentAmount.MoneyToDouble();
var transaction = await _context.Database.BeginTransactionAsync();
var entity = new InstitutionContract(contractNo, previousInstitutionContract.RepresentativeId,
previousInstitutionContract.RepresentativeName,
previousInstitutionContract.ContractingPartyId,
contractingPartyFullName, contractDateGr, contractStart,
institutionContractTemp.Province, institutionContractTemp.City,
institutionContractTemp.Address, contractStartGr,
contractStart, contractEndGr, selectedDuration.ContractEnd,
oneMonthPayment, selectedDuration.DailyCompenseation.MoneyToDouble(),
selectedDuration.Obligation.MoneyToDouble(), totalAmount,
extensionNo, workshopsCount, employeeCount,
previousInstitutionContract.Description,
"NotOfficial", "JobRelation", hasValueAddedTax,
payment.Tax.MoneyToDouble(), [],
request.LawId, payment.DiscountPercetage, payment.DiscountedAmount.MoneyToDouble());
await CreateAsync(entity);
await SaveChangesAsync();
foreach (var workshop in institutionContractTemp.Workshops)
{
var workshopDetail = new InstitutionContractWorkshopInitial(
workshop.WorkshopName, workshop.RollCall, workshop.RollCallInPerson,
workshop.CustomizeCheckout, workshop.ContractAndCheckout,
workshop.ContractAndCheckoutInPerson, workshop.Insurance,
workshop.InsuranceInPerson, workshop.CountPerson, workshop.Price);
workshopDetail.SetWorkshopGroup(entity.WorkshopGroup);
if (workshop.WorkshopId != 0)
{
workshopDetail.SetWorkshopId(workshop.WorkshopId);
}
// Set parent reference
// Add to the parent's collection
entity.WorkshopGroup.InitialWorkshops.Add(workshopDetail);
}
// Save the changes again
await SaveChangesAsync();
FinancialStatment financialStatement;
if (_context.FinancialStatments.Any(x => x.ContractingPartyId == contractingParty.id))
{
financialStatement =
await _context.FinancialStatments.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingParty.id);
}
else
{
financialStatement = new FinancialStatment(contractingParty.id, contractingPartyFullName);
await _context.AddAsync(financialStatement);
}
if (request.IsInstallment && payment is InstitutionContractPaymentMonthlyViewModel monthly)
{
var installments = monthly.Installments.Select(x =>
new InstitutionContractInstallment(x.InstalmentDate.ToGeorgianDateTime(),
x.InstallmentAmountStr.MoneyToDouble(), "")).ToList();
// دریافت مبلغ اولین قسط
//این کار برای این هست که اولین قسط باید با تاریخ امروز باشد و باید به وضعیت مالی بدهی ایجاد شود که یوزر اولین بدهی را وارد کند
var firstInstallmentAmount = installments.First().Amount;
// حذف اولین قسط
installments.RemoveAt(0);
// ایجاد قسط جدید با تاریخ امروز
var todayInstallment = new InstitutionContractInstallment(DateTime.Today, firstInstallmentAmount, "");
// اضافه کردن قسط جدید به ابتدای لیست
installments.Insert(0, todayInstallment);
entity.SetInstallments(installments);
await SaveChangesAsync();
}
foreach (var contactInfo in institutionContractTemp.ContactInfos)
{
if (contactInfo.PhoneNumber != null)
{
var contactinfo = new InstitutionContractContactInfo(contactInfo.PhoneType,
contactInfo.Position, contactInfo.PhoneNumber, contactInfo.FnameLname, entity.id,
contactInfo.SendSmsString == "true");
_context.InstitutionContractContactInfos.Add(contactinfo);
}
}
await SaveChangesAsync();
await _smsService.SendInstitutionCreationVerificationLink(contractingParty.Phone, contractingPartyFullName,
entity.PublicId, contractingParty.id, entity.id);
await SaveChangesAsync();
await transaction.CommitAsync();
return opration.Succcedded();
}
#endregion
public async Task<InstitutionContractAmendmentWorkshopsResponse> GetAmendmentWorkshops(long institutionContractId)
{
var institutionContract = await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.CurrentWorkshops)
.FirstOrDefaultAsync(x => x.id == institutionContractId);
if (institutionContract.WorkshopGroup.CurrentWorkshops.Any(x => x.Price == 0))
{
throw new BadRequestException(
"این قرارداد قابل ارتقا به صورت ظاهری نیست لطفا به صورت دیتابیسی اقدام به ویرایش کنید");
}
var workshops = institutionContract.WorkshopGroup.CurrentWorkshops
.Select(x => new InstitutionContractAmendmentTempPrevWorkshop(x.WorkshopName, x.PersonnelCount,
x.Services.Contract, x.Services.ContractInPerson, x.Services.Insurance,
x.Services.InsuranceInPerson, x.Services.RollCall, x.Services.RollCallInPerson,
x.Services.CustomizeCheckout, x.Price,
x.WorkshopId ?? 0, x.id)).ToList();
var temp = new InstitutionContractAmendmentTemp(workshops, institutionContractId);
await _institutionAmendmentTemp.InsertOneAsync(temp);
var prevWorkshops = workshops.Select(x =>
new InstitutionContractAmendmentTempWorkshopViewModel()
{
WorkshopName = x.WorkshopName,
CountPerson = x.CountPerson,
ContractAndCheckout = x.ContractAndCheckout,
ContractAndCheckoutInPerson = x.ContractAndCheckoutInPerson,
Insurance = x.Insurance,
InsuranceInPerson = x.InsuranceInPerson,
RollCall = x.RollCall,
RollCallInPerson = x.RollCallInPerson,
CustomizeCheckout = x.CustomizeCheckout,
PriceStr = x.Price.ToMoney(),
Price = x.Price,
WorkshopId = x.WorkshopId,
WorkshopTempId = x.Id,
CurrentWorkshopId = x.CurrentWorkshopId,
TempId = temp.Id
})
.ToList();
var res = new InstitutionContractAmendmentWorkshopsResponse()
{
Workshops = prevWorkshops,
TempId = temp.Id
};
return res;
}
public async Task<InsitutionContractAmendmentPaymentResponse> GetAmendmentPaymentDetails(
InsitutionContractAmendmentPaymentRequest request)
{
var institutionContractAmendmentTemp = await _institutionAmendmentTemp
.Find(x => x.Id == request.TempId)
.FirstOrDefaultAsync();
if (institutionContractAmendmentTemp == null)
throw new NotFoundException("دیتای وارد شده نامعتبر است");
var amendmentStart = DateTime.Now;
var institutionContract = await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.CurrentWorkshops)
.FirstOrDefaultAsync(x => x.id == institutionContractAmendmentTemp.InstitutionContractId);
if (institutionContract == null)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
var amendmentEnd = institutionContract.ContractEndGr;
var haContractInPerson = institutionContract.WorkshopGroup.CurrentWorkshops
.Any(x => x.Services.ContractInPerson);
if (!haContractInPerson)
{
if (institutionContractAmendmentTemp.NewWorkshops.Any(x => x.ContractAndCheckoutInPerson))
{
throw new BadRequestException("برای قرارداد آنلاین نمیتوان سرویس حضوری انتخاب کرد");
}
}
var pc = new PersianCalendar();
int startYear = pc.GetYear(amendmentStart);
int startMonth = pc.GetMonth(amendmentStart);
int startDay = pc.GetDayOfMonth(amendmentStart);
int endYear = pc.GetYear(amendmentEnd);
int endMonth = pc.GetMonth(amendmentEnd);
int endDay = pc.GetDayOfMonth(amendmentEnd);
// اختلاف خام ماه‌ها
int monthDiff = (endYear - startYear) * 12 + (endMonth - startMonth);
// اگر حتی چند روز از ماه بعدی هم گذشته بود → رند به بالا
if (endDay > startDay)
monthDiff++;
var sumOneMonth = institutionContractAmendmentTemp.NewWorkshops.Sum(x => x.PriceDifference);
var baseAmount = monthDiff * sumOneMonth;
var tax = baseAmount * 0.10;
var totalPayment = tax + baseAmount;
var res = new InsitutionContractAmendmentPaymentResponse()
{
ContractStart = amendmentStart.ToFarsi(),
ContractEnd = amendmentEnd.ToFarsi(),
OneMonthAmount = sumOneMonth.ToMoney(),
TotalAmount = baseAmount.ToMoney(),
workshops = institutionContractAmendmentTemp.NewWorkshops
.Select(x=>
{
var prevWorkshop = institutionContractAmendmentTemp.PrevWorkshops
.FirstOrDefault(w=> w.Id == x.Id);
var isNewWorkshop = prevWorkshop == null;
return new InsitutionContractAmendmentPaymentWorkshopResponse()
{
WorkshopName = x.WorkshopName,
IsNewWorkshop = isNewWorkshop,
NewPersonnelCount = x.CountPerson,
PrevPersonnelCount = prevWorkshop?.CountPerson??0,
Price = x.PriceDifference,
OldServices = prevWorkshop != null? new WorkshopServicesViewModel()
{
Contract = prevWorkshop.ContractAndCheckout,
ContractInPerson = prevWorkshop.ContractAndCheckoutInPerson,
CustomizeCheckout = prevWorkshop.CustomizeCheckout,
Insurance = prevWorkshop.Insurance,
InsuranceInPerson = prevWorkshop.InsuranceInPerson,
RollCall = prevWorkshop.RollCall,
RollCallInPerson = prevWorkshop.RollCallInPerson,
}: new WorkshopServicesViewModel(),
NewServices = new WorkshopServicesViewModel()
{
Contract = x.ContractAndCheckout,
ContractInPerson = x.ContractAndCheckoutInPerson,
CustomizeCheckout = x.CustomizeCheckout,
Insurance = x.Insurance,
InsuranceInPerson = x.InsuranceInPerson,
RollCall = x.RollCall,
RollCallInPerson = x.RollCallInPerson,
},
};
}).OrderByDescending(x=>x.Price).ToList()
};
res.OneTime = new InstitutionContractPaymentOneTimeViewModel()
{
TotalAmount = baseAmount.ToMoney(),
PaymentAmount = totalPayment.ToMoney(),
Tax = tax.ToMoney()
};
if (haContractInPerson)
{
var installment =
InstitutionMonthlyInstallmentCaculation(monthDiff, totalPayment, amendmentStart.ToFarsi());
var firstPrevInstallment = installment.First();
var lastPrevInstallment = installment.Last();
var firstInstallment = new MonthlyInstallment()
{
InstallmentAmountStr = firstPrevInstallment.InstallmentAmountStr,
InstallmentCounter = firstPrevInstallment.InstallmentCounter,
InstalmentDate = amendmentStart.ToFarsi()
};
var lastInstallment = new MonthlyInstallment()
{
InstallmentAmountStr = lastPrevInstallment.InstallmentAmountStr,
InstallmentCounter = lastPrevInstallment.InstallmentCounter,
InstalmentDate = lastPrevInstallment.InstalmentDate
};
installment.Remove(firstPrevInstallment);
installment.Remove(lastPrevInstallment);
installment.Insert(0, firstInstallment);
installment.Add(lastInstallment);
res.Monthly = new InstitutionContractPaymentMonthlyViewModel()
{
Installments = installment,
TotalAmount = baseAmount.ToMoney(),
PaymentAmount = totalPayment.ToMoney(),
Tax = tax.ToMoney()
};
}
return res;
}
public async Task<InsertAmendmentTempWorkshopResponse> InsertAmendmentTempWorkshops(
InstitutionContractAmendmentTempWorkshopViewModel request)
{
var amendmentTemp = await _institutionAmendmentTemp
.Find(x => x.Id == request.TempId).FirstOrDefaultAsync();
if (amendmentTemp == null)
throw new BadRequestException("دیتای وارد شده نامعتبر است");
var workshopTemp = amendmentTemp.NewWorkshops
.FirstOrDefault(x => x.Id == request.WorkshopTempId);
var planForWorkshop = new WorkshopTempViewModel()
{
WorkshopName = request.WorkshopName,
CountPerson = request.CountPerson,
ContractAndCheckout = request.ContractAndCheckout,
ContractAndCheckoutInPerson = request.ContractAndCheckoutInPerson,
Insurance = request.Insurance,
InsuranceInPerson = request.InsuranceInPerson,
RollCall = request.RollCall,
RollCallInPerson = request.RollCallInPerson,
CustomizeCheckout = request.CustomizeCheckout
};
var price = _planPercentageRepository.GetInstitutionPlanForWorkshop(planForWorkshop)
.OnlineAndInPersonSumAmountDouble;
if (workshopTemp == null)
{
var newWorkshopTemp = new InstitutionContractAmendmentTempNewWorkshop(request.WorkshopName,
request.CountPerson,
request.ContractAndCheckout, request.ContractAndCheckoutInPerson,
request.Insurance, request.InsuranceInPerson,
request.RollCall, request.RollCallInPerson,
request.CustomizeCheckout, price,
request.WorkshopId,0,price,Guid.NewGuid());
workshopTemp = newWorkshopTemp;
amendmentTemp.NewWorkshops.Add(newWorkshopTemp);
await _institutionAmendmentTemp
.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp);
}
else
{
var prevWorkshop = amendmentTemp.PrevWorkshops
.FirstOrDefault(x => x.Id == workshopTemp.Id);
var differencePrice = 0d;
if (prevWorkshop != null)
{
differencePrice = price - prevWorkshop.Price;
}
else
{
differencePrice = price;
}
amendmentTemp.NewWorkshops.Remove(workshopTemp);
if (differencePrice<0)
{
differencePrice = 0;
}
workshopTemp.Edit(request.WorkshopName, request.CountPerson,
request.ContractAndCheckout, request.ContractAndCheckoutInPerson,
request.Insurance, request.InsuranceInPerson,
request.RollCall,
request.CustomizeCheckout, price, differencePrice);
amendmentTemp.NewWorkshops.Add(workshopTemp);
await _institutionAmendmentTemp
.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp);
}
return new InsertAmendmentTempWorkshopResponse()
{
WorkshopTempId = workshopTemp.Id,
Amount = workshopTemp.PriceDifference.ToMoney()
};
}
public async Task RemoveAmendmentWorkshops(Guid workshopTempId)
{
var amendmentTemp = await _institutionAmendmentTemp.Find(x => x.NewWorkshops.Any(w => w.Id == workshopTempId))
.FirstOrDefaultAsync();
if (amendmentTemp == null)
throw new BadRequestException("دیتای وارد شده نامعتبر است");
var workshopTemp = amendmentTemp.NewWorkshops.FirstOrDefault(x => x.Id == workshopTempId);
if (workshopTemp == null)
throw new BadRequestException("دیتای وارد شده نامعتبر است");
if (workshopTemp.CurrentWorkshopId != 0)
throw new BadRequestException("شما نمی توانید این کارگاه را حذف کنید زیرا در قرارداد اصلی وجود دارد");
amendmentTemp.NewWorkshops.Remove(workshopTemp);
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.Where(x => x.ContractingPartyId != 30428)
.Select(x => new InstitutionContractSelectListViewModel()
{
Id = x.id,
Text = x.FullName
});
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();
}
public async Task<List<InstitutionContractPrintViewModel>> PrintAllAsync(List<long> ids)
{
var query = _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.InitialWorkshops)
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.CurrentWorkshops)
.Where(x => ids.Contains(x.id));
var contractingPartyIds = query.Select(x => x.ContractingPartyId).ToList();
var contractingParties = await _context.PersonalContractingParties
.Where(x => contractingPartyIds.Contains(x.id))
.ToListAsync();
var list = query.ToList();
if (list.Count == 0)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
var res = new List<InstitutionContractPrintViewModel>();
foreach (var institution in list)
{
var contractingParty = contractingParties.FirstOrDefault(x => x.id == institution.ContractingPartyId);
if (contractingParty == null)
{
throw new NotFoundException("طرف حساب یافت نشد");
}
var law = await _context.Laws
.FirstOrDefaultAsync(x => x.id == institution.LawId);
var secondParty = new InstitutionContratVerificationParty()
{
Address = contractingParty.Address,
PhoneNumber = contractingParty.Phone,
CeoName = contractingParty.IsLegal == "حقیقی"
? $"{contractingParty.FName} {contractingParty.LName}"
: $"{contractingParty.CeoFName} {contractingParty.CeoLName}",
CompanyNameOrFullName = contractingParty.IsLegal == "حقیقی"
? $"{contractingParty.FName} {contractingParty.LName}"
: contractingParty.LName,
NationalCodeOrNationalId =
contractingParty.IsLegal == "حقیقی" ? contractingParty.Nationalcode : contractingParty.NationalId,
LegalType = contractingParty.IsLegal == "حقیقی" ? LegalType.Real : LegalType.Legal,
};
var lawViewModel = new LawViewModel()
{
Id = law.id,
CreatedAt = law.CreationDate,
HeadTitle = law.HeadTitle,
IsActive = law.IsActive,
Items = law.Items.Select(x => new LawItemViewModel()
{
Details = x.Details,
Header = x.Header
}).ToList(),
Notifications = law.Notifications,
Title = law.Title,
Type = law.Type,
Version = law.Version
};
var item = new InstitutionContractPrintViewModel()
{
ContractStart = institution.ContractStartFa,
ContractEnd = institution.ContractEndFa,
ContractNo = institution.ContractNo,
CreationDate = institution.CreationDate.ToFarsi(),
FirstParty = _firstParty,
SecondParty = secondParty,
LawViewModel = lawViewModel,
Obligation = institution.Obligation.ToMoney(),
PaymentPrice = institution.TotalAmount.ToMoney(),
TotalPrice = (institution.TotalAmount - institution.ValueAddedTax).ToMoney(),
TaxPrice = institution.ValueAddedTax.ToMoney(),
OneMonthPrice = institution.ContractAmountWithTax.ToMoney(),
OneMonthWithoutTax = institution.ContractAmount.ToMoney(),
OneMonthTax = institution.ContractAmountTax.ToMoney(),
VerifierFullName = institution.VerifierFullName,
VerifierPhoneNumber = institution.VerifierPhoneNumber,
VerifyCode = institution.VerifyCode,
VerifyDate = institution.VerifyCodeCreation.ToFarsi(),
VerifyTime = institution.VerifyCodeCreation.ToString("HH:mm:ss"),
Workshops = institution.WorkshopGroup.CurrentWorkshops
.Select(x => new GetInstitutionVerificationDetailsWorkshopsViewModel()
{
Name = x.WorkshopName,
PersonnelCount = x.PersonnelCount,
Services = new WorkshopServicesViewModel()
{
Contract = x.Services.Contract,
ContractInPerson = x.Services.ContractInPerson,
CustomizeCheckout = x.Services.CustomizeCheckout,
Insurance = x.Services.Insurance,
InsuranceInPerson = x.Services.InsuranceInPerson,
RollCall = x.Services.RollCall,
RollCallInPerson = x.Services.RollCallInPerson
},
Price = x.Price.ToMoney()
}).ToList()
};
res.Add(item);
}
return res;
}
public async Task AmendmentComplete(InstitutionContractAmendmentCompleteRequest request)
{
var amendmentTemp = await _institutionAmendmentTemp
.Find(x=>x.Id == request.TempId).FirstOrDefaultAsync();
if (amendmentTemp == null)
throw new BadRequestException("دیتای وارد شده نامعتبر است");
var institutionContract = await _context.InstitutionContractSet
.Include(x=>x.Amendments)
.Include(x=>x.WorkshopGroup)
.ThenInclude(x=>x.CurrentWorkshops)
.FirstOrDefaultAsync(x => x.id == amendmentTemp.InstitutionContractId);
List<InstitutionContractInstallment> installments = [];
double amount = 0;
if (request.IsInstallment)
{
installments = amendmentTemp.MonthlyPayment.Installments.Select(x=>
new InstitutionContractInstallment(x.InstalmentDate.ToGeorgianDateTime(),
x.InstallmentAmountStr.MoneyToDouble(), "")).ToList();
amount = amendmentTemp.MonthlyPayment.PaymentAmount.MoneyToDouble();
}
else
{
amount = amendmentTemp.OneTimePayment.PaymentAmount.MoneyToDouble();
}
var newWorkshops = amendmentTemp
.NewWorkshops.Where(x=>x.CurrentWorkshopId ==0).ToList();
var newWorkshopTempIds = newWorkshops.Select(x=>x.Id).ToList();
var changes = newWorkshops.Select(x=>
InstitutionContractAmendmentChange.CreateWorkshopCreatedChange(DateTime.Now,x.RollCall,x.RollCallInPerson,x.CustomizeCheckout,
x.ContractAndCheckout,x.ContractAndCheckoutInPerson,x.Insurance,x.InsuranceInPerson,x.CountPerson)).ToList();
var changedWorkshops = amendmentTemp.NewWorkshops
.Where(x => !newWorkshopTempIds.Contains(x.Id)).ToList();
foreach (var changedWorkshop in changedWorkshops)
{
var prev = amendmentTemp.PrevWorkshops.FirstOrDefault(x => x.Id == changedWorkshop.Id);
if (prev == null)
throw new BadRequestException("دیتای وارد شده ناقص ذخیره شده است");
// مقایسه مقادیر بولین بین prev و changedWorkshop برای تشخیص تغییرات
var changedBooleans = new Dictionary<string, (bool Previous, bool Current)>();
if (prev.CustomizeCheckout != changedWorkshop.CustomizeCheckout)
changedBooleans.Add("CustomizeCheckout", (prev.CustomizeCheckout, changedWorkshop.CustomizeCheckout));
if (prev.ContractAndCheckout != changedWorkshop.ContractAndCheckout)
changedBooleans.Add("ContractAndCheckout", (prev.ContractAndCheckout, changedWorkshop.ContractAndCheckout));
if (prev.ContractAndCheckoutInPerson != changedWorkshop.ContractAndCheckoutInPerson)
changedBooleans.Add("ContractAndCheckoutInPerson", (prev.ContractAndCheckoutInPerson, changedWorkshop.ContractAndCheckoutInPerson));
if (prev.Insurance != changedWorkshop.Insurance)
changedBooleans.Add("Insurance", (prev.Insurance, changedWorkshop.Insurance));
if (prev.InsuranceInPerson != changedWorkshop.InsuranceInPerson)
changedBooleans.Add("InsuranceInPerson", (prev.InsuranceInPerson, changedWorkshop.InsuranceInPerson));
if (prev.RollCall != changedWorkshop.RollCall)
changedBooleans.Add("RollCall", (prev.RollCall, changedWorkshop.RollCall));
if (prev.RollCallInPerson != changedWorkshop.RollCallInPerson)
changedBooleans.Add("RollCallInPerson", (prev.RollCallInPerson, changedWorkshop.RollCallInPerson));
// اگر تغییری وجود داشته باشد، آن را به لیست تغییرات اضافه کن
if (changedBooleans.Any())
{
var change = InstitutionContractAmendmentChange.CreateServicesChange(
DateTime.Now,
changedWorkshop.WorkshopId,
changedWorkshop.RollCall,
changedWorkshop.RollCallInPerson,
changedWorkshop.CustomizeCheckout,
changedWorkshop.ContractAndCheckout,
changedWorkshop.ContractAndCheckoutInPerson,
changedWorkshop.Insurance,
changedWorkshop.InsuranceInPerson);
changes.Add(change);
}
if (changedWorkshop.CountPerson != prev.CountPerson)
{
var difference = changedWorkshop.CountPerson - prev.CountPerson;
var change = InstitutionContractAmendmentChange.CreatePersonCountChange(
DateTime.Now,
changedWorkshop.CountPerson,
difference,changedWorkshop.WorkshopId);
changes.Add(change);
}
}
var amendment = new InstitutionContractAmendment(institutionContract.id,installments,amount,
request.IsInstallment,changes,request.LawId);
institutionContract.AddAmendment(amendment);
//await _smsService.SendInstitutionAmendmentVerificationLink(
// institutionContract.VerifierPhoneNumber,
// institutionContract.ContractingPartyName,
// institutionContract.PublicId,
// institutionContract.ContractingPartyId,
// institutionContract.id
// );
await _institutionAmendmentTemp.DeleteOneAsync(x=>x.Id == amendmentTemp.Id);
await _context.SaveChangesAsync();
}
public async Task<GetInstitutionAmendmentVerificationDetailsViewModel> GetAmendmentVerificationDetails(Guid id,
long amendmentId)
{
var institutionContract = await _context.InstitutionContractSet
.Include(x => x.Amendments)
.FirstOrDefaultAsync(x => x.PublicId == id);
if (institutionContract == null)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
var amendment = institutionContract.Amendments
.FirstOrDefault(x => x.id == amendmentId);
if (amendment == null)
throw new NotFoundException("ارتقا یافت نشد");
if (amendment.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
throw new BadRequestException("این ارتقا قبلا تایید شده است");
throw new NotImplementedException();
}
public async Task<GetInstitutionContractWorkshopsDetails> GetContractWorkshopsDetails(long id)
{
var institutionContract = await _context.InstitutionContractSet
.Include(x => x.WorkshopGroup)
.ThenInclude(x => x.InitialWorkshops)
.FirstOrDefaultAsync(x => x.id == id);
if (institutionContract == null)
throw new NotFoundException("قرارداد مؤسسه یافت نشد");
var workshops = institutionContract.WorkshopGroup.InitialWorkshops
.Select(x =>
{
var plan = _planPercentageRepository.GetInstitutionPlanForWorkshop(new WorkshopTempViewModel()
{
CountPerson = x.PersonnelCount,
ContractAndCheckout = x.Services.Contract,
ContractAndCheckoutInPerson = x.Services.ContractInPerson,
Insurance = x.Services.Insurance,
InsuranceInPerson = x.Services.InsuranceInPerson,
RollCall = x.Services.RollCall,
RollCallInPerson = x.Services.RollCallInPerson,
CustomizeCheckout = x.Services.CustomizeCheckout,
});
return new InstitutionContractListWorkshop()
{
EmployeeCount = x.PersonnelCount,
Price = x.Price.ToMoney(),
WorkshopName = x.WorkshopName,
WorkshopServices = new WorkshopServicesViewModel()
{
Contract = x.Services.Contract,
ContractPrice =plan.ContractAndCheckout ,
ContractInPerson = x.Services.ContractInPerson,
ContractInPersonPrice = plan.ContractAndCheckoutInPerson,
CustomizeCheckout = x.Services.CustomizeCheckout,
CustomizeCheckoutPrice = plan.CustomizeCheckout,
Insurance = x.Services.Insurance,
InsurancePrice =plan.Insurance ,
InsuranceInPerson = x.Services.InsuranceInPerson,
InsuranceInPersonPrice = plan.InsuranceInPerson,
RollCall = x.Services.RollCall,
RollCallPrice =plan.RollCall ,
RollCallInPerson = x.Services.RollCallInPerson,
RollCallInPersonPrice = "0",
}
};
}).ToList();
return new GetInstitutionContractWorkshopsDetails()
{
Workshops = workshops
};
}
private InstitutionContractExtensionPaymentResponse CalculateInPersonPayment(
InstitutionContractExtensionPlanDetail selectedPlan, double baseAmount, double tenPercent,
InstitutionContractDuration duration)
{
// حالت پرداخت یکجا
var oneTimeBase = baseAmount - tenPercent;
var oneTimeTax = oneTimeBase * 0.10;
var oneTimeTotal = oneTimeBase + oneTimeTax;
var res = new InstitutionContractExtensionPaymentResponse
{
OneTime = new()
{
TotalAmount = oneTimeBase.ToMoney(),
Tax = oneTimeTax.ToMoney(),
PaymentAmount = oneTimeTotal.ToMoney()
}
};
// حالت پرداخت اقساطی
var monthlyTax = baseAmount * 0.10;
var monthlyTotal = baseAmount + monthlyTax;
var installments =
InstitutionMonthlyInstallmentCaculation((int)duration, monthlyTotal, selectedPlan.ContractStart);
res.Monthly = new()
{
TotalAmount = baseAmount.ToMoney(),
Tax = monthlyTax.ToMoney(),
PaymentAmount = monthlyTotal.ToMoney(),
Installments = installments
};
return res;
}
private InstitutionContractExtensionPaymentResponse CalculateOnlinePayment(double baseAmount, double tenPercent)
{
var tax = tenPercent;
var total = baseAmount + tax;
return new InstitutionContractExtensionPaymentResponse
{
OneTime = new()
{
TotalAmount = baseAmount.ToMoney(),
Tax = tax.ToMoney(),
PaymentAmount = total.ToMoney()
}
};
}
private InstitutionContractExtensionPlanDetail CalculateInstitutionPlan(InstitutionContractDuration duration,
double amount,
bool hasInPersonContract, DateTime contractStart)
{
var result = new InstitutionContractExtensionPlanDetail();
var months = (int)duration;
//بدست آوردن جمع کل مبالغ کارگاه بر اساس مدت قراداد
var totalPrice = months * amount;
var contractStartFa = contractStart.ToFarsi();
var findeEnd = Tools.FindEndOfContract(contractStartFa, ((int)duration).ToString());
var contractEndDate = findeEnd.endDateGr;
result.ContractEnd = contractEndDate.ToFarsi();
result.ContractStart = contractStartFa;
result.Obligation = totalPrice.ToMoney();
result.DailyCompenseation = ((amount * 10) / 100).ToMoney();
if (hasInPersonContract)
{
result.OneMonthDiscount = "0";
result.OneMonthOriginalPayment = amount.ToMoney();
result.OneMonthPaymentDiscounted = amount.ToMoney();
result.TotalPayment = totalPrice.ToMoney();
}
else
{
var discount = duration switch
{
InstitutionContractDuration.OneMonth => 0,
InstitutionContractDuration.ThreeMonths => 5,
InstitutionContractDuration.SixMonths => 10,
InstitutionContractDuration.TwelveMonths => 15,
_ => throw new ArgumentOutOfRangeException(nameof(duration), duration, null)
};
var oneMonthDiscountAmount = (amount * discount) / 100;
var oneMonthDiscountedPayment = amount - oneMonthDiscountAmount;
var totalDiscount = oneMonthDiscountAmount * months;
var discountedPayment = totalPrice - totalDiscount;
result.OneMonthDiscount = oneMonthDiscountAmount.ToMoney();
result.OneMonthPaymentDiscounted = oneMonthDiscountedPayment.ToMoney();
result.OneMonthOriginalPayment = totalPrice.ToMoney();
result.TotalPayment = discountedPayment.ToMoney();
}
return result;
}
public static List<MonthlyInstallment> InstitutionMonthlyInstallmentCaculation(int duration,
double monthlyTotalPaymentDouble,
string installmentstart)
{
var originalDay = int.Parse(installmentstart.Substring(8, 2));
var installmentList = new List<MonthlyInstallment>();
int instalmentCount = duration;
var instalmentAmount = monthlyTotalPaymentDouble / instalmentCount;
int currentInstallmentStartDay = int.Parse(installmentstart.Substring(8, 2));
bool endOfMonth = currentInstallmentStartDay == 31;
// Loop through each installment period
for (int i = 1; i <= instalmentCount; i++)
{
string installmentDate;
// For first installment, use the initial date
if (i == 1)
{
installmentDate = installmentstart;
}
else
{
var currentDay = int.Parse(installmentstart.Substring(8, 2));
var currentMonth = int.Parse(installmentstart.Substring(5, 2));
var currentYear = int.Parse(installmentstart.Substring(0, 4));
// Get next month's date
var nextMonthFa = installmentstart.ToGeorgianDateTime().AddMonthsFa(1, out var nextMonth);
var maxDayInNextMonth = int.Parse(nextMonthFa.FindeEndOfMonth().Substring(8, 2));
// Use original day if possible, otherwise use last day of month
var dayToUse = Math.Min(originalDay, maxDayInNextMonth);
installmentDate = nextMonthFa.Substring(0, 8) + dayToUse.ToString("D2");
// Update installmentstart for next iteration
installmentstart = installmentDate;
}
installmentList.Add(new MonthlyInstallment()
{
InstallmentAmountStr = instalmentAmount.ToMoney(),
InstallmentCounter = i switch
{
1 => "اول",
2 => "دوم",
3 => "سوم",
4 => "چهارم",
5 => "پنجم",
6 => "ششم",
7 => "هفتم",
8 => "هشتم",
9 => "نهم",
10 => "دهم",
11 => "یازدهم",
12 => "دوازدهم",
_ => "دوازدهم",
},
InstalmentDate = installmentDate
});
}
return installmentList;
}
#endregion
#region DebtReminderSms
/// <summary>
/// دریافت لیست - ارسال پیامک
/// فراخوانی از سمت بک گراند سرویس
/// </summary>
/// <returns></returns>
public async Task<bool> SendReminderSmsForBackgroundTask()
{
var now = DateTime.Now;
// تبدیل تاریخ میلادی به شمسی
var persianNow = now.ToFarsi();
var persianEndOfMonth = int.Parse(persianNow.FindeEndOfMonth().Substring(8, 2));
var dayOfMonth = int.Parse(persianNow.Substring(8, 2));
var hour = now.Hour;
var minute = now.Minute;
var checkAnyToExecute = false;
//اگر آخرین روز ماه باشد
//اگر روز مثلا عدد روز 31 بود ولی آخرین روز ماه 30 بود
if (dayOfMonth == persianEndOfMonth)
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth >= dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractDebtReminder &&
x.IsActive
);
}
else
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth == dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractDebtReminder &&
x.IsActive
);
}
if (checkAnyToExecute)
{
//اجرای تسک
//دریافت لیست بدهکاران
var smsListData = await GetSmsListData(now, TypeOfSmsSetting.InstitutionContractDebtReminder);
string typeOfSms = "یادآور بدهی ماهانه";
string sendMessStart = "شروع پیامک یادآور";
string sendMessEnd = "پایان پیامک یادآور";
//ارسال پیامک
await SendReminderSmsToContractingParties(smsListData, typeOfSms, sendMessStart, sendMessEnd);
Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute);
return true;
}
return false;
}
#region MonthlySms
/// <summary>
/// ارسال پیامک صورت حساب ماهانه
/// </summary>
/// <param name="now"></param>
/// <returns></returns>
public async Task SendMonthlySms(DateTime now)
{
//دریافت لیست بدهکاران
var smsListData = await GetSmsListData(now, TypeOfSmsSetting.MonthlyInstitutionContract);
string typeOfSms = "صورت حساب ماهانه";
string sendMessStart = "شروع پیامک ماهانه";
string sendMessEnd = "پایان پیامک ماهانه";
//ارسال پیامک
await SendReminderSmsToContractingParties(smsListData, typeOfSms, sendMessStart, sendMessEnd);
}
#endregion
#region BlockSms
/// <summary>
/// پیامک بلاک
/// </summary>
/// <returns></returns>
public async Task SendBlockSmsForBackgroundTask()
{
var now = DateTime.Now;
// تبدیل تاریخ میلادی به شمسی
var persianNow = now.ToFarsi();
var persianEndOfMonth = int.Parse(persianNow.FindeEndOfMonth().Substring(8, 2));
var dayOfMonth = int.Parse(persianNow.Substring(8, 2));
var hour = now.Hour;
var minute = now.Minute;
var checkAnyToExecute = false;
//اگر آخرین روز ماه باشد
//اگر روز مثلا عدد روز 31 بود ولی آخرین روز ماه 30 بود
if (dayOfMonth == persianEndOfMonth)
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth >= dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.BlockContractingParty &&
x.IsActive
);
}
else
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth == dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.BlockContractingParty &&
x.IsActive
);
}
if (checkAnyToExecute)
{
//اجرای تسک
//دریافت لیست بدهکاران
var smsListData = await GetBlockListData(now);
string typeOfSms = "اعلام مسدودی طرف حساب";
string sendMessStart = "شروع پیامک مسدودی";
string sendMessEnd = "پایان پیامک مسدودی";
//ارسال پیامک
await SendBlockSmsToContractingParties(smsListData, typeOfSms, sendMessStart, sendMessEnd);
Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute);
}
}
public async Task<List<BlockSmsListData>> GetBlockListData(DateTime checkDate)
{
var smsList = new List<BlockSmsListData>();
var institutionContracts = await _context.InstitutionContractSet.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
OfficialCompany = x.OfficialCompany
}).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate &&
x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First())
.ToListAsync();
var contractingPartyList = await _context.PersonalContractingParties
.Where(x => institutionContracts.Select(ins => ins.ContractingPartyId).Contains(x.id)).ToListAsync();
var financialStatmentList = await _context.FinancialStatments.AsSplitQuery()
.Where(x => institutionContracts.Select(ins => ins.ContractingPartyId).Contains(x.ContractingPartyId))
.Include(x => x.FinancialTransactionList).Where(x => x.FinancialTransactionList.Count > 0).ToListAsync();
var phoneNumberList = await _context.InstitutionContractContactInfos
.Where(x => institutionContracts.Select(ins => ins.Id).Contains(x.InstitutionContractId))
.Where(x => x.SendSms && x.PhoneType == "شماره همراه" && !string.IsNullOrWhiteSpace(x.PhoneNumber) &&
x.PhoneNumber.Length == 11).ToListAsync();
foreach (var item in institutionContracts)
{
try
{
var contractingParty = contractingPartyList.FirstOrDefault(x => x.id == item.ContractingPartyId);
if (contractingParty != null && contractingParty.IsBlock == "true")
{
var partyName = contractingParty.IsLegal == "حقیقی"
? $"{contractingParty.FName} {contractingParty.LName}"
: $"{contractingParty.LName}";
if (!string.IsNullOrWhiteSpace(contractingParty.SureName))
partyName = $"{partyName} ({contractingParty.SureName})";
if (partyName.Length > 25) partyName = $"{partyName.Substring(0, 25)}";
var isLegal = contractingParty.IsLegal == "حقوقی" ? true : false;
var hasFinancialStatment =
financialStatmentList.Any(x =>
x.ContractingPartyId == item.ContractingPartyId & x.FinancialTransactionList.Count > 0);
var hasPhonNumber = phoneNumberList.Any(x => x.InstitutionContractId == item.Id);
if (hasFinancialStatment && hasPhonNumber)
{
var transactions =
financialStatmentList.FirstOrDefault(x => x.ContractingPartyId == item.ContractingPartyId);
var debtor = transactions.FinancialTransactionList.Sum(x => x.Deptor);
var creditor = transactions.FinancialTransactionList.Sum(x => x.Creditor);
var id = $"{item.ContractingPartyId}";
var aprove = $"{transactions.id}";
var balance = debtor - creditor;
if (balance > 0)
{
var jobRelation = "بابت قرارداد مابین (روابط کار)";
var taxAndFinancial = "بابت قرارداد مابین (حسابداری و مالیات)";
var jobRelationContract = transactions.FinancialTransactionList
.OrderByDescending(x => x.TdateGr).FirstOrDefault(x =>
x.TypeOfTransaction == "debt" && x.DescriptionOption == jobRelation);
var taxAndFinancialContract = transactions.FinancialTransactionList
.OrderByDescending(x => x.TdateGr).FirstOrDefault(x =>
x.TypeOfTransaction == "debt" && x.DescriptionOption == taxAndFinancial);
var jobRelationContractAmounts =
jobRelationContract != null ? jobRelationContract.Deptor : 0;
var taxAndFinancialContractAmounts =
taxAndFinancialContract != null ? taxAndFinancialContract.Deptor : 0;
var sumOfAmounts = jobRelationContractAmounts * 2 + taxAndFinancialContractAmounts * 2;
if (balance >= sumOfAmounts)
{
var phoneNumbers = new List<CreateContactInfo>();
phoneNumbers = phoneNumberList.Where(x => x.InstitutionContractId == item.Id)
.Select(x => new CreateContactInfo
{
PhoneType = x.PhoneType,
PhoneNumber = x.PhoneNumber,
InstitutionContractId = x.InstitutionContractId,
SendSms = x.SendSms
}).Where(x => x.PhoneNumber.Length == 11).ToList();
var accountType = item.OfficialCompany == "Official" ? "ol" : "nol";
var balanceToMoney = balance.ToMoney();
var amount = balanceToMoney + " " + "ریال" + " ";
foreach (var number in phoneNumbers)
{
smsList.Add(new BlockSmsListData()
{
PhoneNumber = number.PhoneNumber,
PartyName = partyName,
AccountType = accountType,
Amount = amount,
ContractingPartyId = contractingParty.id,
InstitutionContractId = item.Id,
AproveId = aprove
});
}
}
}
}
}
}
catch (Exception e)
{
string name = item.ContractingPartyName.Length > 18
? item.ContractingPartyName.Substring(0, 18)
: item.ContractingPartyName;
string errMess = $"{name}-خطا";
await _smsService.Alarm("09114221321", errMess);
}
}
return smsList;
}
#endregion
/// <summary>
///دریافت لیست بدهکارن
/// جهت ارسال پیامک
/// </summary>
/// <returns></returns>
public async Task<List<SmsListData>> GetSmsListData(DateTime checkDate, TypeOfSmsSetting typeOfSmsSetting)
{
var watch = new Stopwatch();
var smsList = new List<SmsListData>();
var currentMonthStart = ($"{(checkDate.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
var previusMonthEnd = currentMonthStart.AddDays(-1);
var previusMonthStart = ($"{(previusMonthEnd.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
watch.Start();
//دریافت اطلاعات بدهکارن و ساخت لیست پیامک
#region GetSmsListData
//var rollcallServiceList = _context.RollCallServices.Where(x => x.StartService.Date <= previusMonthStart.Date && x.EndService.Date >= previusMonthEnd.Date).ToList();
var institutionContracts = await _context.InstitutionContractSet.AsSplitQuery().Select(x =>
new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
OfficialCompany = x.OfficialCompany
}).Where(x => x.ContractStartGr < checkDate && x.ContractEndGr >= checkDate &&
x.ContractAmountDouble > 0).GroupBy(x => x.ContractingPartyId).Select(x => x.First())
.ToListAsync();
var contractingPartyList = await _context.PersonalContractingParties
.Where(x => institutionContracts.Select(ins => ins.ContractingPartyId).Contains(x.id)).ToListAsync();
var financialStatmentList = await _context.FinancialStatments.AsSplitQuery()
.Where(x => institutionContracts.Select(ins => ins.ContractingPartyId).Contains(x.ContractingPartyId))
.Include(x => x.FinancialTransactionList).Where(x => x.FinancialTransactionList.Count > 0).ToListAsync();
var phoneNumberList = await _context.InstitutionContractContactInfos
.Where(x => institutionContracts.Select(ins => ins.Id).Contains(x.InstitutionContractId))
.Where(x => x.SendSms && x.PhoneType == "شماره همراه" && !string.IsNullOrWhiteSpace(x.PhoneNumber) &&
x.PhoneNumber.Length == 11).ToListAsync();
Console.WriteLine("database query: " + watch.Elapsed);
watch.Stop();
watch.Start();
foreach (var item in institutionContracts)
{
try
{
var contractingParty = contractingPartyList.FirstOrDefault(x => x.id == item.ContractingPartyId);
//var isSend = sendedSms.Any(x => x.ContractingPatyId == contractingParty.Id);
if (!string.IsNullOrWhiteSpace(contractingParty.LName))
{
//Thread.Sleep(500);
var partyName = contractingParty.IsLegal == "حقیقی"
? $"{contractingParty.FName} {contractingParty.LName}"
: $"{contractingParty.LName}";
if (!string.IsNullOrWhiteSpace(contractingParty.SureName))
partyName = $"{partyName} ({contractingParty.SureName})";
if (partyName.Length > 25) partyName = $"{partyName.Substring(0, 25)}";
var isLegal = contractingParty.IsLegal == "حقوقی" ? true : false;
var isBlock = contractingParty.IsBlock == "true" ? true : false;
var isActive = contractingParty.IsActiveString == "true" ? true : false;
if (!string.IsNullOrWhiteSpace(contractingParty.IsActiveString) && isActive)
{
var hasFinancialStatement =
financialStatmentList.Any(x => x.ContractingPartyId == item.ContractingPartyId);
var hasPhonNumber = phoneNumberList.Any(x => x.InstitutionContractId == item.Id);
if (hasFinancialStatement && hasPhonNumber)
{
var phoneNumbers = phoneNumberList.Where(x => x.InstitutionContractId == item.Id)
.Select(x => new CreateContactInfo
{
PhoneType = x.PhoneType,
PhoneNumber = x.PhoneNumber,
InstitutionContractId = x.InstitutionContractId,
SendSms = x.SendSms
}).Where(x => x.PhoneNumber.Length == 11).ToList();
var transactions = financialStatmentList.FirstOrDefault(x =>
x.ContractingPartyId == item.ContractingPartyId);
var debtor = transactions.FinancialTransactionList.Sum(x => x.Deptor);
var creditor = transactions.FinancialTransactionList.Sum(x => x.Creditor);
var id = $"{item.ContractingPartyId}";
var aprove = $"{transactions.id}";
var balance = debtor - creditor;
if (balance > 0) // اگر بدهکار بود
{
//var employers = _context.Employers.Where(x => x.ContractingPartyId == item.ContractingPartyId)
// .Select(x => x.id);
//var workshops = _context.WorkshopEmployers.Where(x => employers.Contains(x.EmployerId))
// .Select(x => x.WorkshopId).Distinct().ToList();
//var services =
// rollcallServiceList.Where(x => workshops.Contains(x.WorkshopId)).ToList();
//var hasRollCallService = services.Count > 0;
//موقت
var hasRollCallService = false;
//if (hasRollCallService)
//{
// var employees =
// _context.RollCallEmployees.Where(x => workshops.Contains(x.WorkshopId))
// .Select(x => x.id);
// var employeeCount = _context.RollCallEmployeesStatus
// .Where(x => employees.Contains(x.RollCallEmployeeId))
// .Count(x => x.EndDate.Date == activeStatusDate.Date);
// if (employeeCount == 0)
// hasRollCallService = false;
//}
if (isLegal)
{
if (item.OfficialCompany == "Official") // حقوقی بدهکار رسمی
{
var balanceToMoney = balance.ToMoney();
foreach (var number in phoneNumbers)
{
if (!string.IsNullOrWhiteSpace(number.PhoneNumber) &&
number.PhoneNumber.Length == 11)
{
int messageId = 0;
string message = "";
bool isSuccessSend = false;
if (hasRollCallService)
{
string publicId = transactions.PublicIdStr;
string code1 = publicId.Substring(0, 25);
string code2 = publicId.Substring(25);
var templateId = 789638;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 983035;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
{
var templateId = 161233;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 394006;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
}
}
}
else if (item.OfficialCompany == "NotOfficial") // حقوقی بدهکار غیر رسمی
{
var balanceToMoney = balance.ToMoney();
foreach (var number in phoneNumbers)
{
if (!string.IsNullOrWhiteSpace(number.PhoneNumber) &&
number.PhoneNumber.Length == 11)
{
int messageId = 0;
string message = "";
bool isSuccessSend = false;
if (hasRollCallService)
{
string publicId = transactions.PublicIdStr;
string code1 = publicId.Substring(0, 25);
string code2 = publicId.Substring(25);
var templateId = 789638;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 983035;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
{
var templateId = 347415;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 679068;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
}
}
}
}
else
{
if (item.OfficialCompany == "Official") // حقیقی بدهکار رسمی
{
var balanceToMoney = balance.ToMoney();
foreach (var number in phoneNumbers)
{
if (!string.IsNullOrWhiteSpace(number.PhoneNumber) &&
number.PhoneNumber.Length == 11)
{
int messageId = 0;
string message = "";
bool isSuccessSend = false;
if (hasRollCallService)
{
string publicId = transactions.PublicIdStr;
string code1 = publicId.Substring(0, 25);
string code2 = publicId.Substring(25);
var templateId = 768277;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 479624;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
{
var templateId = 998180;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 646040;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
}
}
}
else if (item.OfficialCompany == "NotOfficial") // حقیقی بدهکار غیر رسمی
{
var balanceToMoney = balance.ToMoney();
foreach (var number in phoneNumbers)
{
if (!string.IsNullOrWhiteSpace(number.PhoneNumber) &&
number.PhoneNumber.Length == 11)
{
int messageId = 0;
string message = "";
bool isSuccessSend = false;
if (hasRollCallService)
{
var templateId = 768277;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 479624;
}
string publicId = transactions.PublicIdStr;
string code1 = publicId.Substring(0, 25);
string code2 = publicId.Substring(25);
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBillNew",
Code1 = code1,
Code2 = code2,
InstitutionContractId = item.Id
});
}
else
{
var templateId = 810539;
if (typeOfSmsSetting ==
TypeOfSmsSetting.MonthlyInstitutionContract)
{
templateId = 566537;
}
smsList.Add(new SmsListData()
{
PhoneNumber = number.PhoneNumber,
TemplateId = templateId,
PartyName = partyName,
Amount = balanceToMoney,
ContractingPartyId = contractingParty.id,
AproveId = aprove,
TypeOfSmsMethod = "MonthlyBill",
Code1 = "",
Code2 = "",
InstitutionContractId = item.Id
});
}
}
}
}
}
}
phoneNumbers = new List<CreateContactInfo>();
}
}
}
}
catch (Exception e)
{
string name = item.ContractingPartyName.Length > 18
? item.ContractingPartyName.Substring(0, 18)
: item.ContractingPartyName;
string errMess = $"{name}-خطا";
// _smsService.Alarm("09114221321", errMess);
}
}
#endregion
Console.WriteLine("SmsListData: " + watch.Elapsed);
return smsList;
}
public async Task SendBlockSmsToContractingParties(List<BlockSmsListData> smsListData, string typeOfSms,
string sendMessStart, string sendMessEnd)
{
if (smsListData.Any())
{
await _smsService.Alarm("09114221321", sendMessStart);
Thread.Sleep(1000);
await _smsService.Alarm("09111485044", sendMessStart);
Thread.Sleep(1000);
int successProcess = 1;
int countList = smsListData.Count;
foreach (var item in smsListData)
{
try
{
var smsResult = await _smsService.BlockMessage(item.PhoneNumber, item.PartyName,
item.Amount, item.AccountType, $"{item.ContractingPartyId}", item.AproveId);
Thread.Sleep(1000);
var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(smsResult.messaeId,
smsResult.message, typeOfSms,
item.PartyName, item.PhoneNumber, item.ContractingPartyId, item.InstitutionContractId);
await _smsResultRepository.CreateAsync(createSmsResult);
await _smsResultRepository.SaveChangesAsync();
}
catch (Exception e)
{
string name = item.PartyName.Length > 18 ? item.PartyName.Substring(0, 18) : item.PartyName;
string errMess = $"{name}-خطا";
await _smsService.Alarm("09114221321", errMess);
}
Thread.Sleep(600);
var percent = (successProcess / (double)countList) * 100;
await _hubContext.Clients.Group(SendSmsHub.GetGroupName(10))
.SendAsync("showStatus", (int)percent);
successProcess += 1;
}
await _smsService.Alarm("09114221321", sendMessEnd);
Thread.Sleep(1000);
await _smsService.Alarm("09111485044", sendMessEnd);
}
}
/// <summary>
/// ارسال پیامک های یاد آور بدهی
/// </summary>
/// <returns></returns>
public async Task SendReminderSmsToContractingParties(List<SmsListData> smsListData, string typeOfSms,
string sendMessStart, string sendMessEnd)
{
//ارسال پیامک با اساس لیست
#region SendSMSFromList
if (smsListData.Any())
{
//await _smsService.Alarm("09114221321", sendMessStart);
//Thread.Sleep(1000);
//await _smsService.Alarm("09111485044", sendMessStart);
//Thread.Sleep(1000);
int successProcess = 1;
int countList = smsListData.Count;
foreach (var item in smsListData)
{
try
{
if (item.TypeOfSmsMethod == "MonthlyBill")
{
var res = await _smsService.MonthlyBill(item.PhoneNumber, item.TemplateId, item.PartyName,
item.Amount,
$"{item.ContractingPartyId}", item.AproveId);
if (res.isSucceded)
{
var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
res.message, typeOfSms, item.PartyName, item.PhoneNumber,
item.ContractingPartyId, item.InstitutionContractId);
await _smsResultRepository.CreateAsync(createSmsResult);
await _smsResultRepository.SaveChangesAsync();
}
}
else
{
var res = await _smsService.MonthlyBillNew(item.PhoneNumber, item.TemplateId, item.PartyName,
item.Amount, item.Code1, item.Code2);
if (res.isSucceded)
{
var createSmsResult = new Company.Domain.SmsResultAgg.SmsResult(res.messaeId,
res.message, typeOfSms, item.PartyName, item.PhoneNumber,
item.ContractingPartyId, item.InstitutionContractId);
await _smsResultRepository.CreateAsync(createSmsResult);
await _smsResultRepository.SaveChangesAsync();
}
}
Thread.Sleep(600);
}
catch (Exception e)
{
string name = item.PartyName.Length > 18 ? item.PartyName.Substring(0, 18) : item.PartyName;
string errMess = $"{name}-خطا";
await _smsService.Alarm("09114221321", errMess);
}
var percent = (successProcess / (double)countList) * 100;
await _hubContext.Clients.Group(SendSmsHub.GetGroupName(7))
.SendAsync("showStatus", (int)percent);
successProcess += 1;
}
//await _smsService.Alarm("09114221321", sendMessEnd);
//Thread.Sleep(1000);
//await _smsService.Alarm("09111485044", sendMessEnd);
}
#endregion
}
#region PrivateMetods
/// <summary>
/// دریافت صورت حساب مالی با آی دی طرف حساب
/// </summary>
/// <param name="contractingPartyId"></param>
/// <returns></returns>
private async Task<FinancialStatmentViewModel?> GetFinancialByContractingPartyId(long contractingPartyId)
{
return await _context.FinancialStatments.Include(x => x.FinancialTransactionList)
.Select(x => new FinancialStatmentViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
PublicId = x.PublicIdStr,
FinancialTransactionViewModels = x.FinancialTransactionList.Select(t =>
new FinancialTransactionViewModel
{
Id = t.id,
TdateFa = t.TdateFa,
TdateGr = t.TdateGr,
Description = t.TypeOfTransaction == "debt"
? "ایجاد درآمد" + " " + t.DescriptionOption + " " + t.Description
: "دریافت درآمد" + " " + t.DescriptionOption + " " + t.Description,
Deptor = t.Deptor,
DeptorString = t.Deptor != 0 ? t.Deptor.ToMoney() : "",
Creditor = t.Creditor,
CreditorString = t.Creditor != 0 ? t.Creditor.ToMoney() : "",
Balance = t.Balance,
MessageText = t.MessageText,
SentSms = t.SentSms,
SentSmsDateFa = t.SentSmsDateFa,
FinancialStatementId = t.FinancialStatementId,
TypeOfTransaction = t.TypeOfTransaction,
DescriptionOption = t.DescriptionOption
}).OrderBy(t => t.TdateGr).ToList()
})
.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
}
#endregion
#region InstitutionContractConfirm
/// <summary>
/// ارسال پیامک یادآور تایید قراداد مالی
/// </summary>
/// <returns></returns>
public async Task SendInstitutionContractConfirmSmsTask()
{
var now = DateTime.Now;
// تبدیل تاریخ میلادی به شمسی
var persianNow = now.ToFarsi();
var persianEndOfMonth = int.Parse(persianNow.FindeEndOfMonth().Substring(8, 2));
var dayOfMonth = int.Parse(persianNow.Substring(8, 2));
var hour = now.Hour;
var minute = now.Minute;
var checkAnyToExecute = false;
//اگر آخرین روز ماه باشد
//اگر روز مثلا عدد روز 31 بود ولی آخرین روز ماه 30 بود
if (dayOfMonth == persianEndOfMonth)
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth >= dayOfMonth && /// اگر بزرگتر یا مساوی رو جاری بود
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractConfirm &&
x.IsActive
);
}
else
{
checkAnyToExecute = await _context.SmsSettings
.AnyAsync(x =>
x.DayOfMonth == dayOfMonth &&
x.TimeOfDay.Hours == hour &&
x.TimeOfDay.Minutes == minute &&
x.TypeOfSmsSetting == TypeOfSmsSetting.InstitutionContractConfirm &&
x.IsActive
);
}
if (checkAnyToExecute)
{
//اجرای تسک
//دریافت لیست قراداد های تایید نشده
var fromAmonthAgo = now.AddDays(-30);
var pendingContracts = await _context.InstitutionContractSet
.Where(x => x.CreationDate >= fromAmonthAgo && x.CreationDate.Date != now.Date && x.VerificationStatus == InstitutionContractVerificationStatus.PendingForVerify)
.Join(_context.PersonalContractingParties,
contract => contract.ContractingPartyId,
contractingParty => contractingParty.id,
(contract, contractingParty) => new { contract, contractingParty }).Select(x => new InstitutionCreationVerificationSmsDto
{
Number = x.contractingParty.Phone,
FullName = x.contractingParty.IsLegal == "حقیقی" ? $"{x.contractingParty.FName} {x.contractingParty.LName}" : $"{x.contractingParty.LName}",
ContractingPartyId = x.contract.ContractingPartyId,
InstitutionContractId = x.contract.id,
InstitutionId = x.contract.PublicId,
}).ToListAsync();
string typeOfSms = "یادآور تایید قرارداد مالی";
foreach (var item in pendingContracts)
{
var sendResult = await _smsService.SendInstitutionCreationVerificationLink(item.Number, item.FullName,
item.InstitutionId, item.ContractingPartyId, item.InstitutionContractId, typeOfSms);
Thread.Sleep(1000);
}
Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute);
}
}
#endregion
#endregion
#region CreateMontlyTransaction
/// <summary>
/// ایجاد سند مالی برای قرارداد ها
/// </summary>
/// <returns></returns>
public async Task CreateTransactionForInstitutionContracts(DateTime endOfMonthGr, string endOfMonthFa,
string description)
{
#region FindeNextMonth 1th
var firstDayOfMonthGr = ($"{endOfMonthFa.Substring(0, 8)}01").ToGeorgianDateTime();
var nextMonthGr = endOfMonthGr.AddDays(1);
var endOfCurrentMonth = (($"{endOfMonthFa.Substring(0, 8)}/01").FindeEndOfMonth()).ToGeorgianDateTime();
#endregion
#region GetAvtiveContracts
var institutionContracts = await _context.InstitutionContractSet.Where(x => x.IsActiveString == "true")
.Include(x => x.Installments)
.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
TypeOfContract = x.TypeOfContract,
IsInstallment = x.IsInstallment,
VerificationStatus = x.VerificationStatus,
SigningType = x.SigningType,
InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).Where(x =>
x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0 && x.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
.ToListAsync();
#endregion
#region GetFutureContracts
List<InstitutionContractViewModel> futureContracts = await _context.InstitutionContractSet
.Where(x => x.IsActiveString == "true" &&
x.ContractStartGr.Date == nextMonthGr.Date && x.ContractAmount > 0)
.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
}).ToListAsync();
#region GetDectivedContractOnCurrentMonth
if (futureContracts.Any())
{
List<long> futureContractIds = futureContracts.Select(x => x.ContractingPartyId).ToList();
List<InstitutionContractViewModel> deatcivedContract = await _context.InstitutionContractSet
.Where(x => x.IsActiveString == "false" && futureContractIds.Contains(x.ContractingPartyId) &&
x.ContractEndGr.Date == endOfCurrentMonth.Date && x.ContractAmount > 0 && x.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
.Select(x => new InstitutionContractViewModel
{
Id = x.id,
ContractingPartyId = x.ContractingPartyId,
ContractingPartyName = x.ContractingPartyName,
ContractStartGr = x.ContractStartGr,
ContractStartFa = x.ContractStartFa,
ContractEndGr = x.ContractEndGr,
ContractEndFa = x.ContractEndFa,
IsActiveString = x.IsActiveString,
ContractAmountDouble = x.ContractAmount,
TypeOfContract = x.TypeOfContract,
IsInstallment = x.IsInstallment,
VerificationStatus = x.VerificationStatus,
SigningType = x.SigningType,
InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).ToListAsync();
if (deatcivedContract.Any())
institutionContracts.AddRange(deatcivedContract);
}
// قرارداد هایی که پطور یکجا پرداخت شده اند
var paidInFull = institutionContracts.Where(x =>
x.SigningType != InstitutionContractSigningType.Legacy && x.IsInstallment == false && x.SigningType != null).ToList();
//حذف قراداد هایی که یکجا پرداخت شده اند از لیست ایجاد سند ماهانه
institutionContracts = institutionContracts.Except(paidInFull).ToList();
#region RollCallServicCompute
var rollcallServiceList = await
_context.RollCallServices.Where(x => x.IsActiveString == "true").ToListAsync();
var activeStatusDate = new DateTime(2121, 03, 21);
#endregion
int count = 0;
int serviceCounter = 0;
foreach (var item in institutionContracts)
{
var jobRelation = "بابت قرارداد مابین (روابط کار)";
var taxAndFinancial = "بابت قرارداد مابین (حسابداری و مالیات)";
var contractingParty = await
_context.PersonalContractingParties.FirstOrDefaultAsync(x => x.id == item.ContractingPartyId);
string partyName = item.ContractingPartyName;
if (partyName.Length > 18) partyName = $"{partyName.Substring(0, 18)}";
var isblock = contractingParty.IsBlock == "true" ? true : false;
if (contractingParty != null && contractingParty.IsActiveString == "true" &&
endOfMonthGr <= item.ContractEndGr)
{
try
{
var hasFinancialStatment =
await _context.FinancialStatments.AnyAsync(x =>
x.ContractingPartyId == item.ContractingPartyId);
var computeOption = item.TypeOfContract == "JobRelation" ? jobRelation : taxAndFinancial;
if (hasFinancialStatment)
{
var financialStatmentData = await
_context.FinancialStatments.FirstOrDefaultAsync(x =>
x.ContractingPartyId == item.ContractingPartyId);
var financialStatmentId = financialStatmentData.id;
var alreadyCreated = await _context.FinancialTransactions.AnyAsync(x =>
x.DescriptionOption == computeOption && x.TypeOfTransaction == "debt" &&
x.TdateGr.Date == endOfMonthGr.Date && x.FinancialStatementId == financialStatmentId);
if (!alreadyCreated)
{
if (item.IsInstallment)
{
var instalment = item.InstallmentList
.FirstOrDefault(x =>
x.InstallmentDateGr >= firstDayOfMonthGr &&
x.InstallmentDateGr <= endOfMonthGr);
if (instalment != null)
{
var transaction = new FinancialTransaction(financialStatmentId, endOfMonthGr,
endOfMonthFa,
description,
"debt", computeOption, instalment.AmountDouble, 0, 0, isblock);
await _financialTransactionRepository.CreateAsync(transaction);
await _financialTransactionRepository.SaveChangesAsync();
}
}
else
{
var transaction = new FinancialTransaction(financialStatmentId, endOfMonthGr,
endOfMonthFa,
description,
"debt", computeOption, item.ContractAmountDouble, 0, 0, isblock);
await _financialTransactionRepository.CreateAsync(transaction);
await _financialTransactionRepository.SaveChangesAsync();
}
}
}
else
{
var statement = new FinancialStatment(item.ContractingPartyId, item.ContractingPartyName);
await _financialStatmentRepository.CreateAsync(statement);
await _financialStatmentRepository.SaveChangesAsync();
if (item.IsInstallment)
{
var instalment = item.InstallmentList
.FirstOrDefault(x =>
x.InstallmentDateGr >= firstDayOfMonthGr &&
x.InstallmentDateGr <= endOfMonthGr);
if (instalment != null)
{
var transaction = new FinancialTransaction(statement.id, endOfMonthGr, endOfMonthFa,
description,
"debt", computeOption, instalment.AmountDouble, 0, 0, isblock);
await _financialTransactionRepository.CreateAsync(transaction);
await _financialTransactionRepository.SaveChangesAsync();
}
}
else
{
var transaction = new FinancialTransaction(statement.id, endOfMonthGr, endOfMonthFa,
description,
"debt", computeOption, item.ContractAmountDouble, 0, 0, isblock);
await _financialTransactionRepository.CreateAsync(transaction);
await _financialTransactionRepository.SaveChangesAsync();
}
}
#region RollCallServicCompute
//ایجاد سند مالی حضورغیاب
//قرارداد هایی که جدید نیستند و اقساط ندارند
//کارگاه های استثناء : کباب مهدی 30520 و نمونه پروتئین 30739
if (item.SigningType != InstitutionContractSigningType.OtpBased && item.SigningType != InstitutionContractSigningType.Physical
&& !item.IsInstallment && item.ContractingPartyId != 30520 && item.ContractingPartyId != 30739)
{
try
{
//TODO
//@refactor Need
var employers = await _context.Employers
.Where(x => x.ContractingPartyId == item.ContractingPartyId)
.Select(x => x.id).ToListAsync();
var workshops = await _context.WorkshopEmployers
.Where(x => employers.Contains(x.EmployerId))
.Select(x => x.WorkshopId).Distinct().ToListAsync();
var services =
rollcallServiceList.Where(x => workshops.Contains(x.WorkshopId)).ToList();
if (services.Any())
{
foreach (var rollCallService in services)
{
//var spaning = (int)(endOfMonthGr - rollCallService.StartService).TotalDays + 1;
int monthCounter = 0;
//var currentMonthStart = ($"{(endOfMonthGr.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
//var prevMonthEnd = currentMonthStart.AddDays(-1);
//var prevMonthStart = ($"{(prevMonthEnd.ToFarsi()).Substring(0, 8)}01").ToGeorgianDateTime();
var monthCurrent = endOfMonthFa.Substring(5, 2);
var yearCurrent = endOfMonthFa.Substring(0, 4);
var currentMonthName = monthCurrent.ToFarsiMonthByNumber();
var workshop =
await _context.Workshops.FirstOrDefaultAsync(x =>
x.id == rollCallService.WorkshopId);
string rollCallTransactionDescription = "";
//if (rollCallService.StartService <= prevMonthStart)
//{
// var monthPrev = prevMonthEnd.ToFarsi().Substring(5, 2);
// var yearPrev = prevMonthEnd.ToFarsi().Substring(0, 4);
// var prevMonthName = monthPrev.ToFarsiMonthByNumber();
// description =
// $"{prevMonthName} و {currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
// monthCounter = 2;
//}
//else if (rollCallService.StartService <= currentMonthStart &&
// rollCallService.StartService > prevMonthStart)
//{
// monthCounter = 1;
// description = $"{currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
//}
if (rollCallService.StartService <= firstDayOfMonthGr)
{
monthCounter = 1;
rollCallTransactionDescription =
$"{currentMonthName} {yearCurrent} - {workshop.WorkshopFullName}";
}
var employees = await
_context.RollCallEmployees
.Where(x => x.WorkshopId == rollCallService.WorkshopId)
.Select(x => x.id).ToListAsync();
var employeeCount = await _context.RollCallEmployeesStatus
.Where(x => employees.Contains(x.RollCallEmployeeId))
.CountAsync(x => x.EndDate.Date == activeStatusDate.Date);
if (employeeCount > 0 && monthCounter > 0)
{
var dailyWageYearlySalery = await _context.YearlySalaries
.Include(i => i.YearlySalaryItemsList)
.FirstOrDefaultAsync(x =>
x.StartDate.Date <= DateTime.Now.Date &&
x.EndDate >= DateTime.Now.Date);
var dailyWage = dailyWageYearlySalery.YearlySalaryItemsList
.Where(x => x.ItemName == "مزد روزانه")
.Select(x => x.ItemValue).FirstOrDefault();
var planPercentage = await _context.PlanPercentages.FirstOrDefaultAsync();
var countPersonnel = employeeCount;
var planByCountPerson = await _context.InstitutionPlans
.FirstOrDefaultAsync(x => x.CountPerson == countPersonnel);
var amountForOneMonth = (((dailyWage * planPercentage.RollCallPercent) / 100) *
planByCountPerson.CountPerson *
planByCountPerson.IncreasePercentage);
var amountWithoutTax = amountForOneMonth * monthCounter;
var tenPercent = amountWithoutTax * 10 / 100;
var totalAmonut = amountWithoutTax + tenPercent;
double roundFloor = Math.Floor(totalAmonut);
double result = Math.Ceiling(roundFloor / 10000.0) * 10000;
var financialStatment = await
_context.FinancialStatments.FirstOrDefaultAsync(x =>
x.ContractingPartyId == item.ContractingPartyId);
long financialStatementId = 0;
if (financialStatment != null)
{
financialStatementId = financialStatment.id;
}
else
{
var statement = new FinancialStatment(item.ContractingPartyId,
item.ContractingPartyName);
await _context.FinancialStatments.AddAsync(statement);
await _context.SaveChangesAsync();
financialStatementId = statement.id;
}
var transaction = new FinancialTransaction(financialStatementId, endOfMonthGr,
endOfMonthFa,
rollCallTransactionDescription,
"debt", "بابت سرویس حضور غیاب", result, 0, 0);
var alreadyCreated = await _context.FinancialTransactions.AnyAsync(x =>
x.FinancialStatementId == financialStatementId &&
x.Description == rollCallTransactionDescription &&
x.DescriptionOption == "بابت سرویس حضور غیاب" &&
x.TypeOfTransaction == "debt" &&
x.TdateFa == endOfMonthFa);
if (!alreadyCreated)
{
serviceCounter++;
Console.WriteLine(serviceCounter + " - " +
rollCallService.StartService.ToFarsi() + " - " +
rollCallService.WorkshopId + " - " + employeeCount +
$" - {totalAmonut} - round {result}");
await _context.FinancialTransactions.AddAsync(transaction);
await _context.SaveChangesAsync();
}
//Console.WriteLine(" number : " + counter + " - " + rollCallService.StartService.ToFarsi() + " - WorkshopId : " + rollCallService.WorkshopId + " - monthCount : " + monthCounter + " - employeeCount : " + employeeCount + $" - Amount : {amountWithoutTax.ToMoney()}" + $" - ten : {tenPercent.ToMoney()} total : {totalAmonut.ToMoney()}");
}
}
}
}
catch (Exception)
{
string errMess = $"{item.ContractingPartyId}-RollCall";
await _smsService.Alarm("09114221321", errMess);
}
}
#endregion
}
catch (Exception e)
{
string name = partyName.Length > 18 ? partyName.Substring(0, 18) : partyName;
string errMess = $"{name}-خطا";
await _smsService.Alarm("09114221321", errMess);
}
count += 1;
Console.WriteLine(count);
}
}
#endregion
#endregion
}
public async Task<long> GetIdByInstallmentId(long installmentId)
{
return await _context.InstitutionContractSet.Include(x => x.Installments)
.Where(x => x.Installments.Any(i => i.Id == installmentId))
.Select(x => x.id).FirstOrDefaultAsync();
}
#endregion
#region CustomViewModels
public class WorkshopsAndEmployeeViewModel
{
public List<WorkshopViewModel> WorkshopViewModels { get; set; }
public string WorkshopCount { get; set; }
public string EmployeeCount { get; set; }
public int ArchiveCode { get; set; }
}
#endregion
}