Files
Backend-Api/CompanyManagment.Application/LoanApplication.cs

338 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Threading.Tasks;
using System.Transactions;
using _0_Framework.Application;
using Company.Domain.CheckoutAgg;
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;
using Hangfire.States;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Configuration.UserSecrets;
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;
public LoanApplication(ILoanRepository loanRepository, ICustomizeCheckoutRepository customizeCheckoutRepository, ICustomizeCheckoutTempRepository customizeCheckoutTempRepository, IAuthHelper authHelper, ICustomizeCheckoutApplication customizeCheckoutApplication, ICustomizeCheckoutTempApplication customizeCheckoutTempApplication)
{
_loanRepository = loanRepository;
_customizeCheckoutRepository = customizeCheckoutRepository;
_authHelper = authHelper;
_customizeCheckoutApplication = customizeCheckoutApplication;
_customizeCheckoutTempApplication = customizeCheckoutTempApplication;
_customizeCheckoutTempRepository = customizeCheckoutTempRepository;
}
public List<LoanViewModel> GetSearchList(LoanSearchViewModel searchModel)
{
return _loanRepository.GetSearchList(searchModel);
}
public async Task<LoanDetailsViewModel> 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<LoanInstallmentViewModel> 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<LoanInstallmentViewModel>();
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)
};
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)
};
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)
};
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)
};
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 (_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<long> ids)
{
OperationResult op = new OperationResult();
var loans = _loanRepository.GetBy(ids);
_loanRepository.RemoveRange(loans);
_loanRepository.SaveChanges();
return op.Succcedded();
}
public LoanGroupedViewModel GetSearchListAsGrouped(LoanSearchViewModel searchModel)
{
return _loanRepository.GetSearchListAsGrouped(searchModel);
}
}