Compare commits

...

26 Commits

Author SHA1 Message Date
SamSys
69476f3f2d add multiple get list for leaveController 2025-12-24 12:53:06 +03:30
SamSys
4bc65e500d Merge branch 'Feature/ClientLeavePageApi' of https://github.com/samsyntax24/OriginalGozareshgir into Feature/ClientLeavePageApi 2025-12-24 11:53:15 +03:30
07587d162f add: implement PrintAllAsync and PrintOneAsync methods for leave printing functionality 2025-12-24 11:17:53 +03:30
SamSys
59bbb7aae6 ini leave groupList 2025-12-23 18:15:48 +03:30
SamSys
89de3162de GetLewvList Api 2025-12-23 17:03:54 +03:30
SamSys
132c8ac5a4 init 2025-12-23 15:10:17 +03:30
SamSys
f00fde4084 Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-23 13:47:25 +03:30
SamSys
e8b3700cdf GetList PlanPercentage CountAsync 2025-12-23 13:46:59 +03:30
0ca35e3295 Merge remote-tracking branch 'origin/master' 2025-12-23 11:51:47 +03:30
1a91743916 add: update CalculateDiscount method to include contractStart parameter 2025-12-23 10:50:11 +03:30
SamSys
dd68473150 Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-23 04:18:08 +03:30
SamSys
72e3859d2c next ui upload from wbe completed 2025-12-23 04:17:52 +03:30
46d193b45e Merge branch 'Feature/program-manager/test-upload' 2025-12-22 19:51:49 +03:30
1bfe41418b add: enhance ProjectBoardDetailResponse to include RemainingTime and user time details 2025-12-22 19:51:21 +03:30
6a446d5972 add: implement AutoStopOverTimeTaskSections command and related functionality 2025-12-22 19:13:34 +03:30
Mahan Chamani
acec101c4c Update deployment password in workflow file 2025-12-22 18:24:02 +03:30
SamSys
7d92321d1c Merge branch 'master' of https://github.com/samsyntax24/OriginalGozareshgir 2025-12-22 17:46:31 +03:30
SamSys
19f78a230c change 2025-12-22 17:46:02 +03:30
0e91e6f287 Merge remote-tracking branch 'origin/master' 2025-12-22 17:44:20 +03:30
9df56ee19b Merge branch 'Feature/institution-contract/verify-mannually' 2025-12-22 17:44:04 +03:30
8750604d96 feat: add financial transaction handling during institution contract verification 2025-12-22 17:43:32 +03:30
f27ce460fd feat: integrate RollCallService repository into InstitutionContractApplication and WorkshopApplication 2025-12-22 17:33:37 +03:30
SamSys
934019c6c6 InsuranceNotCreated tab backend changed 2025-12-22 16:34:42 +03:30
SamSys
82bf10c2d5 ServiceAmount GetList 2025-12-22 14:21:01 +03:30
SamSys
19a72ac78d load data and create service percentage 2025-12-22 12:35:51 +03:30
SamSys
9cb42b7cef background job changed 2025-12-22 11:16:50 +03:30
39 changed files with 1478 additions and 78 deletions

View File

@@ -37,7 +37,7 @@ jobs:
& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" ` & "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
-verb:sync ` -verb:sync `
-source:contentPath="$publishFolder" ` -source:contentPath="$publishFolder" `
-dest:contentPath="dadmehrg",computerName="https://171.22.24.15:8172/msdeploy.axd?site=dadmehrg",userName="Administrator",password="R2rNpdnetP3j>q5b18",authType="Basic" ` -dest:contentPath="dadmehrg",computerName="https://171.22.24.15:8172/msdeploy.axd?site=dadmehrg",userName="Administrator",password="R",authType="Basic" `
-allowUntrusted ` -allowUntrusted `
-enableRule:AppOffline -enableRule:AppOffline

View File

@@ -39,4 +39,15 @@ public static class StaticWorkshopAccounts
/// که کاربر همچنان به کارگاه دسترسی دارد /// که کاربر همچنان به کارگاه دسترسی دارد
/// </summary> /// </summary>
public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1); public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1);
/// <summary>
/// لیستی آی دی نقش هایی که مسئول بیمه کارگاه هستند
/// 7 : بیمه ارشد
/// 8 : بیمه ساده
/// </summary>
public static List<long> InsuranceAccountsRoleIds = [7, 8];
} }

View File

@@ -1,5 +1,6 @@
using _0_Framework.Application; using _0_Framework.Application;
using _0_Framework.Application.Sms;
using Company.Domain.ContarctingPartyAgg; using Company.Domain.ContarctingPartyAgg;
using Company.Domain.InstitutionContractAgg; using Company.Domain.InstitutionContractAgg;
using Hangfire; using Hangfire;
@@ -13,13 +14,15 @@ public class JobSchedulerRegistrator
private readonly IInstitutionContractRepository _institutionContractRepository; private readonly IInstitutionContractRepository _institutionContractRepository;
private static DateTime? _lastRunCreateTransaction; private static DateTime? _lastRunCreateTransaction;
private static DateTime? _lastRunSendMonthlySms; private static DateTime? _lastRunSendMonthlySms;
private readonly ISmsService _smsService;
public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient, IInstitutionContractRepository institutionContractRepository) public JobSchedulerRegistrator(SmsReminder smsReminder, IBackgroundJobClient backgroundJobClient, IInstitutionContractRepository institutionContractRepository, ISmsService smsService)
{ {
_smsReminder = smsReminder; _smsReminder = smsReminder;
_backgroundJobClient = backgroundJobClient; _backgroundJobClient = backgroundJobClient;
_institutionContractRepository = institutionContractRepository; _institutionContractRepository = institutionContractRepository;
_smsService = smsService;
} }
public void Register() public void Register()
@@ -91,7 +94,7 @@ public class JobSchedulerRegistrator
} }
catch (Exception e) catch (Exception e)
{ {
//_smsService.Alarm("09114221321", "خطا-ایجاد سند مالی"); await _smsService.Alarm("09114221321", "خطا-ایجاد سند مالی");
} }

View File

@@ -0,0 +1,10 @@
using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
public class NullBoardNotificationPublisher:IBoardNotificationPublisher
{
public Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus, TaskSectionStatus newStatus, Guid sectionId)
{
throw new NotImplementedException();
}
}

View File

@@ -8,6 +8,7 @@ using BackgroundInstitutionContract.Task.Jobs;
using CompanyManagment.App.Contracts.Hubs; using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.EFCore.Services; using CompanyManagment.EFCore.Services;
using GozareshgirProgramManager.Application._Bootstrapper; using GozareshgirProgramManager.Application._Bootstrapper;
using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser;
using GozareshgirProgramManager.Infrastructure; using GozareshgirProgramManager.Infrastructure;
using GozareshgirProgramManager.Infrastructure.Persistence.Seed; using GozareshgirProgramManager.Infrastructure.Persistence.Seed;
@@ -31,7 +32,7 @@ builder.Services.AddTransient<ISmsService, SmsService>();
builder.Services.AddTransient<IUidService, UidService>(); builder.Services.AddTransient<IUidService, UidService>();
builder.Services.AddTransient<IFileUploader, FileUploader>(); builder.Services.AddTransient<IFileUploader, FileUploader>();
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration); builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
builder.Services.AddScoped<IBoardNotificationPublisher, NullBoardNotificationPublisher>();
#region MongoDb #region MongoDb
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb"); var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");

View File

@@ -56,7 +56,7 @@ public interface IInstitutionContractRepository : IRepository<long, InstitutionC
void UpdateStatusIfNeeded(long institutionContractId); void UpdateStatusIfNeeded(long institutionContractId);
Task<GetInstitutionVerificationDetailsViewModel> GetVerificationDetails(Guid id); Task<GetInstitutionVerificationDetailsViewModel> GetVerificationDetails(Guid id);
Task<InstitutionContract> GetByPublicIdAsync(Guid id); Task<InstitutionContract> GetByPublicIdAsync(Guid id);
InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request); InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request,string contractStart = null);
InstitutionContractDiscountResponse ResetDiscountCreate(InstitutionContractResetDiscountForCreateRequest request); InstitutionContractDiscountResponse ResetDiscountCreate(InstitutionContractResetDiscountForCreateRequest request);

View File

@@ -1,7 +1,9 @@
using _0_Framework.Domain; using _0_Framework.Application;
using _0_Framework.Domain;
using CompanyManagment.App.Contracts.InstitutionPlan; using CompanyManagment.App.Contracts.InstitutionPlan;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace Company.Domain.InstitutionPlanAgg; namespace Company.Domain.InstitutionPlanAgg;
@@ -26,4 +28,18 @@ public interface IPlanPercentageRepository : IRepository<long, PlanPercentage>
/// <param name="command"></param> /// <param name="command"></param>
/// <returns></returns> /// <returns></returns>
InstitutionPlanViewModel GetInstitutionPlanForWorkshop(WorkshopTempViewModel command); InstitutionPlanViewModel GetInstitutionPlanForWorkshop(WorkshopTempViewModel command);
/// <summary>
/// دریافت دیتای مودال ایجاد
/// </summary>
/// <returns></returns>
Task<CreateServiceAmountDto> GetCreateModalData();
/// <summary>
/// دریافت لیست مبالغ سرویس ها
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<PagedResult<InstitutionPlanListDto>> GetList(
InstitutionPlanSearchModel searchModel);
} }

View File

@@ -1,8 +1,10 @@
using System; using _0_Framework.Application;
using System.Collections.Generic;
using _0_Framework.Application;
using _0_Framework.Domain; using _0_Framework.Domain;
using CompanyManagment.App.Contracts.InstitutionPlan;
using CompanyManagment.App.Contracts.Leave; using CompanyManagment.App.Contracts.Leave;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Company.Domain.LeaveAgg; namespace Company.Domain.LeaveAgg;
@@ -28,10 +30,28 @@ public interface ILeaveRepository : IRepository<long, Leave>
LeavePrintViewModel PrintOne(long id); LeavePrintViewModel PrintOne(long id);
List<LeavePrintViewModel> PrintAll(List<long> id); List<LeavePrintViewModel> PrintAll(List<long> id);
Task<List<LeavePrintResponseViewModel>> PrintAllAsync(List<long> ids, long workshopId);
#region Vafa #region Vafa
List<LeaveViewModel> LastLeaveMain(LeaveSearchModel searchModel); List<LeaveViewModel> LastLeaveMain(LeaveSearchModel searchModel);
#endregion #endregion
bool CheckIfValidToEdit(long id); bool CheckIfValidToEdit(long id);
/// <summary>
/// دریافت لیست مرخصی ها در کلاینت
/// Api
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<PagedResult<leaveListDto>> GetList(
LeaveListSearchModel searchModel);
/// <summary>
/// دریافت لیست گروه بندی شده
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<List<GroupLeaveListDto>> GetGroupList(LeaveListSearchModel searchModel);
} }

