379 lines
15 KiB
C#
379 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using _0_Framework.Application;
|
|
using Company.Domain.EmployeeAgg;
|
|
using Company.Domain.LeaveAgg;
|
|
using Company.Domain.RollCallAgg;
|
|
using Company.Domain.RollCallEmployeeAgg;
|
|
using CompanyManagment.App.Contracts.Employee;
|
|
using CompanyManagment.App.Contracts.RollCall;
|
|
|
|
namespace CompanyManagment.Application;
|
|
|
|
public class RollCallApplication : IRollCallApplication
|
|
{
|
|
private readonly IRollCallRepository _rollCallRepository;
|
|
private readonly IEmployeeApplication _employeeApplication;
|
|
private readonly IRollCallEmployeeRepository _rollCallEmployeeRepository;
|
|
private readonly IEmployeeRepository _employeeRepository;
|
|
private readonly ILeaveRepository _leaveRepository;
|
|
|
|
public RollCallApplication(IRollCallRepository rollCallRepository, IEmployeeApplication employeeApplication, IRollCallEmployeeRepository rollCallEmployeeRepository, IEmployeeRepository employeeRepository, ILeaveRepository leaveRepository)
|
|
{
|
|
_rollCallRepository = rollCallRepository;
|
|
_employeeApplication = employeeApplication;
|
|
_rollCallEmployeeRepository = rollCallEmployeeRepository;
|
|
_employeeRepository = employeeRepository;
|
|
_leaveRepository = leaveRepository;
|
|
}
|
|
|
|
public OperationResult Create(CreateRollCall command)
|
|
{
|
|
var opration = new OperationResult();
|
|
var startDateFa = command.StartDate.ToFarsi();
|
|
|
|
var yearFa = Convert.ToInt32(startDateFa.Substring(0, 4));
|
|
var monthFa = Convert.ToInt32(startDateFa.Substring(5, 2));
|
|
var employeeName = _employeeApplication.GetDetails(command.EmployeeId).EmployeeFullName;
|
|
var create = new RollCall(command.WorkshopId, command.EmployeeId, employeeName, command.StartDate, null,
|
|
yearFa, monthFa);
|
|
_rollCallRepository.Create(create);
|
|
_rollCallRepository.SaveChanges();
|
|
return opration.Succcedded();
|
|
}
|
|
|
|
public OperationResult Edit(long id)
|
|
{
|
|
var opration = new OperationResult();
|
|
var personRollCall = _rollCallRepository.Get(id);
|
|
if (personRollCall == null)
|
|
opration.Failed("رکورد مورد نظر وجود ندارد");
|
|
var now = DateTime.Now;
|
|
personRollCall.SetEndDateTime(now);
|
|
_rollCallRepository.SaveChanges();
|
|
return opration.Succcedded();
|
|
}
|
|
|
|
public EditRollCall GetByEmployeeIdAndWorkshopId(long employeeId, long workshopId)
|
|
{
|
|
return _rollCallRepository.GetByEmployeeIdAndWorkshopId(employeeId, workshopId);
|
|
}
|
|
|
|
|
|
|
|
public EditRollCall GetById(long id)
|
|
{
|
|
return _rollCallRepository.GetById(id);
|
|
}
|
|
|
|
public List<RollCallViewModel> Search(RollCallSearchModel searchModel)
|
|
{
|
|
return _rollCallRepository.Search(searchModel);
|
|
}
|
|
|
|
|
|
#region Pooya
|
|
public TimeSpan GetEmployeeRollCallTimeSpanForDuration(long employeeId, long workshopId, string startFa,
|
|
string endFa)
|
|
{
|
|
if (startFa.TryToGeorgianDateTime(out DateTime startDateTime) == false)
|
|
return TimeSpan.Zero;
|
|
if (endFa.TryToGeorgianDateTime(out DateTime endDateTime) == false)
|
|
return TimeSpan.Zero;
|
|
|
|
if(startDateTime > endDateTime)
|
|
return TimeSpan.Zero;
|
|
|
|
return _rollCallRepository.GetEmployeeRollCallTimeSpanForDuration(employeeId, workshopId, startDateTime, endDateTime);
|
|
}
|
|
public OperationResult RemoveEmployeeRollCallsInDate(long workshopId, long employeeId, string dateFa)
|
|
{
|
|
OperationResult op = new();
|
|
var date = dateFa.ToGeorgianDateTime();
|
|
if (date == Tools.GetUndefinedDateTime())
|
|
return op.Failed("خطای سیستمی");
|
|
_rollCallRepository.RemoveEmployeeRollCallsInDate(workshopId, employeeId, date);
|
|
_rollCallRepository.SaveChanges();
|
|
return op.Succcedded();
|
|
}
|
|
public RollCallsByDateViewModel GetWorkshopRollCallHistory(RollCallSearchModel searchModel)
|
|
{
|
|
return _rollCallRepository.GetWorkshopRollCallHistory(searchModel);
|
|
}
|
|
|
|
public CurrentDayRollCall GetWorkshopCurrentDayRollCalls(long workshopId)
|
|
{
|
|
return _rollCallRepository.GetWorkshopCurrentDayRollCalls(workshopId);
|
|
}
|
|
|
|
public List<CheckoutDailyRollCallViewModel> GetActiveEmployeeRollCallsForDuration(long employeeId, long workshopId, string startDate,
|
|
string endDate)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(startDate) || !string.IsNullOrWhiteSpace(endDate))
|
|
return new();
|
|
|
|
var startDateGr = startDate.ToGeorgianDateTime();
|
|
var endDateGr = endDate.ToGeorgianDateTime();
|
|
|
|
if (startDateGr >= endDateGr)
|
|
return new();
|
|
|
|
//if (!_rollCallEmployeeRepository.Exists(x => x.EmployeeId == employeeId &&
|
|
// x.WorkshopId == workshopId && x.IsActiveString == "true"))
|
|
// return new();
|
|
return _rollCallRepository.GetEmployeeRollCallsForMonth(employeeId, workshopId, startDateGr, endDateGr);
|
|
}
|
|
|
|
|
|
public EmployeeRollCallsByMonthViewModel GetEmployeeRollCallsHistory(long employeeId, long workshopId, string startDateTime, string endDateTime, string exactDateTime,
|
|
string dateIndex)
|
|
{
|
|
DateTime? startDateTimeGr = null;
|
|
DateTime? endDateTimeGr = null;
|
|
if (!string.IsNullOrWhiteSpace(startDateTime) && !string.IsNullOrWhiteSpace(endDateTime))
|
|
{
|
|
startDateTimeGr = startDateTime.ToGeorgianDateTime();
|
|
endDateTimeGr = endDateTime.ToGeorgianDateTime();
|
|
if (endDateTimeGr < startDateTimeGr)
|
|
{
|
|
return new();
|
|
}
|
|
|
|
}
|
|
|
|
DateTime? exactDateTimeGr =
|
|
!string.IsNullOrWhiteSpace(exactDateTime) ? exactDateTime.ToGeorgianDateTime() : null;
|
|
|
|
|
|
DateTime? index = null;
|
|
if (!string.IsNullOrWhiteSpace(dateIndex))
|
|
{
|
|
index = dateIndex.ToGeorgianDateTime();
|
|
index = (index.Value.Date >= DateTime.Now) || (index.Value == new DateTime(3000, 12, 20, new PersianCalendar())) ? null : index;
|
|
|
|
}
|
|
|
|
return _rollCallRepository.GetEmployeeRollCallsHistory(employeeId, workshopId, startDateTimeGr, endDateTimeGr, exactDateTimeGr, index);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// افزودن حضور غیاب به صورت دستی. اگر آیدی رکورد صفر باشد رکورد جدید، در غیر این صورت ویرایش می کند
|
|
/// </summary>
|
|
public OperationResult ManualEdit(CreateOrEditEmployeeRollCall command)
|
|
{
|
|
var operation = new OperationResult();
|
|
var activities = command.RollCallRecords.Select(x => (x.StartTime, x.EndTime));
|
|
|
|
DateTime date = command.DateFa.ToGeorgianDateTime();
|
|
if (date == Tools.GetUndefinedDateTime())
|
|
return operation.Failed("فرمت تاریخ وارد شده صحیح نمی باشد");
|
|
|
|
if (date >= DateTime.Now.Date)
|
|
{
|
|
return operation.Failed("امکان اضافه کردن حضور غیاب برای روز جاری و روز های آینده وجود ندارد");
|
|
}
|
|
|
|
if (command.WorkshopId < 1)
|
|
{
|
|
return operation.Failed("خطای سیستمی");
|
|
}
|
|
|
|
if (command.RollCallRecords == null || command.RollCallRecords.Count == 0)
|
|
return operation.Failed("خطای سیستمی");
|
|
|
|
if (_leaveRepository.HasDailyLeave(command.EmployeeId, command.WorkshopId, date))
|
|
return operation.Failed("در روز مرخصی کارمند نمی توانید حضور غیاب ثبت کنید");
|
|
|
|
var employeeStatuses = _rollCallEmployeeRepository.GetByEmployeeIdWithStatuses(command.EmployeeId)
|
|
.FirstOrDefault(x => x.WorkshopId == command.WorkshopId)?.Statuses;
|
|
|
|
var employeeRollCalls = _rollCallRepository.GetWorkshopEmployeeRollCallsForDate(command.WorkshopId, command.EmployeeId, date);
|
|
|
|
if (employeeRollCalls.Any(x => x.EndDate == null))
|
|
return operation.Failed("به دلیل عدم ثبت خروج پرسنل در این تاریخ، شما قادر به افزودن رکورد جدید نمی باشید");
|
|
|
|
if (command.RollCallRecords.Any(x => string.IsNullOrWhiteSpace(x.StartTime) || string.IsNullOrWhiteSpace(x.EndTime)))
|
|
return operation.Failed("ساعات شروع و پایان نمیتوانند خالی باشد");
|
|
|
|
#region RollCallTimes validation and parse to DateTime
|
|
|
|
List<(TimeOnly start, TimeOnly end, long rollCallId)> preprocessedRollCalls = new();
|
|
try
|
|
{
|
|
preprocessedRollCalls = command.RollCallRecords.Select(x =>
|
|
{
|
|
|
|
if (!TimeOnly.TryParseExact(x.StartTime, "HH:mm", out TimeOnly start))
|
|
throw new Exception();
|
|
if (!TimeOnly.TryParseExact(x.EndTime, "HH:mm", out TimeOnly end))
|
|
throw new Exception();
|
|
return (start, end, x.RollCallId);
|
|
|
|
}).ToList();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
|
|
return operation.Failed("فرمت ساعات ورودی نادرست می باشد");
|
|
}
|
|
|
|
DateTime day = command.DateFa.ToGeorgianDateTime();
|
|
if (day == Tools.GetUndefinedDateTime())
|
|
return operation.Failed("خطای سیستمی");
|
|
DateTime previousEnd = new DateTime();
|
|
preprocessedRollCalls = preprocessedRollCalls.OrderBy(x => x.start).ToList();
|
|
List<(DateTime Start, DateTime End, long RollCallId)> result = new();
|
|
|
|
|
|
foreach (var item in preprocessedRollCalls)
|
|
{
|
|
(DateTime Start, DateTime End, long RollCallId) rollCallWithDateTime =
|
|
new()
|
|
{
|
|
Start = new DateTime(DateOnly.FromDateTime(day), item.start),
|
|
End = new DateTime(DateOnly.FromDateTime(day), item.end),
|
|
RollCallId = item.rollCallId
|
|
|
|
};
|
|
|
|
if (previousEnd != new DateTime())
|
|
{
|
|
if (rollCallWithDateTime.Start < previousEnd)
|
|
{
|
|
rollCallWithDateTime.Start = rollCallWithDateTime.Start.AddDays(1);
|
|
}
|
|
if (rollCallWithDateTime.Start == previousEnd)
|
|
return operation.Failed("ساعت ورود نمی تواند با ساعت خروج حضور غیاب دیگری در آن روز برابر باشد");
|
|
|
|
}
|
|
while (rollCallWithDateTime.Start >= rollCallWithDateTime.End)
|
|
{
|
|
rollCallWithDateTime.End = rollCallWithDateTime.End.AddDays(1);
|
|
}
|
|
result.Add(rollCallWithDateTime);
|
|
previousEnd = rollCallWithDateTime.End;
|
|
}
|
|
var firstShiftStart = result.OrderBy(x => x.Start).FirstOrDefault().Start;
|
|
var lastShiftEnd = result.OrderByDescending(x => x.Start).FirstOrDefault().End;
|
|
var lastShiftStart = result.OrderByDescending(x => x.Start).FirstOrDefault().Start;
|
|
|
|
if (firstShiftStart.AddDays(1) < lastShiftEnd)
|
|
return operation.Failed("بازه زمانی وارد شده نا معتبر است");
|
|
if (result.Sum(x => (x.End - x.Start).TotalHours) > 24)
|
|
{
|
|
return operation.Failed("بازه زمانی نمیتواند بیشتر از 24 ساعت باشد");
|
|
}
|
|
if (firstShiftStart.Date != lastShiftStart.Date)
|
|
return operation.Failed("شروع رکورد حضور غیاب نمی تواند در روز های بعد از تاریخ تعیین شده باشد");
|
|
|
|
#endregion
|
|
foreach (var activity in result)
|
|
{
|
|
|
|
//مرخصی روزانه در بالا چک شده است
|
|
var leave = _leaveRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, command.EmployeeId, activity.Start, activity.End)
|
|
.Where(x => x.PaidLeaveType == "ساعتی");
|
|
if (leave.Any())
|
|
return operation.Failed("کارمند در بازه انتخاب شده مرخصی ساعتی دارد");
|
|
}
|
|
|
|
if (result == null || !result.All(x => employeeStatuses.Any(y => x.Start >= y.StartDateGr && x.End <= y.EndDateGr)))
|
|
return operation.Failed("کارمند در بازه وارد شده غیر فعال است");
|
|
|
|
|
|
var name = _rollCallEmployeeRepository.GetByEmployeeIdAndWorkshopId(command.EmployeeId, command.WorkshopId).EmployeeFullName;
|
|
var rollCallsAsEntityModels = result.Select(x => new RollCall(command.WorkshopId, command.EmployeeId, name, x.Start, x.End,
|
|
Convert.ToInt32(x.Start.ToFarsi().Substring(0, 4)), Convert.ToInt32(x.Start.ToFarsi().Substring(5, 2)), RollCallModifyType.EditByEmployer)).ToList();
|
|
_rollCallRepository.RemoveEmployeeRollCallsInDate(command.WorkshopId, command.EmployeeId, date);
|
|
|
|
|
|
_rollCallRepository.AddRange(rollCallsAsEntityModels);
|
|
_rollCallRepository.SaveChanges();
|
|
return operation.Succcedded();
|
|
}
|
|
|
|
public List<RollCallViewModel> GetWorkshopEmployeeRollCallsForDate(long workshopId, long employeeId, string dateFa)
|
|
{
|
|
DateTime date = Tools.ToGeorgianDateTime(dateFa);
|
|
if (date == Tools.GetUndefinedDateTime())
|
|
return new();
|
|
var res = _rollCallRepository.GetWorkshopEmployeeRollCallsForDate(workshopId, employeeId, date);
|
|
return res;
|
|
}
|
|
|
|
public IEnumerable<RollCallViewModel> GetNotSlicedRollCallsByWorkshopId(long workshopId, DateTime durationStart, DateTime durationEnd)
|
|
{
|
|
return _rollCallRepository.GetNotSlicedRollCallsByWorkshopId(workshopId, durationStart, durationEnd);
|
|
}
|
|
|
|
public List<RollCallsByDateViewModel> GetWorkshopAbsentHistory(long workshopId, DateTime startSearch, DateTime endSearch)
|
|
{
|
|
return _rollCallRepository.GetWorkshopAbsentHistory(workshopId, startSearch, endSearch);
|
|
}
|
|
|
|
public OperationResult SetModifyTypeToNone(long rollCallId)
|
|
{
|
|
var operation = new OperationResult();
|
|
|
|
var rollCall = _rollCallRepository.Get(rollCallId);
|
|
|
|
if (rollCall == null)
|
|
return operation.Failed("چنین آیتمی یافت نشد");
|
|
|
|
rollCall.SetModifyType(RollCallModifyType.None);
|
|
|
|
_rollCallRepository.SaveChanges();
|
|
|
|
return operation.Succcedded();
|
|
}
|
|
|
|
public OperationResult SetModifyTypeToEditByEmployer(long rollCallId)
|
|
{
|
|
var operation = new OperationResult();
|
|
|
|
var rollCall = _rollCallRepository.Get(rollCallId);
|
|
|
|
if (rollCall == null)
|
|
return operation.Failed("چنین آیتمی یافت نشد");
|
|
|
|
rollCall.SetModifyType(RollCallModifyType.EditByEmployer);
|
|
|
|
_rollCallRepository.SaveChanges();
|
|
|
|
return operation.Succcedded();
|
|
}
|
|
|
|
|
|
|
|
public List<RollCallsByDateViewModel> GetRollCallWorkFlowsCutByBgService(long workshopId, DateTime start, DateTime end)
|
|
{
|
|
return _rollCallRepository.GetRollCallWorkFlowsCutByBgService(workshopId, start, end);
|
|
|
|
}
|
|
|
|
public int GetCountCutRollCallByBgService(long accId, long workshopId)
|
|
{
|
|
return _rollCallRepository.GetCountCutRollCallByBgService(accId, workshopId);
|
|
}
|
|
|
|
|
|
public RollCallViewModel GetDetails(long rollCallId)
|
|
{
|
|
return _rollCallRepository.GetDetails(rollCallId);
|
|
}
|
|
#endregion
|
|
public long Flag(long employeeId, long workshopId)
|
|
{
|
|
return _rollCallRepository.Flag(employeeId, workshopId);
|
|
}
|
|
|
|
public string CheckRepeat(long employeeId, long workshopId)
|
|
{
|
|
return _rollCallRepository.CheckRepeat(employeeId, workshopId);
|
|
}
|
|
} |