From c8018948c2b467ffbb98c428941a81c984fcfeee Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 16 Oct 2025 11:56:45 +0330 Subject: [PATCH 01/10] feat: add validation to prevent upgrading institution contracts with zero-priced workshops --- .../Repository/InstitutionContractRepository.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index c553896f..ae238e9b 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -2343,6 +2343,11 @@ public class InstitutionContractRepository : RepositoryBase x.CurrentWorkshops) .FirstOrDefaultAsync(x => x.id == institutionContractId); + if (institutionContract.WorkshopGroup.CurrentWorkshops.Any(x=>x.Price == 0)) + { + throw new BadRequestException("این قرارداد قابل ارتقا به صورت ظاهری نیست لطفا به صورت دیتابیسی اقدام به ویرایش کنید"); + } + var workshops = institutionContract.WorkshopGroup.CurrentWorkshops.Select(x => new WorkshopTempViewModel() { Id = x.id, From 7d6b57affdabd06b3b3501609de5aebace318096 Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 18 Oct 2025 16:50:40 +0330 Subject: [PATCH 02/10] feat: make Workshops property public and update CalculateInstallment method visibility --- .../IInstitutionContractApplication.cs | 2 +- .../InstitutionContractApplication.cs | 2 +- .../InstitutionContractRepository.cs | 116 +++++++++++++++--- 3 files changed, 99 insertions(+), 21 deletions(-) diff --git a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs index 9a290f56..fd2d8cfe 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs @@ -240,7 +240,7 @@ public interface IInstitutionContractApplication public class InsitutionContractAmendmentPaymentRequest { - List Workshops { get; set; } + public List Workshops { get; set; } public long InstitutionContractId { get; set; } } diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index c67d29f1..45289281 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -1407,7 +1407,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication return operation.Succcedded(personalContractingParty); } - private List CalculateInstallment(double amount, int installmentCount, + public static List CalculateInstallment(double amount, int installmentCount, string loanStartDate, bool getRounded) { int day = Convert.ToInt32(loanStartDate.Substring(8, 2)); diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index ae238e9b..ea5fe182 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Drawing; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; @@ -2235,7 +2236,7 @@ public class InstitutionContractRepository : RepositoryBase x.ContractingPartyId == contractingParty.id)) { @@ -2343,9 +2343,10 @@ public class InstitutionContractRepository : RepositoryBase x.CurrentWorkshops) .FirstOrDefaultAsync(x => x.id == institutionContractId); - if (institutionContract.WorkshopGroup.CurrentWorkshops.Any(x=>x.Price == 0)) + if (institutionContract.WorkshopGroup.CurrentWorkshops.Any(x => x.Price == 0)) { - throw new BadRequestException("این قرارداد قابل ارتقا به صورت ظاهری نیست لطفا به صورت دیتابیسی اقدام به ویرایش کنید"); + throw new BadRequestException( + "این قرارداد قابل ارتقا به صورت ظاهری نیست لطفا به صورت دیتابیسی اقدام به ویرایش کنید"); } var workshops = institutionContract.WorkshopGroup.CurrentWorkshops.Select(x => new WorkshopTempViewModel() @@ -2363,7 +2364,6 @@ public class InstitutionContractRepository : RepositoryBase GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request) + public async Task GetAmendmentPaymentDetails( + InsitutionContractAmendmentPaymentRequest request) { - var institutionContract =await _context.InstitutionContractSet + var institutionContract = await _context.InstitutionContractSet .Include(x => x.WorkshopGroup) .ThenInclude(x => x.CurrentWorkshops) .FirstOrDefaultAsync(x => x.id == request.InstitutionContractId); @@ -2383,10 +2384,86 @@ public class InstitutionContractRepository : RepositoryBase x.ContractAndCheckoutInPerson); + if (!haContractInPerson) + { + if (request.Workshops.Any(x => x.ContractAndCheckoutInPerson)) + { + throw new BadRequestException("برای قرارداد آنلاین نمیتوان سرویس حضوری انتخاب کرد"); + } + } + + var pc = new PersianCalendar(); + + int startYear = pc.GetYear(amendmentStart); + int startMonth = pc.GetMonth(amendmentStart); + int startDay = pc.GetDayOfMonth(amendmentStart); + + int endYear = pc.GetYear(amendmentEnd); + int endMonth = pc.GetMonth(amendmentEnd); + int endDay = pc.GetDayOfMonth(amendmentEnd); + + // اختلاف خام ماه‌ها + int monthDiff = (endYear - startYear) * 12 + (endMonth - startMonth); + + // اگر حتی چند روز از ماه بعدی هم گذشته بود → رند به بالا + if (endDay > startDay) + monthDiff++; + + var sumOneMonth = request.Workshops.Sum(x => x.WorkshopServicesAmount); + //TODO:مقدار جمع مبالغ باید از دیتابیس موقت گرفته شود. + + var baseAmount = monthDiff * sumOneMonth; + var tax = baseAmount*0.10; + var totalPayment = tax+baseAmount; + + + var res = new InsitutionContractAmendmentPaymentResponse() + { + ContractStart = amendmentStart.ToFarsi(), + ContractEnd = amendmentEnd.ToFarsi(), + OneMonthAmount = sumOneMonth.ToMoney(), + TotalAmount = baseAmount.ToMoney(), + }; + + res.OneTime = new InstitutionContractPaymentOneTimeViewModel() + { + TotalAmount = baseAmount.ToMoney(), + PaymentAmount = totalPayment.ToMoney(), + Tax = tax.ToMoney() + }; + + if (haContractInPerson) + { + var installment = InstitutionMonthlyInstallmentCaculation(monthDiff,totalPayment, amendmentStart.ToFarsi()); + var firstInstallment = new MonthlyInstallment() + { + InstallmentAmountStr = installment.First().InstallmentAmountStr, + InstallmentCounter = installment.First().InstallmentCounter, + InstalmentDate = amendmentStart.ToFarsi() + }; + var lastInstallment = new MonthlyInstallment() + { + InstallmentAmountStr = installment.Last().InstallmentAmountStr, + InstallmentCounter = installment.Last().InstallmentCounter, + InstalmentDate = installment.Last().InstalmentDate + }; + installment.Remove(installment.First()); + installment.Remove(installment.Last()); + installment.Insert(0, firstInstallment); + installment.Add(lastInstallment); + res.Monthly = new InstitutionContractPaymentMonthlyViewModel() + { + Installments = installment, + TotalAmount = baseAmount.ToMoney(), + PaymentAmount = totalPayment.ToMoney(), + Tax = tax.ToMoney() + + }; + + } + return res; } private InstitutionContractExtensionPaymentResponse CalculateInPersonPayment( @@ -2411,7 +2488,7 @@ public class InstitutionContractRepository : RepositoryBase InstitutionMonthlyInstallmentCaculation(InstitutionContractDuration duration, + public static List InstitutionMonthlyInstallmentCaculation(int duration, double monthlyTotalPaymentDouble, string installmentstart) { @@ -2501,7 +2578,7 @@ public class InstitutionContractRepository : RepositoryBase(); - int instalmentCount = (int)duration; + int instalmentCount = duration; var instalmentAmount = monthlyTotalPaymentDouble / instalmentCount; int currentInstallmentStartDay = int.Parse(installmentstart.Substring(8, 2)); bool endOfMonth = currentInstallmentStartDay == 31; @@ -2561,6 +2638,7 @@ public class InstitutionContractRepository : RepositoryBase Date: Mon, 20 Oct 2025 13:13:43 +0330 Subject: [PATCH 03/10] feat: add temporary workshop management for institution contract amendments --- .../IInstitutionContractRepository.cs | 4 +- .../InstitutionContractAmendmentTemp.cs | 114 +++++++++++++++++ .../IInstitutionContractApplication.cs | 23 +--- ...situtionContractAmendmentPaymentRequest.cs | 10 ++ ...itutionContractAmendmentPaymentResponse.cs | 11 ++ ...nContractAmendmentTempWorkshopViewModel.cs | 64 ++++++++++ .../InstitutionContractApplication.cs | 10 ++ .../TemporaryClientRegistrationApplication.cs | 2 +- .../InstitutionContractRepository.cs | 120 +++++++++++++++--- 9 files changed, 320 insertions(+), 38 deletions(-) create mode 100644 Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs create mode 100644 CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs create mode 100644 CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentResponse.cs create mode 100644 CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractAmendmentTempWorkshopViewModel.cs diff --git a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs index 69f1a430..d0b3d8c6 100644 --- a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs +++ b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs @@ -65,11 +65,13 @@ public interface IInstitutionContractRepository : IRepository GetAmendmentWorkshops(long institutionContractId); Task GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request); + Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); #endregion + Task RemoveAmendmentWorkshops(Guid workshopTempId); } \ No newline at end of file diff --git a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs new file mode 100644 index 00000000..d60379e0 --- /dev/null +++ b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using MongoDB.Bson.Serialization.Attributes; + +namespace Company.Domain.InstitutionContractAmendmentTempAgg; + +public class InstitutionContractAmendmentTemp +{ + public InstitutionContractAmendmentTemp(List prevWorkshops, + long institutionContractId) + { + Id = Guid.NewGuid(); + PrevWorkshops = prevWorkshops; + NewWorkshops = prevWorkshops; + InstitutionContractId = institutionContractId; + } + [BsonId] + public Guid Id { get; private set; } + public List PrevWorkshops { get; private set; } + public List NewWorkshops { get; private set; } + public long InstitutionContractId { get; private set; } + + +} +public class InstitutionContractAmendmentTempWorkshop +{ + public InstitutionContractAmendmentTempWorkshop(string workshopName, int countPerson, bool contractAndCheckout, bool contractAndCheckoutInPerson, + bool insurance, bool insuranceInPerson, + bool rollCall,bool rollCallInPerson, bool customizeCheckout,double price,long workshopId,long currentWorkshopId, string priceStr) + { + Id = Guid.NewGuid(); + WorkshopName = workshopName; + CountPerson = countPerson; + ContractAndCheckout = contractAndCheckout; + Insurance = insurance; + RollCall = rollCall; + CustomizeCheckout = customizeCheckout; + ContractAndCheckoutInPerson = contractAndCheckoutInPerson; + InsuranceInPerson = insuranceInPerson; + RollCallInPerson = rollCallInPerson; + Price = price; + WorkshopId = workshopId; + CurrentWorkshopId = currentWorkshopId; + PriceStr = priceStr; + } + public Guid Id { get; set; } + + public long CurrentWorkshopId { get; private set; } + public long WorkshopId { get; set; } + + /// + /// نام کارگاه + /// + public string WorkshopName { get; private set; } + + /// + /// تعداد پرسنل + /// + public int CountPerson { get; private set; } + + + #region ServiceSelection + + /// + /// قرارداد و تصفیه + /// + public bool ContractAndCheckout { get; private set; } + + /// + /// بیمه + /// + public bool Insurance { get; private set; } + + /// + /// حضورغباب + /// + public bool RollCall { get; private set; } + + public bool RollCallInPerson { get; set; } + + /// + /// فیش غیر رسمی + /// + public bool CustomizeCheckout { get;private set; } + + /// + /// خدمات حضوری قرداد و تصفیه + /// + public bool ContractAndCheckoutInPerson { get; private set; } + + /// + /// خدمات حضوری بیمه + /// + public bool InsuranceInPerson { get; private set; } + + public double Price{ get; set; } + public string PriceStr { get; set; } + + #endregion + + public void Edit(string workshopName, int countPerson, bool contractAndCheckout, bool contractAndCheckoutInPerson, + bool insurance, bool insuranceInPerson, bool rollCall, bool customizeCheckout) + { + WorkshopName = workshopName; + CountPerson = countPerson; + ContractAndCheckout = contractAndCheckout; + Insurance = insurance; + RollCall = rollCall; + CustomizeCheckout = customizeCheckout; + ContractAndCheckoutInPerson = contractAndCheckoutInPerson; + InsuranceInPerson = insuranceInPerson; + + } +} \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs index fd2d8cfe..5a7edc00 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs @@ -232,34 +232,21 @@ public interface IInstitutionContractApplication #region Upgrade (Amendment) Task GetAmendmentWorkshops(long institutionContractId); + Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); + Task RemoveAmendmentWorkshops(Guid workshopTempId); Task GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request); - #endregion } -public class InsitutionContractAmendmentPaymentRequest -{ - public List Workshops { get; set; } - public long InstitutionContractId { get; set; } -} - -public class InsitutionContractAmendmentPaymentResponse -{ - public InstitutionContractPaymentOneTimeViewModel OneTime { get; set; } - public InstitutionContractPaymentMonthlyViewModel Monthly { get; set; } - public string ContractStart { get; set; } - public string ContractEnd { get; set; } - public string OneMonthAmount { get; set; } - public string TotalAmount { get; set; } -} - public class InstitutionContractAmendmentWorkshopsResponse { /// /// /// - public List Workshops { get; set; } + public List Workshops { get; set; } + + public Guid TempId { get; set; } } diff --git a/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs new file mode 100644 index 00000000..0b9bc8aa --- /dev/null +++ b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using CompanyManagment.App.Contracts.TemporaryClientRegistration; + +namespace CompanyManagment.App.Contracts.InstitutionContract; + +public class InsitutionContractAmendmentPaymentRequest +{ + public List Workshops { get; set; } + public long InstitutionContractId { get; set; } +} \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentResponse.cs b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentResponse.cs new file mode 100644 index 00000000..f6a90dc4 --- /dev/null +++ b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentResponse.cs @@ -0,0 +1,11 @@ +namespace CompanyManagment.App.Contracts.InstitutionContract; + +public class InsitutionContractAmendmentPaymentResponse +{ + public InstitutionContractPaymentOneTimeViewModel OneTime { get; set; } + public InstitutionContractPaymentMonthlyViewModel Monthly { get; set; } + public string ContractStart { get; set; } + public string ContractEnd { get; set; } + public string OneMonthAmount { get; set; } + public string TotalAmount { get; set; } +} \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractAmendmentTempWorkshopViewModel.cs b/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractAmendmentTempWorkshopViewModel.cs new file mode 100644 index 00000000..242d6287 --- /dev/null +++ b/CompanyManagment.App.Contracts/InstitutionContract/InstitutionContractAmendmentTempWorkshopViewModel.cs @@ -0,0 +1,64 @@ +using System; + +namespace CompanyManagment.App.Contracts.InstitutionContract; + +public class InstitutionContractAmendmentTempWorkshopViewModel +{ + public Guid TempId { get; set; } + + public Guid WorkshopTempId { get; set; } + + public long CurrentWorkshopId { get; set; } + + public long WorkshopId { get; set; } + + /// + /// نام کارگاه + /// + public string WorkshopName { get; set; } + + /// + /// تعداد پرسنل + /// + public int CountPerson { get; set; } + + + #region ServiceSelection + + /// + /// قرارداد و تصفیه + /// + public bool ContractAndCheckout { get; set; } + + /// + /// بیمه + /// + public bool Insurance { get; set; } + + /// + /// حضورغباب + /// + public bool RollCall { get; set; } + + public bool RollCallInPerson { get; set; } + + /// + /// فیش غیر رسمی + /// + public bool CustomizeCheckout { get; set; } + + /// + /// خدمات حضوری قرداد و تصفیه + /// + public bool ContractAndCheckoutInPerson { get; set; } + + /// + /// خدمات حضوری بیمه + /// + public bool InsuranceInPerson { get; set; } + + public double Price{ get; set; } + public string PriceStr{ get; set; } + + #endregion +} \ No newline at end of file diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index 45289281..40df4fa9 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -1307,6 +1307,16 @@ public class InstitutionContractApplication : IInstitutionContractApplication return await _institutionContractRepository.GetAmendmentWorkshops(institutionContractId); } + public async Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request) + { + return await _institutionContractRepository.InsertAmendmentTempWorkshops(request); + } + + public Task RemoveAmendmentWorkshops(Guid workshopTempId) + { + return _institutionContractRepository.RemoveAmendmentWorkshops(workshopTempId); + } + public Task GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request) { return _institutionContractRepository.GetAmendmentPaymentDetails(request); diff --git a/CompanyManagment.Application/TemporaryClientRegistrationApplication.cs b/CompanyManagment.Application/TemporaryClientRegistrationApplication.cs index b376875f..fb81f9d6 100644 --- a/CompanyManagment.Application/TemporaryClientRegistrationApplication.cs +++ b/CompanyManagment.Application/TemporaryClientRegistrationApplication.cs @@ -674,7 +674,7 @@ public class TemporaryClientRegistrationApplication : ITemporaryClientRegistrati result.MonthlyValueAddedTaxStr= tenPercent.ToMoney(); var monthlyTotalPaymentDouble = sumOfWorkshopsPaymentDouble + tenPercent; result.MonthlyTotalPaymentStr = monthlyTotalPaymentDouble.ToMoney(); - var installmentList = InstitutionContractRepository.InstitutionMonthlyInstallmentCaculation(duration, monthlyTotalPaymentDouble, installmentstart); + var installmentList = InstitutionContractRepository.InstitutionMonthlyInstallmentCaculation((int)duration, monthlyTotalPaymentDouble, installmentstart); #endregion diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index ea5fe182..3a48708d 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -17,6 +17,7 @@ using Company.Domain.empolyerAgg; using Company.Domain.FinancialStatmentAgg; using Company.Domain.FinancialTransactionAgg; using Company.Domain.InstitutionContractAgg; +using Company.Domain.InstitutionContractAmendmentTempAgg; using Company.Domain.InstitutionContractContactInfoAgg; using Company.Domain.InstitutionContractExtensionTempAgg; using Company.Domain.InstitutionPlanAgg; @@ -43,6 +44,7 @@ public class InstitutionContractRepository : RepositoryBase _institutionExtensionTemp; + private readonly IMongoCollection _institutionAmendmentTemp; private readonly IPlanPercentageRepository _planPercentageRepository; private readonly ISmsService _smsService; @@ -57,6 +59,8 @@ public class InstitutionContractRepository : RepositoryBase("InstitutionContractExtensionTemp"); + _institutionAmendmentTemp = + database.GetCollection("InstitutionContractAmendmentTemp"); } public EditInstitutionContract GetDetails(long id) @@ -2342,33 +2346,52 @@ public class InstitutionContractRepository : RepositoryBase x.WorkshopGroup) .ThenInclude(x => x.CurrentWorkshops) .FirstOrDefaultAsync(x => x.id == institutionContractId); - + if (institutionContract.WorkshopGroup.CurrentWorkshops.Any(x => x.Price == 0)) { throw new BadRequestException( "این قرارداد قابل ارتقا به صورت ظاهری نیست لطفا به صورت دیتابیسی اقدام به ویرایش کنید"); } - var workshops = institutionContract.WorkshopGroup.CurrentWorkshops.Select(x => new WorkshopTempViewModel() - { - Id = x.id, - ContractAndCheckout = x.Services.Contract, - ContractAndCheckoutInPerson = x.Services.ContractInPerson, - CustomizeCheckout = x.Services.CustomizeCheckout, - CountPerson = x.PersonnelCount, - Insurance = x.Services.Insurance, - InsuranceInPerson = x.Services.InsuranceInPerson, - RollCall = x.Services.RollCall, - WorkshopName = x.WorkshopName, - WorkshopServicesAmountStr = x.Price.ToMoney(), - WorkshopServicesAmount = x.Price, - WorkshopId = x.WorkshopId ?? 0, - RollCallInPerson = x.Services.RollCallInPerson, - }).ToList(); + var workshops = institutionContract.WorkshopGroup.CurrentWorkshops + .Select(x => new InstitutionContractAmendmentTempWorkshop(x.WorkshopName,x.PersonnelCount, + x.Services.Contract,x.Services.ContractInPerson,x.Services.Insurance, + x.Services.InsuranceInPerson,x.Services.RollCall,x.Services.RollCallInPerson, + x.Services.CustomizeCheckout,x.Price, + x.WorkshopId??0,x.id,x.Price.ToMoney())).ToList(); + + + + var temp = new InstitutionContractAmendmentTemp(workshops, institutionContractId); + + await _institutionAmendmentTemp.InsertOneAsync(temp); + + var prevWorkshops = workshops.Select(x => + new InstitutionContractAmendmentTempWorkshopViewModel() + { + WorkshopName = x.WorkshopName, + CountPerson = x.CountPerson, + ContractAndCheckout = x.ContractAndCheckout, + ContractAndCheckoutInPerson = x.ContractAndCheckoutInPerson, + Insurance = x.Insurance, + InsuranceInPerson = x.InsuranceInPerson, + RollCall = x.RollCall, + RollCallInPerson = x.RollCallInPerson, + CustomizeCheckout = x.CustomizeCheckout, + PriceStr = x.PriceStr, + Price = x.Price, + WorkshopId = x.WorkshopId, + WorkshopTempId = x.Id, + CurrentWorkshopId = x.CurrentWorkshopId, + TempId =temp.Id + }) + .ToList(); var res = new InstitutionContractAmendmentWorkshopsResponse() { - Workshops = workshops + Workshops = prevWorkshops, + TempId = temp.Id }; + return res; } @@ -2466,6 +2489,67 @@ public class InstitutionContractRepository : RepositoryBase InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request) + { + var amendmentTemp =await _institutionAmendmentTemp + .Find(x=> x.Id == request.TempId).FirstOrDefaultAsync(); + + if (amendmentTemp == null) + throw new BadRequestException("دیتای وارد شده نامعتبر است"); + + var workshopTemp = amendmentTemp.NewWorkshops + .FirstOrDefault(x => x.Id == request.WorkshopTempId); + + if (workshopTemp == null) + { + var newWorkshopTemp = new InstitutionContractAmendmentTempWorkshop(request.WorkshopName, + request.CountPerson, + request.ContractAndCheckout, request.ContractAndCheckoutInPerson, + request.Insurance, request.InsuranceInPerson, + request.RollCall, request.RollCallInPerson, + request.CustomizeCheckout, request.Price, + request.WorkshopId,0,request.PriceStr); + + amendmentTemp.NewWorkshops.Add(newWorkshopTemp); + + await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); + + return newWorkshopTemp.Id; + } + + amendmentTemp.NewWorkshops.Remove(workshopTemp); + + workshopTemp.Edit(request.WorkshopName, request.CountPerson, + request.ContractAndCheckout, request.ContractAndCheckoutInPerson, + request.Insurance, request.InsuranceInPerson, + request.RollCall, + request.CustomizeCheckout); + + amendmentTemp.NewWorkshops.Add(workshopTemp); + + await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); + return workshopTemp.Id; + } + + public async Task RemoveAmendmentWorkshops(Guid workshopTempId) + { + var amendmentTemp = await _institutionAmendmentTemp.Find(x => x.NewWorkshops.Any(w => w.Id == workshopTempId)) + .FirstOrDefaultAsync(); + if (amendmentTemp == null) + throw new BadRequestException("دیتای وارد شده نامعتبر است"); + var workshopTemp = amendmentTemp.NewWorkshops.FirstOrDefault(x => x.Id == workshopTempId); + if (workshopTemp == null) + throw new BadRequestException("دیتای وارد شده نامعتبر است"); + + if (workshopTemp.CurrentWorkshopId!=0) + throw new BadRequestException("شما نمی توانید این کارگاه را حذف کنید زیرا در قرارداد اصلی وجود دارد"); + + amendmentTemp.NewWorkshops.Remove(workshopTemp); + + await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); + + } + private InstitutionContractExtensionPaymentResponse CalculateInPersonPayment( InstitutionContractExtensionPlanDetail selectedPlan, double baseAmount, double tenPercent, InstitutionContractDuration duration) From acdd7de4f68644994e121d680f59e945b600bc16 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 11:02:10 +0330 Subject: [PATCH 04/10] feat: update InsertAmendmentTempWorkshops method to return detailed response and refactor related classes --- .../IInstitutionContractRepository.cs | 2 +- .../InstitutionContract.cs | 4 +- .../InstitutionContractAmendmentTemp.cs | 83 +++++++++---- .../IInstitutionContractApplication.cs | 8 +- ...situtionContractAmendmentPaymentRequest.cs | 4 +- .../InstitutionContractApplication.cs | 2 +- .../InstitutionContractRepository.cs | 117 ++++++++++++------ 7 files changed, 152 insertions(+), 68 deletions(-) diff --git a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs index d0b3d8c6..e4970d7b 100644 --- a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs +++ b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs @@ -70,7 +70,7 @@ public interface IInstitutionContractRepository : IRepository GetAmendmentWorkshops(long institutionContractId); Task GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request); - Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); + Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); #endregion Task RemoveAmendmentWorkshops(Guid workshopTempId); diff --git a/Company.Domain/InstitutionContractAgg/InstitutionContract.cs b/Company.Domain/InstitutionContractAgg/InstitutionContract.cs index 1193023d..f0770dab 100644 --- a/Company.Domain/InstitutionContractAgg/InstitutionContract.cs +++ b/Company.Domain/InstitutionContractAgg/InstitutionContract.cs @@ -252,6 +252,7 @@ public class InstitutionContract : EntityBase public class InstitutionContractAmendment : EntityBase { + private InstitutionContractAmendment(){} public InstitutionContractAmendment(long institutionContractId, InstitutionContract institutionContract, List installments, double amount, bool hasInstallment, InstitutionContractAmendmentChange amendmentChange, long lawId) @@ -285,7 +286,8 @@ public class InstitutionContractAmendment : EntityBase public class InstitutionContractAmendmentChange : EntityBase { - private InstitutionContractAmendmentChange(long institutionContractAmendmentId, + private InstitutionContractAmendmentChange(){} + public InstitutionContractAmendmentChange(long institutionContractAmendmentId, InstitutionContractAmendment institutionContractAmendment, InstitutionContractAmendmentChangeType changeType, DateTime changeDateGr, bool? hasRollCallPlan, bool? hasCustomizeCheckoutPlan, bool? hasContractPlan, bool? hasContractPlanInPerson, bool? hasInsurancePlan, bool? hasInsurancePlanInPerson, int? personnelCount, diff --git a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs index d60379e0..02925e68 100644 --- a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs +++ b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs @@ -1,32 +1,65 @@ using System; using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; namespace Company.Domain.InstitutionContractAmendmentTempAgg; public class InstitutionContractAmendmentTemp { - public InstitutionContractAmendmentTemp(List prevWorkshops, + public InstitutionContractAmendmentTemp(List prevWorkshops, long institutionContractId) { Id = Guid.NewGuid(); PrevWorkshops = prevWorkshops; - NewWorkshops = prevWorkshops; + NewWorkshops = prevWorkshops.Select(x=> new InstitutionContractAmendmentTempNewWorkshop( + x.WorkshopName, x.CountPerson, x.ContractAndCheckout, x.ContractAndCheckoutInPerson, x.Insurance, + x.InsuranceInPerson, x.RollCall, x.RollCallInPerson, x.CustomizeCheckout, x.Price, x.WorkshopId, + x.CurrentWorkshopId, 0)).ToList(); InstitutionContractId = institutionContractId; } - [BsonId] - public Guid Id { get; private set; } - public List PrevWorkshops { get; private set; } - public List NewWorkshops { get; private set; } + + [BsonId] public Guid Id { get; private set; } + public List PrevWorkshops { get; private set; } + public List NewWorkshops { get; private set; } public long InstitutionContractId { get; private set; } - - } -public class InstitutionContractAmendmentTempWorkshop + +public class InstitutionContractAmendmentTempNewWorkshop : InstitutionContractAmendmentTempPrevWorkshop { - public InstitutionContractAmendmentTempWorkshop(string workshopName, int countPerson, bool contractAndCheckout, bool contractAndCheckoutInPerson, + public InstitutionContractAmendmentTempNewWorkshop(string workshopName, int countPerson, bool contractAndCheckout, + bool contractAndCheckoutInPerson, bool insurance, bool insuranceInPerson, bool rollCall, bool rollCallInPerson, + bool customizeCheckout, double price, long workshopId, long currentWorkshopId,double priceDifference) : base( + workshopName, countPerson, contractAndCheckout, contractAndCheckoutInPerson, insurance, insuranceInPerson, + rollCall, rollCallInPerson, customizeCheckout, price, workshopId, currentWorkshopId) + { + PriceDifference = priceDifference; + } + + /// + /// مبلغ اختلاف کارگاه جدید با کارگاه قبلی(مبلغ اصلی ارتقاء) + /// + public double PriceDifference { get; private set; } + + + public void Edit(string workshopName, int countPerson, bool contractAndCheckout, + bool contractAndCheckoutInPerson, + bool insurance, bool insuranceInPerson, bool rollCall, bool customizeCheckout, + double price,double priceDifference) + { + base.Edit(workshopName, countPerson, contractAndCheckout, contractAndCheckoutInPerson, insurance, + insuranceInPerson, rollCall, customizeCheckout, price); + PriceDifference = priceDifference; + } +} + +public class InstitutionContractAmendmentTempPrevWorkshop +{ + public InstitutionContractAmendmentTempPrevWorkshop(string workshopName, int countPerson, bool contractAndCheckout, + bool contractAndCheckoutInPerson, bool insurance, bool insuranceInPerson, - bool rollCall,bool rollCallInPerson, bool customizeCheckout,double price,long workshopId,long currentWorkshopId, string priceStr) + bool rollCall, bool rollCallInPerson, bool customizeCheckout, double price, long workshopId, + long currentWorkshopId) { Id = Guid.NewGuid(); WorkshopName = workshopName; @@ -41,8 +74,8 @@ public class InstitutionContractAmendmentTempWorkshop Price = price; WorkshopId = workshopId; CurrentWorkshopId = currentWorkshopId; - PriceStr = priceStr; } + public Guid Id { get; set; } public long CurrentWorkshopId { get; private set; } @@ -56,50 +89,50 @@ public class InstitutionContractAmendmentTempWorkshop /// /// تعداد پرسنل /// - public int CountPerson { get; private set; } - - + public int CountPerson { get; private set; } + + #region ServiceSelection /// /// قرارداد و تصفیه /// - public bool ContractAndCheckout { get; private set; } + public bool ContractAndCheckout { get; private set; } /// /// بیمه /// - public bool Insurance { get; private set; } + public bool Insurance { get; private set; } /// /// حضورغباب /// - public bool RollCall { get; private set; } + public bool RollCall { get; private set; } public bool RollCallInPerson { get; set; } /// /// فیش غیر رسمی /// - public bool CustomizeCheckout { get;private set; } + public bool CustomizeCheckout { get; private set; } /// /// خدمات حضوری قرداد و تصفیه /// - public bool ContractAndCheckoutInPerson { get; private set; } + public bool ContractAndCheckoutInPerson { get; private set; } /// /// خدمات حضوری بیمه /// - public bool InsuranceInPerson { get; private set; } + public bool InsuranceInPerson { get; private set; } - public double Price{ get; set; } - public string PriceStr { get; set; } + public double Price { get; private set; } #endregion public void Edit(string workshopName, int countPerson, bool contractAndCheckout, bool contractAndCheckoutInPerson, - bool insurance, bool insuranceInPerson, bool rollCall, bool customizeCheckout) + bool insurance, bool insuranceInPerson, bool rollCall, bool customizeCheckout, + double price) { WorkshopName = workshopName; CountPerson = countPerson; @@ -109,6 +142,6 @@ public class InstitutionContractAmendmentTempWorkshop CustomizeCheckout = customizeCheckout; ContractAndCheckoutInPerson = contractAndCheckoutInPerson; InsuranceInPerson = insuranceInPerson; - + Price = price; } } \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs index 5a7edc00..6435c525 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/IInstitutionContractApplication.cs @@ -232,13 +232,19 @@ public interface IInstitutionContractApplication #region Upgrade (Amendment) Task GetAmendmentWorkshops(long institutionContractId); - Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); + Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request); Task RemoveAmendmentWorkshops(Guid workshopTempId); Task GetAmendmentPaymentDetails(InsitutionContractAmendmentPaymentRequest request); #endregion } +public class InsertAmendmentTempWorkshopResponse +{ + public Guid WorkshopTempId { get; set; } + public string Amount { get; set; } +} + public class InstitutionContractAmendmentWorkshopsResponse { /// diff --git a/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs index 0b9bc8aa..c1444835 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/InsitutionContractAmendmentPaymentRequest.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using CompanyManagment.App.Contracts.TemporaryClientRegistration; @@ -5,6 +6,5 @@ namespace CompanyManagment.App.Contracts.InstitutionContract; public class InsitutionContractAmendmentPaymentRequest { - public List Workshops { get; set; } - public long InstitutionContractId { get; set; } + public Guid TempId { get; set; } } \ No newline at end of file diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index 40df4fa9..f303ffa4 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -1307,7 +1307,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication return await _institutionContractRepository.GetAmendmentWorkshops(institutionContractId); } - public async Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request) + public async Task InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request) { return await _institutionContractRepository.InsertAmendmentTempWorkshops(request); } diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 3a48708d..d96e1aa9 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -2354,11 +2354,11 @@ public class InstitutionContractRepository : RepositoryBase new InstitutionContractAmendmentTempWorkshop(x.WorkshopName,x.PersonnelCount, + .Select(x => new InstitutionContractAmendmentTempPrevWorkshop(x.WorkshopName,x.PersonnelCount, x.Services.Contract,x.Services.ContractInPerson,x.Services.Insurance, x.Services.InsuranceInPerson,x.Services.RollCall,x.Services.RollCallInPerson, x.Services.CustomizeCheckout,x.Price, - x.WorkshopId??0,x.id,x.Price.ToMoney())).ToList(); + x.WorkshopId??0,x.id)).ToList(); @@ -2378,7 +2378,7 @@ public class InstitutionContractRepository : RepositoryBase GetAmendmentPaymentDetails( InsitutionContractAmendmentPaymentRequest request) { - var institutionContract = await _context.InstitutionContractSet - .Include(x => x.WorkshopGroup) - .ThenInclude(x => x.CurrentWorkshops) - .FirstOrDefaultAsync(x => x.id == request.InstitutionContractId); - if (institutionContract == null) - throw new NotFoundException("قرارداد مالی یافت نشد"); + var institutionContractAmendmentTemp = await _institutionAmendmentTemp + .Find(x=>x.Id == request.TempId) + .FirstOrDefaultAsync(); + if (institutionContractAmendmentTemp == null) + throw new NotFoundException("دیتای وارد شده نامعتبر است"); var amendmentStart = DateTime.Now; + + var institutionContract = await _context.InstitutionContractSet + .Include(x=>x.WorkshopGroup) + .ThenInclude(x=>x.CurrentWorkshops) + .FirstOrDefaultAsync(x => x.id == institutionContractAmendmentTemp.InstitutionContractId); + + if (institutionContract == null) + throw new NotFoundException("قرارداد مؤسسه یافت نشد"); + var amendmentEnd = institutionContract.ContractEndGr; - var haContractInPerson = request.Workshops.Any(x => x.ContractAndCheckoutInPerson); + var haContractInPerson = institutionContract.WorkshopGroup.CurrentWorkshops + .Any(x => x.Services.ContractInPerson); if (!haContractInPerson) { - if (request.Workshops.Any(x => x.ContractAndCheckoutInPerson)) + if (institutionContractAmendmentTemp.NewWorkshops.Any(x => x.ContractAndCheckoutInPerson)) { throw new BadRequestException("برای قرارداد آنلاین نمیتوان سرویس حضوری انتخاب کرد"); } @@ -2434,8 +2443,7 @@ public class InstitutionContractRepository : RepositoryBase startDay) monthDiff++; - var sumOneMonth = request.Workshops.Sum(x => x.WorkshopServicesAmount); - //TODO:مقدار جمع مبالغ باید از دیتابیس موقت گرفته شود. + var sumOneMonth = institutionContractAmendmentTemp.NewWorkshops.Sum(x => x.PriceDifference); var baseAmount = monthDiff * sumOneMonth; var tax = baseAmount*0.10; @@ -2460,22 +2468,30 @@ public class InstitutionContractRepository : RepositoryBase InsertAmendmentTempWorkshops(InstitutionContractAmendmentTempWorkshopViewModel request) + public async Task InsertAmendmentTempWorkshops( + InstitutionContractAmendmentTempWorkshopViewModel request) { var amendmentTemp =await _institutionAmendmentTemp .Find(x=> x.Id == request.TempId).FirstOrDefaultAsync(); @@ -2500,35 +2517,61 @@ public class InstitutionContractRepository : RepositoryBase x.Id == request.WorkshopTempId); + var planForWorkshop = new WorkshopTempViewModel() + { + WorkshopName = request.WorkshopName, + CountPerson = request.CountPerson, + ContractAndCheckout = request.ContractAndCheckout, + ContractAndCheckoutInPerson = request.ContractAndCheckoutInPerson, + Insurance = request.Insurance, + InsuranceInPerson = request.InsuranceInPerson, + RollCall = request.RollCall, + RollCallInPerson = request.RollCallInPerson, + CustomizeCheckout = request.CustomizeCheckout + }; + var price = _planPercentageRepository.GetInstitutionPlanForWorkshop(planForWorkshop) + .OnlineAndInPersonSumAmountDouble; + if (workshopTemp == null) { - var newWorkshopTemp = new InstitutionContractAmendmentTempWorkshop(request.WorkshopName, + var newWorkshopTemp = new InstitutionContractAmendmentTempNewWorkshop(request.WorkshopName, request.CountPerson, request.ContractAndCheckout, request.ContractAndCheckoutInPerson, request.Insurance, request.InsuranceInPerson, request.RollCall, request.RollCallInPerson, - request.CustomizeCheckout, request.Price, - request.WorkshopId,0,request.PriceStr); + request.CustomizeCheckout, price, + request.WorkshopId,0,price); + + workshopTemp = newWorkshopTemp; + amendmentTemp.NewWorkshops.Add(newWorkshopTemp); - await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); - - return newWorkshopTemp.Id; + await _institutionAmendmentTemp + .ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); } - - amendmentTemp.NewWorkshops.Remove(workshopTemp); + else + { + amendmentTemp.NewWorkshops.Remove(workshopTemp); - workshopTemp.Edit(request.WorkshopName, request.CountPerson, - request.ContractAndCheckout, request.ContractAndCheckoutInPerson, - request.Insurance, request.InsuranceInPerson, - request.RollCall, - request.CustomizeCheckout); + var differencePrice = price - workshopTemp.Price; + workshopTemp.Edit(request.WorkshopName, request.CountPerson, + request.ContractAndCheckout, request.ContractAndCheckoutInPerson, + request.Insurance, request.InsuranceInPerson, + request.RollCall, + request.CustomizeCheckout, price,differencePrice); - amendmentTemp.NewWorkshops.Add(workshopTemp); + amendmentTemp.NewWorkshops.Add(workshopTemp); - await _institutionAmendmentTemp.ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); - return workshopTemp.Id; + await _institutionAmendmentTemp + .ReplaceOneAsync(x => x.Id == amendmentTemp.Id, amendmentTemp); + } + + return new InsertAmendmentTempWorkshopResponse() + { + WorkshopTempId = workshopTemp.Id, + Amount = workshopTemp.PriceDifference.ToMoney() + }; } public async Task RemoveAmendmentWorkshops(Guid workshopTempId) From c5b521bc5098d835a6295d74bce2265a235b0dc6 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 11:04:46 +0330 Subject: [PATCH 05/10] feat: add endpoints for inserting, removing, and retrieving amendment workshops and payment details --- .../institutionContractController.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index fc17dbcf..ec71ffe3 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -519,6 +519,25 @@ public class institutionContractController : AdminBaseController var res =await _institutionContractApplication.GetAmendmentWorkshops(institutionContractId); return res; } + + [HttpPost("amendment/insert-temp-workshops")] + public async Task> InsertAmendmentTempWorkshops([FromBody]InstitutionContractAmendmentTempWorkshopViewModel request) + { + var res =await _institutionContractApplication.InsertAmendmentTempWorkshops(request); + return res; + } + [HttpDelete("amendment/remove-temp-workshops/{workshopTempId:guid}")] + public async Task RemoveAmendmentWorkshops(Guid workshopTempId) + { + await _institutionContractApplication.RemoveAmendmentWorkshops(workshopTempId); + return Ok(); + } + [HttpPost("amendment/payment-details")] + public async Task> GetAmendmentPaymentDetails([FromBody]InsitutionContractAmendmentPaymentRequest request) + { + var res =await _institutionContractApplication.GetAmendmentPaymentDetails(request); + return res; + } } From c2a08d9c33e8db8e4ec2255fded99d2c664cf968 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 14:37:11 +0330 Subject: [PATCH 06/10] feat: add BsonRepresentation attribute to Id property for string representation in MongoDB --- .../InstitutionContractAmendmentTemp.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs index 02925e68..7c13616a 100644 --- a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs +++ b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace Company.Domain.InstitutionContractAmendmentTempAgg; @@ -19,7 +20,9 @@ public class InstitutionContractAmendmentTemp InstitutionContractId = institutionContractId; } - [BsonId] public Guid Id { get; private set; } + [BsonId] + [BsonRepresentation(BsonType.String)] + public Guid Id { get; private set; } public List PrevWorkshops { get; private set; } public List NewWorkshops { get; private set; } public long InstitutionContractId { get; private set; } From d4c2ab939e0faba3821abb652c751fc67d54383e Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 14:55:23 +0330 Subject: [PATCH 07/10] fix: correct workshop ID reference in employee count calculation --- .../Repository/InstitutionContractRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 0d523aa8..1af2342f 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1309,7 +1309,7 @@ public class InstitutionContractRepository : RepositoryBase workshops.Select(w => w.id).Contains(l.id)) + .Where(l => workshops.Select(w => w.id).Contains(l.WorkshopId)) .Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now), EmployerNames = employers.Select(e => e.FullName).ToList(), ListStatus = status, From 68f1f81b5337e5affef2b47a98fbd72554d23a52 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 15:05:48 +0330 Subject: [PATCH 08/10] feat: add BSON representation for Id property in InstitutionContractAmendmentTemp --- .../InstitutionContractAmendmentTemp.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs index 7c13616a..bac4cd56 100644 --- a/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs +++ b/Company.Domain/InstitutionContractAmendmentTempAgg/InstitutionContractAmendmentTemp.cs @@ -79,6 +79,7 @@ public class InstitutionContractAmendmentTempPrevWorkshop CurrentWorkshopId = currentWorkshopId; } + [BsonRepresentation(BsonType.String)] public Guid Id { get; set; } public long CurrentWorkshopId { get; private set; } From 7fd8851f71993b1d68dbe3e215cc53611f2fb903 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 21 Oct 2025 21:57:04 +0330 Subject: [PATCH 09/10] refactor: optimize employee count calculation in InstitutionContractRepository --- .../Repository/InstitutionContractRepository.cs | 9 +++++---- .../Admin/Controllers/institutionContractController.cs | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 1af2342f..3fc6e407 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1245,7 +1245,6 @@ public class InstitutionContractRepository : RepositoryBase { - Console.WriteLine(x.contractingParty.id); var workshops = x.contractingParty.Employers .SelectMany(e => e.WorkshopEmployers.Select(we => we.Workshop)).DistinctBy(w => w.id).ToList(); @@ -1294,6 +1293,10 @@ public class InstitutionContractRepository : RepositoryBase workshops.Select(w => w.id).Contains(l.WorkshopId)) + .Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now); return new GetInstitutionContractListItemsViewModel() { ContractAmount = x.contract.ContractAmount, @@ -1308,9 +1311,7 @@ public class InstitutionContractRepository : RepositoryBase workshops.Select(w => w.id).Contains(l.WorkshopId)) - .Count(l => l.StartWorkDate <= DateTime.Now && l.LeftWorkDate >= DateTime.Now), + EmployeesCount = employeesCount, EmployerNames = employers.Select(e => e.FullName).ToList(), ListStatus = status, IsExpired = x.contract.ContractEndGr <= endThisMontGr, diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index 63934e56..b98ecbf3 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -553,6 +553,7 @@ public class institutionContractController : AdminBaseController var res =await _institutionContractApplication.GetAmendmentPaymentDetails(request); return res; } + } From a8274708314cb8393e173b269e5bd7661829e0fa Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 22 Oct 2025 15:19:17 +0330 Subject: [PATCH 10/10] feat: add API for editing old institution contracts with new properties --- ...etInstitutionContractListItemsViewModel.cs | 4 + .../InstitutionContractRepository.cs | 6 +- .../institutionContractController.cs | 190 ++++++++++++++++++ 3 files changed, 199 insertions(+), 1 deletion(-) diff --git a/CompanyManagment.App.Contracts/InstitutionContract/GetInstitutionContractListItemsViewModel.cs b/CompanyManagment.App.Contracts/InstitutionContract/GetInstitutionContractListItemsViewModel.cs index 65392104..123dc18a 100644 --- a/CompanyManagment.App.Contracts/InstitutionContract/GetInstitutionContractListItemsViewModel.cs +++ b/CompanyManagment.App.Contracts/InstitutionContract/GetInstitutionContractListItemsViewModel.cs @@ -87,6 +87,10 @@ public class GetInstitutionContractListItemsViewModel public long ContractingPartyId { get; set; } public List Workshops { get; set; } + + public bool IsInPersonContract { get; set; } + + public bool IsOldContract { get; set; } } public class InstitutionContractListWorkshop diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 0a2b0709..18c03a04 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1310,7 +1310,11 @@ public class InstitutionContractRepository : RepositoryBasey.Services.ContractInPerson)??true, + IsOldContract = x.contract.WorkshopGroup?.CurrentWorkshops + .Any(y=>y.Price == 0)??true }; }).ToList() }; diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index 00fdc34b..dad7ddf9 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -534,6 +534,196 @@ public class institutionContractController : AdminBaseController var res = await _institutionContractApplication.ResendVerifyLink(institutionContractId); return res; } + + [HttpGet("edit-old/{id}")] + public ActionResult GetEditOldDetails(long id) + { + var representativList = new List(); + var contractingPartyList = new List(); + var res = _institutionContractApplication.GetDetails(id); + + var representative = new RepresentativeViewModel + { + Id = res.RepresentativeId, + FullName = res.RepresentativeName + }; + representativList.Add(representative); + var contractingParty = new PersonalContractingPartyViewModel + { + id = res.ContractingPartyId, + FullName = _contractingPartyApplication.GetFullName(res.ContractingPartyId) + }; + contractingPartyList.Add(contractingParty); + res.RepresentativeSelectList = + new SelectList(representativList, "Id", "FullName"); + res.ContractingPartiesSelectList = + new SelectList(contractingPartyList, "id", "FullName"); + + var employer = _employerApplication.GetEmployerByContracrtingPartyID(res.ContractingPartyId); + var emplId = employer.Select(x => x.Id).ToList(); + + var w = _workshopApplication.GetWorkshopsByEmployerId(emplId); + var workshopIds = w.Select(x => x.Id).ToList(); + var workshopCount = Convert.ToString(w.Count); + var pCount = 0; + if (workshopIds.Count > 0) + { + foreach (var workshopId in workshopIds) + { + var p = _workshopApplication.PersonnelCount(workshopId); + pCount += p; + } + + res.EmployeeCount = Convert.ToString(pCount); + } + else + { + res.EmployeeCount = "0"; + } + + res.WorkshopCount = workshopCount; + + + var contactInfo = _contactInfoApplication.GetContactInfolist(id); + if (contactInfo.Count > 0) + { + res.ContactInfoCounter = contactInfo.Count; + res.ContactInformationList = contactInfo; + } + else + { + res.ContactInfoCounter = 0; + } + + if (res.HasValueAddedTax == "true") + { + res.ContractAmount -= res.ValueAddedTax; + res.ContractAmountOAlone = res.ContractAmount.ToMoney(); + res.ValueAddedTaxStr = res.ValueAddedTax.ToMoney(); + } + else + { + res.ContractAmountOAlone = res.ContractAmountString; + res.ValueAddedTaxStr = "0"; + } + return res; + } + + [HttpPost("edit-old")] + public ActionResult EditOld([FromBody] EditInstitutionContract command) + { + var op = new OperationResult(); + var phoneNumber = command.ContactInformationList.FirstOrDefault(x => + x.SendSmsString == "true" && x.Position == "طرف قرارداد" && x.PhoneType == "شماره همراه"); + var conractingParty = _contractingPartyApplication.GetDetails(command.ContractingPartyId); + + if (conractingParty.IsLegal == "حقیقی" && string.IsNullOrWhiteSpace(conractingParty.Nationalcode)) + return new JsonResult(op.Failed("کد ملی طرف حساب وجود ندارد")); + if (conractingParty.IsLegal == "حقوقی" && string.IsNullOrWhiteSpace(conractingParty.NationalId)) + return new JsonResult(op.Failed("شناسه ملی طرف حساب وجود ندارد")); + if (phoneNumber == null) + return new JsonResult(op.Failed("تعیین شماره همراه با سمت طرف قرارداد اجباریست")); + //if (string.IsNullOrWhiteSpace(command.HasValueAddedTax)) + // command.HasValueAddedTax = "false"; + var result = _institutionContractApplication.Edit(command); + var contractingPartyId = _institutionContractApplication.GetDetails(result.SendId); + var counter = command.ContactInformationList.Count; + var getOldContarct = _institutionContractApplication.NewSearch(new InstitutionContractSearchModel() + { ContractingPartyId = contractingPartyId.ContractingPartyId, IsActiveString = "both" }).Where(x=>x.IsActiveString == "false" || x.IsActiveString == "blue").ToList(); + if (result.IsSuccedded && counter > 0) + { + + if (getOldContarct.Count > 0) + { + foreach (var item in getOldContarct) + { + _contactInfoApplication.RemoveContactInfo(item.Id); + foreach (var phone in command.ContactInformationList) + { + if (phone.PhoneNumber != null) + { + var contactinfo = new CreateContactInfo + { + InstitutionContractId = item.Id, + PhoneType = phone.PhoneType, + Position = phone.Position, + PhoneNumber = phone.PhoneNumber, + FnameLname = phone.FnameLname, + SendSms = phone.SendSmsString == "true" ? true : false + }; + _contactInfoApplication.Create(contactinfo); + } + + Thread.Sleep(500); + } + } + } + _contactInfoApplication.RemoveContactInfo(command.Id); + foreach (var item in command.ContactInformationList) + { + if (item.PhoneNumber != null) + { + var contactinfo = new CreateContactInfo + { + InstitutionContractId = result.SendId, + PhoneType = item.PhoneType, + Position = item.Position, + PhoneNumber = item.PhoneNumber, + FnameLname = item.FnameLname, + SendSms = item.SendSmsString == "true" ? true : false + }; + _contactInfoApplication.Create(contactinfo); + } + + Thread.Sleep(500); + } + + + //ساخت اکانت کلاینت + var userPass = conractingParty.IsLegal == "حقیقی" + ? conractingParty.Nationalcode + : conractingParty.NationalId; + var checkExistAccount = _accountApplication.CheckExistClientAccount(userPass); + if (!checkExistAccount) + { + + var createAcc = new RegisterAccount + { + Fullname = conractingParty.LName, + Username = userPass, + Password = userPass, + Mobile = phoneNumber.PhoneNumber, + NationalCode = userPass + }; + var res = _accountApplication.RegisterClient(createAcc); + if (res.IsSuccedded) + _institutionContractApplication.CreateContractingPartyAccount(command.ContractingPartyId, res.SendId); + } + } + //Thread.Sleep(500); + //for (int i = 0; i <= counter - 1; i++) + //{ + // if (command.ContactInformationList[i].PhoneNumber != null) + // { + + // var contactinfo = new CreateContactInfo() + // { + // InstitutionContractId = result.SendId, + // PhoneType = command.ContactInformationList[i].PhoneType, + // Position = command.ContactInformationList[i].Position, + // PhoneNumber = command.ContactInformationList[i].PhoneNumber, + // FnameLname = command.ContactInformationList[i].FnameLname, + // SendSms = command.ContactInformationList[i].SendSmsString == "true" ? true : false + // }; + // _contactInfoApplication.Create(contactinfo); + + // } + // Thread.Sleep(500); + //} + + + return result; + } }