using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework.Application.Sms; using _0_Framework.Application.UID; using Company.Domain.ContarctingPartyAgg; using Company.Domain.InstitutionPlanAgg; using Company.Domain.TemporaryClientRegistrationAgg; using CompanyManagment.App.Contracts.InstitutionPlan; using CompanyManagment.App.Contracts.TemporaryClientRegistration; using IPE.SmsIrClient.Models.Results; using Microsoft.EntityFrameworkCore; using PersianTools.Core; namespace CompanyManagment.Application; public class TemporaryClientRegistrationApplication : ITemporaryClientRegistrationApplication { private readonly IContractingPartyTempRepository _contractingPartyTempRepository; private readonly IPersonalContractingPartyRepository _personalContractingPartyRepository; private readonly IUidService _uidService; private readonly IWorkshopTempRepository _workshopTempRepository; private readonly IPlanPercentageRepository _planPercentageRepository; private readonly IWorkshopServicesTempRepository _workshopServicesTempRepository; private readonly IInstitutionContractTempRepository _institutionContractTempRepository; private readonly ISmsService _smsService; public TemporaryClientRegistrationApplication(IContractingPartyTempRepository contractingPartyTempRepository, IPersonalContractingPartyRepository personalContractingPartyRepository, IUidService uidService, IWorkshopTempRepository workshopTempRepository, IPlanPercentageRepository planPercentageRepository, IWorkshopServicesTempRepository workshopServicesTempRepository, IInstitutionContractTempRepository institutionContractTempRepository, ISmsService smsService) { _contractingPartyTempRepository = contractingPartyTempRepository; _personalContractingPartyRepository = personalContractingPartyRepository; _uidService = uidService; _workshopTempRepository = workshopTempRepository; _planPercentageRepository = planPercentageRepository; _workshopServicesTempRepository = workshopServicesTempRepository; _institutionContractTempRepository = institutionContractTempRepository; _smsService = smsService; } /// /// احراز هویت /// /// /// /// /// public async Task> CreateContractingPartyTemp(string nationalCode, string dateOfBirth, string mobile) { var op = new OperationResult(); #region Validations if (string.IsNullOrWhiteSpace(nationalCode) || string.IsNullOrWhiteSpace(dateOfBirth) || string.IsNullOrWhiteSpace(mobile)) return op.Failed("هیچ یک از فیلد ها نمیتواند خالی باشد"); if (nationalCode.NationalCodeValid() != "valid") return op.Failed("کد ملی نا معتبر است"); if (!dateOfBirth.IsPersianDateValid()) return op.Failed("تاریخ تولد نا معتبر است"); if (!mobile.IsMobileValid()) return op.Failed("شماره همراه نا معتبر است"); #endregion var getExistContractingParty = await _contractingPartyTempRepository.CheckExistOrAuthenticated(nationalCode, dateOfBirth); //اگر طرف حساب قبلا در دیتابیس وجود داشت if (getExistContractingParty) { return op.Failed("طرف حساب با این مشخصات در سیستم وجود دارد"); } //اگر طرف حساب وجود نداشت else { //دریافت اطلاعات طرف حساب موقت که قبلا ایجاد شده var getExistTemp = _contractingPartyTempRepository.GetByNationalCode(nationalCode); var dateOfBirthGr = dateOfBirth.ToGeorgianDateTime(); //اگر طرف حساب موقت قبلا ایجاد شده دیتای آن را برمیگرداند if (getExistTemp != null) { var institutionContractTemp = await _institutionContractTempRepository.GetInstitutionContractTemp(0, getExistTemp.Id); if (institutionContractTemp != null) { if (institutionContractTemp.RegistrationStatus == "Completed") return op.Failed("شما قبلا ثبت نام خود را تکمیل نموده اید"); } if (getExistTemp.DateOfBirth != dateOfBirthGr) return op.Failed("تاریخ تولد مطابقت ندارد"); if (getExistTemp.Phone != mobile) return op.Failed("شما قبلا با شماره همراه دیگری ثبت نام نموده اید"); return op.Succcedded(getExistTemp); } //چک کردن مطابقت شماره همراه و کد ملی var isMachMobilAndNationalCode = await _uidService.IsMachPhoneWithNationalCode(nationalCode, mobile); if (isMachMobilAndNationalCode == null) return op.Failed("خطا در سرویس احراز هویت"); if (!isMachMobilAndNationalCode.IsMatched) return op.Failed("شماره همراه وارد شده با کد ملی مطابقت ندارد"); //دریافت اطلاعات احراز هویت var apiRespons = await _uidService.GetPersonalInfo(nationalCode, dateOfBirth); if (apiRespons == null) return op.Failed("خطا در سرویس احراز هویت"); if (apiRespons.ResponseContext.Status.Code != 0) return op.Failed($"{apiRespons.ResponseContext.Status.Message}"); var idNumber = apiRespons.IdentificationInformation.ShenasnamehNumber == "0" ? apiRespons.IdentificationInformation.NationalId : apiRespons.IdentificationInformation.ShenasnamehNumber; //ایجاد طرف حساب موقت var createTemp = new ContractingPartyTemp(apiRespons.BasicInformation.FirstName, apiRespons.BasicInformation.LastName, nationalCode, idNumber, mobile, apiRespons.BasicInformation.FatherName, "", "", "", apiRespons.IdentificationInformation.ShenasnameSeri, apiRespons.IdentificationInformation.ShenasnameSerial, apiRespons.BasicInformation.GenderEnum, dateOfBirthGr); await _contractingPartyTempRepository.CreateAsync(createTemp); await _contractingPartyTempRepository.SaveChangesAsync(); var result = new ContractingPartyTempViewModel(); result.Id = createTemp.id; result.FName = createTemp.FName; result.LName = createTemp.LName; result.DateOfBirthFa = dateOfBirth; result.IdNumber = idNumber; return op.Succcedded(result); } } /// /// تکمیل اطلاعات /// /// /// /// /// /// public async Task UpdateAddress(long id, string state, string city, string address) { var op = new OperationResult(); var contractingPartyTemp = _contractingPartyTempRepository.Get(id); if (string.IsNullOrWhiteSpace(state) || string.IsNullOrWhiteSpace(city) || string.IsNullOrWhiteSpace(address)) return op.Failed("اطلاعات ادرس را تکمیل کنید"); contractingPartyTemp.UpdateAddress(state, city, address); await _contractingPartyTempRepository.SaveChangesAsync(); return op.Succcedded(); } /// /// دریافت کارگاه های ذخیره شده /// /// /// public Task> GetWorkshopTemp(long contractingPartyTempId) { return _workshopTempRepository.GetWorkshopTemp(contractingPartyTempId); } /// /// ایجاد یا ویرایش کارگاه و سرویس های آن /// /// /// public async Task CreateOrUpdateWorkshopTemp(List command) { var op = new OperationResult(); var updateWorkshopList = command.Where(x => x.Id > 0).ToList(); var createNewWorkshopList = command.Where(x => x.Id == 0).ToList(); if (updateWorkshopList.Count == 0 && createNewWorkshopList.Count == 0) return op.Failed("هیچ مجموعه ای ایجاد نشده است"); #region Update if (updateWorkshopList.Count > 0) { foreach (var workshop in updateWorkshopList) { if (string.IsNullOrWhiteSpace(workshop.WorkshopName)) return op.Failed("نام مجموعه نمی تواند خالی باشد"); if (workshop.CountPerson == 0) op.Failed($"تعداد پرسنل مجوعه {workshop.WorkshopName} صفر است"); if (workshop.ContractAndCheckout == false && workshop.CustomizeCheckout == false && workshop.RollCall == false && workshop.Insurance == false) op.Failed($"برای مجموعه {workshop.WorkshopName} هیچ سرویسی انتخاب نشده است"); var existWorkshops = _workshopTempRepository.Get(workshop.Id); if (existWorkshops != null) { if (workshop.ContractAndCheckout) workshop.ContractAndCheckoutInPerson = true; if (workshop.Insurance) workshop.InsuranceInPerson = true; //دریافت مبالغ سرویس ها var plan = _planPercentageRepository.GetInstitutionPlanForWorkshop(workshop); if (plan.OnlineAndInPersonSumAmountDouble > 0) { //ویرایش مشخصات کارگاه existWorkshops.Edit(workshop.WorkshopName, workshop.CountPerson, plan.OnlineAndInPersonSumAmountDouble); await _workshopTempRepository.SaveChangesAsync(); //حذف سرویس های قبلی _workshopServicesTempRepository.RemoveServices(workshop.Id); //سرویس قرداد if (workshop.ContractAndCheckout) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("ContractAndCheckout", workshop.CountPerson, workshop.Id)); //سرویس خدمات حضوری قرارداد if (workshop.ContractAndCheckoutInPerson) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("ContractAndCheckoutInPerson", workshop.CountPerson, workshop.Id)); //سرویس بیمه if (workshop.Insurance) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("Insurance", workshop.CountPerson, workshop.Id)); //سرویس خدمات حضوری بیمه if (workshop.InsuranceInPerson) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("InsuranceInPerson", workshop.CountPerson, workshop.Id)); //سرویس حضورغیاب if (workshop.RollCall) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("RollCall", workshop.CountPerson, workshop.Id)); //سرویس فیش غیر رسمی if (workshop.CustomizeCheckout) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("CustomizeCheckout", workshop.CountPerson, workshop.Id)); } } } } #endregion #region Create if (createNewWorkshopList.Count > 0) { foreach (var workshop in createNewWorkshopList) { if (string.IsNullOrWhiteSpace(workshop.WorkshopName)) return op.Failed("نام مجموعه نمی تواند خالی باشد"); if (workshop.CountPerson == 0) op.Failed($"تعداد پرسنل مجوعه {workshop.WorkshopName} صفر است"); if (workshop.ContractAndCheckout == false && workshop.CustomizeCheckout == false && workshop.RollCall == false && workshop.Insurance == false) op.Failed($"برای مجموعه {workshop.WorkshopName} هیچ سرویسی انتخاب نشده است"); if (workshop.ContractAndCheckout) workshop.ContractAndCheckoutInPerson = true; if (workshop.Insurance) workshop.InsuranceInPerson = true; //دریافت مبالغ سرویس ها var plan = _planPercentageRepository.GetInstitutionPlanForWorkshop(workshop); if (plan.OnlineAndInPersonSumAmountDouble > 0) { var createNewWorkshopTemp = new WorkshopTemp(workshop.WorkshopName, workshop.CountPerson, workshop.ContractingPartyTempId, plan.OnlineAndInPersonSumAmountDouble); await _workshopTempRepository.CreateAsync(createNewWorkshopTemp); await _workshopTempRepository.SaveChangesAsync(); //سرویس قرداد if (workshop.ContractAndCheckout) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("ContractAndCheckout", workshop.CountPerson, createNewWorkshopTemp.id)); //سرویس خدمات حضوری قرارداد if (workshop.ContractAndCheckoutInPerson) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("ContractAndCheckoutInPerson", workshop.CountPerson, createNewWorkshopTemp.id)); //سرویس بیمه if (workshop.Insurance) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("Insurance", workshop.CountPerson, createNewWorkshopTemp.id)); //سرویس خدمات حضوری بیمه if (workshop.InsuranceInPerson) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("InsuranceInPerson", workshop.CountPerson, createNewWorkshopTemp.id)); //سرویس حضورغیاب if (workshop.RollCall) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("RollCall", workshop.CountPerson, createNewWorkshopTemp.id)); //سرویس فیش غیر رسمی if (workshop.CustomizeCheckout) await _workshopServicesTempRepository.CreateAsync( new WorkshopServicesTemp("CustomizeCheckout", workshop.CountPerson, createNewWorkshopTemp.id)); } } } #endregion return op.Succcedded(); } /// /// دریافت جمع کل خدمات برای یک کارگاه /// /// /// public InstitutionPlanViewModel GetInstitutionPlanForWorkshop(WorkshopTempViewModel workshop) { return _planPercentageRepository.GetInstitutionPlanForWorkshop(workshop); } /// /// بررسی و پرداخت /// اطلاعات کامل مبالغ /// /// /// public async Task GetTotalPaymentAndWorkshopList(long contractingPartyTempId, string periodModel = "12", string paymentModel = "OneTime") { //دریافت کارگاه ها var workshops = await _workshopTempRepository.GetWorkshopTemp(contractingPartyTempId); double totalPayment1MonthDouble = 0; //بدست آوردن جمع کل برای یک ماه foreach (var workshop in workshops) { totalPayment1MonthDouble += workshop.WorkshopServicesAmount; } if (totalPayment1MonthDouble == 0) return new ReviewAndPaymentViewModel(); var result = new ReviewAndPaymentViewModel(); int months = 0; months = periodModel switch { "1" => 1, "3" => 3, "6" => 6, "12" => 12, _ => 12, }; //رند کردن مبالغ کارگاه ها var roundAmount = (int)(totalPayment1MonthDouble / 1000000) * 1000000; //بدست آوردن جمع کل مبالغ کارگاه بر اساس مدت قراداد result.SumOfWorkshopsPaymentDouble = roundAmount * months; result.SumOfWorkshopsPaymentPaymentStr = result.SumOfWorkshopsPaymentDouble.ToMoney(); result.PeriodModel = periodModel; result.PaymentModel = paymentModel; if (paymentModel == "OneTime")//تخفیف 10 درصدی درصورت پرداخت یکجا { var tenPercent = result.SumOfWorkshopsPaymentDouble * 10 / 100; double discountOneTimePeyment = result.SumOfWorkshopsPaymentDouble - tenPercent; result.TotalPaymentDouble = discountOneTimePeyment; result.TotalPaymentStr = discountOneTimePeyment.ToMoney(); } else { result.TotalPaymentDouble = result.SumOfWorkshopsPaymentDouble; result.TotalPaymentStr = result.SumOfWorkshopsPaymentPaymentStr; } result.ContractingPartTempId = contractingPartyTempId; return result; } /// /// ایجاد یا ویرایش قرارداد موقت /// /// /// public async Task CreateOrUpdateInstitutionContractTemp(long contractingPartyTempId, string periodModel, string paymentModel, double totalPayment, double valueAddedTax) { var op = new OperationResult(); var institutionContractTemp = await _institutionContractTempRepository.GetInstitutionContractTemp(0, contractingPartyTempId); if (institutionContractTemp == null) { var periodModelInt = Convert.ToInt32(periodModel); var contractstart = DateTime.Now; var contractEnd = DateTime.Now.AddMonths(periodModelInt); var create = new InstitutionContractTemp(contractingPartyTempId,paymentModel,periodModel,totalPayment,contractstart,contractEnd,"official", valueAddedTax,"", "BeforeSendVerifyCode", 0,null,null); _institutionContractTempRepository.Create(create); _institutionContractTempRepository.SaveChanges(); return op.Succcedded(); } else { if (institutionContractTemp.VerifyCodeEndTime != null) { var spaning = (institutionContractTemp.VerifyCodeEndTime.Value - DateTime.Now); if (institutionContractTemp.RegistrationStatus == "VerifyCodeSent" && spaning > new TimeSpan(0, 0, 0) && spaning < new TimeSpan(0, 1, 0)) return op.Failed("شما به تازگی پیامک دریافت نموده اید دو دقیقه صبر کنید و دوباره تلاش کنید"); } if (institutionContractTemp.RegistrationStatus == "Completed") return op.Failed("شما قبلا ثبت نام خود را تکمیل نموده اید"); var periodModelInt = Convert.ToInt32(periodModel); var contractstart = DateTime.Now; var contractEnd = DateTime.Now.AddMonths(periodModelInt); var update = _institutionContractTempRepository.Get(institutionContractTemp.Id); update.Edit(contractingPartyTempId, paymentModel, periodModel, totalPayment, contractstart, contractEnd, "official", valueAddedTax, "", "BeforeSendVerifyCode", 0, null, null); _institutionContractTempRepository.SaveChanges(); return op.Succcedded(); } } /// /// دریافت کد برای کلاینت /// از طرف سرور /// /// /// public async Task ReceivedCodeFromServer(long contractingPartyTempId) { var op = new OperationResult(); var institutionContractTemp = await _institutionContractTempRepository.GetInstitutionContractTemp(0, contractingPartyTempId); if (institutionContractTemp == null) return op.Failed("خظا"); var update = _institutionContractTempRepository.Get(institutionContractTemp.Id); if (institutionContractTemp.RegistrationStatus == "BeforeSendVerifyCode") { //ساخت کد شش رقمی Random generator = new Random(); String code = generator.Next(1, 1000000).ToString("D6"); //ارسال اس ام اس var getContractingPaty = _contractingPartyTempRepository.GetByContractingPartyTempId(contractingPartyTempId); var sendResult = await _smsService.SendVerifyCodeToClient(getContractingPaty.Phone, code); if (!sendResult.IsSuccedded) return op.Failed($"{sendResult.Message}"); //ذخیره کد در دیتا بیس //ذخیره تاریخ ارسال و مهلت پایان //ذخیره آیدی پیامک //تغییر وضعیت به ارسال شده if (update != null) { update.Update(code, "VerifyCodeSent", sendResult.MessageId, DateTime.Now, DateTime.Now.AddMinutes(2)); _institutionContractTempRepository.SaveChanges(); return op.Succcedded(1, "کد برای شما پیامک شد"); } } if (institutionContractTemp.RegistrationStatus == "VerifyCodeSent") { var spaning = (institutionContractTemp.VerifyCodeEndTime.Value - DateTime.Now); if ((spaning > new TimeSpan(0, 0, 0) && spaning < new TimeSpan(0, 1, 0))) return op.Failed("شما به تازگی پیامک دریافت نموده اید دو دقیقه صبر کنید و دوباره تلاش کنید"); if ((spaning > new TimeSpan(0, 0, 0) && spaning > new TimeSpan(0, 1, 0))) { //ساخت کد شش رقمی Random generator = new Random(); String code = generator.Next(1, 1000000).ToString("D6"); //ارسال اس ام اس var getContractingPaty = _contractingPartyTempRepository.GetByContractingPartyTempId(contractingPartyTempId); var sendResult =await _smsService.SendVerifyCodeToClient(getContractingPaty.Phone, code); if(!sendResult.IsSuccedded) return op.Failed($"{sendResult.Message}"); //ذخیره کد در دیتا بیس //ذخیره تاریخ ارسال و مهلت پایان //ذخیره آیدی پیامک //تغییر وضعیت به ارسال شده if (update != null) { update.Update(code, "VerifyCodeSent",sendResult.MessageId, DateTime.Now, DateTime.Now.AddMinutes(2)); _institutionContractTempRepository.SaveChanges(); return op.Succcedded(1, "کد برای شما پیامک شد"); } } } //if (institutionContractTemp.RegistrationStatus == "ReceivedCodeFromClient") // return op.Succcedded(2, "انتقال به بخش پرداخت"); if (institutionContractTemp.RegistrationStatus == "Completed") return op.Failed("شما قبلا ثبت نام خود را تکمیل نموده اید"); return op.Failed("خظا"); } /// /// ورود کد از طرف کلاینت /// برا چک کردن /// /// /// /// public async Task CheckVerifyCodeIsTrue(long contractingPartyTempId, string verifyCode) { var op = new OperationResult(); var institutionContractTemp = await _institutionContractTempRepository.GetInstitutionContractTemp(0, contractingPartyTempId); if (institutionContractTemp == null) return op.Failed("خظا"); if(institutionContractTemp.RegistrationStatus != "VerifyCodeSent") return op.Failed("خطا"); if(institutionContractTemp.VerifyCodeEndTime < DateTime.Now) return op.Failed("کد شما منقضی شده است"); if(institutionContractTemp.SendVerifyCodeTime < DateTime.Now && institutionContractTemp.VerifyCodeEndTime >= DateTime.Now) { if (institutionContractTemp.VerifyCode == verifyCode) { return op.Succcedded(); } else { return op.Failed("کد وارد شده صحیح نیست"); } } return op.Failed("کد وارد شده صحیح نیست"); } /// /// تکمیل پرداخت /// /// /// /// public async Task PayOffCompleted(long contractingPartyTempId) { var op = new OperationResult(); return op.Succcedded(); } }