View File

@@ -76,5 +76,7 @@ public class InstitutionContractViewModel
public bool IsInstallment { get; set; } public bool IsInstallment { get; set; }
public InstitutionContractVerificationStatus VerificationStatus { get; set; } public InstitutionContractVerificationStatus VerificationStatus { get; set; }
public InstitutionContractSigningType? SigningType { get; set; }
public List<InstitutionContractInstallmentViewModel> InstallmentList { get; set; } public List<InstitutionContractInstallmentViewModel> InstallmentList { get; set; }
} }

View File

@@ -0,0 +1,51 @@
namespace CompanyManagment.App.Contracts.InstitutionPlan;
public class CreateServiceAmountDto
{
/// <summary>
/// آی دی
/// </summary>
public long Id { get; set; }
/// <summary>
/// قرارداد و تصفیه
/// درصد از مزد روزانه
/// string
/// </summary>
public string ContractAndCheckoutPercentStr { get; set; }
/// <summary>
/// بیمه
/// درصد از مزد روزانه
/// string
/// </summary>
public string InsurancePercentStr { get; set; }
/// <summary>
/// حضورغباب
/// درصد از مزد روزانه
/// string
/// </summary>
public string RollCallPercentStr { get; set; }
/// <summary>
/// فیش غیر رسمی
/// درصد از مزد روزانه
/// string
/// </summary>
public string CustomizeCheckoutPercentStr { get; set; }
/// <summary>
/// خدمات حضوری قرداد و تصفیه
/// درصد از مزد روزانه
/// string
/// </summary>
public string ContractAndCheckoutInPersonPercentStr { get; set; }
/// <summary>
/// خدمات حضوری بیمه
/// درصد از مزد روزانه
/// string
/// </summary>
public string InsuranceInPersonPercentStr { get; set; }
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using _0_Framework.Application;
using _0_Framework.Application;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace CompanyManagment.App.Contracts.InstitutionPlan; namespace CompanyManagment.App.Contracts.InstitutionPlan;
@@ -34,4 +35,27 @@ public interface IInstitutionPlanApplication
/// <param name="command"></param> /// <param name="command"></param>
/// <returns></returns> /// <returns></returns>
InstitutionPlanViewModel GetInstitutionPlanForWorkshop(WorkshopTempViewModel command); InstitutionPlanViewModel GetInstitutionPlanForWorkshop(WorkshopTempViewModel command);
/// <summary>
/// دریافت دیتای درصد سرویس برای مودال ایجاد
/// </summary>
/// <returns></returns>
Task<CreateServiceAmountDto> GetCreateModalData();
/// <summary>
/// ایجاد درصد سرویس
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
Task<OperationResult> CreateInstitutionPlanPercentage(CreateServiceAmountDto command);
/// <summary>
/// دریافت لیست مبالغ سرویس ها
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<PagedResult<InstitutionPlanListDto>> GetList(
InstitutionPlanSearchModel searchModel);
} }

View File

@@ -0,0 +1,84 @@
namespace CompanyManagment.App.Contracts.InstitutionPlan;
public class InstitutionPlanListDto
{
/// <summary>
/// تعداد پرسنل
/// </summary>
public int CountPerson { get; set; }
/// <summary>
/// مبلغ قرارداد و تصفیه
/// </summary>
public string ContractAndCheckout { get; set; }
/// <summary>
/// مبلغ بیمه
/// </summary>
public string Insurance { get; set; }
/// <summary>
/// مبلغ حضورغباب
/// </summary>
public string RollCall { get; set; }
/// <summary>
/// مبلغ فیش غیر رسمی
/// </summary>
public string CustomizeCheckout { get; set; }
/// <summary>
/// مبلغ خدمات حضوری قرداد و تصفیه
/// </summary>
public string ContractAndCheckoutInPerson { get; set; }
/// <summary>
/// مبلغ خدمات حضوری بیمه
/// </summary>
public string InsuranceInPerson { get; set; }
#region Total
/// <summary>
/// مبلغ کل خدمات حضوری
/// </summary>
public string InPersonSumAmountStr { get; set; }
/// <summary>
/// مبلغ کل خدمات آنلاین
/// </summary>
public string OnlineOnlySumAmountStr { get; set; }
/// <summary>
/// مبلغ کل خدمات حضوری و آنلاین
/// </summary>
public string OnlineAndInPersonSumAmountStr { get; set; }
/// <summary>
/// مبلغ کل خدمات حضوری و آنلاین
/// double
/// </summary>
public double OnlineAndInPersonSumAmountDouble { get; set; }
/// <summary>
/// مبلغ کل خدمات حضوری
/// double
/// </summary>
public double InPersonSumAmountDouble { get; set; }
/// <summary>
/// مبلغ کل خدمات آنلاین
/// double
/// </summary>
public double OnlineOnlySumAmountDouble { get; set; }
#endregion
}

View File

@@ -0,0 +1,11 @@
using _0_Framework.Application;
namespace CompanyManagment.App.Contracts.InstitutionPlan;
public class InstitutionPlanSearchModel : PaginationRequest
{
/// <summary>
/// تعداد پرسنل برای جستجو
/// </summary>
public int CountPerson { get; set; }
}

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.Leave;
public class GroupLeaveListDto
{
/// <summary>
/// سال مرخصی
/// </summary>
public string YearStr { get; set; }
/// <summary>
/// ماه مرخصی
/// </summary>
public string MonthStr { get; set; }
/// <summary>
/// آیتم های هر گروه
/// </summary>
public List<LeaveListItemsDto> LeaveListItemsDto { get; set; }
}
/// <summary>
/// آیتم های هر گروه
/// </summary>
public class LeaveListItemsDto
{
/// <summary>
/// نوع مرخصی، استحقاقی/استعلاجی
/// </summary>
public string LeaveType { get; set; }
/// <summary>
/// تاریخ شروع مرخصی
/// </summary>
public string StartLeave { get; set; }
/// <summary>
/// تاریخ پایان مرخصی
/// </summary>
public string EndLeave { get; set; }
/// <summary>
/// زمان مرخصی
/// بازه مرخصی ساعتی
/// </summary>
public string HourlyInterval { get; set; }
/// <summary>
/// مدت مرخصی
/// </summary>
public string LeaveDuration { get; set; }
/// <summary>
/// موافقت/عدم موافقت کارفرما
/// </summary>
public bool IsAccepted { get; set; }
/// <summary>
/// آی دی
/// </summary>
public long Id { get; set; }
/// <summary>
/// آی دی گارگاه
/// </summary>
public long WorkshopId { get; set; }
/// <summary>
/// آی دی پرسنل
/// </summary>
public long EmployeeId { get; set; }
/// <summary>
///آیا فاقد اعتبار است. فاقد اعتبار ها فقط برای فیش های غیررسمی مورد استفاده قرار میگیرند
/// </summary>
public bool IsInvalid { get; set; }
}

View File

@@ -37,4 +37,66 @@ public interface ILeaveApplication
string type); string type);
#endregion #endregion
/// <summary>
/// دریافت لیست مرخصی ها در کلاینت
/// Api
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<PagedResult<leaveListDto>> GetList(
LeaveListSearchModel searchModel);
/// <summary>
/// دریافت لیست گروه بندی شده
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
Task<List<GroupLeaveListDto>> GetGroupList(LeaveListSearchModel searchModel);
/// <summary>
/// دریافت مجکوع مرخصی پرسنل
/// اگر آی دی پرسنل، سال و ماه خالی نباشد
/// </summary>
/// <param name="workshopId"></param>
/// <param name="employeeId"></param>
/// <param name="yearStr"></param>
/// <param name="monthStr"></param>
/// <param name="leaveType"></param>
/// <returns></returns>
TimeSpan SumOfEmployeeLeaveTimeSpanInDates(long workshopId, long employeeId, string yearStr, string monthStr,
LeaveType leaveType);
Task<List<LeavePrintResponseViewModel>> PrintAllAsync(List<long> ids, long workshopId);
Task<LeavePrintResponseViewModel> PrintOneAsync(long id, long workshopId);
}
public class LeavePrintResponseViewModel
{
public string FullName { get; set; }
public string NationalCode { get; set; }
public string WorkshopName { get; set; }
public List<string> EmployerNames { get; set; }
public string PaidLeaveType { get; set; }
public string ContractNo { get; set; }
public LeavePrintHourlyResponseViewModel HourlyLeave { get; set; }
public LeavePrintDailyResponseViewModel DailyLeave { get; set; }
}
public class LeavePrintDailyResponseViewModel
{
public string StartLeave { get; set; }
public string EndLeave { get; set; }
public string TotalDay { get; set; }
}
public class LeavePrintHourlyResponseViewModel
{
public string LeaveDate { get; set; }
public string StartHour { get; set; }
public string EndHour { get; set; }
public string TotalHour { get; set; }
} }

View File

@@ -0,0 +1,24 @@
using _0_Framework.Application;
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.Leave;
public class LeaveListMultipleDto
{
/// <summary>
/// لیست گروهبندی شده بر اساس سال و ماه
/// اگر در جستجو پرسنل انتخاب شود
/// </summary>
public List<GroupLeaveListDto>? GroupLeaveListDto { get; set; }
/// <summary>
/// لیست نرمال PageResult
/// </summary>
public PagedResult<leaveListDto>? leaveListDto { get; set; }
/// <summary>
/// مجموع مرخصی پرسنل
/// اگر پرسنل انتخاب شده باشد
/// </summary>
public string? SumOfEmployeeleaves { get; set; }
}

View File

