Compare commits

...

33 Commits

Author SHA1 Message Date
aa37ca4b28 add: enhance deployment status validation in ChangeDeployStatusProject command and include Activities in ProjectDeployBoardList query 2025-12-30 17:19:59 +03:30
45615684ed add: enhance skill calculation in ProjectDeployBoardDetailsQueryHandler and refine query conditions in ProjectDeployBoardListQueryHandler 2025-12-30 15:55:57 +03:30
94955ea1b4 add: update GetProjectDeployBoardDetails method to use ProjectDeployBoardDetailsQuery 2025-12-30 12:54:53 +03:30
656bb49fab add: remove GetByIdAsync method and add Id property to ProjectDeployBoardListItem 2025-12-30 12:30:06 +03:30
fb5b98bf25 add: update UpdateDeployStatus method to archive project phase upon deployment 2025-12-30 11:54:56 +03:30
1e733f3f20 add: implement ChangeDeployStatusProject command and handler for updating project deployment status 2025-12-30 11:10:40 +03:30
d855684cd7 add: implement AutoUpdateDeployStatusCommand for automatic deployment status updates 2025-12-29 12:16:51 +03:30
9e5e8d8e5d refactor: improve code formatting and structure in ProjectController 2025-12-29 11:45:32 +03:30
9eefdd8fd1 add: implement GetProjectDeployBoardDetails endpoint for retrieving project board details 2025-12-29 10:27:23 +03:30
2159901614 add: implement ProjectDeployBoardDetailsQuery and its handler with validation for project phase details 2025-12-27 19:42:13 +03:30
7ce7854091 add: include DeployStatus in ProjectDeployBoardListItem for deployment status tracking 2025-12-27 16:26:07 +03:30
4c638cbdae add: implement DeployStatus and IsArchived properties in ProjectPhase, and create ProjectDeployBoardListQueryHandler for project deployment management 2025-12-27 13:59:37 +03:30
39a5918a11 add: implement ProjectDeployBoardListQueryHandler and initialize GetProjectsListQueryHandler structure 2025-12-24 18:55:01 +03:30
b9e271de1a fix: update OccurredOn property to use DateTime.Now instead of DateTime.UtcNow in event records 2025-12-23 15:00:18 +03:30
e661bc2dcb add: enhance ProjectBoardListQueryHandler and ProjectPhase to manage task section statuses and deployment states 2025-12-23 14:52:41 +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
12fab5a9a5 add {id:guid} convention for controllers 2025-12-20 20:57:34 +03:30
20dd8f64f4 add: include OneMonthWithoutTax and OneMonthTax properties in InstitutionContractPrintViewModel 2025-12-20 20:28:08 +03:30
b827493306 refactor: remove unused discount-related classes from IInstitutionContractApplicationpnpm 2025-12-20 20:12:31 +03:30
04c65eae93 Merge branch 'Feature/institution-contract/print'
# Conflicts:
#	CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs
2025-12-20 20:10:30 +03:30
b4526a4338 Merge branch 'Feature/institution-contract/verify-mannually' 2025-12-20 20:09:13 +03:30
2d879ce80a fix: update workshop identification logic in InstitutionContractApplication 2025-12-20 20:06:28 +03:30
56e79d2099 fix: correct ContractAmountWithTax calculation for old contracts 2025-12-20 19:38:32 +03:30
93891f3837 add one month more details for InstitutionContract.cs print 2025-12-20 19:18:27 +03:30
SamSys
5bdfbc572b add next deploy and contractingParty add to workshop on AndroidApk page 2025-12-20 18:42:53 +03:30
4385a65cbc feat: add manual verification endpoint for institution contracts 2025-12-20 18:27:59 +03:30
722f8dae7c feat: implement manual verification for institution contracts and add signing type handling 2025-12-20 18:27:17 +03:30
SamSys
07113353c4 add uploadFrontEnd btn to AndroidApk page 2025-12-20 16:01:07 +03:30
8c6336b9bd fix: correct IsOldContract logic to properly identify old contracts 2025-12-20 14:35:02 +03:30
20e3d454cf feat: add ContractAmountWithTax calculation and update related references 2025-12-20 13:35:52 +03:30
2bf31db6b2 fix: enhance parameter binding logic for route parameters 2025-12-20 12:05:34 +03:30
7a4a6de84f feat: add OneMonthPrice to institution contract details 2025-12-20 10:56:36 +03:30
53 changed files with 13574 additions and 264 deletions

View File

@@ -98,6 +98,11 @@ public class InstitutionContract : EntityBase
// مبلغ قرارداد // مبلغ قرارداد
public double ContractAmount { get; private set; } public double ContractAmount { get; private set; }
public double ContractAmountWithTax => !IsOldContract ? ContractAmount + ContractAmountTax
: ContractAmount;
public double ContractAmountTax => ContractAmount*0.10;
//خسارت روزانه //خسارت روزانه
public double DailyCompenseation { get; private set; } public double DailyCompenseation { get; private set; }
@@ -159,6 +164,10 @@ public class InstitutionContract : EntityBase
public List<InstitutionContractAmendment> Amendments { get; private set; } public List<InstitutionContractAmendment> Amendments { get; private set; }
public InstitutionContractSigningType? SigningType { get; private set; }
public bool IsOldContract => LawId== 0;
public InstitutionContract() public InstitutionContract()
{ {
ContactInfoList = []; ContactInfoList = [];
@@ -262,6 +271,10 @@ public class InstitutionContract : EntityBase
{ {
WorkshopGroup = null; WorkshopGroup = null;
} }
public void SetSigningType(InstitutionContractSigningType signingType)
{
SigningType = signingType;
}
} }
public class InstitutionContractAmendment : EntityBase public class InstitutionContractAmendment : EntityBase

View File

@@ -10,13 +10,15 @@ public class InstitutionContractWorkshopCurrent:InstitutionContractWorkshopBase
public InstitutionContractWorkshopCurrent(string workshopName, bool hasRollCallPlan, public InstitutionContractWorkshopCurrent(string workshopName, bool hasRollCallPlan,
bool hasRollCallPlanInPerson, bool hasCustomizeCheckoutPlan, bool hasContractPlan, bool hasRollCallPlanInPerson, bool hasCustomizeCheckoutPlan, bool hasContractPlan,
bool hasContractPlanInPerson, bool hasInsurancePlan, bool hasInsurancePlanInPerson, bool hasContractPlanInPerson, bool hasInsurancePlan, bool hasInsurancePlanInPerson,
int personnelCount, double price,long institutionContractWorkshopGroupId,InstitutionContractWorkshopGroup workshopGroup,long workshopId) : base(workshopName, hasRollCallPlan, int personnelCount, double price,long institutionContractWorkshopGroupId,
InstitutionContractWorkshopGroup workshopGroup,long workshopId,long initialWorkshopId) : base(workshopName, hasRollCallPlan,
hasRollCallPlanInPerson, hasCustomizeCheckoutPlan, hasContractPlan, hasRollCallPlanInPerson, hasCustomizeCheckoutPlan, hasContractPlan,
hasContractPlanInPerson, hasInsurancePlan, hasInsurancePlanInPerson, personnelCount, price) hasContractPlanInPerson, hasInsurancePlan, hasInsurancePlanInPerson, personnelCount, price)
{ {
InstitutionContractWorkshopGroupId = institutionContractWorkshopGroupId; InstitutionContractWorkshopGroupId = institutionContractWorkshopGroupId;
WorkshopGroup = workshopGroup; WorkshopGroup = workshopGroup;
WorkshopId = workshopId; WorkshopId = workshopId;
InitialWorkshopId = initialWorkshopId;
} }
public long InstitutionContractWorkshopGroupId { get; private set; } public long InstitutionContractWorkshopGroupId { get; private set; }
public InstitutionContractWorkshopGroup WorkshopGroup { get; private set; } public InstitutionContractWorkshopGroup WorkshopGroup { get; private set; }

View File

@@ -37,4 +37,10 @@ public class InstitutionContractWorkshopGroup : EntityBase
CurrentWorkshops = updatedDetails.ToList(); CurrentWorkshops = updatedDetails.ToList();
LastModifiedDate = DateTime.Now; LastModifiedDate = DateTime.Now;
} }
public void AddCurrentWorkshop(InstitutionContractWorkshopCurrent currentWorkshop)
{
CurrentWorkshops.Add(currentWorkshop);
LastModifiedDate = DateTime.Now;
}
} }

View File

@@ -31,7 +31,7 @@ public class InstitutionContractWorkshopInitial:InstitutionContractWorkshopBase
WorkshopCreated = true; WorkshopCreated = true;
WorkshopCurrent = new InstitutionContractWorkshopCurrent(WorkshopName,Services.RollCall,Services.RollCallInPerson, WorkshopCurrent = new InstitutionContractWorkshopCurrent(WorkshopName,Services.RollCall,Services.RollCallInPerson,
Services.CustomizeCheckout,Services.Contract,Services.ContractInPerson,Services.Insurance, Services.CustomizeCheckout,Services.Contract,Services.ContractInPerson,Services.Insurance,
Services.InsuranceInPerson,PersonnelCount,Price,InstitutionContractWorkshopGroupId,WorkshopGroup,workshopId); Services.InsuranceInPerson,PersonnelCount,Price,InstitutionContractWorkshopGroupId,WorkshopGroup,workshopId,id);
WorkshopCurrent.SetEmployers(Employers.Select(x=>x.EmployerId).ToList()); WorkshopCurrent.SetEmployers(Employers.Select(x=>x.EmployerId).ToList());
} }

View File

