300 lines
14 KiB
C#
300 lines
14 KiB
C#
using _0_Framework.Application;
|
|
using CompanyManagment.EFCore;
|
|
using Microsoft.AspNetCore.Http;
|
|
using OfficeOpenXml;
|
|
using LicenseContext = OfficeOpenXml.LicenseContext;
|
|
|
|
namespace CompanyManagement.Infrastructure.Excel.SalaryAid;
|
|
|
|
public record SalaryAidImportData(long EmployeeId, long WorkshopId, string FullName, double Amount, string AccountNumber, string NationalCode, string SalaryAidDateTime, int calculationMonth, int calculationYear, int Row, bool Duplicated);
|
|
|
|
public class ExcelValidation<T>
|
|
{
|
|
public List<T> ValidData { get; set; } = [];
|
|
public List<T> RawData { get; set; } = [];
|
|
public List<SalaryAidImportExcelError> Errors { get; set; } = [];
|
|
};
|
|
|
|
public record SalaryAidImportExcelError(string Message, int Row, string Columns);
|
|
|
|
public enum SalaryAidExcelColumns
|
|
{
|
|
None = 0,
|
|
FullName = 1,
|
|
NationalCode = 2,
|
|
AccountNumber = 3,
|
|
Amount = 4
|
|
}
|
|
|
|
public class SalaryAidImportExcel
|
|
{
|
|
private readonly CompanyContext _companyContext;
|
|
private const string META_DATA_PASS = "{0B0A49C2-4CA6-456A-BA7B-9FA4D56171C1}";
|
|
|
|
public SalaryAidImportExcel(CompanyContext companyContext)
|
|
{
|
|
_companyContext = companyContext;
|
|
}
|
|
|
|
public ExcelValidation<SalaryAidImportData> ReadAndValidateExcel(IFormFile file, long workshopId)
|
|
{
|
|
var result = new ExcelValidation<SalaryAidImportData>
|
|
{
|
|
ValidData = []
|
|
};
|
|
|
|
ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
|
|
|
|
if (file == null || file.Length == 0)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("فایل اکسل ارسال نشده یا خالی است.", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
using var stream = new MemoryStream();
|
|
|
|
file.CopyTo(stream);
|
|
using var package = new ExcelPackage(stream);
|
|
|
|
var worksheet = package.Workbook.Worksheets[0];
|
|
|
|
if (worksheet == null)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("فایل اکسل معتبر نیست.", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
|
|
var customPropsXml = package.Workbook.Properties.CustomPropertiesXml;
|
|
|
|
// بررسی اینکه آیا ویژگی قبلاً وجود دارد یا نه
|
|
var existingProp = customPropsXml.InnerText;
|
|
|
|
|
|
|
|
if (existingProp != META_DATA_PASS)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("قالب ارسال شده معتبر نمیباشد", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
|
|
// بررسی اینکه هدرها همان چیزی هستند که ما انتظار داریم
|
|
if (worksheet.Cells[3, 1].Text != "نام و نام خانوادگی" ||
|
|
worksheet.Cells[3, 2].Text != "کد ملی" ||
|
|
worksheet.Cells[3, 3].Text != "شماره حساب" ||
|
|
worksheet.Cells[3, 4].Text != "مبلغ قابل پرداخت" ||
|
|
worksheet.Cells[1, 3].Text != "تاریخ پرداخت" ||
|
|
worksheet.Cells[1, 1].Text != "سال محاسبه" ||
|
|
worksheet.Cells[1, 2].Text != "ماه محاسبه")
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("ساختار فایل اکسل اشتباه است.", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
var salaryDateFa = worksheet.Cells[2, 3].Text;
|
|
|
|
var calculationMonth = Convert.ToInt32(string.IsNullOrWhiteSpace(worksheet.Cells[2, 2].Text) ? "0" : worksheet.Cells[2, 2].Text);
|
|
var calculationYear = Convert.ToInt32(string.IsNullOrWhiteSpace(worksheet.Cells[2, 1].Text) ? "0" : worksheet.Cells[2, 1].Text);
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(salaryDateFa))
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("لطفا در سلول زرد رنگ تاریخ پرداخت را وارد کنید", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
if (calculationMonth == 0)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("لطفا در سلول آبی رنگ ماه محاسبه را وارد کنید", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
if (calculationYear == 0)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("لطفا در سلول آبی رنگ سال محاسبه را وارد کنید", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
var calculationDate = $"{calculationYear:0000}/{calculationMonth:00}/01";
|
|
|
|
if (salaryDateFa.TryToGeorgianDateTime(out var salaryDateTime) == false)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("تاریخ وارد شده نامعتبر است", 0, SalaryAidExcelColumns.None.ToString()));
|
|
}
|
|
|
|
if (calculationDate.TryToGeorgianDateTime(out var calculationDateTime) == false)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("تاریخ محاسبه وارد شده نامعتبر است", 0, SalaryAidExcelColumns.None.ToString()));
|
|
}
|
|
|
|
if (salaryDateTime > DateTime.Now)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("تاریخ پرداخت مساعده می بایست تاریخ امروز یا قبل تر باشد", 0, SalaryAidExcelColumns.None.ToString()));
|
|
}
|
|
int rowCount = worksheet.Dimension.Rows;
|
|
|
|
int rowStart = 4;
|
|
|
|
if (rowCount < rowStart)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("دیتا خالی میباشد", 0, SalaryAidExcelColumns.None.ToString()));
|
|
return result;
|
|
}
|
|
|
|
|
|
for (var row = rowStart; row <= rowCount; row++)
|
|
{
|
|
var fullName = worksheet.Cells[row, 1]?.Text?.Trim();
|
|
var nationalCode = worksheet.Cells[row, 2]?.Text?.Trim();
|
|
var accountNumber = worksheet.Cells[row, 3]?.Value?.ToString()?.Trim();
|
|
var amountText = worksheet.Cells[row, 4]?.Value?.ToString()?.Trim();
|
|
|
|
if (!double.TryParse(amountText, out double amount) || amount <= 0)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("مبلغ خالی یا نامعتبر است", row, SalaryAidExcelColumns.Amount.ToString()));
|
|
|
|
}
|
|
result.RawData.Add(new SalaryAidImportData(0, workshopId, fullName, amount, accountNumber, nationalCode, salaryDateFa, calculationMonth, calculationYear, row, false));
|
|
|
|
if (string.IsNullOrWhiteSpace(fullName))
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError(" نام و نام خانوادگی خالی است", row, SalaryAidExcelColumns.FullName.ToString()));
|
|
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(accountNumber))
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError(" شماره حساب خالی است", row, SalaryAidExcelColumns.AccountNumber.ToString()));
|
|
|
|
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(nationalCode))
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("کدملی خالی است", row, SalaryAidExcelColumns.NationalCode.ToString()));
|
|
|
|
|
|
}
|
|
|
|
//if (accountNumber is { Length: < 10 or > 16 })
|
|
//{
|
|
// result.Errors.Add(new SalaryAidImportExcelError("شماره حساب نامعتبر است", row, SalaryAidExcelColumns.AccountNumber.ToString()));
|
|
|
|
//}
|
|
|
|
if (nationalCode.NationalCodeValid() != "valid")
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError("کد ملی نامعتبر است", row, SalaryAidExcelColumns.NationalCode.ToString()));
|
|
|
|
}
|
|
|
|
var employee = _companyContext.Employees.FirstOrDefault(x => x.NationalCode == nationalCode);
|
|
if (employee == null)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError($" پرسنلی با کد ملی {nationalCode} یافت نشد", row, SalaryAidExcelColumns.NationalCode.ToString()));
|
|
continue;
|
|
}
|
|
|
|
const double threshold = 0.4;
|
|
|
|
var inputWords = fullName.Split(' ').ToArray();
|
|
var dbWords = string.Join(" ", employee.FullName.Split(' '));
|
|
var inputMatchCount = inputWords.Count(dbWords.Contains);
|
|
var accuracyDbToInput = (double)inputMatchCount / inputWords.Length;
|
|
|
|
var dbArray = dbWords.Split(' ').ToArray();
|
|
var dataBaseMatchCount = dbArray.Count(fullName.Contains);
|
|
|
|
var accuracyInputToDb = (double)dataBaseMatchCount / dbArray.Length;
|
|
|
|
if (accuracyDbToInput < threshold || accuracyInputToDb < threshold)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError($" نام و نام خانوادگی {fullName} با کد ملی وارد شده مطابقت ندارد", row, SalaryAidExcelColumns.FullName.ToString()));
|
|
}
|
|
|
|
if ((_companyContext.LeftWorkList.Any(x => x.EmployeeId == employee.id && x.WorkshopId == workshopId) ||
|
|
_companyContext.LeftWorkInsuranceList.Any(x => x.EmployeeId == employee.id && x.WorkshopId == workshopId)) == false)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError($" پرسنل {fullName} در کارگاه مورد نظر یافت نشد", row, SalaryAidExcelColumns.None.ToString()));
|
|
continue;
|
|
}
|
|
|
|
if (_companyContext.EmployeeBankInformationSet.Any(x => x.EmployeeId == employee.id && x.BankAccountNumber == accountNumber) == false)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError($"شماره حساب {accountNumber} برای پرسنل {fullName} یافت نشد", row, SalaryAidExcelColumns.AccountNumber.ToString()));
|
|
|
|
}
|
|
|
|
var month = Convert.ToInt32(salaryDateFa.Substring(5, 2));
|
|
var year = Convert.ToInt32(salaryDateFa.Substring(0, 4));
|
|
|
|
|
|
//if (_companyContext.CustomizeCheckouts.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employee.id && x.YearInt == year && x.MonthInt == month))
|
|
//{
|
|
// result.Errors.Add(new SalaryAidImportExcelError($" پرسنل {fullName} در تاریخ {salaryDateFa} دارای فیش حقوقی غیررسمی است.", row, SalaryAidExcelColumns.None.ToString()));
|
|
//}
|
|
|
|
|
|
_ = DateTime.Now.Date.AddMonthsFa(-1, out var oneMonthAgoGr);
|
|
|
|
if (oneMonthAgoGr > calculationDateTime)
|
|
{
|
|
bool customizeCheckout = false;
|
|
bool customizeCheckoutTemp = false;
|
|
bool checkout = false;
|
|
if (_companyContext.CustomizeCheckouts.Any(x => x.WorkshopId == workshopId && employee.id == x.EmployeeId &&
|
|
x.ContractStart <= oneMonthAgoGr && x.ContractEnd >= calculationDateTime))
|
|
{
|
|
customizeCheckout = true;
|
|
}
|
|
|
|
if (_companyContext.CustomizeCheckoutTemps.Any(x => x.WorkshopId == workshopId && employee.id == x.EmployeeId &&
|
|
x.ContractStart <= calculationDateTime && x.ContractEnd >= oneMonthAgoGr))
|
|
{
|
|
customizeCheckoutTemp = true;
|
|
}
|
|
|
|
if (_companyContext.CheckoutSet.Any(x => x.WorkshopId == workshopId && employee.id == x.EmployeeId &&
|
|
x.ContractStart <= calculationDateTime && x.ContractEnd >= oneMonthAgoGr))
|
|
{
|
|
checkout = true;
|
|
}
|
|
if (customizeCheckout || customizeCheckoutTemp)
|
|
{
|
|
result.Errors.Add(new SalaryAidImportExcelError($"شما نمیتوانید به پرسنل {fullName} در تاریخ قبل از یک ماه گذشته که فیش صادر شده باشد مساعده دهید", row, SalaryAidExcelColumns.None.ToString()));
|
|
}
|
|
}
|
|
|
|
//if(_companyContext.CheckoutSet.Any(x => x.WorkshopId == workshopId && employee.id == x.EmployeeId &&
|
|
// x.ContractStart <= calculationDateTime && x.ContractEnd >= calculationDateTime))
|
|
// result.Errors.Add(new SalaryAidImportExcelError($"پرسنل {fullName} در تاریخ {calculationDate} دارای فیش رسمی میباشد", row, SalaryAidExcelColumns.None.ToString()));
|
|
|
|
|
|
if (_companyContext.SalaryAids.Any(x => x.Amount == amount && x.EmployeeId == employee.id && x.WorkshopId == workshopId && x.SalaryAidDateTime == salaryDateTime))
|
|
{
|
|
// TODO MAHAN: Vafa Add this Code! Please Check it!
|
|
|
|
result.RawData.Add(new SalaryAidImportData(employee.id, workshopId, fullName, amount, accountNumber, nationalCode, salaryDateFa, calculationMonth, calculationYear, row, true));
|
|
continue;
|
|
}
|
|
result.ValidData.Add(new SalaryAidImportData(employee.id, workshopId, fullName, amount, accountNumber, nationalCode, salaryDateFa, calculationMonth, calculationYear, row, false));
|
|
}
|
|
|
|
result.RawData = result.RawData.GroupBy(x => x.Row).Select(x => new SalaryAidImportData(x.Last().EmployeeId,
|
|
x.First().WorkshopId, x.First().FullName,
|
|
x.First().Amount, x.First().AccountNumber, x.First().NationalCode, x.First().SalaryAidDateTime, x.First().calculationMonth, x.First().calculationYear, x.Key,
|
|
x.Any(s => s.Duplicated))).ToList();
|
|
|
|
|
|
//result.Errors.GroupBy(x => x.Row).Select(x => new
|
|
//{
|
|
// Row = x.Key,
|
|
// Data =x.Select(s=>new
|
|
// {
|
|
// s.Columns,
|
|
// s.Message
|
|
// })
|
|
//}).ToList();
|
|
|
|
return result;
|
|
}
|
|
} |