@@ -0,0 +1,45 @@
using _0_Framework.Application;
namespace CompanyManagment.App.Contracts.Leave;
public class LeaveListSearchModel : PaginationRequest
{
/// <summary>
/// آی دی کارگاه
/// </summary>
public long WorkshopId { get; set; }
/// <summary>
/// نوع مرخصی، استحقاقی/استعلاجی
/// </summary>
public LeaveType LeaveType { get; set; }
/// <summary>
/// سال مرخصی
/// </summary>
public string YearStr { get; set; }
/// <summary>
/// ماه مرخصی
/// </summary>
public string MonthStr { get; set; }
/// <summary>
///آیا فاقد اعتبار است. فاقد اعتبار ها فقط برای فیش های غیررسمی مورد استفاده قرار میگیرند
/// </summary>
public bool IsInvalid { get; private set; }
/// <summary>
/// تاریخ شروع مرخصی
/// </summary>
public string StartLeave { get; set; }
/// <summary>
/// تاریخ پایان مرخصی
/// </summary>
public string EndLeave { get; set; }
/// <summary>
/// آی دی پرسنل
/// </summary>
public long EmployeeId { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace CompanyManagment.App.Contracts.Leave;
public enum LeaveType
{
/// <summary>
/// هر دو
/// </summary>
Both,
/// <summary>
/// مرخصی استعلاجی
/// </summary>
SickLeave,
/// <summary>
/// مرخصی استحقاقی
/// </summary>
PaidLeave
}

View File

@@ -0,0 +1,84 @@
namespace CompanyManagment.App.Contracts.Leave;
public class leaveListDto
{
/// <summary>
/// نام کامل پرسنل
/// </summary>
public string EmployeeFullName { get; set; }
/// <summary>
/// سال مرخصی
/// </summary>
public string YearStr { get; set; }
/// <summary>
/// ماه مرخصی
/// </summary>
public string MonthStr { get; set; }
/// <summary>
/// نوع مرخصی، استحقاقی/استعلاجی
/// </summary>
public string LeaveType { get; set; }
/// <summary>
/// تاریخ شروع مرخصی
/// </summary>
public string StartLeave { get; set; }
/// <summary>
/// تاریخ پایان مرخصی
/// </summary>
public string EndLeave { get; set; }
/// <summary>
/// زمان مرخصی
/// بازه مرخصی ساعتی
/// </summary>
public string HourlyInterval { get; set; }
/// <summary>
/// مدت مرخصی
/// </summary>
public string LeaveDuration { get; set; }
/// <summary>
/// موافقت/عدم موافقت کارفرما
/// </summary>
public bool IsAccepted { get; set; }
/// <summary>
/// آی دی
/// </summary>
public long Id { get; set; }
/// <summary>
/// آی دی گارگاه
/// </summary>
public long WorkshopId { get; set; }
/// <summary>
/// آی دی پرسنل
/// </summary>
public long EmployeeId { get; set; }
/// <summary>
///آیا فاقد اعتبار است. فاقد اعتبار ها فقط برای فیش های غیررسمی مورد استفاده قرار میگیرند
/// </summary>
public bool IsInvalid { get; set; }
}

View File

@@ -22,6 +22,7 @@ using Company.Domain.InstitutionContractAgg;
using Company.Domain.LeftWorkAgg; using Company.Domain.LeftWorkAgg;
using Company.Domain.PaymentTransactionAgg; using Company.Domain.PaymentTransactionAgg;
using Company.Domain.RepresentativeAgg; using Company.Domain.RepresentativeAgg;
using Company.Domain.RollCallServiceAgg;
using Company.Domain.TemporaryClientRegistrationAgg; using Company.Domain.TemporaryClientRegistrationAgg;
using Company.Domain.WorkshopAgg; using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.FinancialInvoice; using CompanyManagment.App.Contracts.FinancialInvoice;
@@ -59,6 +60,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
private readonly IFinancialInvoiceRepository _financialInvoiceRepository; private readonly IFinancialInvoiceRepository _financialInvoiceRepository;
private readonly IPaymentGateway _paymentGateway; private readonly IPaymentGateway _paymentGateway;
private readonly IPaymentTransactionRepository _paymentTransactionRepository; private readonly IPaymentTransactionRepository _paymentTransactionRepository;
private readonly IRollCallServiceRepository _rollCallServiceRepository;
public InstitutionContractApplication(IInstitutionContractRepository institutionContractRepository, public InstitutionContractApplication(IInstitutionContractRepository institutionContractRepository,
@@ -70,7 +72,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
IFinancialStatmentRepository financialStatmentRepository, IContactInfoApplication contactInfoApplication, IFinancialStatmentRepository financialStatmentRepository, IContactInfoApplication contactInfoApplication,
IAccountApplication accountApplication, ISmsService smsService, IUidService uidService, IAccountApplication accountApplication, ISmsService smsService, IUidService uidService,
IFinancialInvoiceRepository financialInvoiceRepository, IHttpClientFactory httpClientFactory, IFinancialInvoiceRepository financialInvoiceRepository, IHttpClientFactory httpClientFactory,
IPaymentTransactionRepository paymentTransactionRepository) IPaymentTransactionRepository paymentTransactionRepository, IRollCallServiceRepository rollCallServiceRepository)
{ {
_institutionContractRepository = institutionContractRepository; _institutionContractRepository = institutionContractRepository;
_contractingPartyRepository = contractingPartyRepository; _contractingPartyRepository = contractingPartyRepository;
@@ -88,6 +90,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
_uidService = uidService; _uidService = uidService;
_financialInvoiceRepository = financialInvoiceRepository; _financialInvoiceRepository = financialInvoiceRepository;
_paymentTransactionRepository = paymentTransactionRepository; _paymentTransactionRepository = paymentTransactionRepository;
_rollCallServiceRepository = rollCallServiceRepository;
_paymentGateway = new SepehrPaymentGateway(httpClientFactory); _paymentGateway = new SepehrPaymentGateway(httpClientFactory);
} }
@@ -1555,13 +1558,34 @@ public class InstitutionContractApplication : IInstitutionContractApplication
.Where(x => x.WorkshopCreated && x.WorkshopId is > 0).ToList(); .Where(x => x.WorkshopCreated && x.WorkshopId is > 0).ToList();
var currentWorkshops = institutionContract.WorkshopGroup.CurrentWorkshops.ToList(); var currentWorkshops = institutionContract.WorkshopGroup.CurrentWorkshops.ToList();
var accountId = _contractingPartyRepository
.GetAccountByPersonalContractingParty(institutionContract.ContractingPartyId).Id;
foreach (var createdWorkshop in initialCreatedWorkshops) foreach (var createdWorkshop in initialCreatedWorkshops)
{ {
if (currentWorkshops.Any(x => x.WorkshopId == createdWorkshop.WorkshopId)) if (currentWorkshops.Any(x => x.WorkshopId == createdWorkshop.WorkshopId))
{ {
continue; //rollcall serviecs
if (createdWorkshop.Services.RollCall)
{
var ActiveService = _rollCallServiceRepository.GetActiveServiceByWorkshopId(createdWorkshop.WorkshopId!.Value);
var startTime = institutionContract.ContractStartGr;
var endTime = institutionContract.ContractEndGr;
if (ActiveService != null)
{
if (ActiveService.EndService> startTime)
{
startTime = ActiveService.EndService;
} }
}
var rollCallService = new RollCallService("BasedOnIC",
startTime, endTime, createdWorkshop.WorkshopId.Value,accountId,createdWorkshop.PersonnelCount,
0,"12");
await _rollCallServiceRepository.CreateAsync(rollCallService);
}
}
else
{
var currentWorkshop = new InstitutionContractWorkshopCurrent(createdWorkshop.WorkshopName, var currentWorkshop = new InstitutionContractWorkshopCurrent(createdWorkshop.WorkshopName,
createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson, createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson,
createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract, createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract,
@@ -1570,13 +1594,12 @@ public class InstitutionContractApplication : IInstitutionContractApplication
createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup, createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup,
createdWorkshop.WorkshopId!.Value, createdWorkshop.id); createdWorkshop.WorkshopId!.Value, createdWorkshop.id);
institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop); institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop);
}
} }
if (institutionContract.WorkshopGroup.InitialWorkshops.All(x => x.WorkshopCreated && x.WorkshopId is > 0)) if (institutionContract.WorkshopGroup.InitialWorkshops.All(x => x.WorkshopCreated && x.WorkshopId is > 0))
{ {
institutionContract.Verified(); institutionContract.Verified();
} }
else else
@@ -1611,9 +1634,23 @@ public class InstitutionContractApplication : IInstitutionContractApplication
var transaction = await _institutionContractRepository.BeginTransactionAsync(); var transaction = await _institutionContractRepository.BeginTransactionAsync();
await SetPendingWorkflow(institutionContractId,InstitutionContractSigningType.Physical); await SetPendingWorkflow(institutionContractId,InstitutionContractSigningType.Physical);
var financialStatement = await _financialStatmentRepository
.GetByContractingPartyId(institutionContract.ContractingPartyId);
DateTime today = DateTime.Today;
var description = institutionContract.IsInstallment
? "قسط اول سرویس"
: "پرداخت کل سرویس";
var debtorAmount = institutionContract.IsInstallment
? institutionContract.Installments.First().Amount
: institutionContract.TotalAmount;
var financialTransaction = new FinancialTransaction(0, today, today.ToFarsi(),
description, "debt", "بابت خدمات", debtorAmount, 0, 0);
financialStatement.AddFinancialTransaction(financialTransaction);
await transaction.CommitAsync();
await _institutionContractRepository.SaveChangesAsync(); await _institutionContractRepository.SaveChangesAsync();
await transaction.CommitAsync();
return op.Succcedded(); return op.Succcedded();
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using _0_Framework.Application; using _0_Framework.Application;
using Company.Domain.InstitutionPlanAgg; using Company.Domain.InstitutionPlanAgg;
using CompanyManagment.App.Contracts.InstitutionPlan; using CompanyManagment.App.Contracts.InstitutionPlan;
@@ -84,4 +85,73 @@ public class InstitutionPlanApplication : IInstitutionPlanApplication
{ {
return _planPercentageRepository.GetInstitutionPlanForWorkshop(command); return _planPercentageRepository.GetInstitutionPlanForWorkshop(command);
} }
#region ForApi
public async Task<CreateServiceAmountDto> GetCreateModalData()
{
return await _planPercentageRepository.GetCreateModalData();
}
public async Task<OperationResult> CreateInstitutionPlanPercentage(CreateServiceAmountDto command)
{
var op = new OperationResult();
if (string.IsNullOrWhiteSpace(command.ContractAndCheckoutInPersonPercentStr) || command.ContractAndCheckoutInPersonPercentStr == "0" ||
string.IsNullOrWhiteSpace(command.ContractAndCheckoutPercentStr) || (command.ContractAndCheckoutPercentStr == "0" ||
string.IsNullOrWhiteSpace(command.CustomizeCheckoutPercentStr) || command.CustomizeCheckoutPercentStr == "0" ||
string.IsNullOrWhiteSpace(command.InsuranceInPersonPercentStr) || command.InsuranceInPersonPercentStr == "0" ||
string.IsNullOrWhiteSpace(command.InsurancePercentStr) || command.InsurancePercentStr == "0" ||
string.IsNullOrWhiteSpace(command.RollCallPercentStr) || command.RollCallPercentStr == "0"))
return op.Failed("هیچ یک از فیلدها نمیتوانند صفر باشند");
int contractAndCheckoutInPersonPercent = 0;
int contractAndCheckoutPercent = 0;
int customizeCheckoutPercent = 0;
int insuranceInPersonPercent = 0;
int insurancePercent = 0;
int rollCallPercent = 0;
try
{
contractAndCheckoutInPersonPercent = Convert.ToInt32(command.ContractAndCheckoutInPersonPercentStr);
contractAndCheckoutPercent = Convert.ToInt32(command.ContractAndCheckoutPercentStr);
customizeCheckoutPercent = Convert.ToInt32(command.CustomizeCheckoutPercentStr);
insuranceInPersonPercent = Convert.ToInt32(command.InsuranceInPersonPercentStr);
insurancePercent = Convert.ToInt32(command.InsurancePercentStr);
rollCallPercent = Convert.ToInt32(command.RollCallPercentStr);
}
catch (Exception e)
{
return op.Failed("لطفا عدد معتبر وارد کنید");
}
var firstPlan =await _planPercentageRepository.GetCreateModalData();
if (firstPlan != null)
{
var planPercentage = _planPercentageRepository.Get(firstPlan.Id);
planPercentage.Edit(contractAndCheckoutPercent, insurancePercent, rollCallPercent, customizeCheckoutPercent, contractAndCheckoutInPersonPercent, insuranceInPersonPercent);
_planPercentageRepository.SaveChanges();
}
else
{
var create = new PlanPercentage(contractAndCheckoutPercent, insurancePercent, rollCallPercent,
customizeCheckoutPercent, contractAndCheckoutInPersonPercent, insuranceInPersonPercent);
await _planPercentageRepository.CreateAsync(create);
await _planPercentageRepository.SaveChangesAsync();
}
return op.Succcedded();
}
public async Task<PagedResult<InstitutionPlanListDto>> GetList(InstitutionPlanSearchModel searchModel)
{
return await _planPercentageRepository.GetList(searchModel);
}
#endregion
} }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using _0_Framework.Application; using _0_Framework.Application;
using _0_Framework.Domain.CustomizeCheckoutShared.Enums; using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg; using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg;
@@ -590,6 +591,8 @@ public class LeaveApplication : ILeaveApplication
return leaveTotalTimeSpan; return leaveTotalTimeSpan;
} }
private TimeSpan CalculateTotalLeaveTimeSpan(List<LeavePrintViewModel> leaves) private TimeSpan CalculateTotalLeaveTimeSpan(List<LeavePrintViewModel> leaves)
{ {
var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType != "روزانه").Sum(x => (x.EndLeaveGr - x.StartLeaveGr).Ticks)); var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType != "روزانه").Sum(x => (x.EndLeaveGr - x.StartLeaveGr).Ticks));
@@ -597,4 +600,77 @@ public class LeaveApplication : ILeaveApplication
return timeSpanHourlyLeave + dailyLeaveCount; return timeSpanHourlyLeave + dailyLeaveCount;
} }
#endregion #endregion
#region ForApi
public async Task<PagedResult<leaveListDto>> GetList(LeaveListSearchModel searchModel)
{
return await _leaveRepository.GetList(searchModel);
}
public async Task<List<GroupLeaveListDto>> GetGroupList(LeaveListSearchModel searchModel)
{
return await _leaveRepository.GetGroupList(searchModel);
}
public TimeSpan SumOfEmployeeLeaveTimeSpanInDates(long workshopId, long employeeId, string yearStr, string monthStr, LeaveType leaveType)
{
var startFa = $"{yearStr}/{monthStr:00}/01";
var endFa = startFa.FindeEndOfMonth();
if (startFa.TryToGeorgianDateTime(out var start) == false || endFa.TryToGeorgianDateTime(out var end) == false)
return TimeSpan.Zero;
var leaveTotalTimeSpan = TimeSpan.Zero;
var leaves = _leaveRepository.GetByWorkshopIdEmployeeIdInDates(workshopId, employeeId, start, end);
//var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType != "روزانه").Sum(x => (x.EndLeaveGr - x.StartLeaveGr).Ticks));
//var dailyLeaveCount = leaves.Count(x => x.PaidLeaveType == "روزانه") * new TimeSpan(1, 0, 0, 0);
if (leaveType == LeaveType.PaidLeave)
{
var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType == "ساعتی" && x.LeaveType == "استحقاقی")
.Sum(x => TimeOnly.Parse(x.LeaveHourses).Ticks));
var dailyLeaveTime = leaves.Where(x => x.PaidLeaveType == "روزانه" && x.LeaveType == "استحقاقی")
.Sum(x => Convert.ToInt32(x.LeaveHourses)) * TimeSpan.FromDays(1);
leaveTotalTimeSpan = timeSpanHourlyLeave + dailyLeaveTime;
}
else if (leaveType == LeaveType.SickLeave)
{
var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType == "ساعتی" && x.LeaveType == "استعلاجی")
.Sum(x => TimeOnly.Parse(x.LeaveHourses).Ticks));
var dailyLeaveTime = leaves.Where(x => x.PaidLeaveType == "روزانه" && x.LeaveType == "استعلاجی")
.Sum(x => Convert.ToInt32(x.LeaveHourses)) * TimeSpan.FromDays(1);
leaveTotalTimeSpan = timeSpanHourlyLeave + dailyLeaveTime;
}
else
{
var timeSpanHourlyLeave = new TimeSpan(leaves.Where(x => x.PaidLeaveType == "ساعتی").Sum(x => TimeOnly.Parse(x.LeaveHourses).Ticks));
var dailyLeaveTime = leaves.Where(x => x.PaidLeaveType == "روزانه").Sum(x => Convert.ToInt32(x.LeaveHourses)) * TimeSpan.FromDays(1);
leaveTotalTimeSpan = timeSpanHourlyLeave + dailyLeaveTime;
}
return leaveTotalTimeSpan;
}
public async Task<List<LeavePrintResponseViewModel>> PrintAllAsync(List<long> ids,long workshopId)
{
return await _leaveRepository.PrintAllAsync(ids,workshopId);
}
public async Task<LeavePrintResponseViewModel> PrintOneAsync(long id, long workshopId)
{
return (await _leaveRepository.PrintAllAsync([id],workshopId)).FirstOrDefault();
}
#endregion
} }