@@ -316,7 +316,10 @@ public class Workshop : EntityBase
IsStaticCheckout = isStaticCheckout; IsStaticCheckout = isStaticCheckout;
} }
public void AddContractingPartyId(long contractingPartyId)
{
ContractingPartyId = contractingPartyId;
}
public void Active(string archiveCode) public void Active(string archiveCode)
{ {
this.IsActive = true; this.IsActive = true;

View File

@@ -0,0 +1,17 @@
namespace CompanyManagment.App.Contracts.InstitutionContract;
public enum InstitutionContractSigningType
{
/// <summary>
/// قدیمی
/// </summary>
Legacy = 0,
/// <summary>
/// الکترونیکی با کد یکبار مصرف
/// </summary>
OtpBased = 1,
/// <summary>
/// به صورت فیزیکی
/// </summary>
Physical = 2
}

View File

@@ -7,7 +7,6 @@ using System.Threading.Tasks;
using _0_Framework.Application; using _0_Framework.Application;
using _0_Framework.Application.Sms; using _0_Framework.Application.Sms;
using CompanyManagment.App.Contracts.Checkout; using CompanyManagment.App.Contracts.Checkout;
using CompanyManagment.App.Contracts.Law;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop; using CompanyManagment.App.Contracts.Workshop;
using CompanyManagment.App.Contracts.WorkshopPlan; using CompanyManagment.App.Contracts.WorkshopPlan;
@@ -260,154 +259,13 @@ public interface IInstitutionContractApplication
/// <returns></returns> /// <returns></returns>
Task<InstitutionContractPrintViewModel> PrintOneAsync(long id); Task<InstitutionContractPrintViewModel> PrintOneAsync(long id);
Task<OperationResult> SetPendingWorkflow(long entityId); Task<OperationResult> SetPendingWorkflow(long entityId,InstitutionContractSigningType signingType);
Task<long> GetIdByInstallmentId(long installmentId); Task<long> GetIdByInstallmentId(long installmentId);
}
public class InstitutionContractDiscountResponse
{
public InstitutionContractDiscountOneTimeViewModel OneTime { get; set; }
public InstitutionContractDiscountMonthlyViewModel Monthly { get; set; }
}
public class InstitutionContractDiscountMonthlyViewModel:InstitutionContractDiscountOneTimeViewModel
{
public List<MonthlyInstallment> Installments { get; set; }
}
public class InstitutionContractDiscountOneTimeViewModel
{
/// <summary> /// <summary>
/// مجموع مبالغ /// تایید قرارداد مالی به صورت دستی
/// </summary> /// </summary>
public string TotalAmount { get; set; } /// <param name="institutionContractId"></param>
/// <summary> /// <returns></returns>
/// ارزش افزوده Task<OperationResult> VerifyInstitutionContractManually(long institutionContractId);
/// </summary>
public string Tax { get; set; }
/// <summary>
/// مبلغ قابل پرداخت
/// </summary>
public string PaymentAmount { get; set; }
public string DiscountedAmount { get; set; }
public int DiscountPercetage { get; set; }
public string Obligation { get; set; }
public string OneMonthAmount { get; set; }
}
public class InstitutionContractResetDiscountForCreateRequest
{
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public bool IsInstallment { get; set; }
public InstitutionContractDuration Duration { get; set; }
public double OneMonthAmount { get; set; }
}
public class InstitutionContractSetDiscountForExtensionRequest
{
public Guid TempId { get; set; }
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public bool IsInstallment { get; set; }
}
public class InstitutionContractResetDiscountForExtensionRequest
{
public Guid TempId { get; set; }
public bool IsInstallment { get; set; }
}
public class InstitutionContractSetDiscountRequest
{
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public InstitutionContractDuration Duration { get; set; }
public double OneMonthAmount { get; set; }
public bool IsInstallment { get; set; }
}
public class InstitutionContractPrintViewModel
{
public InstitutionContratVerificationParty FirstParty { get; set; }
public InstitutionContratVerificationParty SecondParty { get; set; }
public string ContractNo { get; set; }
public string CreationDate { get; set; }
public string ContractStart { get; set; }
public string ContractEnd { get; set; }
public List<GetInstitutionVerificationDetailsWorkshopsViewModel> Workshops { get; set; }
public string TotalPrice { get; set; }
public string TaxPrice { get; set; }
public string PaymentPrice { get; set; }
public string VerifyCode { get; set; }
public string VerifyDate { get; set; }
public string VerifyTime { get; set; }
public string VerifierFullName { get; set; }
public string VerifierPhoneNumber { get; set; }
public LawViewModel LawViewModel { get; set; }
public string Obligation { get; set; }
}
public class InsertAmendmentTempWorkshopResponse
{
public Guid WorkshopTempId { get; set; }
public string Amount { get; set; }
}
public class InstitutionContractAmendmentWorkshopsResponse
{
/// <summary>
///
/// </summary>
public List<InstitutionContractAmendmentTempWorkshopViewModel> Workshops { get; set; }
public Guid TempId { get; set; }
} }
public class InstitutionContractSelectListViewModel : SelectListViewModel;
public class InstitutionContractExtensionInquiryResponse
{
public long Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string DateOfBirthFa { get; set; }
public string FatherName { get; set; }
public string IdNumberSerial { get; set; }
public string IdNumber { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string City { get; set; }
public string State { get; set; }
public long RepresentativeId { get; set; }
public string NationalCode { get; set; }
}
public class InstitutionContractExtensionPaymentMonthly:InstitutionContractExtensionPaymentOneTime
{
public List<MonthlyInstallment> Installments { get; set; }
}
public class InstitutionContractExtensionPaymentOneTime
{
/// <summary>
/// مجموع مبالغ
/// </summary>
public string TotalAmount { get; set; }
/// <summary>
/// ارزش افزوده
/// </summary>
public string Tax { get; set; }
/// <summary>
/// مبلغ قابل پرداخت
/// </summary>
public string PaymentAmount { get; set; }
}

View File

@@ -0,0 +1,9 @@
using System;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InsertAmendmentTempWorkshopResponse
{
public Guid WorkshopTempId { get; set; }
public string Amount { get; set; }
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractAmendmentWorkshopsResponse
{
/// <summary>
///
/// </summary>
public List<InstitutionContractAmendmentTempWorkshopViewModel> Workshops { get; set; }
public Guid TempId { get; set; }
}

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractDiscountResponse
{
public InstitutionContractDiscountOneTimeViewModel OneTime { get; set; }
public InstitutionContractDiscountMonthlyViewModel Monthly { get; set; }
}
public class InstitutionContractDiscountMonthlyViewModel:InstitutionContractDiscountOneTimeViewModel
{
public List<MonthlyInstallment> Installments { get; set; }
}
public class InstitutionContractDiscountOneTimeViewModel
{
/// <summary>
/// مجموع مبالغ
/// </summary>
public string TotalAmount { get; set; }
/// <summary>
/// ارزش افزوده
/// </summary>
public string Tax { get; set; }
/// <summary>
/// مبلغ قابل پرداخت
/// </summary>
public string PaymentAmount { get; set; }
public string DiscountedAmount { get; set; }
public int DiscountPercetage { get; set; }
public string Obligation { get; set; }
public string OneMonthAmount { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractExtensionInquiryResponse
{
public long Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string DateOfBirthFa { get; set; }
public string FatherName { get; set; }
public string IdNumberSerial { get; set; }
public string IdNumber { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string City { get; set; }
public string State { get; set; }
public long RepresentativeId { get; set; }
public string NationalCode { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractExtensionPaymentMonthly:InstitutionContractExtensionPaymentOneTime
{
public List<MonthlyInstallment> Installments { get; set; }
}
public class InstitutionContractExtensionPaymentOneTime
{
/// <summary>
/// مجموع مبالغ
/// </summary>
public string TotalAmount { get; set; }
/// <summary>
/// ارزش افزوده
/// </summary>
public string Tax { get; set; }
/// <summary>
/// مبلغ قابل پرداخت
/// </summary>
public string PaymentAmount { get; set; }
}

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
using CompanyManagment.App.Contracts.Law;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractPrintViewModel
{
public InstitutionContratVerificationParty FirstParty { get; set; }
public InstitutionContratVerificationParty SecondParty { get; set; }
public string ContractNo { get; set; }
public string CreationDate { get; set; }
public string ContractStart { get; set; }
public string ContractEnd { get; set; }
public List<GetInstitutionVerificationDetailsWorkshopsViewModel> Workshops { get; set; }
public string TotalPrice { get; set; }
public string TaxPrice { get; set; }
public string PaymentPrice { get; set; }
public string OneMonthPrice { get; set; }
public string VerifyCode { get; set; }
public string VerifyDate { get; set; }
public string VerifyTime { get; set; }
public string VerifierFullName { get; set; }
public string VerifierPhoneNumber { get; set; }
public LawViewModel LawViewModel { get; set; }
public string Obligation { get; set; }
public string OneMonthWithoutTax { get; set; }
public string OneMonthTax { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractResetDiscountForCreateRequest
{
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public bool IsInstallment { get; set; }
public InstitutionContractDuration Duration { get; set; }
public double OneMonthAmount { get; set; }
}

View File

@@ -0,0 +1,9 @@
using System;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractResetDiscountForExtensionRequest
{
public Guid TempId { get; set; }
public bool IsInstallment { get; set; }
}

View File

@@ -0,0 +1,5 @@
using _0_Framework.Application;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractSelectListViewModel : SelectListViewModel;

View File

@@ -0,0 +1,11 @@
using System;
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractSetDiscountForExtensionRequest
{
public Guid TempId { get; set; }
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public bool IsInstallment { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace CompanyManagment.App.Contracts.InstitutionContract;
public class InstitutionContractSetDiscountRequest
{
public int DiscountPercentage { get; set; }
public double TotalAmount { get; set; }
public InstitutionContractDuration Duration { get; set; }
public double OneMonthAmount { get; set; }
public bool IsInstallment { get; set; }
}

View File

@@ -1537,7 +1537,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
return (await _institutionContractRepository.PrintAllAsync([id])).FirstOrDefault(); return (await _institutionContractRepository.PrintAllAsync([id])).FirstOrDefault();
} }
public async Task<OperationResult> SetPendingWorkflow(long entityId) public async Task<OperationResult> SetPendingWorkflow(long entityId,InstitutionContractSigningType signingType)
{ {
var op = new OperationResult(); var op = new OperationResult();
var institutionContract = await _institutionContractRepository.GetIncludeWorkshopDetailsAsync(entityId); var institutionContract = await _institutionContractRepository.GetIncludeWorkshopDetailsAsync(entityId);
@@ -1551,6 +1551,30 @@ public class InstitutionContractApplication : IInstitutionContractApplication
return op.Failed("وضعیت قرارداد مالی برای این عملیات مناسب نمی باشد"); return op.Failed("وضعیت قرارداد مالی برای این عملیات مناسب نمی باشد");
} }
var initialCreatedWorkshops = institutionContract.WorkshopGroup.InitialWorkshops
.Where(x => x.WorkshopCreated && x.WorkshopId is > 0).ToList();
var currentWorkshops = institutionContract.WorkshopGroup.CurrentWorkshops.ToList();
foreach (var createdWorkshop in initialCreatedWorkshops)
{
if (currentWorkshops.Any(x => x.WorkshopId == createdWorkshop.WorkshopId))
{
continue;
}
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, 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();
@@ -1560,6 +1584,8 @@ public class InstitutionContractApplication : IInstitutionContractApplication
institutionContract.SetPendingWorkflow(); institutionContract.SetPendingWorkflow();
} }
institutionContract.SetSigningType(signingType);
await _institutionContractRepository.SaveChangesAsync(); await _institutionContractRepository.SaveChangesAsync();
return op.Succcedded(); return op.Succcedded();
} }
@@ -1569,6 +1595,28 @@ public class InstitutionContractApplication : IInstitutionContractApplication
return await _institutionContractRepository.GetIdByInstallmentId(installmentId); return await _institutionContractRepository.GetIdByInstallmentId(installmentId);
} }
public async Task<OperationResult> VerifyInstitutionContractManually(long institutionContractId)
{
var op = new OperationResult();
var institutionContract =await _institutionContractRepository
.GetIncludeWorkshopDetailsAsync(institutionContractId);
if (institutionContract == null)
return op.Failed("قرارداد مالی یافت نشد");
if (institutionContract.VerificationStatus == InstitutionContractVerificationStatus.Verified)
return op.Failed("قرارداد مالی قبلا تایید شده است");
var transaction = await _institutionContractRepository.BeginTransactionAsync();
await SetPendingWorkflow(institutionContractId,InstitutionContractSigningType.Physical);
await transaction.CommitAsync();
await _institutionContractRepository.SaveChangesAsync();
return op.Succcedded();
}
private async Task<OperationResult<PersonalContractingParty>> CreateLegalContractingPartyEntity( private async Task<OperationResult<PersonalContractingParty>> CreateLegalContractingPartyEntity(
CreateInstitutionContractLegalPartyRequest request, long representativeId, string address, string city, CreateInstitutionContractLegalPartyRequest request, long representativeId, string address, string city,
string state) string state)

View File

@@ -35,6 +35,10 @@ public class InstitutionContractMapping : IEntityTypeConfiguration<InstitutionCo
builder.Property(x => x.VerificationStatus).HasConversion<string>().HasMaxLength(122); builder.Property(x => x.VerificationStatus).HasConversion<string>().HasMaxLength(122);
builder.Property(x=>x.SigningType).HasConversion<string>()
.HasMaxLength(25)
.IsRequired(false);
builder.HasMany(x => x.Installments) builder.HasMany(x => x.Installments)
.WithOne(x => x.InstitutionContract) .WithOne(x => x.InstitutionContract)
.HasForeignKey(x => x.InstitutionContractId); .HasForeignKey(x => x.InstitutionContractId);
@@ -45,5 +49,10 @@ public class InstitutionContractMapping : IEntityTypeConfiguration<InstitutionCo
builder.HasMany(x => x.Amendments).WithOne(x => x.InstitutionContract) builder.HasMany(x => x.Amendments).WithOne(x => x.InstitutionContract)
.HasForeignKey(x => x.InstitutionContractId); .HasForeignKey(x => x.InstitutionContractId);
builder.Ignore(x => x.ContractAmountWithTax);
builder.Ignore(x => x.ContractAmountTax);
builder.Ignore(x => x.ContractAmountTax);
} }
} }

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace CompanyManagment.EFCore.Migrations
{
/// <inheritdoc />
public partial class addsigningTypeforinstitutioncontract : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "SigningType",
table: "InstitutionContracts",
type: "nvarchar(25)",
maxLength: 25,
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "SigningType",
table: "InstitutionContracts");
}
}
}

