Merge remote-tracking branch 'origin/Main' into Main
# Conflicts: # CompanyManagment.Application/InstitutionContractApplication.cs # CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs
This commit is contained in:
2
.github/workflows/dotnet-developPublish.yml
vendored
2
.github/workflows/dotnet-developPublish.yml
vendored
@@ -36,6 +36,6 @@ 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
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,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);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,27 +1559,48 @@ 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,
|
||||||
|
createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson,
|
||||||
|
createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract,
|
||||||
|
createdWorkshop.Services.ContractInPerson, createdWorkshop.Services.Insurance,
|
||||||
|
createdWorkshop.Services.InsuranceInPerson,createdWorkshop.PersonnelCount, createdWorkshop.Price,
|
||||||
|
createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup,
|
||||||
|
createdWorkshop.WorkshopId!.Value, false,createdWorkshop.id);
|
||||||
|
institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentWorkshop = new InstitutionContractWorkshopCurrent(createdWorkshop.WorkshopName,
|
|
||||||
createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson,
|
|
||||||
createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract,
|
|
||||||
createdWorkshop.Services.ContractInPerson, createdWorkshop.Services.Insurance,
|
|
||||||
createdWorkshop.Services.InsuranceInPerson,createdWorkshop.PersonnelCount, createdWorkshop.Price,
|
|
||||||
createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup,
|
|
||||||
createdWorkshop.WorkshopId!.Value, false,createdWorkshop.id);
|
|
||||||
|
|
||||||
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
|
||||||
@@ -1626,9 +1650,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1898,7 +1898,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;
|
||||||
@@ -2359,7 +2359,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)
|
||||||
@@ -2479,7 +2479,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()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1853,19 +1853,24 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel)
|
public async Task<List<InsuranceListViewModel>> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year))
|
if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year))
|
||||||
{
|
{
|
||||||
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");
|
||||||
|
|
||||||
|
|
||||||
@@ -1879,36 +1884,36 @@ public class InsuranceListRepository : RepositoryBase<long, InsuranceList>, IIns
|
|||||||
.Include(x => x.LeftWorkInsurances)
|
.Include(x => x.LeftWorkInsurances)
|
||||||
.Where(x => x.LeftWorkInsurances.Any(l => l.StartWorkDate <= firstDayOfMonth &&
|
.Where(x => x.LeftWorkInsurances.Any(l => l.StartWorkDate <= firstDayOfMonth &&
|
||||||
(l.LeftWorkDate == null || l.LeftWorkDate >= firstDayOfMonth)));
|
(l.LeftWorkDate == null || l.LeftWorkDate >= firstDayOfMonth)));
|
||||||
|
|
||||||
|
|
||||||
var query = notCreatedWorkshop.Select(result => new InsuranceListViewModel
|
var query = notCreatedWorkshop.Select(result=>new InsuranceListViewModel
|
||||||
{
|
{
|
||||||
Year = searchModel.Year,
|
Year = searchModel.Year,
|
||||||
Month = searchModel.Month,
|
Month = searchModel.Month,
|
||||||
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,
|
||||||
TypeOfInsuranceSend = result.TypeOfInsuranceSend == "NormalList" ? "عادی" :
|
TypeOfInsuranceSend = result.TypeOfInsuranceSend == "NormalList" ? "عادی" :
|
||||||
result.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" :
|
result.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" :
|
||||||
result.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "",
|
result.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "",
|
||||||
FixedSalary = result.FixedSalary,
|
FixedSalary = result.FixedSalary,
|
||||||
StrFixedSalary = result.FixedSalary ? "دارد" : "ندارد",
|
StrFixedSalary = result.FixedSalary ? "دارد" : "ندارد",
|
||||||
EmployerName = result.InsuranceWorkshopInfo != null
|
EmployerName = result.InsuranceWorkshopInfo != null
|
||||||
? result.InsuranceWorkshopInfo.EmployerName
|
? result.InsuranceWorkshopInfo.EmployerName
|
||||||
: result.WorkshopFullName,
|
: result.WorkshopFullName,
|
||||||
Branch = "",
|
Branch = "",
|
||||||
City = "",
|
City = "",
|
||||||
ArchiveCode = result.ArchiveCode,
|
ArchiveCode = result.ArchiveCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(searchModel.Month) && searchModel.Month != "0")
|
if (!string.IsNullOrEmpty(searchModel.Month) && searchModel.Month != "0")
|
||||||
query = query.Where(x => x.Month == searchModel.Month).OrderByDescending(x => x.WorkShopName)
|
query = query.Where(x => x.Month == searchModel.Month).OrderByDescending(x => x.WorkShopName)
|
||||||
.ThenByDescending(x => x.EmployerName).ThenByDescending(x => x.Year);
|
.ThenByDescending(x => x.EmployerName).ThenByDescending(x => x.Year);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(searchModel.Year) && searchModel.Year != "0")
|
if (!string.IsNullOrEmpty(searchModel.Year) && searchModel.Year != "0")
|
||||||
query = query.Where(x => x.Year == searchModel.Year).OrderByDescending(x => x.EmployerName)
|
query = query.Where(x => x.Year == searchModel.Year).OrderByDescending(x => x.EmployerName)
|
||||||
|
|||||||
@@ -340,12 +340,11 @@ public class PlanPercentageRepository : RepositoryBase<long, PlanPercentage>, IP
|
|||||||
.Select(x => x.ItemValue).FirstOrDefault();
|
.Select(x => x.ItemValue).FirstOrDefault();
|
||||||
|
|
||||||
var plans = _context.InstitutionPlans.AsQueryable();
|
var plans = _context.InstitutionPlans.AsQueryable();
|
||||||
|
|
||||||
if (searchModel.CountPerson > 0)
|
if (searchModel.CountPerson > 0)
|
||||||
plans = plans.Where(x => x.CountPerson == searchModel.CountPerson);
|
plans = plans.Where(x => x.CountPerson == searchModel.CountPerson);
|
||||||
|
|
||||||
var count = await plans.CountAsync();
|
var count = await plans.CountAsync();
|
||||||
|
|
||||||
var planQueryFilter =await plans.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
|
var planQueryFilter =await plans.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync();
|
||||||
var planResult = planQueryFilter.Select(plan =>
|
var planResult = planQueryFilter.Select(plan =>
|
||||||
new InstitutionPlanViewModel
|
new InstitutionPlanViewModel
|
||||||
|
|||||||
@@ -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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -850,7 +850,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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -342,19 +342,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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user