View File

@@ -1092,7 +1092,9 @@ public class WorkshopAppliction : IWorkshopApplication
Amount = 1000, Amount = 1000,
MaxPersonValid = 500, MaxPersonValid = 500,
Duration = "12", Duration = "12",
HasCustomizeCheckoutService = command.HasCustomizeCheckoutService HasCustomizeCheckoutService = command.HasCustomizeCheckoutService,
StartService = institutionContract.ContractStartGr,
}; };
_rollCallServiceApplication.Create(commandSave); _rollCallServiceApplication.Create(commandSave);
} }

View File

@@ -1895,7 +1895,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.FirstOrDefaultAsync(x => x.PublicId == id); .FirstOrDefaultAsync(x => x.PublicId == id);
} }
public InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request) public InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request,string contractStart=null)
{ {
var baseAmount = request.TotalAmount; var baseAmount = request.TotalAmount;
var discountAmount = (baseAmount * request.DiscountPercentage) / 100; var discountAmount = (baseAmount * request.DiscountPercentage) / 100;
@@ -2356,7 +2356,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
IsInstallment = request.IsInstallment, IsInstallment = request.IsInstallment,
OneMonthAmount = selectedPlan.OneMonthPaymentDiscounted.MoneyToDouble() OneMonthAmount = selectedPlan.OneMonthPaymentDiscounted.MoneyToDouble()
}; };
var res = CalculateDiscount(calculateRequest); var res = CalculateDiscount(calculateRequest,selectedPlan.ContractStart);
//این به این دلیل هست که متد caclulate discount یکی از مقادیر رو پر میکنه و ما نیاز داریم هر دو مقدار رو داشته باشیم //این به این دلیل هست که متد caclulate discount یکی از مقادیر رو پر میکنه و ما نیاز داریم هر دو مقدار رو داشته باشیم
if (request.IsInstallment) if (request.IsInstallment)
@@ -2476,7 +2476,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
Tax = resetTax.ToMoney(), Tax = resetTax.ToMoney(),
TotalAmount = resetTotalAmount.ToMoney(), TotalAmount = resetTotalAmount.ToMoney(),
Installments = InstitutionMonthlyInstallmentCaculation((int)institutionTemp.Duration.Value, Installments = InstitutionMonthlyInstallmentCaculation((int)institutionTemp.Duration.Value,
paymentAmount, DateTime.Now.ToFarsi()), paymentAmount,selectedPlan.ContractStart),
OneMonthAmount = newOneMonthAmount.ToMoney(), OneMonthAmount = newOneMonthAmount.ToMoney(),
Obligation = resetTotalAmount.ToMoney() Obligation = resetTotalAmount.ToMoney()
}; };
@@ -4364,6 +4364,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
{ {
var sendResult = await _smsService.SendInstitutionCreationVerificationLink(item.Number, item.FullName, var sendResult = await _smsService.SendInstitutionCreationVerificationLink(item.Number, item.FullName,
item.InstitutionId, item.ContractingPartyId, item.InstitutionContractId, typeOfSms); item.InstitutionId, item.ContractingPartyId, item.InstitutionContractId, typeOfSms);
Thread.Sleep(1000);
} }
Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute); Console.WriteLine("executed at : " + persianNow + " - " + hour + ":" + minute);
@@ -4415,12 +4416,13 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
TypeOfContract = x.TypeOfContract, TypeOfContract = x.TypeOfContract,
IsInstallment = x.IsInstallment, IsInstallment = x.IsInstallment,
VerificationStatus = x.VerificationStatus, VerificationStatus = x.VerificationStatus,
SigningType = x.SigningType,
InstallmentList = x.Installments InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel .Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr }) { AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
.OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(), .OrderBy(ins => ins.InstallmentDateGr).Skip(1).ToList(),
}).Where(x => }).Where(x =>
x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0) x.ContractStartGr < endOfMonthGr && x.ContractEndGr >= endOfMonthGr && x.ContractAmountDouble > 0 && x.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
.ToListAsync(); .ToListAsync();
#endregion #endregion
@@ -4444,7 +4446,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
List<long> futureContractIds = futureContracts.Select(x => x.ContractingPartyId).ToList(); List<long> futureContractIds = futureContracts.Select(x => x.ContractingPartyId).ToList();
List<InstitutionContractViewModel> deatcivedContract = await _context.InstitutionContractSet List<InstitutionContractViewModel> deatcivedContract = await _context.InstitutionContractSet
.Where(x => x.IsActiveString == "false" && futureContractIds.Contains(x.ContractingPartyId) && .Where(x => x.IsActiveString == "false" && futureContractIds.Contains(x.ContractingPartyId) &&
x.ContractEndGr.Date == endOfCurrentMonth.Date && x.ContractAmount > 0) x.ContractEndGr.Date == endOfCurrentMonth.Date && x.ContractAmount > 0 && x.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify)
.Select(x => new InstitutionContractViewModel .Select(x => new InstitutionContractViewModel
{ {
Id = x.id, Id = x.id,
@@ -4459,6 +4461,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
TypeOfContract = x.TypeOfContract, TypeOfContract = x.TypeOfContract,
IsInstallment = x.IsInstallment, IsInstallment = x.IsInstallment,
VerificationStatus = x.VerificationStatus, VerificationStatus = x.VerificationStatus,
SigningType = x.SigningType,
InstallmentList = x.Installments InstallmentList = x.Installments
.Select(ins => new InstitutionContractInstallmentViewModel .Select(ins => new InstitutionContractInstallmentViewModel
{ AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr }) { AmountDouble = ins.Amount, InstallmentDateGr = ins.InstallmentDateGr })
@@ -4469,6 +4472,12 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
institutionContracts.AddRange(deatcivedContract); institutionContracts.AddRange(deatcivedContract);
} }
// قرارداد هایی که پطور یکجا پرداخت شده اند
var paidInFull = institutionContracts.Where(x =>
x.SigningType != InstitutionContractSigningType.Legacy && x.IsInstallment == false && x.SigningType != null).ToList();
//حذف قراداد هایی که یکجا پرداخت شده اند از لیست ایجاد سند ماهانه
institutionContracts = institutionContracts.Except(paidInFull).ToList();
#region RollCallServicCompute #region RollCallServicCompute
@@ -4516,8 +4525,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
if (!alreadyCreated) if (!alreadyCreated)
{ {
if (item.IsInstallment && if (item.IsInstallment)
item.VerificationStatus == InstitutionContractVerificationStatus.Verified)
{ {
var instalment = item.InstallmentList var instalment = item.InstallmentList
.FirstOrDefault(x => .FirstOrDefault(x =>
@@ -4551,8 +4559,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
await _financialStatmentRepository.SaveChangesAsync(); await _financialStatmentRepository.SaveChangesAsync();
if (item.IsInstallment && if (item.IsInstallment)
item.VerificationStatus == InstitutionContractVerificationStatus.Verified)
{ {
var instalment = item.InstallmentList var instalment = item.InstallmentList
.FirstOrDefault(x => .FirstOrDefault(x =>
@@ -4579,12 +4586,17 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
#region RollCallServicCompute #region RollCallServicCompute
//ایجاد سند مالی حضورغیاب
if (item.VerificationStatus != InstitutionContractVerificationStatus.Verified && //قرارداد هایی که جدید نیستند و اقساط ندارند
!item.IsInstallment && item.ContractingPartyId != 30520 && item.ContractingPartyId != 30739) //کارگاه های استثناء : کباب مهدی 30520 و نمونه پروتئین 30739
if (item.SigningType != InstitutionContractSigningType.OtpBased && item.SigningType != InstitutionContractSigningType.Physical
&& !item.IsInstallment && item.ContractingPartyId != 30520 && item.ContractingPartyId != 30739)
{ {
try try
{ {
//TODO
//@refactor Need
var employers = await _context.Employers var employers = await _context.Employers
.Where(x => x.ContractingPartyId == item.ContractingPartyId) .Where(x => x.ContractingPartyId == item.ContractingPartyId)
.Select(x => x.id).ToListAsync(); .Select(x => x.id).ToListAsync();

View File

@@ -1827,12 +1827,17 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
return []; return [];
} }
var workshopsHasInsuranceAccount = await _accountContext
.AccountLeftWorks
.Where(x => StaticWorkshopAccounts.InsuranceAccountsRoleIds.Contains(x.RoleId) && x.IsActive)
.Select(x => x.WorkshopId).Distinct().ToListAsync();
var acountId = _authHelper.CurrentAccountId(); var acountId = _authHelper.CurrentAccountId();
var accountWorkshopIds = _context.WorkshopAccounts.Where(x => x.AccountId == acountId) var accountWorkshopIds = _context.WorkshopAccounts.Where(x => x.AccountId == acountId && workshopsHasInsuranceAccount.Contains(x.WorkshopId))
.Select(x => x.WorkshopId); .Select(x => x.WorkshopId);
var firstDayOfMonth = $"{searchModel.Year}/{searchModel.Month}/01".ToGeorgianDateTime(); var firstDayOfMonth = $"{searchModel.Year}/{searchModel.Month}/01".ToGeorgianDateTime();
var insuranceWorkshops = _context.Workshops var insuranceWorkshops = _context.Workshops
.Where(x => x.InsuranceCode != null && x.InsuranceCode.Length >= 10 && accountWorkshopIds.Contains(x.id) && .Where(x => accountWorkshopIds.Contains(x.id) &&
x.IsActiveString == "true"); x.IsActiveString == "true");
@@ -1855,7 +1860,7 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
WorkShopId = result.id, WorkShopId = result.id,
WorkShopCode = result.InsuranceWorkshopInfo != null WorkShopCode = result.InsuranceWorkshopInfo != null
? result.InsuranceWorkshopInfo.InsuranceCode ? result.InsuranceWorkshopInfo.InsuranceCode
: result.InsuranceCode, : string.IsNullOrWhiteSpace(result.InsuranceCode) ? "کد کارگاهی ندارد" : result.InsuranceCode,
WorkShopName = result.InsuranceWorkshopInfo != null WorkShopName = result.InsuranceWorkshopInfo != null
? result.InsuranceWorkshopInfo.WorkshopName ? result.InsuranceWorkshopInfo.WorkshopName
: result.WorkshopFullName, : result.WorkshopFullName,

View File

@@ -1,12 +1,15 @@
using System; using _0_Framework.Application;
using System.Collections.Generic;
using System.Linq;
using _0_Framework.Application;
using _0_Framework.InfraStructure; using _0_Framework.InfraStructure;
using Azure.Core;
using Company.Domain.LeaveAgg; using Company.Domain.LeaveAgg;
using CompanyManagment.App.Contracts.Checkout; using CompanyManagment.App.Contracts.Checkout;
using CompanyManagment.App.Contracts.InstitutionPlan;
using CompanyManagment.App.Contracts.Leave; using CompanyManagment.App.Contracts.Leave;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CompanyManagment.EFCore.Repository; namespace CompanyManagment.EFCore.Repository;
@@ -17,6 +20,7 @@ public class LeaveRepository : RepositoryBase<long, Leave>, ILeaveRepository
public LeaveRepository(CompanyContext context) : base(context) public LeaveRepository(CompanyContext context) : base(context)
{ {
_context = context; _context = context;
} }
public EditLeave GetDetails(long id) public EditLeave GetDetails(long id)
@@ -290,6 +294,65 @@ public class LeaveRepository : RepositoryBase<long, Leave>, ILeaveRepository
return query; return query;
} }
public async Task<List<LeavePrintResponseViewModel>> PrintAllAsync(List<long> ids, long workshopId)
{
var leaves =await _context
.LeaveList.Where(x => ids.Contains(x.id) && x.WorkshopId == workshopId).ToListAsync();
var minLeave = leaves.Min(x => x.StartLeave);
var maxLeave = leaves.Max(x => x.EndLeave);
var employeeIds = leaves.Select(x => x.EmployeeId).Distinct().ToList();
var contracts = await _context.Contracts
.Where(x => x.WorkshopIds == workshopId && employeeIds.Contains(x.EmployeeId)
&& x.ContarctStart<= maxLeave && x.ContractEnd>= minLeave)
.ToListAsync();
var employees = await _context
.Employees.Where(x=> employeeIds.Contains(x.id)).ToListAsync();
var employerNames = _context.WorkshopEmployers.Include(x=>x.Employer)
.Where(x=>x.WorkshopId == workshopId).Select(x=>x.Employer.FName+" "+x.Employer.LName).ToList();
var workshopName = _context.Workshops.FirstOrDefault(x => x.id == workshopId)?.WorkshopName;
var res = leaves.Select(leave =>
{
var employee = employees.FirstOrDefault(x => x.id == leave.EmployeeId);
return new LeavePrintResponseViewModel
{
FullName = employee?.FName + " " +
employee?.LName,
NationalCode = employee?.NationalCode,
WorkshopName = workshopName,
EmployerNames = employerNames,
PaidLeaveType = leave.PaidLeaveType,
ContractNo = contracts.FirstOrDefault(x =>
x.EmployeeId == leave.EmployeeId &&
x.ContarctStart <= leave.StartLeave &&
x.ContractEnd >= leave.EndLeave)?.ContractNo,
DailyLeave = leave.PaidLeaveType == "روزانه" ? new LeavePrintDailyResponseViewModel
{
StartLeave = leave.StartLeave.ToFarsi(),
EndLeave = leave.EndLeave.ToFarsi(),
TotalDay = leave.LeaveHourses
} : null,
HourlyLeave = leave.PaidLeaveType == "ساعتی" ?
new LeavePrintHourlyResponseViewModel
{
LeaveDate = leave.StartLeave.ToFarsi(),
StartHour = leave.StartLeave.ToString("HH:mm"),
EndHour = leave.EndLeave.ToString("HH:mm"),
TotalHour = TimeSpan.Parse(leave.LeaveHourses)
.TotalHours.ToString("F0")
} : null
};
}).ToList();
return res;
}
#region Vafa #region Vafa
public List<LeaveViewModel> LastLeaveMain(LeaveSearchModel searchModel) public List<LeaveViewModel> LastLeaveMain(LeaveSearchModel searchModel)
@@ -371,6 +434,8 @@ public class LeaveRepository : RepositoryBase<long, Leave>, ILeaveRepository
} }
} }
public OperationResult RemoveLeave(long id) public OperationResult RemoveLeave(long id)
{ {
var op = new OperationResult(); var op = new OperationResult();
@@ -536,4 +601,200 @@ public class LeaveRepository : RepositoryBase<long, Leave>, ILeaveRepository
(starContract >= x.StartLeaveGr && starContract <= x.EndLeaveGr) || (starContract >= x.StartLeaveGr && starContract <= x.EndLeaveGr) ||
(endContract >= x.StartLeaveGr && endContract <= x.EndLeaveGr)); (endContract >= x.StartLeaveGr && endContract <= x.EndLeaveGr));
} }
#region ForApi
public async Task<PagedResult<leaveListDto>> GetList(LeaveListSearchModel searchModel)
{
var query = _context.LeaveList.Where(x => x.WorkshopId == searchModel.WorkshopId);
if (searchModel.EmployeeId != 0)
query = query.Where(x => x.EmployeeId == searchModel.EmployeeId);
if (searchModel.LeaveType == LeaveType.PaidLeave)
query = query.Where(x => x.LeaveType == "استحقاقی");
if (searchModel.LeaveType == LeaveType.SickLeave)
query = query.Where(x => x.LeaveType == "استعلاجی");
if (searchModel.IsInvalid)
{
query = query.IgnoreQueryFilters().Where(x => x.IsInvalid);
}
if (!string.IsNullOrWhiteSpace(searchModel.StartLeave) && !string.IsNullOrWhiteSpace(searchModel.EndLeave))
{
var start = new DateTime();
var end = new DateTime();
try
{
start = searchModel.StartLeave.ToGeorgianDateTime();
end = searchModel.EndLeave.ToGeorgianDateTime();
}
catch (Exception e)
{
return new PagedResult<leaveListDto>();
}
query = query.Where(x => x.StartLeave >= start && x.EndLeave <= end);
}
else if (!string.IsNullOrWhiteSpace(searchModel.YearStr) || !string.IsNullOrWhiteSpace(searchModel.MonthStr))
{
if (!string.IsNullOrWhiteSpace(searchModel.YearStr))
{
try
{
int year = Convert.ToInt32(searchModel.YearStr);
query = query.Where(x => x.Year == year);
}
catch (Exception)
{
return new PagedResult<leaveListDto>();
}
}
if (!string.IsNullOrWhiteSpace(searchModel.MonthStr))
{
try
{
int month = Convert.ToInt32(searchModel.MonthStr);
query = query.Where(x => x.Month == month);
}
catch (Exception)
{
return new PagedResult<leaveListDto>();
}
}
}
var count = await query.CountAsync();
query = query.OrderByDescending(x => x.CreationDate);
var queryPaginationFilter = await query.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
var leaveResult = queryPaginationFilter.Select(item => new leaveListDto()
{
Id = item.id,
EmployeeFullName = item.EmployeeFullName,
YearStr = $"{item.Year}",
MonthStr = item.Month.ToFarsiMonthByIntNumber(),
IsInvalid = item.IsInvalid,
LeaveType = item.LeaveType,
StartLeave = item.StartLeave.ToFarsi(),
EndLeave = item.EndLeave.ToFarsi(),
HourlyInterval = item.PaidLeaveType == "ساعتی" ? $"{item.StartLeave.TimeOfDay:hh\\:mm} الی {item.EndLeave.TimeOfDay:hh\\:mm}" : "-",
LeaveDuration = Tools.CalculateLeaveHoursAndDays(item.PaidLeaveType, item.LeaveHourses),
IsAccepted = item.IsAccepted,
WorkshopId = item.WorkshopId,
EmployeeId = item.EmployeeId,
}).ToList();
return new PagedResult<leaveListDto>()
{
TotalCount = count,
List = leaveResult
};
}
public async Task<List<GroupLeaveListDto>> GetGroupList(LeaveListSearchModel searchModel)
{
var query = _context.LeaveList.Where(x => x.WorkshopId == searchModel.WorkshopId && x.EmployeeId == searchModel.EmployeeId);
if (searchModel.LeaveType == LeaveType.PaidLeave)
query = query.Where(x => x.LeaveType == "استحقاقی");
if (searchModel.LeaveType == LeaveType.SickLeave)
query = query.Where(x => x.LeaveType == "استعلاجی");
if (searchModel.IsInvalid)
{
query = query.IgnoreQueryFilters().Where(x => x.IsInvalid);
}
if (!string.IsNullOrWhiteSpace(searchModel.StartLeave) && !string.IsNullOrWhiteSpace(searchModel.EndLeave))
{
var start = new DateTime();
var end = new DateTime();
try
{
start = searchModel.StartLeave.ToGeorgianDateTime();
end = searchModel.EndLeave.ToGeorgianDateTime();
}
catch (Exception e)
{
return new List<GroupLeaveListDto>();
}
query = query.Where(x => x.StartLeave >= start && x.EndLeave <= end);
}
else if (!string.IsNullOrWhiteSpace(searchModel.YearStr) || !string.IsNullOrWhiteSpace(searchModel.MonthStr))
{
if (!string.IsNullOrWhiteSpace(searchModel.YearStr))
{
try
{
int year = Convert.ToInt32(searchModel.YearStr);
query = query.Where(x => x.Year == year);
}
catch (Exception)
{
return new List<GroupLeaveListDto>();
}
}
if (!string.IsNullOrWhiteSpace(searchModel.MonthStr))
{
try
{
int month = Convert.ToInt32(searchModel.MonthStr);
query = query.Where(x => x.Month == month);
}
catch (Exception)
{
return new List<GroupLeaveListDto>();
}
}
}
var leaveList = await query.GroupBy(x => new { x.Year, x.Month })
.OrderByDescending(group => group.Key.Year)
.ThenByDescending(group => group.Key.Month)
.Select(group => new GroupLeaveListDto
{
YearStr = $"{group.Key.Year}",
MonthStr = group.Key.Month.ToFarsiMonthByIntNumber(),
LeaveListItemsDto = group.OrderByDescending(x=>x.StartLeave).Select(item => new LeaveListItemsDto
{
Id = item.id,
IsInvalid = item.IsInvalid,
LeaveType = item.LeaveType,
StartLeave = item.StartLeave.ToFarsi(),
EndLeave = item.EndLeave.ToFarsi(),
HourlyInterval = item.PaidLeaveType == "ساعتی" ? $"{item.StartLeave.TimeOfDay:hh\\:mm} الی {item.EndLeave.TimeOfDay:hh\\:mm}" : "-",
LeaveDuration = Tools.CalculateLeaveHoursAndDays(item.PaidLeaveType, item.LeaveHourses),
IsAccepted = item.IsAccepted,
WorkshopId = item.WorkshopId,
EmployeeId = item.EmployeeId,
}).ToList()
}).ToListAsync();
return leaveList;
}
#endregion
} }

View File

@@ -1,12 +1,14 @@
using System; using _0_Framework.Application;
using System.Collections.Generic;
using System.Linq;
using _0_Framework.Application;
using _0_Framework.InfraStructure; using _0_Framework.InfraStructure;
using Company.Domain.InstitutionPlanAgg; using Company.Domain.InstitutionPlanAgg;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.InstitutionPlan; using CompanyManagment.App.Contracts.InstitutionPlan;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CompanyManagment.EFCore.Repository; namespace CompanyManagment.EFCore.Repository;
@@ -44,6 +46,7 @@ public class PlanPercentageRepository : RepositoryBase<long, PlanPercentage>, IP
}).FirstOrDefault(); }).FirstOrDefault();
} }
public List<InstitutionPlanViewModel> GetInstitutionPlanList(int pageIndex, int countPeron) public List<InstitutionPlanViewModel> GetInstitutionPlanList(int pageIndex, int countPeron)
{ {
var planPercentage = _context.PlanPercentages.FirstOrDefault(); var planPercentage = _context.PlanPercentages.FirstOrDefault();
@@ -303,4 +306,109 @@ public class PlanPercentageRepository : RepositoryBase<long, PlanPercentage>, IP
return new InstitutionPlanViewModel(); return new InstitutionPlanViewModel();
} }
#region ForApi
public async Task<CreateServiceAmountDto> GetCreateModalData()
{
return await _context.PlanPercentages.Select(x => new CreateServiceAmountDto()
{
Id = x.id,
ContractAndCheckoutInPersonPercentStr = $"{x.ContractAndCheckoutInPersonPercent}",
CustomizeCheckoutPercentStr = $"{x.CustomizeCheckoutPercent}",
ContractAndCheckoutPercentStr = $"{x.ContractAndCheckoutPercent}",
InsuranceInPersonPercentStr = $"{x.InsuranceInPersonPercent}",
InsurancePercentStr = $"{x.InsurancePercent}",
RollCallPercentStr = $"{x.RollCallPercent}",
}).FirstOrDefaultAsync();
}
public async Task<PagedResult<InstitutionPlanListDto>> GetList(
InstitutionPlanSearchModel searchModel)
{
var planPercentage = await _context.PlanPercentages.FirstOrDefaultAsync();
if (planPercentage == null)
return new PagedResult<InstitutionPlanListDto>();
var dailyWageYearlySalery = await _context.YearlySalaries.Include(i => i.YearlySalaryItemsList).FirstOrDefaultAsync(x =>
x.StartDate.Date <= DateTime.Now.Date && x.EndDate >= DateTime.Now.Date);
if (dailyWageYearlySalery == null)
return new PagedResult<InstitutionPlanListDto>();
var dailyWage = dailyWageYearlySalery.YearlySalaryItemsList.Where(x => x.ItemName == "مزد روزانه")
.Select(x => x.ItemValue).FirstOrDefault();
var plans = _context.InstitutionPlans.AsQueryable();
if (searchModel.CountPerson > 0)
plans = plans.Where(x => x.CountPerson == searchModel.CountPerson);
var count = await plans.CountAsync();
var planQueryFilter =await plans.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
var planResult = planQueryFilter.Select(plan =>
new InstitutionPlanViewModel
{
CountPerson = plan.CountPerson,
ContractAndCheckoutDouble =
((dailyWage * planPercentage.ContractAndCheckoutPercent / 100) * plan.CountPerson *
plan.IncreasePercentage),
InsuranceDouble = (((dailyWage * planPercentage.InsurancePercent) / 100) * plan.CountPerson *
plan.IncreasePercentage),
RollCallDouble = (((dailyWage * planPercentage.RollCallPercent) / 100) * plan.CountPerson *
plan.IncreasePercentage),
CustomizeCheckoutDouble = (((dailyWage * planPercentage.CustomizeCheckoutPercent) / 100) *
plan.CountPerson *
plan.IncreasePercentage),
ContractAndCheckoutInPersonDouble =
(((dailyWage * planPercentage.ContractAndCheckoutInPersonPercent) / 100) * plan.CountPerson *
plan.IncreasePercentage),
InsuranceInPersonDouble = (((dailyWage * planPercentage.InsuranceInPersonPercent) / 100) *
plan.CountPerson *
plan.IncreasePercentage)
}).ToList();
var finalResult = planResult.Select(plan => new InstitutionPlanListDto()
{
CountPerson = plan.CountPerson,
ContractAndCheckout = plan.ContractAndCheckoutDouble.ToMoney(),
Insurance = plan.InsuranceDouble.ToMoney(),
RollCall = plan.RollCallDouble.ToMoney(),
CustomizeCheckout = plan.CustomizeCheckoutDouble.ToMoney(),
ContractAndCheckoutInPerson = plan.ContractAndCheckoutInPersonDouble.ToMoney(),
InsuranceInPerson = plan.InsuranceInPersonDouble.ToMoney(),
InPersonSumAmountStr =
(plan.ContractAndCheckoutDouble + plan.InsuranceDouble + plan.ContractAndCheckoutInPersonDouble +
plan.InsuranceInPersonDouble).ToMoney(),
OnlineAndInPersonSumAmountStr = (plan.ContractAndCheckoutDouble + plan.InsuranceDouble +
plan.ContractAndCheckoutInPersonDouble + plan.InsuranceInPersonDouble +
plan.RollCallDouble + plan.CustomizeCheckoutDouble).ToMoney(),
OnlineOnlySumAmountStr =
(plan.ContractAndCheckoutDouble + plan.InsuranceDouble + plan.RollCallDouble +
plan.CustomizeCheckoutDouble).ToMoney(),
}).ToList();
return new PagedResult<InstitutionPlanListDto>()
{
TotalCount = count,
List = finalResult
};
}
#endregion
} }