View File

@@ -3462,6 +3462,10 @@ namespace CompanyManagment.EFCore.Migrations
.HasMaxLength(1) .HasMaxLength(1)
.HasColumnType("nvarchar(1)"); .HasColumnType("nvarchar(1)");
b.Property<string>("SigningType")
.HasMaxLength(25)
.HasColumnType("nvarchar(25)");
b.Property<string>("State") b.Property<string>("State")
.HasMaxLength(20) .HasMaxLength(20)
.HasColumnType("nvarchar(20)"); .HasColumnType("nvarchar(20)");

View File

@@ -4,9 +4,7 @@ using _0_Framework.Application.Sms;
using _0_Framework.Exceptions; using _0_Framework.Exceptions;
using _0_Framework.InfraStructure; using _0_Framework.InfraStructure;
using Company.Domain.ContarctingPartyAgg; using Company.Domain.ContarctingPartyAgg;
using Company.Domain.ContractingPartyAccountAgg;
using Company.Domain.empolyerAgg; using Company.Domain.empolyerAgg;
using Company.Domain.FinancialInvoiceAgg;
using Company.Domain.FinancialStatmentAgg; using Company.Domain.FinancialStatmentAgg;
using Company.Domain.FinancialTransactionAgg; using Company.Domain.FinancialTransactionAgg;
using Company.Domain.InstitutionContractAgg; using Company.Domain.InstitutionContractAgg;
@@ -17,7 +15,6 @@ using Company.Domain.InstitutionPlanAgg;
using Company.Domain.SmsResultAgg; using Company.Domain.SmsResultAgg;
using Company.Domain.WorkshopAgg; using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.Employer; using CompanyManagment.App.Contracts.Employer;
using CompanyManagment.App.Contracts.FinancialInvoice;
using CompanyManagment.App.Contracts.FinancialStatment; using CompanyManagment.App.Contracts.FinancialStatment;
using CompanyManagment.App.Contracts.FinancilTransaction; using CompanyManagment.App.Contracts.FinancilTransaction;
using CompanyManagment.App.Contracts.Hubs; using CompanyManagment.App.Contracts.Hubs;
@@ -26,30 +23,17 @@ using CompanyManagment.App.Contracts.InstitutionContractContactinfo;
using CompanyManagment.App.Contracts.Law; using CompanyManagment.App.Contracts.Law;
using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.App.Contracts.Workshop; using CompanyManagment.App.Contracts.Workshop;
using CompanyManagment.App.Contracts.WorkshopPlan;
using CompanyManagment.EFCore.Migrations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MongoDB.Driver; using MongoDB.Driver;
using OfficeOpenXml.Packaging.Ionic.Zip;
using PersianTools.Core; using PersianTools.Core;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
using static System.Runtime.InteropServices.JavaScript.JSType;
using ContractingPartyAccount = Company.Domain.ContractingPartyAccountAgg.ContractingPartyAccount; using ContractingPartyAccount = Company.Domain.ContractingPartyAccountAgg.ContractingPartyAccount;
using FinancialStatment = Company.Domain.FinancialStatmentAgg.FinancialStatment; using FinancialStatment = Company.Domain.FinancialStatmentAgg.FinancialStatment;
using String = System.String; using String = System.String;
@@ -1375,7 +1359,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now); .Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now);
return new GetInstitutionContractListItemsViewModel() return new GetInstitutionContractListItemsViewModel()
{ {
ContractAmount = x.contract.ContractAmount, ContractAmount = x.contract.ContractAmountWithTax,
Balance = statement?.FinancialTransactionList.Sum(ft => ft.Deptor - ft.Creditor) ?? 0, Balance = statement?.FinancialTransactionList.Sum(ft => ft.Deptor - ft.Creditor) ?? 0,
WorkshopsCount = workshops.Count(), WorkshopsCount = workshops.Count(),
ContractStartFa = x.contract.ContractStartGr.ToFarsi(), ContractStartFa = x.contract.ContractStartGr.ToFarsi(),
@@ -1395,9 +1379,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
Workshops = workshopDetails, Workshops = workshopDetails,
IsInPersonContract = x.contract.WorkshopGroup?.CurrentWorkshops IsInPersonContract = x.contract.WorkshopGroup?.CurrentWorkshops
.Any(y => y.Services.ContractInPerson) ?? true, .Any(y => y.Services.ContractInPerson) ?? true,
IsOldContract = x.contract.WorkshopGroup?.CurrentWorkshops == null IsOldContract = x.contract.SigningType == InstitutionContractSigningType.Legacy
|| x.contract.WorkshopGroup.CurrentWorkshops.Count == 0
|| x.contract.WorkshopGroup.CurrentWorkshops.Any(y => y.Price == 0)
}; };
}).ToList() }).ToList()
}; };
@@ -3216,6 +3198,9 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
PaymentPrice = institution.TotalAmount.ToMoney(), PaymentPrice = institution.TotalAmount.ToMoney(),
TotalPrice = (institution.TotalAmount - institution.ValueAddedTax).ToMoney(), TotalPrice = (institution.TotalAmount - institution.ValueAddedTax).ToMoney(),
TaxPrice = institution.ValueAddedTax.ToMoney(), TaxPrice = institution.ValueAddedTax.ToMoney(),
OneMonthPrice = institution.ContractAmountWithTax.ToMoney(),
OneMonthWithoutTax = institution.ContractAmount.ToMoney(),
OneMonthTax = institution.ContractAmountTax.ToMoney(),
VerifierFullName = institution.VerifierFullName, VerifierFullName = institution.VerifierFullName,
VerifierPhoneNumber = institution.VerifierPhoneNumber, VerifierPhoneNumber = institution.VerifierPhoneNumber,
VerifyCode = institution.VerifyCode, VerifyCode = institution.VerifyCode,
@@ -4774,6 +4759,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.Select(x => x.id).FirstOrDefaultAsync(); .Select(x => x.id).FirstOrDefaultAsync();
} }
#endregion #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

