Compare commits

...

9 Commits

Author SHA1 Message Date
4b39994de6 feat: add API endpoint for printing multiple contracts 2025-12-20 15:50:34 +03:30
0dd2dc7c43 add workshopCode on client contract print 2025-12-20 15:21:34 +03:30
20c00893b6 feat: add API endpoint for printing contract details and enhance contract print logic 2025-12-20 14:23:23 +03:30
b0d174a575 feat: implement contract printing methods and view models 2025-12-20 13:04:30 +03:30
0fbd5c9d3e Add print methods and ContractPrintViewModel class
Updated the `IContractApplication` interface:
- Added `PrintOneAsync(long id)` and `PrintAllAsync(List<long> ids)` methods.
- Corrected formatting of `DeleteAllContarcts(List<long> ids)`.
- Grouped changes under the `NewChangeByHeydari` region.

Introduced the `ContractPrintViewModel` class (currently empty).

Implemented `PrintOneAsync` and `PrintAllAsync` in `ContractApplication` with `NotImplementedException`.

These changes prepare the codebase for contract printing functionality.
2025-11-11 19:29:51 +03:30
8436f70aa0 Refactor and enhance contract handling logic
- Added `DailyWage`, `AvgWorkingHour`, and `FamilyAllowance` properties to `GetContractListForClientResponse`.
- Refactored `WorkingHoursWeekly` conversion logic by introducing a reusable `WeeklyHourConvertor` method in `ContractRepository`.
- Updated query result mapping to include new properties and utilize `WeeklyHourConvertor` for `AvgWorkingHour`.
- Improved code readability and maintainability by centralizing repetitive logic.
2025-11-11 19:26:45 +03:30
9cf8447a83 feat: add API for retrieving paginated contract list for client with filtering options 2025-11-03 17:49:51 +03:30
e124a4d5d9 feat: implement method to retrieve paginated contract list for client with filtering options 2025-11-03 17:43:50 +03:30
7b9e7881c6 feat: add commented-out method for retrieving contract list for client 2025-11-03 14:45:41 +03:30
8 changed files with 418 additions and 28 deletions

View File

@@ -48,6 +48,10 @@ public interface IContractRepository : IRepository<long, Contract>
bool Remove(long id);
List<ContractViweModel> SearchForClient(ContractSearchModel searchModel);
Task<PagedResult<GetContractListForClientResponse>> GetContractListForClient(GetContractListForClientRequest searchModel);
Task<List<ContractPrintViewModel>> PrintAllAsync(List<long> ids);
#endregion
#region NewChangeByHeydari
@@ -63,4 +67,8 @@ public interface IContractRepository : IRepository<long, Contract>
ContractViweModel GetByWorkshopIdEmployeeIdInDates(long workshopId, long employeeId, DateTime startOfMonth, DateTime endOfMonth);
List<ContractViweModel> GetByWorkshopIdInDates(long workshopId, DateTime contractStart, DateTime contractEnd);
#endregion
}
}

View File

@@ -0,0 +1,12 @@
namespace CompanyManagment.App.Contracts.Contract;
public enum ContractListOrderType
{
ByContractCreationDate,
BySignedContract,
ByUnSignedContract,
ByPersonnelCode,
ByPersonnelCodeDescending,
ByContractStartDate,
ByContractStartDateDescending
}

View File