View File

@@ -0,0 +1,49 @@
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
using Microsoft.EntityFrameworkCore;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections;
public record AutoStopOverTimeTaskSectionsCommand : IBaseCommand;
public class AutoStopOverTimeTaskSectionsCommandHandler : IBaseCommandHandler<AutoStopOverTimeTaskSectionsCommand>
{
private readonly ITaskSectionRepository _taskSectionRepository;
private readonly IUnitOfWork _unitOfWork;
public AutoStopOverTimeTaskSectionsCommandHandler(ITaskSectionRepository taskSectionRepository,
IUnitOfWork unitOfWork)
{
_taskSectionRepository = taskSectionRepository;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult> Handle(AutoStopOverTimeTaskSectionsCommand request,
CancellationToken cancellationToken)
{
try
{
// دریافت تمام تسک‌های در حال انجام
var taskSections = await _taskSectionRepository.GetActiveSectionsIncludeAllAsync(cancellationToken);
foreach (var taskSection in taskSections)
{
// استفاده از متد Domain برای بررسی و متوقف کردن خودکار
taskSection.AutoStopIfOverTime();
}
// ذخیره تغییرات در دیتابیس
await _unitOfWork.SaveChangesAsync(cancellationToken);
return OperationResult.Success();
}
catch (Exception ex)
{
return OperationResult.Failure($"خطا در ناتمام کردن تسک‌های overtime: {ex.Message}");
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Globalization;
using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common;
@@ -7,21 +8,23 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project
public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery<ProjectBoardDetailResponse>; public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery<ProjectBoardDetailResponse>;
public record ProjectBoardDetailResponse(List<ProjectBoardDetailUserResponse> Users, string TotalTime); public record ProjectBoardDetailResponse(List<ProjectBoardDetailUserResponse> Users, string TotalTime,string RemainingTime );
public record ProjectBoardDetailUserResponse public record ProjectBoardDetailUserResponse
{ {
public List<ProjectBoardDetailUserHistoryResponse> Histories { get; set; } = new(); public List<ProjectBoardDetailUserHistoryResponse> Histories { get; init; }
public string UserFullName { get; set; } public string UserFullName { get; init; }
public long UserId { get; set; } public string TotalTime { get; init; }
public string SpentTime { get; init; }
public long UserId { get; init; }
} }
public class ProjectBoardDetailUserHistoryResponse public record ProjectBoardDetailUserHistoryResponse
{ {
public string Date { get; set; } public string Date { get; init; }
public string startTime { get; set; } public string startTime { get; init; }
public string EndTime { get; set; } public string EndTime { get; init; }
public string TotalTime { get; set; } public string TotalTime { get; init; }
} }
public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDetailQuery, ProjectBoardDetailResponse> public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDetailQuery, ProjectBoardDetailResponse>
@@ -38,6 +41,7 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
{ {
var section = await _programManagerDbContext.TaskSections var section = await _programManagerDbContext.TaskSections
.Include(x => x.Activities) .Include(x => x.Activities)
.Include(x=>x.AdditionalTimes)
.FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken); .FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken);
if (section == null) if (section == null)
@@ -49,16 +53,22 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
.Where(x => userIds.Contains(x.Id)) .Where(x => userIds.Contains(x.Id))
.ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken);
var totalTimeSpan = section.Activities var totalActivityTimeSpan = section.Activities
.Select(x => x.GetTimeSpent()) .Select(x => x.GetTimeSpent())
.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next)); .Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next));
var finalTime = section.FinalEstimatedHours;
var remainingTimeSpan = finalTime >= totalActivityTimeSpan
? TimeSpan.FromTicks(finalTime.Ticks - totalActivityTimeSpan.Ticks)
: TimeSpan.Zero;
var users = section.Activities.GroupBy(x => x.UserId).Select(x => var users = section.Activities.GroupBy(x => x.UserId).Select(x =>
{ {
return new ProjectBoardDetailUserResponse() return new ProjectBoardDetailUserResponse()
{ {
UserId = x.Key, UserId = x.Key,
UserFullName = usersDict[x.Key], UserFullName = usersDict[x.Key],
TotalTime = TimeSpan.FromTicks(x.Sum(h=>h.GetTimeSpent().Ticks)).TotalHours.ToString(CultureInfo.InvariantCulture),
Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse() Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse()
{ {
Date = h.StartDate.ToFarsi(), Date = h.StartDate.ToFarsi(),
@@ -68,7 +78,8 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
}).ToList() }).ToList()
}; };
}).ToList(); }).ToList();
var response = new ProjectBoardDetailResponse(users, $"{(int)totalTimeSpan.TotalHours}:{totalTimeSpan.Minutes:D2}"); var response = new ProjectBoardDetailResponse(users, $"{(int)totalActivityTimeSpan.TotalHours}:{totalActivityTimeSpan.Minutes:D2}",
$"{(int)remainingTimeSpan.TotalHours}:{remainingTimeSpan.Minutes:D2}");
return OperationResult<ProjectBoardDetailResponse>.Success(response); return OperationResult<ProjectBoardDetailResponse>.Success(response);
} }
} }