@@ -0,0 +1,52 @@
using System.Linq;
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using Microsoft.EntityFrameworkCore;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoUpdateDeployStatus;
public record AutoUpdateDeployStatusCommand : IBaseCommand;
public class AutoUpdateDeployStatusCommandHandler : IBaseCommandHandler<AutoUpdateDeployStatusCommand>
{
private readonly IProgramManagerDbContext _dbContext;
public AutoUpdateDeployStatusCommandHandler(IProgramManagerDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<OperationResult> Handle(AutoUpdateDeployStatusCommand request,
CancellationToken cancellationToken)
{
// Fetch all sections whose phase is still marked as not completed
var sections = await _dbContext.TaskSections
.Include(ts => ts.Task)
.ThenInclude(t => t.Phase)
.Where(ts => ts.Task.Phase.DeployStatus == ProjectDeployStatus.NotCompleted)
.ToListAsync(cancellationToken);
if (sections.Count == 0)
return OperationResult.Success();
var phasesToUpdate = sections
.GroupBy(ts => ts.Task.PhaseId)
.Where(g => g.All(s => s.Status == TaskSectionStatus.Completed))
.Select(g => g.First().Task.Phase)
.Distinct()
.ToList();
if (phasesToUpdate.Count == 0)
return OperationResult.Success();
foreach (var phase in phasesToUpdate)
{
phase.UpdateDeployStatus(ProjectDeployStatus.PendingDevDeploy);
}
await _dbContext.SaveChangesAsync(cancellationToken);
return OperationResult.Success();
}
}

View File

@@ -0,0 +1,44 @@
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain._Common;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject;
public record ChangeDeployStatusProjectCommand(Guid PhaseId, ProjectDeployStatus Status):IBaseCommand;
public class ChangeDeployStatusProjectCommandHandler : IBaseCommandHandler<ChangeDeployStatusProjectCommand>
{
private readonly IProjectRepository _projectRepository;
private readonly IProjectPhaseRepository _projectPhaseRepository;
private readonly IUnitOfWork _unitOfWork;
public ChangeDeployStatusProjectCommandHandler(IProjectRepository projectRepository, IUnitOfWork unitOfWork, IProjectPhaseRepository projectPhaseRepository)
{
_projectRepository = projectRepository;
_unitOfWork = unitOfWork;
_projectPhaseRepository = projectPhaseRepository;
}
public async Task<OperationResult> Handle(ChangeDeployStatusProjectCommand request, CancellationToken cancellationToken)
{
var project = await _projectPhaseRepository.GetByIdAsync(request.PhaseId, cancellationToken);
if (project == null)
return OperationResult.NotFound("بخش مورد نظر یافت نشد");
if (project.DeployStatus == ProjectDeployStatus.NotCompleted)
{
return OperationResult.Failure("وضعیت استقرار نمی‌تواند از حالت 'تایید نشده' تغییر کند.");
}
if (request.Status == ProjectDeployStatus.NotCompleted)
{
return OperationResult.Failure("وضعیت استقرار نمی‌تواند به حالت 'تایید نشده' تغییر کند.");
}
project.UpdateDeployStatus(request.Status);
await _unitOfWork.SaveChangesAsync(cancellationToken);
return OperationResult.Success();
}
}

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

@@ -22,8 +22,9 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler<ProjectBoardListQu
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var currentUserId = _authHelper.GetCurrentUserId(); var currentUserId = _authHelper.GetCurrentUserId();
var queryable = _programManagerDbContext.TaskSections.AsNoTracking() var queryable = _programManagerDbContext.TaskSections.AsNoTracking()
.Where(x => x.InitialEstimatedHours > TimeSpan.Zero) .Where(x => x.InitialEstimatedHours > TimeSpan.Zero && x.Status != TaskSectionStatus.Completed)
.Include(x => x.Task) .Include(x => x.Task)
.ThenInclude(x => x.Phase) .ThenInclude(x => x.Phase)
.ThenInclude(x => x.Project) .ThenInclude(x => x.Project)

View File

@@ -0,0 +1,113 @@
using System.Security.AccessControl;
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using Microsoft.EntityFrameworkCore;
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail;
public record ProjectDeployBoardDetailsResponse(
ProjectDeployBoardDetailPhaseItem Phase,
List<ProjectDeployBoardDetailTaskItem> Tasks);
public record ProjectDeployBoardDetailPhaseItem(
string Name,
TimeSpan TotalTimeSpan,
TimeSpan DoneTimeSpan);
public record ProjectDeployBoardDetailTaskItem(
string Name,
TimeSpan TotalTimeSpan,
TimeSpan DoneTimeSpan,
List<ProjectDeployBoardDetailItemSkill> Skills)
: ProjectDeployBoardDetailPhaseItem(Name, TotalTimeSpan, DoneTimeSpan);
public record ProjectDeployBoardDetailItemSkill(string OriginalUserFullName, string SkillName, int TimePercentage);
public record ProjectDeployBoardDetailsQuery(Guid PhaseId) : IBaseQuery<ProjectDeployBoardDetailsResponse>;
public class
ProjectDeployBoardDetailsQueryHandler : IBaseQueryHandler<ProjectDeployBoardDetailsQuery,
ProjectDeployBoardDetailsResponse>
{
private readonly IProgramManagerDbContext _dbContext;
public ProjectDeployBoardDetailsQueryHandler(IProgramManagerDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<OperationResult<ProjectDeployBoardDetailsResponse>> Handle(ProjectDeployBoardDetailsQuery request,
CancellationToken cancellationToken)
{
var phase = await _dbContext.ProjectPhases
.Include(x => x.Tasks)
.ThenInclude(x => x.Sections)
.ThenInclude(x => x.Activities)
.Include(x => x.Tasks)
.ThenInclude(x => x.Sections)
.ThenInclude(x => x.AdditionalTimes)
.Include(x => x.Tasks)
.ThenInclude(x => x.Sections)
.ThenInclude(x => x.Skill)
.FirstOrDefaultAsync(x => x.Id == request.PhaseId, cancellationToken);
if (phase == null)
return OperationResult<ProjectDeployBoardDetailsResponse>.NotFound("بخش اصلی مورد نظر یافت نشد");
var userIds = phase.Tasks
.SelectMany(t => t.Sections)
.Select(s => s.OriginalAssignedUserId)
.Distinct()
.ToList();
var usersDict = await _dbContext.Users
.Where(x => userIds.Contains(x.Id))
.ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken);
var tasksRes = phase.Tasks.Select(t =>
{
var totalTime = t.Sections.Select(s => s.FinalEstimatedHours)
.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next));
var doneTime = t.Sections.Aggregate(TimeSpan.Zero,
(sum, next) => sum.Add(next.GetTotalTimeSpent()));
var skills = t.Sections
.Select(s =>
{
var originalUserFullName = usersDict.GetValueOrDefault(s.OriginalAssignedUserId,
"کاربر ناشناس");
var skillName = s.Skill?.Name ?? "بدون مهارت";
var totalTimeSpent = s.GetTotalTimeSpent();
var timePercentage = s.FinalEstimatedHours.Ticks > 0
? (int)((totalTimeSpent.Ticks / (double)s.FinalEstimatedHours.Ticks) * 100)
: 0;
return new ProjectDeployBoardDetailItemSkill(
originalUserFullName,
skillName,
timePercentage);
}).ToList();
return new ProjectDeployBoardDetailTaskItem(
t.Name,
totalTime,
doneTime,
skills);
}).ToList();
var totalTimeSpan = tasksRes.Aggregate(TimeSpan.Zero,
(sum, next) => sum.Add(next.TotalTimeSpan));
var doneTimeSpan = tasksRes.Aggregate(TimeSpan.Zero,
(sum, next) => sum.Add(next.DoneTimeSpan));
var phaseRes = new ProjectDeployBoardDetailPhaseItem(phase.Name, totalTimeSpan, doneTimeSpan);
var res = new ProjectDeployBoardDetailsResponse(phaseRes, tasksRes);
return OperationResult<ProjectDeployBoardDetailsResponse>.Success(res);
}
}

View File

@@ -0,0 +1,11 @@
using FluentValidation;
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail;
public class ProjectDeployBoardDetailsQueryValidator:AbstractValidator<ProjectDeployBoardDetailsQuery>
{
public ProjectDeployBoardDetailsQueryValidator()
{
RuleFor(x=>x.PhaseId).NotNull().WithMessage("شناسه بخش اصلی نمی‌تواند خالی باشد");
}
}

View File

