عشان نضيف الـ Payment Intent مع الـ Order

نروح أول حاجة للـ Order ونشيل الـ Initial Value اللي كانت بـ empty

// Order
public Order(string buyerEmail, Address shippingAddress, DeliveryMethod deliveryMethod, ICollection<OrderItem> items, decimal subtotal, string paymentIntentId)
{
	// Code
	PaymentIntentId = paymentIntentId;
}
public string PaymentIntentId {get; set;}

نروح للـ Order Service ونروح للجزء اللي بنعمل فيه Create Order

var order = new Order(buyerEmail, shippingAddress, deliveryMethod, orderItems, subtotal, basket.PaymentIntentId);

بس محتاجين نعمل Validation دلوقتي وهي ان مفيش أي payment intent id لأي Order موجود ولو فيه نمسحه لأن لو فيه أكتر من Order بنفسه الـ payment intent id هياخد كل الـ Orders بنفس الدفع الوحيد ودا ممكن يحصل بسبب مشاكل وهو مدفعش مثلًا فالأول فيفضل موجود

والخطوة دي هنعملها قبل ما نعمل Create للـ Order

var ordersRepo = _unitOfWork.Repository<Order>();
// var orderSepc = new OrderSpecifications();
var existingOrder = await ordersRepo.GetEntityWithSpecAsync()
 
// OrderSpecifications
// Make new Ctor to take PaymentIntentId
public OrderSpecifications(string paymentIntentId)
	:base(O => O.PaymentIntentId == paymentIntentId)
{
	
}

نغير اسم GetByIdWithSpecAsync اللي احنا عاملينها لـ GetEntityWithSpecAsync عشان تبقا معبرة أكتر وتعمل ctrl + . وتعمل Rename

بس هتلاقي فيه مشكلة ان عندي Ctor تاني بياخد برضو بارمتر واحد وبرضو string فهيزعل فهضطر اعمل class جديد ليها وخلاص

Core Specifications OrderSpecs

public class OrderWithPaymentIntentSpecifications : BaseSpecifications<Order>
{
	public OrderWithPaymentIntentSpecifications(string paymentIntentId)
		:base(O => O.PaymentIntentId == paymentIntentId)
	{
		
	}
}

خطوة الـ Validation بقا

// Inject Payment Service in ctor
IPaymentService paymentService
 
// Validate
var ordersRepo = _unitOfWork.Repository<Order>();
var orderSepc = new OrderWithPaymentIntentSpecifications(basket.PaymentIntentId);
var existingOrder = await ordersRepo.GetEntityWithSpecAsync(orderSpecs);
if(existingOrder != null)
{
	ordersRepo.Delete(existingOrder);
	// Update Amount in PaymentIntent because it's not same order
	await _paymentService.CreatOrUpdatePaymentIntent(basketId);
}
 
// New Order
var order = new Order(buyerEmail, shippingAddress, deliveryMethod, orderItems, subtotal, basket.PaymentIntentId);
 
await ordersRepo.AddAsync(order);
 
// Save to Database
var result = await _unitOfWork.CompleteAsync();