View File

@@ -217,4 +217,39 @@ public class TaskSection : EntityBase<Guid>
var finalEstimate = FinalEstimatedHours; var finalEstimate = FinalEstimatedHours;
return totalSpent < finalEstimate; return totalSpent < finalEstimate;
} }
/// <summary>
/// اگر زمان کار شده بیش از تایم تعیین شده باشد، تسک را متوقف می‌کند
/// و EndDate را به طوری تنظیم می‌کند که کل زمان برابر با FinalEstimatedHours شود
/// </summary>
public void AutoStopIfOverTime()
{
if (Status != TaskSectionStatus.InProgress)
return;
var activeActivity = _activities.FirstOrDefault(a => a.IsActive);
if (activeActivity == null)
return;
// محاسبه کل زمان صرف شده تا کنون (بدون فعالیت فعال)
var totalTimeSpentExcludingActive = _activities.Where(a => !a.IsActive).Sum(a => a.GetTimeSpent().Ticks);
var totalTimeSpentTimeSpan = TimeSpan.FromTicks(totalTimeSpentExcludingActive);
var finalEstimate = FinalEstimatedHours;
// اگر زمان صرف شده (بدون فعالیت فعال) + فعالیت فعال > تایم تعیین شده
var activeTimeSpent = activeActivity.GetTimeSpent();
if (totalTimeSpentTimeSpan + activeTimeSpent > finalEstimate)
{
// محاسبه مدت زمانی که این فعالیت باید برای رسیدن به FinalEstimatedHours داشته باشد
var remainingTime = finalEstimate - totalTimeSpentTimeSpan;
// EndDate = StartDate + remainingTime
var adjustedEndDate = activeActivity.StartDate.Add(remainingTime);
// متوقف کردن فعالیت با EndDate دقیق شده
activeActivity.StopWorkWithSpecificTime(adjustedEndDate, "متوقف خودکار - بیش از تایم تعیین شده");
UpdateStatus(TaskSectionStatus.Incomplete);
}
}
} }