@@ -0,0 +1,74 @@
using System.Xml.Schema;
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using Microsoft.EntityFrameworkCore;
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardList;
public record ProjectDeployBoardListItem()
{
public Guid Id { get; set; }
public string ProjectName { get; set; }
public string PhaseName { get; set; }
public int TotalTasks { get; set; }
public int DoneTasks { get; set; }
public TimeSpan TotalTimeSpan { get; set; }
public TimeSpan DoneTimeSpan { get; set; }
public ProjectDeployStatus DeployStatus { get; set; }
}
public record GetProjectsDeployBoardListResponse(List<ProjectDeployBoardListItem> Items);
public record GetProjectDeployBoardListQuery():IBaseQuery<GetProjectsDeployBoardListResponse>;
public class ProjectDeployBoardListQueryHandler:IBaseQueryHandler<GetProjectDeployBoardListQuery, GetProjectsDeployBoardListResponse>
{
private readonly IProgramManagerDbContext _dbContext;
private readonly IAuthHelper _authHelper;
public ProjectDeployBoardListQueryHandler(IProgramManagerDbContext dbContext, IAuthHelper authHelper)
{
_dbContext = dbContext;
_authHelper = authHelper;
}
public async Task<OperationResult<GetProjectsDeployBoardListResponse>> Handle(GetProjectDeployBoardListQuery request, CancellationToken cancellationToken)
{
var userId = _authHelper.GetCurrentUserId();
if (userId == null)
{
return OperationResult<GetProjectsDeployBoardListResponse>.NotFound("کاربر یافت نشد");
}
var query =await _dbContext.TaskSections
.Include(x=>x.Activities)
.Include(x=>x.Task)
.ThenInclude(x => x.Phase)
.ThenInclude(x => x.Project)
.AsNoTracking()
.Where(x => x.Status == TaskSectionStatus.Completed
|| x.Status == TaskSectionStatus.PendingForCompletion
|| (x.Task.Phase.DeployStatus != ProjectDeployStatus.NotCompleted
&& x.InitialEstimatedHours>TimeSpan.Zero))
.GroupBy(x=>x.Task.PhaseId).ToListAsync(cancellationToken: cancellationToken);
var list = query.Select(g => new ProjectDeployBoardListItem
{
Id = g.Key,
ProjectName = g.First().Task.Phase.Project.Name,
PhaseName = g.First().Task.Phase.Name,
TotalTasks = g.Select(x => x.TaskId).Distinct().Count(),
DoneTasks = g.Where(x => x.Status == TaskSectionStatus.Completed)
.Select(x => x.TaskId).Distinct().Count(),
TotalTimeSpan = TimeSpan.FromTicks(g.Sum(x => x.InitialEstimatedHours.Ticks)),
DoneTimeSpan = TimeSpan.FromTicks(g.Sum(x=>x.GetTotalTimeSpent().Ticks)),
DeployStatus = g.First().Task.Phase.DeployStatus
}).ToList();
var response = new GetProjectsDeployBoardListResponse(list);
return OperationResult<GetProjectsDeployBoardListResponse>.Success(response);
}
}

View File

@@ -23,6 +23,7 @@ public class ProjectPhase : ProjectHierarchyNode
ProjectId = projectId; ProjectId = projectId;
_tasks = new List<ProjectTask>(); _tasks = new List<ProjectTask>();
_phaseSections = new List<PhaseSection>(); _phaseSections = new List<PhaseSection>();
DeployStatus = ProjectDeployStatus.NotCompleted;
AddDomainEvent(new PhaseCreatedEvent(Id, projectId, name)); AddDomainEvent(new PhaseCreatedEvent(Id, projectId, name));
} }
@@ -36,6 +37,8 @@ public class ProjectPhase : ProjectHierarchyNode
public DateTime? StartDate { get; private set; } public DateTime? StartDate { get; private set; }
public DateTime? EndDate { get; private set; } public DateTime? EndDate { get; private set; }
public int OrderIndex { get; private set; } public int OrderIndex { get; private set; }
public bool IsArchived { get; set; }
public ProjectDeployStatus DeployStatus { get; set; }
#region Task Management #region Task Management
@@ -196,4 +199,30 @@ public class ProjectPhase : ProjectHierarchyNode
} }
#endregion #endregion
public void SetArchived()
{
IsArchived = true;
}
public void SetUnarchived()
{
IsArchived = false;
}
public void UpdateDeployStatus(ProjectDeployStatus status)
{
DeployStatus = status;
if (status == ProjectDeployStatus.Deployed)
{
IsArchived = true;
}
}
}
public enum ProjectDeployStatus
{
NotCompleted,
PendingDevDeploy,
DevDeployed,
PendingDeploy,
Deployed
} }

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

@@ -6,5 +6,6 @@ public enum TaskSectionStatus
ReadyToStart = 1, // آماده شروع ReadyToStart = 1, // آماده شروع
InProgress = 2, // درحال انجام InProgress = 2, // درحال انجام
Incomplete = 3, // ناتمام شده Incomplete = 3, // ناتمام شده
Completed = 4 // تکمیل شده PendingForCompletion = 4, // در انتظار تکمیل
Completed = 5 // تکمیل شده
} }

View File

