diff --git a/backend/app/Services/Domain/Order/OrderCancelService.php b/backend/app/Services/Domain/Order/OrderCancelService.php index 2c02a40ddf..7a19e3ac00 100644 --- a/backend/app/Services/Domain/Order/OrderCancelService.php +++ b/backend/app/Services/Domain/Order/OrderCancelService.php @@ -81,8 +81,14 @@ private function adjustProductQuantities(OrderDomainObject $order): void { $attendees = $this->attendeeRepository->findWhere([ 'order_id' => $order->getId(), - 'status' => AttendeeStatus::ACTIVE->name, - ]); + ])->filter(function (AttendeeDomainObject $attendee) use ($order) { + if ($order->isOrderAwaitingOfflinePayment()) { + return $attendee->getStatus() === AttendeeStatus::ACTIVE->name + || $attendee->getStatus() === AttendeeStatus::AWAITING_PAYMENT->name; + } + + return $attendee->getStatus() === AttendeeStatus::ACTIVE->name; + }); $productIdCountMap = $attendees ->map(fn(AttendeeDomainObject $attendee) => $attendee->getProductPriceId())->countBy(); diff --git a/backend/tests/Unit/Services/Domain/Order/OrderCancelServiceTest.php b/backend/tests/Unit/Services/Domain/Order/OrderCancelServiceTest.php index d40e0313af..50dbc68554 100644 --- a/backend/tests/Unit/Services/Domain/Order/OrderCancelServiceTest.php +++ b/backend/tests/Unit/Services/Domain/Order/OrderCancelServiceTest.php @@ -16,7 +16,6 @@ use HiEvents\Services\Infrastructure\DomainEvents\DomainEventDispatcherService; use HiEvents\Services\Infrastructure\DomainEvents\Enums\DomainEventType; use HiEvents\Services\Infrastructure\DomainEvents\Events\OrderEvent; -use HiEvents\Services\Infrastructure\Webhook\WebhookDispatchService; use Illuminate\Contracts\Mail\Mailer; use Illuminate\Database\DatabaseManager; use Illuminate\Support\Collection; @@ -64,6 +63,81 @@ public function testCancelOrder(): void $order->shouldReceive('getEventId')->andReturn(1); $order->shouldReceive('getId')->andReturn(1); $order->shouldReceive('getEmail')->andReturn('customer@example.com'); + $order->shouldReceive('isOrderAwaitingOfflinePayment')->andReturn(false); + + $order->shouldReceive('getLocale')->andReturn('en'); + + $attendees = new Collection([ + m::mock(AttendeeDomainObject::class)->shouldReceive('getproductPriceId')->andReturn(1)->mock(), + m::mock(AttendeeDomainObject::class)->shouldReceive('getproductPriceId')->andReturn(2)->mock(), + ]); + + $this->attendeeRepository + ->shouldReceive('findWhere') + ->once() + ->with([ + 'order_id' => $order->getId(), + ]) + ->andReturn($attendees); + + $this->attendeeRepository->shouldReceive('updateWhere')->once(); + + $this->productQuantityService->shouldReceive('decreaseQuantitySold')->twice(); + + $this->orderRepository->shouldReceive('updateWhere')->once(); + + $event = new EventDomainObject(); + $event->setEventSettings(new EventSettingDomainObject()); + $this->eventRepository + ->shouldReceive('loadRelation') + ->once() + ->andReturnSelf() + ->getMock() + ->shouldReceive('findById')->once()->andReturn($event); + + $this->mailer->shouldReceive('to') + ->once() + ->andReturnSelf(); + + $this->mailer->shouldReceive('locale') + ->once() + ->andReturnSelf(); + + $this->mailer->shouldReceive('send')->once()->withArgs(function ($mail) { + return $mail instanceof OrderCancelled; + }); + + $this->domainEventDispatcherService->shouldReceive('dispatch') + ->withArgs(function (OrderEvent $event) use ($order) { + return $event->type === DomainEventType::ORDER_CANCELLED + && $event->orderId === $order->getId(); + }) + ->once(); + + $this->databaseManager->shouldReceive('transaction')->once()->andReturnUsing(function ($callback) { + $callback(); + }); + + $attendees->each(function ($attendee) { + $attendee->shouldReceive('getStatus')->andReturn(AttendeeStatus::ACTIVE->name); + }); + + try { + $this->service->cancelOrder($order); + } catch (Throwable $e) { + $this->fail("Failed to cancel order: " . $e->getMessage()); + } + + $this->assertTrue(true, "Order cancellation proceeded without throwing an exception."); + } + + public function testCancelOrderAwaitingOfflinePayment(): void + { + $order = m::mock(OrderDomainObject::class); + $order->shouldReceive('getEventId')->andReturn(1); + $order->shouldReceive('getId')->andReturn(1); + $order->shouldReceive('getEmail')->andReturn('customer@example.com'); + $order->shouldReceive('isOrderAwaitingOfflinePayment')->andReturn(true); $order->shouldReceive('getLocale')->andReturn('en'); $attendees = new Collection([ @@ -76,7 +150,6 @@ public function testCancelOrder(): void ->once() ->with([ 'order_id' => $order->getId(), - 'status' => AttendeeStatus::ACTIVE->name, ]) ->andReturn($attendees); @@ -118,6 +191,10 @@ public function testCancelOrder(): void $callback(); }); + $attendees->each(function ($attendee) { + $attendee->shouldReceive('getStatus')->andReturn(AttendeeStatus::AWAITING_PAYMENT->name); + }); + try { $this->service->cancelOrder($order); } catch (Throwable $e) {