View File

@@ -40,6 +40,22 @@ public class TaskSectionActivity : EntityBase<Guid>
IsActive = false; IsActive = false;
} }
/// <summary>
/// متوقف کردن فعالیت با مشخص کردن EndDate دقیق
/// </summary>
public void StopWorkWithSpecificTime(DateTime endDate, string? endNotes = null)
{
if (!IsActive)
throw new InvalidOperationException("این فعالیت قبلاً متوقف شده است.");
if (endDate < StartDate)
throw new InvalidOperationException("تاریخ پایان نمی‌تواند قبل از تاریخ شروع باشد.");
EndDate = endDate;
EndNotes = endNotes;
IsActive = false;
}
public TimeSpan GetTimeSpent() public TimeSpan GetTimeSpent()
{ {
if (IsActive) if (IsActive)

View File

@@ -1,3 +1,4 @@
using System.Collections;
using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
@@ -11,4 +12,5 @@ public interface ITaskSectionRepository: IRepository<Guid,TaskSection>
Task<TaskSection?> GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default); Task<TaskSection?> GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default);
Task<List<TaskSection>> GetAssignedToUserAsync(long userId); Task<List<TaskSection>> GetAssignedToUserAsync(long userId);
Task<List<TaskSection>> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken);
} }

View File

