import Excel SalaryAid

This commit is contained in:
SamSys
2025-03-04 21:40:02 +03:30
parent 21bdf1e696
commit 2843ab8b47
31 changed files with 2074 additions and 109 deletions

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EPPlus" Version="7.5.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AccountMangement.Infrastructure.EFCore\AccountMangement.Infrastructure.EFCore.csproj" />
<ProjectReference Include="..\CompanyManagment.EFCore\CompanyManagment.EFCore.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,240 @@
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 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.LicenseContext = LicenseContext.NonCommercial;
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[2, 1].Text != "نام و نام خانوادگی" ||
worksheet.Cells[2, 2].Text != "کد ملی" ||
worksheet.Cells[2, 3].Text != "شماره حساب" ||
worksheet.Cells[2, 4].Text != "مبلغ قابل پرداخت" ||
worksheet.Cells[1, 1].Text != "تاریخ پرداخت")
{
result.Errors.Add(new SalaryAidImportExcelError("ساختار فایل اکسل اشتباه است.", 0, SalaryAidExcelColumns.None.ToString()));
return result;
}
var salaryDateFa = worksheet.Cells[1, 4].Text;
if (string.IsNullOrWhiteSpace(salaryDateFa))
{
result.Errors.Add(new SalaryAidImportExcelError("لطفا در سلول زرد رنگ تاریخ پرداخت را وارد کنید", 0, SalaryAidExcelColumns.None.ToString()));
return result;
}
if (salaryDateFa.TryToGeorgianDateTime(out var salaryDateTime) == 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 = 3;
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, 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()));
}
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, row, true));
continue;
}
result.ValidData.Add(new SalaryAidImportData(employee.id, workshopId, fullName, amount, accountNumber, nationalCode, salaryDateFa, row, false));
}
result.RawData = result.RawData.GroupBy(x => x.Row).Select(x => new SalaryAidImportData(x.First().EmployeeId,
x.First().WorkshopId, x.First().FullName,
x.First().Amount, x.First().AccountNumber, x.First().NationalCode, x.First().SalaryAidDateTime, 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;
}
}