Add discount support for institution contract extensions

- Introduce DiscountPercentage and DiscountAmount fields to contract creation and payment models
- Implement discount calculation logic in repository
- Add SetDiscountForExtension API endpoint and related request/response models
- Update contract creation and extension flows to handle discounts
This commit is contained in:
2025-11-29 09:44:30 +03:30
parent 95891d5bae
commit 511932fa58
9 changed files with 147 additions and 6 deletions

View File

@@ -1870,6 +1870,51 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
.FirstOrDefaultAsync(x => x.PublicId == id);
}
public InstitutionContractExtensionPaymentResponse CalculateDiscount(InstitutionContractSetDiscountRequest request)
{
var baseAmount = request.PaymentAmount;
var discountAmount = (baseAmount * request.DiscountPercentage) / 100;
var paymentAmount = baseAmount - discountAmount;
var taxAmount = paymentAmount * 0.10;
var totalAmount = paymentAmount + taxAmount;
InstitutionContractPaymentMonthlyViewModel monthlyPayment = null;
InstitutionContractPaymentOneTimeViewModel oneTimePayment = null;
if (request.IsInstallment)
{
monthlyPayment = new InstitutionContractPaymentMonthlyViewModel()
{
TotalAmount = totalAmount.ToMoney(),
PaymentAmount = paymentAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
DiscountedAmount = discountAmount.ToMoney(),
DiscountPercetage = request.DiscountPercentage,
Installments = InstitutionMonthlyInstallmentCaculation((int)request.Duration,
totalAmount, DateTime.Now.ToFarsi())
};
}
else
{
oneTimePayment = new InstitutionContractPaymentOneTimeViewModel()
{
TotalAmount = totalAmount.ToMoney(),
PaymentAmount = paymentAmount.ToMoney(),
Tax = taxAmount.ToMoney(),
DiscountedAmount = discountAmount.ToMoney(),
DiscountPercetage = request.DiscountPercentage
};
}
if (discountAmount > baseAmount)
throw new BadRequestException("مقدار تخفیف نمی‌تواند بیشتر از مبلغ کل باشد");
return new InstitutionContractExtensionPaymentResponse()
{
Monthly = monthlyPayment,
OneTime = oneTimePayment
};
}
#region Extension
public async Task<InstitutionContractExtensionInquiryResult> GetExtensionInquiry(long previousContractId)
@@ -2177,6 +2222,58 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
return res;
}
public async Task<InstitutionContractExtensionPaymentResponse> SetDiscountForExtension(InstitutionContractSetDiscountForExtensionRequest request)
{
if (request.DiscountPercentage <= 0)
throw new BadRequestException("مقدار تخفیف نمی‌تواند برابر یا کمتر از صفر باشد");
var institutionTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TempId)
.FirstOrDefaultAsync();
if (institutionTemp == null)
{
throw new BadRequestException("اطلاعات وارد شده نامعتبر است");
}
if (request.IsInstallment)
{
if(institutionTemp.MonthlyPayment.DiscountPercetage>0)
throw new BadRequestException("تخفیف قبلا برای این قرارداد اعمال شده است");
}
else
{
if(institutionTemp.OneTimePayment.DiscountPercetage>0)
throw new BadRequestException("تخفیف قبلا برای این قرارداد اعمال شده است");
}
var calculateRequest = new InstitutionContractSetDiscountRequest()
{
Duration = institutionTemp.Duration.Value,
PaymentAmount = request.PaymentAmount,
DiscountPercentage = request.DiscountPercentage,
IsInstallment = request.IsInstallment
};
var res = CalculateDiscount(calculateRequest);
//این به این دلیل هست که متد caclulate discount یکی از مقادیر رو پر میکنه و ما نیاز داریم هر دو مقدار رو داشته باشیم
if (request.IsInstallment)
{
res.OneTime = institutionTemp.OneTimePayment;
}
else
{
res.Monthly = institutionTemp.MonthlyPayment;
}
institutionTemp.SetAmountAndDuration(institutionTemp.Duration.Value, res.Monthly, res.OneTime);
await _institutionExtensionTemp.ReplaceOneAsync(x => x.Id == institutionTemp.Id,
institutionTemp);
return new()
{
OneTime = institutionTemp.OneTimePayment,
Monthly = institutionTemp.MonthlyPayment
};
}
public async Task<OperationResult> ExtensionComplete(InstitutionContractExtensionCompleteRequest request)
{
var institutionContractTemp = await _institutionExtensionTemp.Find(x => x.Id == request.TemporaryId)
@@ -2321,7 +2418,7 @@ public class InstitutionContractRepository : RepositoryBase<long, InstitutionCon
previousInstitutionContract.Description,
"NotOfficial", "JobRelation", hasValueAddedTax,
payment.Tax.MoneyToDouble(), [],
request.LawId);
request.LawId,payment.DiscountPercetage,payment.DiscountedAmount.MoneyToDouble());
await CreateAsync(entity);
await SaveChangesAsync();