@@ -1,4 +1,5 @@
using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Infrastructure.Persistence._Common;
using GozareshgirProgramManager.Infrastructure.Persistence.Context; using GozareshgirProgramManager.Infrastructure.Persistence.Context;
@@ -35,4 +36,13 @@ public class TaskSectionRepository:RepositoryBase<Guid,TaskSection>,ITaskSection
.Where(x => x.CurrentAssignedUserId == userId) .Where(x => x.CurrentAssignedUserId == userId)
.ToListAsync(); .ToListAsync();
} }
public Task<List<TaskSection>> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken)
{
return _context.TaskSections
.Where(x => x.Status == TaskSectionStatus.InProgress)
.Include(x => x.Activities)
.Include(x => x.AdditionalTimes)
.ToListAsync(cancellationToken);
}
} }

View File

@@ -1,6 +1,7 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject;
@@ -98,6 +99,9 @@ public class ProjectController : ProgramManagerBaseController
[HttpGet("board")] [HttpGet("board")]
public async Task<ActionResult<OperationResult<List<ProjectBoardListResponse>>>> GetProjectBoard([FromQuery] ProjectBoardListQuery query) public async Task<ActionResult<OperationResult<List<ProjectBoardListResponse>>>> GetProjectBoard([FromQuery] ProjectBoardListQuery query)
{ {
// اجرای Command برای متوقف کردن تسک‌های overtime قبل از نمایش
await _mediator.Send(new AutoStopOverTimeTaskSectionsCommand());
var res = await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }

View File

@@ -0,0 +1,63 @@
using _0_Framework.Application;
using AccountManagement.Application.Contracts.Ticket;
using CompanyManagment.App.Contracts.InstitutionPlan;
using CompanyManagment.App.Contracts.Workshop;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
namespace ServiceHost.Areas.Admin.Controllers;
public class ServiceAmountsManagement : AdminBaseController
{
private readonly IInstitutionPlanApplication _institutionPlanApplication;
private readonly IAuthHelper _authHelper;
public ServiceAmountsManagement(IInstitutionPlanApplication institutionPlanApplication, IAuthHelper authHelper)
{
_institutionPlanApplication = institutionPlanApplication;
_authHelper = authHelper;
}
/// <summary>
/// دریافت دیتای مودال ایجاد
/// </summary>
/// <returns></returns>
[HttpGet("GetCreateModalData")]
public async Task<ActionResult<CreateServiceAmountDto>> GetCreateModalData()
{
if(!_authHelper.HasPermission(315))
return Forbid();
var data = await _institutionPlanApplication.GetCreateModalData();
return data;
}
/// <summary>
/// ذخیره درصدها
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
[HttpPost("CreateServicePercentage")]
public async Task<ActionResult<OperationResult>> CreateServicePercentage([FromBody] CreateServiceAmountDto command)
{
if (!_authHelper.HasPermission(315))
return Forbid();
var result = await _institutionPlanApplication.CreateInstitutionPlanPercentage(command);
return result;
}
/// <summary>
/// دریافت لیست مبالغ سرویس ها
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
[HttpGet("GetList")]
public async Task<ActionResult<PagedResult<InstitutionPlanListDto>>> GetList(InstitutionPlanSearchModel searchModel)
{
return await _institutionPlanApplication.GetList(searchModel);
}
}

View File

@@ -809,7 +809,7 @@ public class institutionContractController : AdminBaseController
} }
[HttpPost("mannual-verify/{id}")] [HttpPost("mannual-verify/{id}")]
public async Task<ActionResult<OperationResult>> VerifyInstitutionContractMannualy(long id) public async Task<ActionResult<OperationResult>> VerifyInstitutionContractManually(long id)
{ {
var res= await _institutionContractApplication.VerifyInstitutionContractManually(id); var res= await _institutionContractApplication.VerifyInstitutionContractManually(id);
return res; return res;

View File

@@ -74,8 +74,8 @@
</form> </form>
<div class="lineDiv"></div> <div class="lineDiv"></div>
<div class="row m-t-20"> <div class="row m-t-20">
<div class="col-4"></div> <div class="col-md-4 visible-md visible-lg"></div>
<div class="col-2"> <div class="col-6 col-md-2">
<form asp-page-handler="UploadFrontEnd" id="12" method="post"> <form asp-page-handler="UploadFrontEnd" id="12" method="post">
<button type="submit" <button type="submit"
class="btn btn-danger" class="btn btn-danger"
@@ -84,14 +84,14 @@
</button> </button>
</form> </form>
</div> </div>
<div class="col-2"> <div class="col-6 col-md-2">
<button type="button" class="btn btn-outline-secondary" <button type="button" class="btn btn-outline-secondary"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#logModal"> data-bs-target="#logModal">
مشاهده لاگ Deploy مشاهده لاگ Deploy
</button> </button>
</div> </div>
<div class="col-4"></div> <div class="col-md-4 visible-md visible-lg"></div>
</div> </div>
<div class="lineDiv"></div> <div class="lineDiv"></div>

View File

@@ -332,19 +332,39 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
var validAccountId = _authHelper.CurrentAccountId(); var validAccountId = _authHelper.CurrentAccountId();
if (validAccountId == 2 || validAccountId == 322) if (validAccountId == 2 || validAccountId == 322)
{ {
var batPath = @"C:\next-ui\deploy-next-ui.bat"; //var batPath = @"C:\next-ui\deploy-next-ui.bat";
//var psi = new ProcessStartInfo
//{
// FileName = batPath,
// UseShellExecute = true, // خیلی مهم
// Verb = "runas", // اجرای Administrator
// CreateNoWindow = true,
// WindowStyle = ProcessWindowStyle.Hidden
//};
//Process.Start(psi);
var psi = new ProcessStartInfo var psi = new ProcessStartInfo
{ {
FileName = batPath, FileName = "cmd.exe",
UseShellExecute = true, // خیلی مهم Arguments = "/c schtasks /run /tn \"DeployNextUI\"",
Verb = "runas", // اجرای Administrator UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true
WindowStyle = ProcessWindowStyle.Hidden
}; };
Process.Start(psi); Process.Start(psi);
//var psi = new ProcessStartInfo
//{
// FileName = @"C:\next-ui\deploy-next-ui.bat",
// UseShellExecute = false,
// CreateNoWindow = false
//};
//Process.Start(psi);
TempData["Message"] = "فرآیند Deploy شروع شد. لاگ را بررسی کنید."; TempData["Message"] = "فرآیند Deploy شروع شد. لاگ را بررسی کنید.";
return RedirectToPage(); return RedirectToPage();
} }

View File

@@ -0,0 +1,65 @@
using _0_Framework.Application;
using Company.Domain.EmployeeAgg;
using CompanyManagment.App.Contracts.InsuranceList;
using CompanyManagment.App.Contracts.Leave;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
using System.Security.Cryptography;
namespace ServiceHost.Areas.Client.Controllers;
public class LeaveController : ClientBaseController
{
private readonly ILeaveApplication _leaveApplication;
private long _workshopId;
public LeaveController(ILeaveApplication leaveApplication, IAuthHelper authHelper)
{
_leaveApplication = leaveApplication;
_workshopId = authHelper.GetWorkshopId();
}
/// <summary>
/// دریافت لیست مرخصی ها
/// </summary>
/// <param name="searchModel"></param>
/// <returns></returns>
[HttpGet("GetLeaveList")]
public async Task<ActionResult<LeaveListMultipleDto>> GetLeaveList(LeaveListSearchModel searchModel)
{
var result = new LeaveListMultipleDto();
searchModel.WorkshopId = _workshopId;
if (searchModel.EmployeeId > 0)
{
//لیست گروه بندی شده
result.GroupLeaveListDto = await _leaveApplication.GetGroupList(searchModel);
if (!string.IsNullOrWhiteSpace(searchModel.YearStr) && !string.IsNullOrWhiteSpace(searchModel.MonthStr))
{
TimeSpan timeSpan = _leaveApplication.SumOfEmployeeLeaveTimeSpanInDates(_workshopId, searchModel.EmployeeId, searchModel.YearStr, searchModel.MonthStr, searchModel.LeaveType);
//مجموع مرخصی پرسنل
result.SumOfEmployeeleaves = timeSpan.ToFarsiDaysAndHoursAndMinutes();
}
return Ok(result);
}
//لیست نرمال PageResult
result.leaveListDto = await _leaveApplication.GetList(searchModel);
return Ok(result);
}
[HttpGet("print/{id}")]
public async Task<ActionResult<LeavePrintResponseViewModel>> PrintOneAsync(long id)
{
var leavePrint = await _leaveApplication.PrintOneAsync(id, _workshopId);
return leavePrint;
}
[HttpGet("print")]
public async Task<ActionResult<List<LeavePrintResponseViewModel>>> PrintAllAsync([FromQuery] List<long> ids)
{
var leavePrints = await _leaveApplication.PrintAllAsync(ids, _workshopId);
return Ok(leavePrints);
}
}