@@ -0,0 +1,13 @@
using _0_Framework.Application;
namespace CompanyManagment.App.Contracts.Contract;
public class GetContractListForClientRequest: PaginationRequest
{
public int Year { get; set; }
public int Month { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public long EmployeeId { get; set; }
public ContractListOrderType? OrderType { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace CompanyManagment.App.Contracts.Contract;
public class GetContractListForClientResponse
{
public long Id { get; set; }
public string PersonnelCode { get; set; }
public string ContractNo { get; set; }
public string EmployeeFullName { get; set; }
public string ContractStart { get; set; }
public string ContractEnd { get; set; }
public bool IsSigned { get; set; }
public string DailyWage { get; set; }
public string AvgWorkingHour { get; set; }
public string FamilyAllowance { get; set; }
}

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using _0_Framework.Application;
using CompanyManagment.App.Contracts.Workshop;
using System.Threading.Tasks;
using _0_Framework.Application.Enums;
namespace CompanyManagment.App.Contracts.Contract;
public interface IContractApplication
@@ -45,16 +47,101 @@ public interface IContractApplication
#region Client
OperationResult Remove(long id);
[Obsolete("این متد منسوخ شده است. لطفاً از متد GetContractListForClient استفاده کنید.")]
List<ContractViweModel> SearchForClient(ContractSearchModel searchModel);
#endregion
/// <summary>
/// لیست قراردادها برای کلاینت
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<PagedResult<GetContractListForClientResponse>>
GetContractListForClient(GetContractListForClientRequest searchModel);
Task<ContractPrintViewModel> PrintOneAsync(long id);
Task<List<ContractPrintViewModel>> PrintAllAsync(List<long> ids);
#region NewChangeByHeydari
#endregion
OperationResult DeleteAllContarcts(List<long> ids);
#region NewChangeByHeydari
OperationResult DeleteAllContarcts(List<long> ids);
OperationResult DeleteContarcts(long id);
List<long> CheckHasCheckout(List<long> ids);
List<long> CheckHasSignature(List<long> ids);
List<ContractViweModel> SearchForMainContract(ContractSearchModel searchModel);
#endregion
}
public class ContractPrintViewModel
{
public string ContractNo { get; set; }
public ContractPrintEmployerViewModel Employer { get; set; }
public ContractPrintEmployeeViewModel Employee { get; set; }
public ContractPrintTypeOfContractViewModel TypeOfContract { get; set; }
public ContractPrintFeesViewModel Fees { get; set; }
public string ConditionAndDetials { get; set; }
}
public class ContractPrintFeesViewModel
{
public string DailyWage { get; set; }
public string FamilyAllowance { get; set; }
public string ConsumableItems { get; set; }
public string HousingAllowance { get; set; }
}
public class ContractPrintTypeOfContractViewModel
{
public string ContractType { get; set; }
public string JobName { get; set; }
public string SetContractDate { get; set; }
public string ContarctStart { get; set; }
public string ContractEnd { get; set; }
public string WorkingHoursWeekly { get; set; }
public List<string> WorkshopAddress { get; set; }
}
public class ContractPrintEmployeeViewModel
{
public string FullName { get; set; }
public string NationalCode { get; set; }
public string IdNumber { get; set; }
public string DateOfBirth { get; set; }
public string FatherName { get; set; }
public string LevelOfEducation { get; set; }
public string Address { get; set; }
}
public class ContractPrintEmployerViewModel
{
public LegalType LegalType { get; set; }
public ContractPrintRealEmployerViewModel RealEmployer { get; set; }
public ContractPrintLegalEmployerViewModel LegalEmployer { get; set; }
public string WorkshopName { get; set; }
public string Address { get; set; }
public string WorkshopCode { get; set; }
}
public class ContractPrintLegalEmployerViewModel
{
public string CompanyName { get; set; }
public string NationalId { get; set; }
public string RegisterId { get; set; }
}
public class ContractPrintRealEmployerViewModel
{
public string FullName { get; set; }
public string NationalCode { get; set; }
public string IdNumber { get; set; }
}

View File

@@ -2712,7 +2712,9 @@ public class ContractApplication : IContractApplication
var emp = workshopEmpList.Where(x => x.WorkshopId == res.WorkshopIds)
.Select(x => x.EmployerId).ToList();
res.Employers = _employerRepository.GetEmployers(emp);
var workshopSelect = _workshopApplication.GetDetails(res.WorkshopIds);
var workshop = new WorkshopViewModel()
{
@@ -3107,6 +3109,21 @@ public class ContractApplication : IContractApplication
return _contractRepository.SearchForClient(searchModel);
}
public async Task<PagedResult<GetContractListForClientResponse>> GetContractListForClient(GetContractListForClientRequest searchModel)
{
return await _contractRepository.GetContractListForClient(searchModel);
}
public async Task<ContractPrintViewModel> PrintOneAsync(long id)
{
return (await _contractRepository.PrintAllAsync([id])).FirstOrDefault();
}
public async Task<List<ContractPrintViewModel>> PrintAllAsync(List<long> ids)
{
return await _contractRepository.PrintAllAsync(ids);
}
#endregion
#region NewChangeByHeydari

View File

@@ -5,6 +5,8 @@ using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Exceptions;
using _0_Framework.InfraStructure;
using Company.Domain.ContractAgg;
using Company.Domain.empolyerAgg;
@@ -1081,30 +1083,7 @@ public class ContractRepository : RepositoryBase<long, Contract>, IContractRepos
var weeklyDouble = 0.0;
var weekly = c.WorkingHoursWeekly;
if (!string.IsNullOrWhiteSpace(weekly) &&
weekly != "24 - 12" && weekly != "24 - 24" && weekly != "36 - 12" && weekly != "48 - 24")
{
if (weekly.Contains("/"))
{
weeklyDouble = double.Parse(weekly);
var minute = (int)((weeklyDouble % 1) * 60);
var hour = (int)(weeklyDouble);
c.WorkingHoursWeekly = hour + " " + "ساعت و" + " " + minute + " " + "دقیقه";
}
else if (weekly.Contains("."))
{
weeklyDouble = double.Parse(weekly, CultureInfo.InvariantCulture);
var minute = (int)((weeklyDouble % 1) * 60);
var hour = (int)(weeklyDouble);
c.WorkingHoursWeekly = hour + " " + "ساعت و" + " " + minute + " " + "دقیقه";
}
else
{
c.WorkingHoursWeekly = c.WorkingHoursWeekly + " " + "ساعت";
}
}
c.WorkingHoursWeekly = WeeklyHourConvertor(weekly);
var emp = workshopEmpList.Where(x => x.WorkshopId == c.WorkshopIds)
.Select(x => x.EmployerId).ToList();
c.Employers = _employerRepository.GetEmployers(emp);
@@ -1161,6 +1140,37 @@ public class ContractRepository : RepositoryBase<long, Contract>, IContractRepos
return query;
}
private static string WeeklyHourConvertor(string weekly)
{
double weeklyDouble;
if (!string.IsNullOrWhiteSpace(weekly) &&
weekly != "24 - 12" && weekly != "24 - 24" && weekly != "36 - 12" && weekly != "48 - 24")
{
if (weekly.Contains("/"))
{
weeklyDouble = double.Parse(weekly);
var minute = (int)((weeklyDouble % 1) * 60);
var hour = (int)(weeklyDouble);
return hour + " " + "ساعت و" + " " + minute + " " + "دقیقه";
}
else if (weekly.Contains("."))
{
weeklyDouble = double.Parse(weekly, CultureInfo.InvariantCulture);
var minute = (int)((weeklyDouble % 1) * 60);
var hour = (int)(weeklyDouble);
return hour + " " + "ساعت و" + " " + minute + " " + "دقیقه";
}
else
{
return weekly + " " + "ساعت";
}
}
return "";
}
public IQueryable<WorkshopEmployerViewModel> GetWorkshopEmployer()
{
return _context.WorkshopEmployers.Select(x => new WorkshopEmployerViewModel
@@ -1506,6 +1516,195 @@ public class ContractRepository : RepositoryBase<long, Contract>, IContractRepos
}
public async Task<PagedResult<GetContractListForClientResponse>> GetContractListForClient(GetContractListForClientRequest searchModel)
{
var workshopId = _authHelper.GetWorkshopId();
var query = _context.Contracts
.Where(c => c.WorkshopIds == workshopId);
#region Search
if (searchModel.EmployeeId > 0)
query = query.Where(x => x.EmployeeId == searchModel.EmployeeId);
if (!string.IsNullOrWhiteSpace(searchModel.StartDate) && string.IsNullOrWhiteSpace(searchModel.EndDate))
{
if (!searchModel.StartDate.TryToGeorgianDateTime(out var startDate))
throw new BadRequestException("تاریخ شروع وارد شده معتبر نمی باشد.");
if (!searchModel.EndDate.TryToGeorgianDateTime(out var endDate))
throw new BadRequestException("تاریخ پایان وارد شده معتبر نمی باشد.");
query = query.Where(x => x.ContarctStart <=endDate && x.ContractEnd >= startDate);
}
if (searchModel.Year>0 && searchModel.Month >0)
{
var startDateFa = $"{searchModel.Year:0000}/{searchModel.Month:00}/01";
if (!startDateFa.TryToGeorgianDateTime(out var startDate))
throw new BadRequestException("سال و ماه وارد شده معتبر نمی باشد.");
if(!startDateFa.FindeEndOfMonth().TryToGeorgianDateTime(out var endDate))
throw new BadRequestException("سال و ماه وارد شده معتبر نمی باشد.");
query = query.Where(x => x.ContarctStart <=endDate && x.ContractEnd >= startDate);
}
if (searchModel.OrderType != null)
{
switch (searchModel.OrderType)
{
case ContractListOrderType.ByContractCreationDate:
query = query.OrderBy(x => x.CreationDate);
break;
case ContractListOrderType.ByContractStartDate:
query = query.OrderBy(x => x.ContarctStart);
break;
case ContractListOrderType.ByContractStartDateDescending:
query = query.OrderByDescending(x=>x.ContarctStart);
break;
case ContractListOrderType.ByPersonnelCode:
query = query.OrderBy(x => x.PersonnelCode);
break;
case ContractListOrderType.ByPersonnelCodeDescending:
query = query.OrderByDescending(x => x.PersonnelCode);
break;
case ContractListOrderType.BySignedContract:
query = query.OrderByDescending(x => x.Signature == "1");
break;
case ContractListOrderType.ByUnSignedContract:
query = query.OrderBy(x => x.Signature == "1");
break;
}
}
else
{
query = query.OrderByDescending(x => x.id);
}
#endregion
var pagedList =await query
.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
var employeeIds = pagedList.Select(x => x.EmployeeId).ToList();
var employees = await _context.Employees
.Where(x => employeeIds.Contains(x.id)).Select(x => new
{
Id = x.id,
x.FullName
}).ToListAsync();
var result = new PagedResult<GetContractListForClientResponse>
{
TotalCount = await query.CountAsync(),
List = pagedList.Select(c =>
{
var employeeFullName = employees
.FirstOrDefault(e => e.Id == c.EmployeeId)?.FullName ?? "";
return new GetContractListForClientResponse
{
Id = c.id,
PersonnelCode = c.PersonnelCode.ToString(),
ContractStart = c.ContarctStart.ToFarsi(),
ContractEnd = c.ContractEnd.ToFarsi(),
ContractNo = c.ContractNo,
IsSigned = c.Signature == "1",
EmployeeFullName = employeeFullName,
AvgWorkingHour = WeeklyHourConvertor(c.WorkingHoursWeekly),
DailyWage = c.DayliWage,
FamilyAllowance = c.FamilyAllowance
};
}).ToList()
};
return result;
}
public async Task<List<ContractPrintViewModel>> PrintAllAsync(List<long> ids)
{
var query =await _context.Contracts.Include(x => x.Employer)
.Include(x => x.Employee).Where(x => ids.Contains(x.id))
.ToListAsync();
var workshopIds = query.Select(x => x.WorkshopIds).Distinct().ToList();
var workshops = await _context.Workshops
.Where(x => workshopIds.Contains(x.id))
.ToListAsync();
List<long> exceptionWorkshops = [516,63,38,39];
var res = query.Select(x =>
{
var workshop = workshops.FirstOrDefault(w => w.id == x.WorkshopIds);
var employerRes = new ContractPrintEmployerViewModel()
{
WorkshopName = workshop!.WorkshopName,
Address =$"{workshop.State} - {workshop.City} - {workshop.Address}",
LegalType = x.Employer.IsLegal == "حقیقی" ? LegalType.Real : LegalType.Legal,
LegalEmployer = x.Employer.IsLegal == "حقیقی"
? null
: new ContractPrintLegalEmployerViewModel()
{
NationalId = x.Employer.NationalId,
RegisterId = x.Employer.RegisterId,
CompanyName = x.Employer.LName,
},
RealEmployer = x.Employer.IsLegal == "حقیقی"
? new ContractPrintRealEmployerViewModel()
{
FullName = x.Employer.FullName,
IdNumber = x.Employer.IdNumber,
NationalCode = x.Employer.Nationalcode
}
: null,
WorkshopCode = workshop.InsuranceCode
};
var employeeRes = new ContractPrintEmployeeViewModel()
{
Address =$"{x.Employee.State} - {x.Employee.City} - {x.Employee.Address}" ,
FullName = x.Employee.FullName,
IdNumber = x.Employee.IdNumber,
NationalCode = x.Employee.NationalCode,
DateOfBirth = x.Employee.DateOfBirth.ToFarsi(),
FatherName = x.Employee.FatherName,
LevelOfEducation = x.Employee.LevelOfEducation
};
var typeOfContract = new ContractPrintTypeOfContractViewModel()
{
ContarctStart = x.ContarctStart.ToFarsi(),
ContractEnd = x.ContractEnd.ToFarsi(),
JobName = x.JobType,
ContractType = x.ContractType,
SetContractDate = x.SetContractDate.ToFarsi(),
WorkingHoursWeekly = WeeklyHourConvertor(x.WorkingHoursWeekly),
WorkshopAddress = [x.WorkshopAddress1, x.WorkshopAddress2],
};
ContractPrintFeesViewModel fees= new ContractPrintFeesViewModel()
{
DailyWage = x.DayliWage,
FamilyAllowance = x.FamilyAllowance,
HousingAllowance = x.HousingAllowance,
ConsumableItems = x.ConsumableItems,
};
return new ContractPrintViewModel()
{
Employer = employerRes,
Employee = employeeRes,
TypeOfContract = typeOfContract,
Fees = fees,
ContractNo = x.ContractNo,
ConditionAndDetials = exceptionWorkshops.Contains(x.WorkshopIds) ? "بر اساس ماده 190 قانون کار جمهوری اسلامی ایران ، پرسنل اقرار مینماید کلیه مبالغ پیش بینی شده در قانون کار را وفق قرارداد منعقده دریافت مینماید. این مبالغ قسمتی بصورت مستقیم از سوی کارفرما و قسمتی بر اساس شرایط کارگاه از محل درآمد حاصله از مشتری اخذ میگردد . با توجه به شرایط کارگاه کلیه مبالغ بصورت واریز به حساب و وجه نقد رایج کشور ، تواما به پرسنل پرداخت میگردد. امضا تصفیه حساب دارای مبالغ ، توسط پرسنل نشانگر تصفیه قطعی ایشان میباشد.": "",
};
}).ToList();
return res;
}
#endregion
#region NewChangeByHeydari

View File

@@ -0,0 +1,39 @@
using _0_Framework.Application;
using Company.Domain.ContractAgg;
using CompanyManagment.App.Contracts.Contract;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
namespace ServiceHost.Areas.Client.Controllers;
public class ContractController:ClientBaseController
{
private readonly IContractApplication _contractApplication;
public ContractController(IContractApplication contractApplication)
{
_contractApplication = contractApplication;
}
[HttpGet]
public async Task<ActionResult<PagedResult<GetContractListForClientResponse>>> GetList(
GetContractListForClientRequest searchModel)
{
var res = await _contractApplication
.GetContractListForClient(searchModel);
return res;
}
[HttpGet("print/{id}")]
public async Task<ActionResult<ContractPrintViewModel>> PrintOne(long id)
{
var res = await _contractApplication.PrintOneAsync(id);
return res;
}
[HttpGet("print")]
public async Task<ActionResult<List<ContractPrintViewModel>>> PrintAll([FromQuery] List<long> ids)
{
var res = await _contractApplication.PrintAllAsync(ids);
return res;
}
}