using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Transactions; using _0_Framework.Application; using Company.Domain.CustomizeCheckoutAgg; using Company.Domain.CustomizeCheckoutTempAgg; using Company.Domain.LoanAgg; using Company.Domain.LoanAgg.Entities; using CompanyManagment.App.Contracts.CustomizeCheckout; using CompanyManagment.App.Contracts.Loan; namespace CompanyManagment.Application; public class LoanApplication : ILoanApplication { private readonly ILoanRepository _loanRepository; private readonly ICustomizeCheckoutRepository _customizeCheckoutRepository; private readonly IAuthHelper _authHelper; private readonly ICustomizeCheckoutTempRepository _customizeCheckoutTempRepository; private readonly ICustomizeCheckoutApplication _customizeCheckoutApplication; private readonly ICustomizeCheckoutTempApplication _customizeCheckoutTempApplication; private readonly ICustomizeCheckoutRepository _checkoutRepository; public LoanApplication(ILoanRepository loanRepository, ICustomizeCheckoutRepository customizeCheckoutRepository, ICustomizeCheckoutTempRepository customizeCheckoutTempRepository, IAuthHelper authHelper, ICustomizeCheckoutApplication customizeCheckoutApplication, ICustomizeCheckoutTempApplication customizeCheckoutTempApplication, ICustomizeCheckoutRepository checkoutRepository) { _loanRepository = loanRepository; _customizeCheckoutRepository = customizeCheckoutRepository; _authHelper = authHelper; _customizeCheckoutApplication = customizeCheckoutApplication; _customizeCheckoutTempApplication = customizeCheckoutTempApplication; _checkoutRepository = checkoutRepository; _customizeCheckoutTempRepository = customizeCheckoutTempRepository; } public List GetSearchList(LoanSearchViewModel searchModel) { return _loanRepository.GetSearchList(searchModel); } public async Task GetDetails(long id) { return await _loanRepository.GetDetails(id); } public OperationResult Create(CreateLoanViewModel command) { var op = new OperationResult(); var startInstallmentDate = command.StartInstallmentPayment.ToGeorgianDateTime(); var loanGrantDate = command.LoanGrantDate.ToGeorgianDateTime(); var now = DateTime.Now; if (command.Amount.Length > 15) { return op.Failed("مبلغ وارد شده معتبر نیست"); } var amountD = command.Amount.MoneyToDouble(); var installment = CalculateLoanInstallment(command.Amount, command.Count, command.StartInstallmentPayment, command.GetRounded); var lastInstallment = installment.MaxBy(x => x.DateGr).DateGr; #region Validation if (startInstallmentDate.Date < now.Date) { return op.Failed("تاریخ شروع وام نمیتواند در گذشته باشد"); } if (loanGrantDate > now) { return op.Failed("تاریخ پرداخت وام می بایست تاریخ امروز یا قبل تر باشد"); } if (!command.LoanGrantDate.TryToGeorgianDateTime(out var grantDate)) { return op.Failed("تاریخ وارد شده نامعتبر است"); } if (amountD < 1000000) return op.Failed("حداقل مبلغ وام 1.000.000 ریال میباشد"); var existsCheckouts = _customizeCheckoutRepository.ValidateExistsCheckouts(startInstallmentDate, lastInstallment, command.WorkshopId, command.EmployeeIds); if (existsCheckouts.Checkout) { return op.Failed("پرسنل در این تاریخ دارای فیش حقوقی رسمی است"); } #endregion var (userId, userType, _) = _authHelper.GetUserTypeWithId(); using var transaction = new TransactionScope(); foreach (var employeeId in command.EmployeeIds) { var entity = new Loan(employeeId, command.WorkshopId, startInstallmentDate, command.Count.ToString(), command.Amount.MoneyToDouble(), installment.First().Amount.MoneyToDouble(), installment.Select(x => new LoanInstallment(x.Amount.MoneyToDouble(), x.Month, x.Year, x.DateGr)).ToList() , command.GetRounded, grantDate, userId, userType); _loanRepository.Create(entity); //var existInCheckout = _customizeCheckoutApplication.ValidateExistsCheckouts(startInstallmentDate, lastInstallment, // command.WorkshopId, [employeeId]); //if (existInCheckout.CustomizeCheckout) //{ // var customizeCheckouts = _customizeCheckoutRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, employeeId, // startInstallmentDate, lastInstallment); // var ccRemoveResult = _customizeCheckoutApplication.GroupRemove(command.WorkshopId, // customizeCheckouts.Select(x => x.id).ToList()); // if (!ccRemoveResult.IsSuccedded) // return op.Failed("خطا در حذف فیش غیررسمی نهایی:"+ccRemoveResult.Message); // var groupedCustomizeCheckouts= customizeCheckouts.GroupBy(x => new { x.Month, x.Year }).ToList(); // foreach (var groupedCustomizeCheckout in groupedCustomizeCheckouts) // { // var ccCreateResult = _customizeCheckoutApplication.GroupCreate(new CreateCustomizeCheckoutGroup() // { // WorkshopId = command.WorkshopId, // EmployeeIds = groupedCustomizeCheckout.Select(x => x.EmployeeId).ToList(), // MonthFa = groupedCustomizeCheckout.First().MonthInt, // YearFa = groupedCustomizeCheckout.First().YearInt, // }); // if (!ccCreateResult.IsSuccedded) // return op.Failed("خطا در ایجاد فیش غیررسمی نهایی:" + ccCreateResult.Message); // } //} //if (existInCheckout.CustomizeCheckoutTemp) //{ // var customizeCheckoutsTemp = _customizeCheckoutTempRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, employeeId, // startInstallmentDate, lastInstallment); // var groupedCustomizeCheckoutsTemp = customizeCheckoutsTemp.GroupBy(x => new { x.Month, x.Year}).ToList(); // foreach (var groupedCustomizeCheckout in groupedCustomizeCheckoutsTemp) // { // var ccCreateResult = _customizeCheckoutTempApplication.GroupCreate(new CreateCustomizeCheckoutTempGroup() // { // WorkshopId = command.WorkshopId, // EmployeeIds = groupedCustomizeCheckout.Select(x=>x.EmployeeId).ToList(), // MonthFa = groupedCustomizeCheckout.First().MonthInt, // YearFa = // }); // if (!ccCreateResult.IsSuccedded) // return op.Failed("خطا در ایجاد فیش غیررسمی نهایی:" + ccCreateResult.Message); // } // if (!ccRemoveResult.IsSuccedded) // return op.Failed("خطا در حذف فیش غیررسمی نهایی:" + ccRemoveResult.Message); //} } _loanRepository.SaveChanges(); transaction.Complete(); return op.Succcedded(); } public List CalculateLoanInstallment(string amount, int installmentCount, string loanStartDate, bool getRounded) { int day = Convert.ToInt32(loanStartDate.Substring(8, 2)); int month = Convert.ToInt32(loanStartDate.Substring(5, 2)); int year = Convert.ToInt32(loanStartDate.Substring(0, 4)); var installments = new List(); bool endOfMonth = day == 31; double amountD = amount.MoneyToDouble(); var dividedAmount = amountD / installmentCount; double moneyPerMonth = 0; if (getRounded) moneyPerMonth = Math.Floor(dividedAmount / 1000) * 1000; else moneyPerMonth = Math.Floor(dividedAmount); double lastLoan = amountD - (moneyPerMonth * (installmentCount - 1)); if (endOfMonth) { for (int i = 1; i < installmentCount; i++) { var installment = new LoanInstallmentViewModel() { DateFa = loanStartDate, Amount = moneyPerMonth.ToMoney(), DateGr = loanStartDate.ToGeorgianDateTime(), Month = loanStartDate.Substring(5, 2), Year = loanStartDate.Substring(0, 4), Day = loanStartDate.Substring(8, 2), AmountDouble = moneyPerMonth }; installments.Add(installment); if (month == 12) { year++; month = 1; } else { month++; } loanStartDate = $"{year:0000}/{month:00}/01".FindeEndOfMonth(); } var lastInstallment = new LoanInstallmentViewModel() { DateFa = loanStartDate, Amount = lastLoan.ToMoney(), DateGr = loanStartDate.ToGeorgianDateTime(), Month = loanStartDate.Substring(5, 2), Year = loanStartDate.Substring(0, 4), Day = loanStartDate.Substring(8, 2), AmountDouble = lastLoan }; installments.Add(lastInstallment); return installments; } else { for (int i = 1; i < installmentCount; i++) { var installment = new LoanInstallmentViewModel() { DateFa = loanStartDate, Amount = moneyPerMonth.ToMoney(), DateGr = loanStartDate.ToGeorgianDateTime(), Month = loanStartDate.Substring(5, 2), Year = loanStartDate.Substring(0, 4), Day = loanStartDate.Substring(8, 2), AmountDouble = moneyPerMonth }; installments.Add(installment); var endDay = 0; if (month == 12) { year++; month = 1; } else { month++; } if (day == 30) { if (month == 12) { var lastYearDay = Convert.ToInt32($"{year:0000}/{month:00}/1".FindeEndOfMonth().Substring(8, 2)); endDay = lastYearDay == 30 ? lastYearDay : 29; } } loanStartDate = endDay == 0 ? $"{year:0000}/{month:00}/{day:00}" : $"{year:0000}/{month:00}/{endDay:00}"; } var lastInstallment = new LoanInstallmentViewModel() { DateFa = loanStartDate, Amount = lastLoan.ToMoney(), DateGr = loanStartDate.ToGeorgianDateTime(), Month = loanStartDate.Substring(5, 2), Year = loanStartDate.Substring(0, 4), Day = loanStartDate.Substring(8, 2), AmountDouble = lastLoan }; installments.Add(lastInstallment); return installments; } } public OperationResult Remove(long id) { OperationResult op = new OperationResult(); var entity = _loanRepository.Get(id); if (entity == null) return op.Failed("این آیتم وجود ندارد"); var lastInstallment = entity.LoanInstallments.MaxBy(x => x.InstallmentDate).InstallmentDate; if (_customizeCheckoutRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("این پرسنل در این تاریخ دارای فیش حقوقی است"); } if (_checkoutRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("پرسنل در بازه اقساط خود دارای فیش رسمی است"); } if (_customizeCheckoutTempRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("پرسنل در بازه اقساط خود دارای فیش غیررسمی است"); } _loanRepository.Remove(entity); _loanRepository.SaveChanges(); return op.Succcedded(); } public OperationResult RemoveRange(IEnumerable ids) { OperationResult op = new OperationResult(); var loans = _loanRepository.GetBy(ids); foreach (var entity in loans) { var lastInstallment = entity.LoanInstallments.MaxBy(x => x.InstallmentDate).InstallmentDate; if (_customizeCheckoutRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("این پرسنل در این تاریخ دارای فیش حقوقی است"); } if (_checkoutRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("پرسنل در بازه اقساط خود دارای فیش رسمی است"); } if (_customizeCheckoutTempRepository.Exists(x => entity.EmployeeId == x.EmployeeId && x.WorkshopId == entity.WorkshopId && (x.ContractStart >= entity.StartInstallmentPayment && x.ContractStart <= lastInstallment))) { return op.Failed("پرسنل در بازه اقساط خود دارای فیش غیررسمی است"); } } _loanRepository.RemoveRange(loans); _loanRepository.SaveChanges(); return op.Succcedded(); } public LoanGroupedViewModel GetSearchListAsGrouped(LoanSearchViewModel searchModel) { return _loanRepository.GetSearchListAsGrouped(searchModel); } }