@@ -8,171 +8,171 @@ namespace GozareshgirProgramManager.Domain.ProjectAgg.Events;
// Project Events // Project Events
public record ProjectCreatedEvent(Guid ProjectId, string Name) : IDomainEvent public record ProjectCreatedEvent(Guid ProjectId, string Name) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectStatusUpdatedEvent(Guid ProjectId, ProjectStatus Status) : IDomainEvent public record ProjectStatusUpdatedEvent(Guid ProjectId, ProjectStatus Status) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectAssignedEvent(Guid ProjectId, long UserId) : IDomainEvent public record ProjectAssignedEvent(Guid ProjectId, long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectUnassignedEvent(Guid ProjectId) : IDomainEvent public record ProjectUnassignedEvent(Guid ProjectId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
// Phase Events // Phase Events
public record PhaseCreatedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent public record PhaseCreatedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record PhaseAddedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent public record PhaseAddedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record PhaseRemovedEvent(Guid PhaseId, Guid ProjectId) : IDomainEvent public record PhaseRemovedEvent(Guid PhaseId, Guid ProjectId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record PhaseStatusUpdatedEvent(Guid PhaseId, PhaseStatus Status) : IDomainEvent public record PhaseStatusUpdatedEvent(Guid PhaseId, PhaseStatus Status) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record PhaseAssignedEvent(Guid PhaseId, long UserId) : IDomainEvent public record PhaseAssignedEvent(Guid PhaseId, long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record PhaseUnassignedEvent(Guid PhaseId) : IDomainEvent public record PhaseUnassignedEvent(Guid PhaseId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
// Task Events // Task Events
public record TaskCreatedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent public record TaskCreatedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskAddedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent public record TaskAddedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskRemovedEvent(Guid TaskId, Guid PhaseId) : IDomainEvent public record TaskRemovedEvent(Guid TaskId, Guid PhaseId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskStatusUpdatedEvent(Guid TaskId, TaskStatus Status) : IDomainEvent public record TaskStatusUpdatedEvent(Guid TaskId, TaskStatus Status) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskPriorityUpdatedEvent(Guid TaskId, TaskPriority Priority) : IDomainEvent public record TaskPriorityUpdatedEvent(Guid TaskId, TaskPriority Priority) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskAssignedEvent(Guid TaskId, long UserId) : IDomainEvent public record TaskAssignedEvent(Guid TaskId, long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskUnassignedEvent(Guid TaskId) : IDomainEvent public record TaskUnassignedEvent(Guid TaskId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskSectionAddedEvent(Guid TaskId, Guid SectionId, Guid SkillId) : IDomainEvent public record TaskSectionAddedEvent(Guid TaskId, Guid SectionId, Guid SkillId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskSectionRemovedEvent(Guid TaskId, Guid SectionId) : IDomainEvent public record TaskSectionRemovedEvent(Guid TaskId, Guid SectionId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
// TaskSection Events // TaskSection Events
public record TaskSectionStatusChangedEvent(Guid SectionId, TaskSectionStatus OldStatus, public record TaskSectionStatusChangedEvent(Guid SectionId, TaskSectionStatus OldStatus,
TaskSectionStatus NewStatus,long UserId) : IDomainEvent TaskSectionStatus NewStatus,long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent public record TaskSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record TaskSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent public record TaskSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
// Section Events (Legacy - keeping for backward compatibility) // Section Events (Legacy - keeping for backward compatibility)
public record ProjectPhaseAddedEvent(Guid ProjectId, Guid PhaseId, string PhaseName) : IDomainEvent public record ProjectPhaseAddedEvent(Guid ProjectId, Guid PhaseId, string PhaseName) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectTaskStatusChangedEvent(Guid SectionId, TaskStatus OldStatus, TaskStatus NewStatus) : IDomainEvent public record ProjectTaskStatusChangedEvent(Guid SectionId, TaskStatus OldStatus, TaskStatus NewStatus) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectSectionAddedEvent(Guid SectionId, Guid TaskId) : IDomainEvent public record ProjectSectionAddedEvent(Guid SectionId, Guid TaskId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent public record ProjectSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent public record ProjectSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record WorkStartedEvent(Guid SectionId, long UserId, DateTime StartTime, string? Notes) : IDomainEvent public record WorkStartedEvent(Guid SectionId, long UserId, DateTime StartTime, string? Notes) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record WorkStoppedEvent(Guid SectionId, long UserId, DateTime StartTime, DateTime EndTime, TimeSpan Duration, string? Notes) : IDomainEvent public record WorkStoppedEvent(Guid SectionId, long UserId, DateTime StartTime, DateTime EndTime, TimeSpan Duration, string? Notes) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record ProjectSectionCompletedEvent(Guid ProjectId, long UserId, TimeSpan TotalTimeSpent, string? Notes) : IDomainEvent public record ProjectSectionCompletedEvent(Guid ProjectId, long UserId, TimeSpan TotalTimeSpent, string? Notes) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record AdditionalTimeAddedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan Hours, string? Reason, long? AddedByUserId) : IDomainEvent public record AdditionalTimeAddedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan Hours, string? Reason, long? AddedByUserId) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record AdditionalTimeRemovedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan RemovedHours) : IDomainEvent public record AdditionalTimeRemovedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan RemovedHours) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }
public record InitialEstimatedTimeUpdatedEvent(Guid ProjectId, TimeSpan OldEstimate, TimeSpan NewEstimate) : IDomainEvent public record InitialEstimatedTimeUpdatedEvent(Guid ProjectId, TimeSpan OldEstimate, TimeSpan NewEstimate) : IDomainEvent
{ {
public DateTime OccurredOn { get; init; } = DateTime.UtcNow; public DateTime OccurredOn { get; init; } = DateTime.Now;
} }

View File

@@ -5,7 +5,6 @@ namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
public interface ITaskSectionActivityRepository:IRepository<Guid,TaskSectionActivity> public interface ITaskSectionActivityRepository:IRepository<Guid,TaskSectionActivity>
{ {
Task<TaskSectionActivity?> GetByIdAsync(Guid id);
Task<List<TaskSectionActivity>> GetBySectionIdAsync(Guid sectionId); Task<List<TaskSectionActivity>> GetBySectionIdAsync(Guid sectionId);
Task<List<TaskSectionActivity>> GetByUserIdAsync(long userId); Task<List<TaskSectionActivity>> GetByUserIdAsync(long userId);
Task<List<TaskSectionActivity>> GetActiveByUserAsync(long userId); Task<List<TaskSectionActivity>> GetActiveByUserAsync(long userId);

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

@@ -5,7 +5,7 @@ namespace GozareshgirProgramManager.Domain._Common;
public interface IRepository<TKey, T> where T:class public interface IRepository<TKey, T> where T:class
{ {
T Get(TKey id); T Get(TKey id);
Task<T?> GetByIdAsync(TKey id); Task<T?> GetByIdAsync(TKey id, CancellationToken cancellationToken = default);
List<T> Get(); List<T> Get();
IQueryable<T> GetQueryable(); IQueryable<T> GetQueryable();
void Create(T entity); void Create(T entity);

View File

@@ -0,0 +1,865 @@
// <auto-generated />
using System;
using GozareshgirProgramManager.Infrastructure.Persistence.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GozareshgirProgramManager.Infrastructure.Migrations
{
[DbContext(typeof(ProgramManagerDbContext))]
[Migration("20251227094008_add phase deploy status and is archived")]
partial class addphasedeploystatusandisarchived
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CheckoutEndDate")
.HasColumnType("datetime2");
b.Property<DateTime>("CheckoutStartDate")
.HasColumnType("datetime2");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<double>("DeductionFromSalary")
.HasColumnType("float");
b.Property<string>("FullName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("MandatoryHours")
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<double>("MonthlySalaryDefined")
.HasColumnType("float");
b.Property<double>("MonthlySalaryPay")
.HasColumnType("float");
b.Property<int>("RemainingHours")
.HasColumnType("int");
b.Property<int>("TotalDaysWorked")
.HasColumnType("int");
b.Property<int>("TotalHoursWorked")
.HasColumnType("int");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Checkouts", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.HasKey("Id");
b.ToTable("Customers", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<Guid>("PhaseId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("PhaseId");
b.HasIndex("SkillId");
b.ToTable("PhaseSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<DateTime?>("PlannedEndDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("PlannedStartDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Projects", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("DeployStatus")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<bool>("IsArchived")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("OrderIndex")
.HasColumnType("int");
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.ToTable("ProjectPhases", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.HasIndex("SkillId");
b.ToTable("ProjectSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("AllocatedTime")
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime?>("DueDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit");
b.Property<bool>("HasTimeOverride")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("OrderIndex")
.HasColumnType("int");
b.Property<Guid>("PhaseId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Priority")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime?>("StartDate")
.HasColumnType("datetime2");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.HasIndex("PhaseId");
b.ToTable("ProjectTasks", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long>("CurrentAssignedUserId")
.HasColumnType("bigint");
b.Property<string>("InitialDescription")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("InitialEstimatedHours")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<long>("OriginalAssignedUserId")
.HasColumnType("bigint");
b.Property<Guid>("SkillId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<Guid>("TaskId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("SkillId");
b.HasIndex("TaskId");
b.ToTable("TaskSections", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndDate")
.HasColumnType("datetime2");
b.Property<string>("EndNotes")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Notes")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<Guid>("SectionId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("StartDate")
.HasColumnType("datetime2");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("SectionId");
b.ToTable("TaskSectionActivities", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime2");
b.Property<long?>("AddedByUserId")
.HasColumnType("bigint");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Hours")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<string>("Reason")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<Guid?>("TaskSectionId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("TaskSectionId");
b.ToTable("TaskSectionAdditionalTimes", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long?>("GozareshgirRoleId")
.HasColumnType("bigint");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.HasKey("Id");
b.ToTable("PmRoles", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("EndSettingDate")
.HasColumnType("datetime2");
b.Property<bool>("HolidayWorking")
.HasColumnType("bit");
b.Property<double>("MonthlySalary")
.HasColumnType("float");
b.Property<DateTime?>("StartSettingDate")
.HasColumnType("datetime2");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("SalaryPaymentSetting", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.HasKey("Id");
b.ToTable("Skills", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<long?>("AccountId")
.HasColumnType("bigint");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Email")
.HasMaxLength(150)
.HasColumnType("nvarchar(150)");
b.Property<string>("FullName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Mobile")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<string>("Password")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("ProfilePhotoPath")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("VerifyCode")
.HasMaxLength(10)
.HasColumnType("nvarchar(10)");
b.HasKey("Id");
b.ToTable("Users", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<DateTime>("ExpiresAt")
.HasColumnType("datetime2");
b.Property<string>("IpAddress")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime?>("RevokedAt")
.HasColumnType("datetime2");
b.Property<string>("Token")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<string>("UserAgent")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("ExpiresAt");
b.HasIndex("Token")
.IsUnique();
b.HasIndex("UserId");
b.ToTable("UserRefreshTokens", (string)null);
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
.WithMany("PhaseSections")
.HasForeignKey("PhaseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Phase");
b.Navigation("Skill");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project")
.WithMany("Phases")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project")
.WithMany("ProjectSections")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany()
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Project");
b.Navigation("Skill");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase")
.WithMany("Tasks")
.HasForeignKey("PhaseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Phase");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill")
.WithMany("Sections")
.HasForeignKey("SkillId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task")
.WithMany("Sections")
.HasForeignKey("TaskId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Skill");
b.Navigation("Task");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section")
.WithMany("Activities")
.HasForeignKey("SectionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Section");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null)
.WithMany("AdditionalTimes")
.HasForeignKey("TaskSectionId");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<int>("Code")
.HasColumnType("int");
b1.Property<long>("RoleId")
.HasColumnType("bigint");
b1.HasKey("Id");
b1.HasIndex("RoleId");
b1.ToTable("PmRolePermissions", (string)null);
b1.WithOwner("Role")
.HasForeignKey("RoleId");
b1.Navigation("Role");
});
b.Navigation("Permissions");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<TimeSpan>("EndShiftOne")
.HasColumnType("time(0)");
b1.Property<TimeSpan>("EndShiftTwo")
.HasColumnType("time(0)");
b1.Property<bool>("HasRestTime")
.HasColumnType("bit");
b1.Property<bool>("HasShiftOne")
.HasColumnType("bit");
b1.Property<bool>("HasShiftTow")
.HasColumnType("bit");
b1.Property<bool>("IsActiveDay")
.HasColumnType("bit");
b1.Property<int>("PersianDayOfWeek")
.HasColumnType("int");
b1.Property<TimeSpan>("RestTime")
.HasColumnType("time(0)");
b1.Property<long>("SalaryPaymentSettingId")
.HasColumnType("bigint");
b1.Property<int>("ShiftDurationInMinutes")
.HasColumnType("int");
b1.Property<TimeSpan>("StartShiftOne")
.HasColumnType("time(0)");
b1.Property<TimeSpan>("StartShiftTwo")
.HasColumnType("time(0)");
b1.HasKey("Id");
b1.HasIndex("SalaryPaymentSettingId");
b1.ToTable("WorkingHours", (string)null);
b1.WithOwner("SalaryPaymentSetting")
.HasForeignKey("SalaryPaymentSettingId");
b1.Navigation("SalaryPaymentSetting");
});
b.Navigation("WorkingHoursList");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 =>
{
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
b1.Property<long>("RoleId")
.HasColumnType("bigint");
b1.Property<long>("UserId")
.HasColumnType("bigint");
b1.HasKey("Id");
b1.HasIndex("UserId");
b1.ToTable("RoleUsers", (string)null);
b1.WithOwner("User")
.HasForeignKey("UserId");
b1.Navigation("User");
});
b.Navigation("RoleUser");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b =>
{
b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User")
.WithMany("RefreshTokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b =>
{
b.Navigation("Phases");
b.Navigation("ProjectSections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b =>
{
b.Navigation("PhaseSections");
b.Navigation("Tasks");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b =>
{
b.Navigation("Sections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b =>
{
b.Navigation("Activities");
b.Navigation("AdditionalTimes");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b =>
{
b.Navigation("Sections");
});
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b =>
{
b.Navigation("RefreshTokens");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GozareshgirProgramManager.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class addphasedeploystatusandisarchived : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "DeployStatus",
table: "ProjectPhases",
type: "nvarchar(30)",
maxLength: 30,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<bool>(
name: "IsArchived",
table: "ProjectPhases",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DeployStatus",
table: "ProjectPhases");
migrationBuilder.DropColumn(
name: "IsArchived",
table: "ProjectPhases");
}
}
}

View File

@@ -179,6 +179,11 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.Property<DateTime>("CreationDate") b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<string>("DeployStatus")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("nvarchar(30)");
b.Property<string>("Description") b.Property<string>("Description")
.HasMaxLength(1000) .HasMaxLength(1000)
.HasColumnType("nvarchar(1000)"); .HasColumnType("nvarchar(1000)");
@@ -189,6 +194,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
b.Property<bool>("HasAssignmentOverride") b.Property<bool>("HasAssignmentOverride")
.HasColumnType("bit"); .HasColumnType("bit");
b.Property<bool>("IsArchived")
.HasColumnType("bit");
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasMaxLength(200) .HasMaxLength(200)

View File

@@ -48,6 +48,9 @@ public class ProjectPhaseMapping : IEntityTypeConfiguration<ProjectPhase>
builder.Property(ph => ph.HasAssignmentOverride) builder.Property(ph => ph.HasAssignmentOverride)
.IsRequired(); .IsRequired();
builder.Property(x => x.DeployStatus)
.HasConversion<string>().HasMaxLength(30);
// Relationship with Project // Relationship with Project
builder.HasOne(ph => ph.Project) builder.HasOne(ph => ph.Project)
.WithMany(p => p.Phases) .WithMany(p => p.Phases)

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

@@ -43,9 +43,9 @@ public class RepositoryBase<TKey, T> : IRepository<TKey, T> where T : class
return _context.Find<T>(id); return _context.Find<T>(id);
} }
public async Task<T?> GetByIdAsync(TKey id) public async Task<T?> GetByIdAsync(TKey id, CancellationToken cancellationToken = default)
{ {
return await _context.Set<T>().FindAsync(id); return await _context.Set<T>().FindAsync([id], cancellationToken);
} }
public List<T> Get() public List<T> Get()

View File

@@ -1,6 +1,9 @@
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.AutoUpdateDeployStatus;
using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject;
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;
@@ -11,6 +14,8 @@ using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectA
using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardList;
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -28,63 +33,68 @@ public class ProjectController : ProgramManagerBaseController
} }
[HttpGet] [HttpGet]
public async Task<ActionResult<OperationResult<GetProjectsListResponse>>> Get([FromQuery]GetProjectsListQuery query) public async Task<ActionResult<OperationResult<GetProjectsListResponse>>> Get(
[FromQuery] GetProjectsListQuery query)
{ {
var res=await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }
[HttpPost] [HttpPost]
public async Task<ActionResult<OperationResult>> Create([FromBody] CreateProjectCommand command) public async Task<ActionResult<OperationResult>> Create([FromBody] CreateProjectCommand command)
{ {
var res=await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
[HttpPut] [HttpPut]
public async Task<ActionResult<OperationResult>> Edit([FromBody] EditProjectCommand command) public async Task<ActionResult<OperationResult>> Edit([FromBody] EditProjectCommand command)
{ {
var res=await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
[HttpDelete] [HttpDelete]
public async Task<ActionResult<OperationResult>> Delete([FromQuery] DeleteProjectCommand command) public async Task<ActionResult<OperationResult>> Delete([FromQuery] DeleteProjectCommand command)
{ {
var res=await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
[HttpGet("assign")] [HttpGet("assign")]
public async Task<ActionResult<OperationResult<GetProjectAssignDetailsResponse>>> GetAssignableProjects(GetProjectAssignDetailsQuery query) public async Task<ActionResult<OperationResult<GetProjectAssignDetailsResponse>>> GetAssignableProjects(
GetProjectAssignDetailsQuery query)
{ {
var res=await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }
[HttpPost("assign")] [HttpPost("assign")]
public async Task<ActionResult<OperationResult>> Assign(AssignProjectCommand command) public async Task<ActionResult<OperationResult>> Assign(AssignProjectCommand command)
{ {
var res=await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
[HttpGet("set-time")] [HttpGet("set-time")]
public async Task<ActionResult<OperationResult<ProjectSetTimeResponse>>> GetSetTimeProjectDetails(ProjectSetTimeDetailsQuery query) public async Task<ActionResult<OperationResult<ProjectSetTimeResponse>>> GetSetTimeProjectDetails(
ProjectSetTimeDetailsQuery query)
{ {
var res=await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }
[HttpPost("set-time")] [HttpPost("set-time")]
public async Task<ActionResult<OperationResult>> SetTimeProject(SetTimeProjectCommand command) public async Task<ActionResult<OperationResult>> SetTimeProject(SetTimeProjectCommand command)
{ {
var res=await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
[HttpPost("change-status")] [HttpPost("change-status")]
public async Task<ActionResult<OperationResult>> ChangeStatus(ChangeStatusSectionCommand command) public async Task<ActionResult<OperationResult>> ChangeStatus(ChangeStatusSectionCommand command)
{ {
var res = await _mediator.Send(command); var res = await _mediator.Send(command);
return res; return res;
} }
@@ -96,11 +106,16 @@ 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;
} }
[HttpGet("board/details")] [HttpGet("board/details")]
public async Task<ActionResult<OperationResult<ProjectBoardDetailResponse>>> GetProjectBoardDetails(Guid id) public async Task<ActionResult<OperationResult<ProjectBoardDetailResponse>>> GetProjectBoardDetails(Guid id)
{ {
@@ -108,4 +123,28 @@ public class ProjectController : ProgramManagerBaseController
var res = await _mediator.Send(query); var res = await _mediator.Send(query);
return res; return res;
} }
[HttpGet("deploy-board")]
public async Task<ActionResult<OperationResult<GetProjectsDeployBoardListResponse>>> GetProjectDeployBoard()
{
// قبل از دریافت دیتا، وضعیت دیپلوی را بر اساس تکمیل شدن تمام سکشن‌ها به‌روزرسانی می‌کنیم
await _mediator.Send(new AutoUpdateDeployStatusCommand());
var request = new GetProjectDeployBoardListQuery();
return await _mediator.Send(request);
}
[HttpGet("deploy-board/details")]
public async Task<ActionResult<OperationResult<ProjectDeployBoardDetailsResponse>>> GetProjectDeployBoardDetails(Guid id)
{
var query = new ProjectDeployBoardDetailsQuery(id);
var res = await _mediator.Send(query);
return res;
}
[HttpPost("deploy-board/change-status")]
public async Task<ActionResult<OperationResult>> ChangeDeployStatus(ChangeDeployStatusProjectCommand command)
{
var res = await _mediator.Send(command);
return res;
}
} }

View File

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

View File

@@ -0,0 +1,15 @@
@page
<h4>Deploy Log</h4>
<pre style="
background:#111;
color:#0f0;
padding:15px;
max-height:600px;
overflow:auto;
font-size:13px;
border-radius:6px;">
</pre>

View File

@@ -2,6 +2,14 @@
@model ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel @model ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel
@{ @{
ViewData["Title"] = "File Upload"; ViewData["Title"] = "File Upload";
<style>
.lineDiv {
width: 100%;
height: 2px;
background-image: linear-gradient(to right, #ffffff, #e5e5e5, #cbcbcb, #b2b2b2, #9a9a9a, #9a9a9a, #9a9a9a, #9a9a9a, #b2b2b2, #cbcbcb, #e5e5e5, #ffffff);
margin: 10px;
}
</style>
} }
<h1>Upload APK File</h1> <h1>Upload APK File</h1>
@@ -60,16 +68,85 @@
</form> </form>
<form style="margin:50px" asp-page-handler="PaymentGateWay" id="11" method="post"> <form style="margin:30px" asp-page-handler="PaymentGateWay" id="11" method="post">
<button type="submit">درگاه پرداخت تستی </button> <button type="submit">درگاه پرداخت تستی </button>
</form> </form>
<div class="lineDiv"></div>
<div class="row m-t-20">
<div class="col-4"></div>
<div class="col-2">
<form asp-page-handler="UploadFrontEnd" id="12" method="post">
<button type="submit"
class="btn btn-danger"
onclick="return confirm('آیا از انتشار نسخه جدید فرانت مطمئن هستید؟');">
🚀 Deploy Next UI
</button>
</form>
</div>
<div class="col-2">
<button type="button" class="btn btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#logModal">
مشاهده لاگ Deploy
</button>
</div>
<div class="col-4"></div>
</div>
<div class="lineDiv"></div>
<div class="modal fade" id="logModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Deploy Log</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<pre id="logContent"
style="background: #111;
color: #0f0;
padding: 15px;
font-size: 13px;
text-align: left;
direction: ltr;">
</pre>
</div>
</div>
</div>
</div>
<form style="margin:20px" asp-page-handler="ContractingPartyToWorkshop" id="13" method="post">
<button class="btn btn-outline-secondary" type="submit"> افزودن آی دی طرف حساب به کارگاه </button>
</form>
@if (ViewData["message"] != null) @if (ViewData["message"] != null)
{ {
<p>@ViewData["message"]</p> <p>@ViewData["message"]</p>
} }
<script>
document.getElementById('logModal')
.addEventListener('show.bs.modal', function () {
fetch('?handler=Log')
.then(r => r.text())
.then(t => {
document.getElementById('logContent').textContent = t;
});
});
</script>
@* <script> @* <script>

View File

@@ -1,36 +1,40 @@
using _0_Framework.Application; using _0_Framework.Application;
using _0_Framework.Application.Enums;
using _0_Framework.Application.FaceEmbedding;
using _0_Framework.Application.PaymentGateway;
using _0_Framework.Domain.CustomizeCheckoutShared.Enums; using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
using AccountManagement.Domain.AccountLeftWorkAgg; using AccountManagement.Domain.AccountLeftWorkAgg;
using AccountMangement.Infrastructure.EFCore; using AccountMangement.Infrastructure.EFCore;
using Company.Domain.AndroidApkVersionAgg; using Company.Domain.AndroidApkVersionAgg;
using Company.Domain.CustomizeCheckoutAgg.ValueObjects; using Company.Domain.CustomizeCheckoutAgg.ValueObjects;
using Company.Domain.CustomizeCheckoutTempAgg.ValueObjects; using Company.Domain.CustomizeCheckoutTempAgg.ValueObjects;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.InstitutionPlanAgg;
using Company.Domain.PaymentTransactionAgg;
using Company.Domain.RewardAgg; using Company.Domain.RewardAgg;
using Company.Domain.RollCallAgg.DomainService; using Company.Domain.RollCallAgg.DomainService;
using CompanyManagement.Infrastructure.Excel.WorkshopsRollCall;
using CompanyManagment.App.Contracts.AndroidApkVersion; using CompanyManagment.App.Contracts.AndroidApkVersion;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.PaymentTransaction;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using CompanyManagment.EFCore; using CompanyManagment.EFCore;
using Hangfire;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Net.Http;
using System.Security.Cryptography.Xml;
using System.Text.Json.Serialization;
using _0_Framework.Application.PaymentGateway;
using Company.Domain.InstitutionContractAgg;
using Company.Domain.InstitutionPlanAgg;
using Company.Domain.PaymentTransactionAgg;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.PaymentTransaction;
using CompanyManagment.App.Contracts.TemporaryClientRegistration;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Parbad; using Parbad;
using Parbad.AspNetCore; using Parbad.AspNetCore;
using Parbad.Gateway.Sepehr; using Parbad.Gateway.Sepehr;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using _0_Framework.Application.Enums; using System.Diagnostics;
using _0_Framework.Application.FaceEmbedding; using System.Net.Http;
using CompanyManagement.Infrastructure.Excel.WorkshopsRollCall; using System.Security.Cryptography.Xml;
using System.Text;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Authentication;
using static ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel2; using static ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel2;
namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
@@ -47,6 +51,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory _httpClientFactory;
private readonly IOnlinePayment _onlinePayment; private readonly IOnlinePayment _onlinePayment;
private readonly IFaceEmbeddingService _faceEmbeddingService; private readonly IFaceEmbeddingService _faceEmbeddingService;
private readonly IAuthHelper _authHelper;
[BindProperty] public IFormFile File { get; set; } [BindProperty] public IFormFile File { get; set; }
@@ -61,13 +66,18 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
[Display(Name = "کد ورژن")] [Display(Name = "کد ورژن")]
public string VersionCode { get; set; } public string VersionCode { get; set; }
/// <summary>
/// لاگ آپلود فرانت
/// </summary>
public string LogContent { get; set; }
[BindProperty] public ApkType SelectedApkType { get; set; } [BindProperty] public ApkType SelectedApkType { get; set; }
[BindProperty] public bool IsForce { get; set; } [BindProperty] public bool IsForce { get; set; }
public IndexModel(IAndroidApkVersionApplication application, IRollCallDomainService rollCallDomainService, public IndexModel(IAndroidApkVersionApplication application, IRollCallDomainService rollCallDomainService,
CompanyContext context, AccountContext accountContext, IHttpClientFactory httpClientFactory, CompanyContext context, AccountContext accountContext, IHttpClientFactory httpClientFactory,
IOptions<AppSettingConfiguration> appSetting, IOptions<AppSettingConfiguration> appSetting,
ITemporaryClientRegistrationApplication clientRegistrationApplication, IOnlinePayment onlinePayment, IFaceEmbeddingService faceEmbeddingService) ITemporaryClientRegistrationApplication clientRegistrationApplication, IOnlinePayment onlinePayment, IFaceEmbeddingService faceEmbeddingService, IAuthHelper authHelper)
{ {
_application = application; _application = application;
_rollCallDomainService = rollCallDomainService; _rollCallDomainService = rollCallDomainService;
@@ -77,6 +87,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
_clientRegistrationApplication = clientRegistrationApplication; _clientRegistrationApplication = clientRegistrationApplication;
_onlinePayment = onlinePayment; _onlinePayment = onlinePayment;
_faceEmbeddingService = faceEmbeddingService; _faceEmbeddingService = faceEmbeddingService;
_authHelper = authHelper;
_paymentGateway = new SepehrPaymentGateway(httpClientFactory); _paymentGateway = new SepehrPaymentGateway(httpClientFactory);
} }
@@ -140,11 +151,34 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
public async Task<IActionResult> OnPostShiftDateNew() public async Task<IActionResult> OnPostShiftDateNew()
{ {
//await UpdateInstitutionContract(); //await UpdateInstitutionContract();
await UpdateFaceEmbeddingNames(); //await UpdateFaceEmbeddingNames();
await SetInstitutionContractSigningType();
ViewData["message"] = "تومام یک"; ViewData["message"] = "تومام یک";
return Page(); return Page();
} }
private async System.Threading.Tasks.Task SetInstitutionContractSigningType()
{
var query = _context.InstitutionContractSet
.Where(x=>x.VerificationStatus != InstitutionContractVerificationStatus.PendingForVerify);
var otpSigned = query.Where(x=>x.VerifierFullName != null && x.LawId != 0).ToList();
foreach (var institutionContract in otpSigned)
{
institutionContract.SetSigningType(InstitutionContractSigningType.OtpBased);
}
var lagacySigned = query.Where(x=>x.VerifierFullName == null && x.LawId == 0).ToList();
foreach (var institutionContract in lagacySigned)
{
institutionContract.SetSigningType(InstitutionContractSigningType.Legacy);
}
await _context.SaveChangesAsync();
}
public async Task<IActionResult> OnPostShiftDateNew2() public async Task<IActionResult> OnPostShiftDateNew2()
{ {
//var startRollCall = new DateTime(2025, 3, 21); //var startRollCall = new DateTime(2025, 3, 21);
@@ -292,6 +326,105 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
//TranslateCode(result?.ErrorCode); //TranslateCode(result?.ErrorCode);
return Page(); return Page();
} }
[DisableConcurrentExecution(timeoutInSeconds: 120)]
public async Task<IActionResult> OnPostUploadFrontEnd(CancellationToken cancellationToken)
{
var validAccountId = _authHelper.CurrentAccountId();
if (validAccountId == 2 || validAccountId == 322)
{
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);
TempData["Message"] = "فرآیند Deploy شروع شد. لاگ را بررسی کنید.";
return RedirectToPage();
}
return Forbid();
}
/// <summary>
/// افزودن آی دی طرف حساب به کارگاه
/// </summary>
/// <returns></returns>
[DisableConcurrentExecution(timeoutInSeconds: 120)]
public async Task<IActionResult> OnPostContractingPartyToWorkshop()
{
var workshops = await _context.Workshops.Where(x => x.ContractingPartyId == 0).ToListAsync();
var worskhopEmployeer = await _context.WorkshopEmployers.Include(x => x.Employer).ToListAsync();
var contractingParties = await _context.PersonalContractingParties.ToListAsync();
foreach (var workshop in workshops)
{
var employers = worskhopEmployeer.Where(x => x.WorkshopId == workshop.id);
var contractingPartyIdList = new List<long>();
foreach (var employer in employers)
{
if (contractingParties.Any(x => x.id == employer.Employer.ContractingPartyId))
{
contractingPartyIdList.Add(employer.Employer.ContractingPartyId);
}
}
if (contractingPartyIdList.Count > 0)
{
if (contractingPartyIdList.Count == 1)
{
workshop.AddContractingPartyId(contractingPartyIdList[0]);
await _context.SaveChangesAsync();
}
else
{
var idDistinct = contractingPartyIdList.Distinct().ToList();
if (idDistinct.Count == 1)
{
workshop.AddContractingPartyId(contractingPartyIdList[0]);
await _context.SaveChangesAsync();
}
}
}
}
ViewData["message"] = "آی دی های طرف حساب اضافه شد";
return Page();
}
/// <summary>
/// دریافت لاگ آپلود فرانت
/// </summary>
/// <returns></returns>
public IActionResult OnGetLog()
{
var validAccountId = _authHelper.CurrentAccountId();
if (validAccountId == 2 || validAccountId == 322)
{
var logPath = @"C:\next-ui\log.txt";
if (!System.IO.File.Exists(logPath))
return Content("Log file not found.");
var content = System.IO.File.ReadAllText(logPath, Encoding.UTF8);
return Content(content);
}
return Content("شما مجاز به دیدن لاگ نیستید");
}
public async System.Threading.Tasks.Task OnGetCallback(string? transid, string? cardnumber, public async System.Threading.Tasks.Task OnGetCallback(string? transid, string? cardnumber,
string? tracking_number, string status) string? tracking_number, string status)
@@ -902,7 +1035,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
x.PersonnelCount, x.PersonnelCount,
x.Price, x.InstitutionContractWorkshopGroupId, x.Price, x.InstitutionContractWorkshopGroupId,
group, group,
x.WorkshopId.Value); x.WorkshopId.Value,x.id);
entity.SetEmployers(x.Employers.Select(e => e.EmployerId).ToList()); entity.SetEmployers(x.Employers.Select(e => e.EmployerId).ToList());
return entity; return entity;

View File

@@ -164,7 +164,7 @@ public class GeneralController : GeneralBaseController
.Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContract); .Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContract);
foreach (var editFinancialInvoiceItem in financialItems) foreach (var editFinancialInvoiceItem in financialItems)
{ {
await _institutionContractApplication.SetPendingWorkflow(editFinancialInvoiceItem.EntityId); await _institutionContractApplication.SetPendingWorkflow(editFinancialInvoiceItem.EntityId,InstitutionContractSigningType.OtpBased);
} }
var financialInstallmentItems = financialInvoice.Items var financialInstallmentItems = financialInvoice.Items
.Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContractInstallment); .Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContractInstallment);
@@ -174,7 +174,7 @@ public class GeneralController : GeneralBaseController
var institutionContractId = var institutionContractId =
await _institutionContractApplication.GetIdByInstallmentId( await _institutionContractApplication.GetIdByInstallmentId(
editFinancialInvoiceItem.EntityId); editFinancialInvoiceItem.EntityId);
await _institutionContractApplication.SetPendingWorkflow(institutionContractId); await _institutionContractApplication.SetPendingWorkflow(institutionContractId,InstitutionContractSigningType.OtpBased);
} }
} }

View File

@@ -70,7 +70,8 @@ public class ParameterBindingConvention : IApplicationModelConvention
{ {
if (selector.AttributeRouteModel?.Template != null) if (selector.AttributeRouteModel?.Template != null)
{ {
if (selector.AttributeRouteModel.Template.Contains($"{{{parameterName}}}", StringComparison.OrdinalIgnoreCase)) if (selector.AttributeRouteModel.Template.Contains($"{{{parameterName}}}", StringComparison.OrdinalIgnoreCase) ||
selector.AttributeRouteModel.Template.Contains($"{{{parameterName}:", StringComparison.OrdinalIgnoreCase))
return true; return true;
} }
} }
@@ -80,7 +81,8 @@ public class ParameterBindingConvention : IApplicationModelConvention
{ {
if (selector.AttributeRouteModel?.Template != null) if (selector.AttributeRouteModel?.Template != null)
{ {
if (selector.AttributeRouteModel.Template.Contains($"{{{parameterName}}}", StringComparison.OrdinalIgnoreCase)) if (selector.AttributeRouteModel.Template.Contains($"{{{parameterName}}}", StringComparison.OrdinalIgnoreCase) ||
selector.AttributeRouteModel.Template.Contains($"{{{parameterName}:", StringComparison.OrdinalIgnoreCase))
return true; return true;
} }
} }