using System.Collections.Concurrent; using System.Transactions; using _0_Framework.Application; using _0_Framework.Application.Enums; using _0_Framework.Application.Sms; using _0_Framework.Exceptions; using AccountManagement.Application.Contracts.Account; using Company.Domain.TemporaryClientRegistrationAgg; using CompanyManagement.Infrastructure.Excel.InstitutionContract; using CompanyManagment.App.Contracts.Employer; using CompanyManagment.App.Contracts.InstitutionContract; using CompanyManagment.App.Contracts.InstitutionContractContactinfo; using CompanyManagment.App.Contracts.InstitutionPlan; using CompanyManagment.App.Contracts.PersonalContractingParty; using CompanyManagment.App.Contracts.Representative; using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.Workshop; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using ServiceHost.Areas.Client.Pages.Company.PaymentToEmployee; using ServiceHost.BaseControllers; namespace ServiceHost.Areas.Admin.Controllers; /// /// کنترلر قرارداد های مالی موسسه /// public class institutionContractController : AdminBaseController { private readonly IInstitutionContractApplication _institutionContractApplication; private readonly IPersonalContractingPartyApp _contractingPartyApplication; private readonly IContactInfoApplication _contactInfoApplication; private readonly IAccountApplication _accountApplication; private readonly IEmployerApplication _employerApplication; private readonly IWorkshopApplication _workshopApplication; private readonly ITemporaryClientRegistrationApplication _temporaryClientRegistration; private readonly ITemporaryClientRegistrationApplication _clientRegistrationApplication; private static readonly ConcurrentDictionary _locks = new ConcurrentDictionary(); public institutionContractController(IInstitutionContractApplication institutionContractApplication, IPersonalContractingPartyApp contractingPartyApplication, IContactInfoApplication contactInfoApplication, IAccountApplication accountApplication, IEmployerApplication employerApplication, IWorkshopApplication workshopApplication, ITemporaryClientRegistrationApplication temporaryClientRegistration, ITemporaryClientRegistrationApplication clientRegistrationApplication) { _institutionContractApplication = institutionContractApplication; _contractingPartyApplication = contractingPartyApplication; _contactInfoApplication = contactInfoApplication; _accountApplication = accountApplication; _employerApplication = employerApplication; _workshopApplication = workshopApplication; _temporaryClientRegistration = temporaryClientRegistration; _clientRegistrationApplication = clientRegistrationApplication; } /// /// لیست قرارداد های مالی /// /// [HttpGet] public async Task>> GetList( InstitutionContractListSearchModel searchModel) { return await _institutionContractApplication.GetList(searchModel); } /// /// وضعیت تب ها /// /// /// [HttpGet("stats")] public async Task> GetListStats( InstitutionContractListSearchModel searchModel) { return await _institutionContractApplication.GetListStats(searchModel); } /// /// ویرایش /// /// [HttpPut] public async Task> Edit([FromBody] EditInstitutionContractRequest command) { var op = new OperationResult(); var phoneNumber = command.ContactInfos.FirstOrDefault(x => x.SendSmsString == "true" && x.Position == "طرف قرارداد" && x.PhoneType == "شماره همراه"); var conractingParty = _contractingPartyApplication.GetDetails(command.ContractingPartyId); if (conractingParty.IsLegal == "حقیقی" && string.IsNullOrWhiteSpace(conractingParty.Nationalcode)) return new JsonResult(op.Failed("کد ملی طرف حساب وجود ندارد")); if (conractingParty.IsLegal == "حقوقی" && string.IsNullOrWhiteSpace(conractingParty.NationalId)) return new JsonResult(op.Failed("شناسه ملی طرف حساب وجود ندارد")); if (phoneNumber == null) return new JsonResult(op.Failed("تعیین شماره همراه با سمت طرف قرارداد اجباریست")); //if (string.IsNullOrWhiteSpace(command.HasValueAddedTax)) // command.HasValueAddedTax = "false"; var result = await _institutionContractApplication.EditAsync(command); var contractingPartyId = _institutionContractApplication.GetDetails(result.SendId); var counter = command.ContactInfos.Count; var getOldContarct = _institutionContractApplication.NewSearch(new InstitutionContractSearchModel() { ContractingPartyId = contractingPartyId.ContractingPartyId, IsActiveString = "both" }) .Where(x => x.IsActiveString == "false" || x.IsActiveString == "blue").ToList(); if (result.IsSuccedded && counter > 0) { if (getOldContarct.Count > 0) { foreach (var item in getOldContarct) { _contactInfoApplication.RemoveContactInfo(item.Id); foreach (var phone in command.ContactInfos) { if (phone.PhoneNumber != null) { var contactinfo = new CreateContactInfo { InstitutionContractId = item.Id, PhoneType = phone.PhoneType, Position = phone.Position, PhoneNumber = phone.PhoneNumber, FnameLname = phone.FnameLname, SendSms = phone.SendSmsString == "true" ? true : false }; _contactInfoApplication.Create(contactinfo); } Thread.Sleep(500); } } } _contactInfoApplication.RemoveContactInfo(command.Id); foreach (var item in command.ContactInfos) { if (item.PhoneNumber != null) { var contactinfo = new CreateContactInfo { InstitutionContractId = result.SendId, PhoneType = item.PhoneType, Position = item.Position, PhoneNumber = item.PhoneNumber, FnameLname = item.FnameLname, SendSms = item.SendSmsString == "true" ? true : false }; _contactInfoApplication.Create(contactinfo); } Thread.Sleep(500); } //ساخت اکانت کلاینت var userPass = conractingParty.IsLegal == "حقیقی" ? conractingParty.Nationalcode : conractingParty.NationalId; var checkExistAccount = _accountApplication.CheckExistClientAccount(userPass); if (!checkExistAccount) { var createAcc = new RegisterAccount { Fullname = conractingParty.LName, Username = userPass, Password = userPass, Mobile = phoneNumber.PhoneNumber, NationalCode = userPass }; var res = _accountApplication.RegisterClient(createAcc); if (res.IsSuccedded) _institutionContractApplication.CreateContractingPartyAccount(command.ContractingPartyId, res.SendId); } } //Thread.Sleep(500); //for (int i = 0; i <= counter - 1; i++) //{ // if (command.ContactInformationList[i].PhoneNumber != null) // { // var contactinfo = new CreateContactInfo() // { // InstitutionContractId = result.SendId, // PhoneType = command.ContactInformationList[i].PhoneType, // Position = command.ContactInformationList[i].Position, // PhoneNumber = command.ContactInformationList[i].PhoneNumber, // FnameLname = command.ContactInformationList[i].FnameLname, // SendSms = command.ContactInformationList[i].SendSmsString == "true" ? true : false // }; // _contactInfoApplication.Create(contactinfo); // } // Thread.Sleep(500); //} return new JsonResult(result); } /// /// حذف قرارداد مالی /// /// /// [HttpDelete("{id}")] public async Task> Remove(long id) { _institutionContractApplication.RemoveContract(id); return new OperationResult().Succcedded(); } [HttpPost("deActive/{id}")] public ActionResult DeActive(long id, string balance) { var result = new OperationResult(); if (balance == "0") { result = _institutionContractApplication.DeActive(id); if (result.IsSuccedded) result = _institutionContractApplication.DeActiveAllConnections(id); } else { result = _institutionContractApplication.DeActiveBlue(id); if (result.IsSuccedded) result = _institutionContractApplication.DeActiveAllConnections(id); } return result; } /// /// غیر فعال /// /// /// [HttpPost("active/{id}")] public ActionResult IsActive(long id) { var result = _institutionContractApplication.Active(id); if (result.IsSuccedded) { result = _institutionContractApplication.ReActiveAllConnections(id); } return result; } [HttpPost("sign/{id}")] public ActionResult Sign(long Id) { var result = _institutionContractApplication.Sign(Id); if (result.IsSuccedded) return new JsonResult(new { isSuccedded = true }); return new JsonResult(new { isSuccedded = false }); } [HttpPost("unsign/{id}")] public ActionResult UnSign(long Id) { var id = Convert.ToInt64(Id); var result = _institutionContractApplication.UnSign(Id); if (result.IsSuccedded) return new JsonResult(new { isSuccedded = true }); return new JsonResult(new { isSuccedded = false }); } /// /// بلاک طرف حساب /// /// /// [HttpPost("block-contracting-party/{id}")] public IActionResult OnPostBlockContractingParty(long id) { var result = _contractingPartyApplication.Block(id); var afterActtion = _contractingPartyApplication.GetDetails(id); return new JsonResult(new { isSuccedded = result.IsSuccedded, isBlock = afterActtion.IsBlock, blockTimes = afterActtion.BlockTimes }); } /// /// آنبلاک طرف حساب /// /// /// [HttpPost("unblock-contracting-party/{id}")] public IActionResult OnPostUnBlockContractingParty(long id) { var result = _contractingPartyApplication.DisableBlock(id); var afterActtion = _contractingPartyApplication.GetDetails(id); return new JsonResult(new { isSuccedded = result.IsSuccedded, isBlock = afterActtion.IsBlock, blockTimes = afterActtion.BlockTimes }); } /// /// دانلود اکسل /// /// [HttpGet("excel")] public IActionResult OnGetDownloadExcel() { var institutionContractViewModels = _institutionContractApplication.NewSearch(new() { IsActiveString = "both", TypeOfContract = "both" }); var bytes = InstitutionContractExcelGenerator.GenerateExcel(institutionContractViewModels); return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"قرارداد های مالی.xlsx"); } [HttpPost("create/inquiry")] public async Task>> CreateInquiry( [FromBody] CreateInquiryRequest request) { var res = await _temporaryClientRegistration.CreateContractingPartyTemp(request.NationalCode, request.DateOfBirth, request.Mobile); return res; } [HttpPost("workshop-service-calculator")] public ActionResult WorkshopServiceCalculator([FromBody]CreateWorkshopTemp command) { var workshopTemp = new WorkshopTempViewModel { WorkshopName = command.WorkshopName, CountPerson = command.CountPerson, ContractAndCheckout = command.ContractAndCheckout, Insurance = command.Insurance, RollCall = command.RollCall, CustomizeCheckout = command.CustomizeCheckout, ContractAndCheckoutInPerson = command.ContractAndCheckoutInPerson, InsuranceInPerson = command.InsuranceInPerson }; var response = _temporaryClientRegistration.GetInstitutionPlanForWorkshop(workshopTemp); var result = new WorkshopServiceCalculatorResponse { TotalAmount = response.OnlineAndInPersonSumAmountStr }; return result; } [HttpPost("create/institution-plan-calculator")] public async Task> InstitutionPlanCalculator( [FromBody] InstitutionPlanCalculatorRequest request) { var res = await _temporaryClientRegistration.GetTotalPaymentAndWorkshopList(request.TotalAmountMonth,duration: request.Duration,request.HasInPersonContract); var result = new InstitutionPlanCalculatorResponse() { TotalAmountWithTax = res.OneTimeTotalPaymentStr, OneTimeTotalAmountWithoutTax = res.OneTimeWithoutTaxPaymentStr, OneTimeValueAddedTaxStr = res.OneTimeValueAddedTaxStr, Installments = res.MonthlyInstallments, OneTimeTotalAmount = res.OneTimeTotalPaymentStr, MonthlyTotalAmount = res.MonthlyTotalPaymentStr, MonthlyTotalAmountWithoutTax = res.MonthlyWithoutTaxPaymentStr, ContractStart = res.ContractStartFa, ContractEnd = res.ContractEndFa, Discount = res.Discount, MonthlyValueAddedTaxStr = res.MonthlyValueAddedTaxStr, DailyCompensation = res.DailyCompensation, Obligation = res.OneTimeTotalPaymentStr, PaymentForOneMonth = res.SumOfWorkshopsPayment, DiscountedAmountForOneMonth = res.DiscountedAmountForOneMonth }; return result; } /// /// ایجاد /// /// /// [HttpPost] public async Task> Create([FromBody]CreateInstitutionContractRequest command) { var res =await _institutionContractApplication.CreateAsync(command); if(!res.IsSuccedded) throw new BadRequestException(res.Message); return res; } /// /// ارسال لینک تایید قوانین و مقررات به طرف حساب /// /// /// [HttpPost("create/send-link/{contractingPartyTempId}")] public async Task> SendAgreementLink(long contractingPartyTempId) { return await _temporaryClientRegistration.SendAgreementLink(contractingPartyTempId); } [HttpPost("create/verify-code")] public async Task> CheckVerifyCode(VerifyCodeRequest request) { using var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); var operationResult = await _clientRegistrationApplication.CheckVerifyCodeIsTrue(request.ContractingPartyId, request.verifyCode); if (!operationResult.IsSuccedded) return operationResult; operationResult = await _temporaryClientRegistration.PayOffCompleted(request.ContractingPartyId); if (operationResult.IsSuccedded) transaction.Complete(); return operationResult; } /// /// /// /// /// [HttpGet("/api/institutionContract/Verification/{id:guid}")] [AllowAnonymous] public async Task> GetVerificationDetails(Guid id) { return await _institutionContractApplication.GetVerificationDetails(id); } [HttpPost("/api/institutionContract/Verify")] [AllowAnonymous] public async Task> Verify([FromBody] InstitutionVerificationRequest command) { var res = await _institutionContractApplication.VerifyOtp(command.Id, command.Code); return res; } [HttpPost("/api/institutionContract/Verification/{id:guid}/send-otp")] [AllowAnonymous] public async Task>> SendVerifyOtp(Guid id) { var sem = _locks.GetOrAdd(id, _ => new SemaphoreSlim(1, 1)); await sem.WaitAsync(); try { var res = await _institutionContractApplication.SendVerifyOtp(id); return res; } finally { sem.Release(); } } [HttpGet("extenstion/inquiry/{previousContractId}")] public async Task> ExtensionInquiry(long previousContractId) { var res= await _institutionContractApplication.GetExtensionInquiry(previousContractId); return res; } [HttpPost("extenstion/workshops")] public async Task> ExtensionWorkshops([FromBody] InstitutionContractExtensionWorkshopsRequest request) { var res =await _institutionContractApplication.GetExtensionWorkshops(request); return res; } [HttpPost("extenstion/institution-plan")] public async Task> ExtensionInstitutionPlan([FromBody]InstitutionContractExtensionPlanRequest request) { var res =await _institutionContractApplication.GetExtensionInstitutionPlan(request); return res; } [HttpPost("extenstion/payment-method")] public async Task> GetExtensionPaymentMethod([FromBody]InstitutionContractExtensionPaymentRequest request) { var res =await _institutionContractApplication.GetExtensionPaymentMethod(request); return res; } [HttpPost("extenstion/complete")] public async Task> ExtensionComplete([FromBody]InstitutionContractExtensionCompleteRequest request) { var res =await _institutionContractApplication.ExtensionComplete(request); return res; } } public class VerifyOtpRequest { public Guid PublicId { get; set; } public string Code { get; set; } } public class InstitutionVerificationRequest { public Guid Id { get; set; } public string Code { get; set; } } public class InstitutionPlanCalculatorResponse { public string TotalAmountWithTax { get; set; } public string OneTimeTotalAmountWithoutTax { get; set; } public string OneTimeTotalAmount { get; set; } public string OneTimeValueAddedTaxStr { get; set; } public string MonthlyTotalAmount { get; set; } public string MonthlyTotalAmountWithoutTax { get; set; } public string ContractStart { get; set; } public string ContractEnd { get; set; } public string MonthlyValueAddedTaxStr { get; set; } public string DailyCompensation { get; set; } public string Obligation { get; set; } public string PaymentForOneMonth { get; set; } public string DiscountedAmountForOneMonth { get; set; } public string Discount { get; set; } public List Installments { get; set; } } public class WorkshopServiceCalculatorResponse { public string TotalAmount { get; set; } } public record InstitutionPlanCalculatorRequest(double TotalAmountMonth,bool HasInPersonContract, InstitutionContractDuration Duration = InstitutionContractDuration.TwelveMonths); public class CreateInquiryRequest { public string NationalCode { get; set; } public string DateOfBirth { get; set; } public string Mobile { get; set; } } public class VerifyCodeRequest { public long ContractingPartyId { get; set; } public string verifyCode { get; set; } }