$customerData */ public function updateCustomer(Purchase $purchase, array $customerData): Purchase { return DB::transaction(function () use ($purchase, $customerData): Purchase { $purchase = $this->lockPurchase($purchase); $this->assertEditable($purchase); $purchase->update($customerData); return $this->loadPurchase($purchase); }); } private function assertEditable(Purchase $purchase): void { if ( ! in_array($purchase->status, [ Purchase::STATUS_CREATED, Purchase::STATUS_PENDING_PAYMENT, ], true) || $this->hasExpired($purchase) ) { throw ValidationException::withMessages([ 'purchase' => __('api.purchase.not_editable'), ]); } } private function hasExpired(Purchase $purchase): bool { return $purchase->expires_at !== null && $purchase->expires_at->isPast(); } private function lockPurchase(Purchase $purchase): Purchase { /** @var Purchase */ return Purchase::query()->lockForUpdate()->findOrFail($purchase->getKey()); } private function loadPurchase(Purchase $purchase): Purchase { return $purchase->load([ 'items.imageAttachment', 'cart.items.catalogItem.inventory', 'cart.items.catalogItem.attachments', 'cart.items.variant.inventory', 'cart.items.variant.attachments', 'cart.items.variant.definitions.itemAttribute.attribute', 'cart.items.variant.eventDates', 'cart.items.variant.eventDate', ]); } }