Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
QuoteConversionWebController
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 convert
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Modules\Quotes\Presentation\Web;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Application\Security\PermissionContextFactory;
12use App\Modules\Quotes\Application\Service\QuoteConversionApplicationServiceInterface;
13use Nyholm\Psr7\Factory\Psr17Factory;
14use Psr\Http\Message\ResponseInterface;
15use Psr\Http\Message\ServerRequestInterface;
16use Throwable;
17
18/**
19 * Web controller handling conversion of approved Quotes into Sales Orders.
20 */
21final readonly class QuoteConversionWebController
22{
23    public function __construct(
24        private QuoteConversionApplicationServiceInterface $conversionService,
25        private PermissionContextFactory $contextFactory,
26        private Psr17Factory $psr17Factory,
27    ) {
28    }
29
30    /**
31     * Converts a quote into a new sales order with field mapping and line items duplication.
32     */
33    public function convert(ServerRequestInterface $request, int $quoteId): ResponseInterface
34    {
35        try {
36            $context = $this->contextFactory->createFromRequest($request);
37            $newOrderId = $this->conversionService->convertQuoteToOrder($quoteId, $context);
38
39            $targetUrl = "/orders/{$newOrderId}";
40
41            if ($request->hasHeader('HX-Request')) {
42                return $this->psr17Factory->createResponse(200)
43                    ->withHeader('HX-Redirect', $targetUrl);
44            }
45
46            return $this->psr17Factory->createResponse(303)
47                ->withHeader('Location', $targetUrl);
48        } catch (Throwable $e) {
49            $escaped = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
50            $response = $this->psr17Factory->createResponse(400)
51                ->withHeader('Content-Type', 'text/html; charset=utf-8');
52            $response->getBody()->write("<div class='alert alert-danger mb-3'>{$escaped}</div>");
53            return $response;
54        }
55    }
56}