浏览代码

resolve conflicts

Olivier Massot 9 月之前
父节点
当前提交
41aa21a27f

+ 1 - 0
config/opentalent/products.yaml

@@ -19,6 +19,7 @@ parameters:
           - UploadRequest
           - SubdomainAvailability
           - UserSearchItem
+          - DolibarrDocDownload
         roles:
           - ROLE_IMPORT
           - ROLE_TAGG

+ 88 - 0
src/ApiResources/Dolibarr/DolibarrDocDownload.php

@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\ApiResources\Dolibarr;
+
+use ApiPlatform\Metadata\ApiProperty;
+use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Metadata\Get;
+use App\Enum\Dolibarr\DolibarrDocTypeEnum;
+use App\State\Provider\Dolibarr\DolibarrDocDownloadProvider;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * Demande de téléchargement d'un fichier depuis Dolibarr (facture, bon de commande, etc).
+ */
+#[ApiResource(
+    operations: [
+        new Get(
+            uriTemplate: '/dolibarr/download/{dolibarrDocType}/{ref}',
+            requirements: [
+                'ref' => '[\w-]+',
+            ],
+            security: '(is_granted("ROLE_ADMIN_CORE") or 
+                            is_granted("ROLE_ADMINISTRATIF_MANAGER_CORE") or 
+                            is_granted("ROLE_PEDAGOGICS_MANAGER_CORE") or 
+                            is_granted("ROLE_FINANCIAL_MANAGER_CORE"))',
+            provider: DolibarrDocDownloadProvider::class
+        ),
+    ]
+)]
+class DolibarrDocDownload
+{
+    /**
+     * Id 'bidon' ajouté par défaut pour permettre la construction
+     * de l'IRI par api platform.
+     */
+    #[ApiProperty(identifier: true)]
+    protected int $id = 0;
+
+    /**
+     * Type de fichier à télécharger.
+     */
+    #[Assert\Type(type: DolibarrDocTypeEnum::class)]
+    protected DolibarrDocTypeEnum $dolibarrDocType;
+
+    /**
+     * The dolibarr reference of the document (ex: CO2502-0380, FA2101-02988, ...)
+     * Must be URL Encoded.
+     */
+    protected string $ref;
+
+    public function getId(): int
+    {
+        return $this->id;
+    }
+
+    public function setId(int $id): self
+    {
+        $this->id = $id;
+
+        return $this;
+    }
+
+    public function getDolibarrDocType(): DolibarrDocTypeEnum
+    {
+        return $this->dolibarrDocType;
+    }
+
+    public function setDolibarrDocType(DolibarrDocTypeEnum $dolibarrDocType): self
+    {
+        $this->dolibarrDocType = $dolibarrDocType;
+
+        return $this;
+    }
+
+    public function getRef(): string
+    {
+        return $this->ref;
+    }
+
+    public function setRef(string $ref): self
+    {
+        $this->ref = $ref;
+
+        return $this;
+    }
+}

+ 19 - 0
src/Enum/Dolibarr/DolibarrDocTypeEnum.php

@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Enum\Dolibarr;
+
+use App\Enum\EnumMethodsTrait;
+
+/**
+ * Formats de sortie des fichiers exportés.
+ */
+enum DolibarrDocTypeEnum: string
+{
+    use EnumMethodsTrait;
+
+    case ORDER = 'order'; // Bon de commande
+    case INVOICE = 'invoice'; // Facture
+    case CONTRACT = 'contract'; // Contrat
+}

+ 24 - 0
src/Service/Dolibarr/DolibarrApiService.php

@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Service\Dolibarr;
 
 use App\Entity\Organization\Organization;
+use App\Enum\Dolibarr\DolibarrDocTypeEnum;
 use App\Service\Rest\ApiRequestService;
 use JetBrains\PhpStorm\Pure;
 use Symfony\Component\HttpFoundation\Response;
@@ -220,4 +221,27 @@ class DolibarrApiService extends ApiRequestService
             throw new HttpException($res->getStatusCode(), 'Error while updating the society in Dolibarr');
         }
     }
+
+    /**
+     * @return array<string, string|number> The resulting document. Ex :
+     *                                      {
+     *                                      "filename": "CO2502-0380.pdf",
+     *                                      "content-type": "application/pdf",
+     *                                      "filesize": 10660,
+     *                                      "content": "JVBERi0xLjcKJeLjz9MKNyAwIG9iago8PCAvV...",
+     *                                      "encoding": "base64"
+     *                                      }
+     *
+     * @throws \JsonException
+     */
+    public function downloadBillingDocPdf(string $type, string $docRef): array
+    {
+        if (!DolibarrDocTypeEnum::tryFrom($type)) {
+            throw new \InvalidArgumentException(sprintf('Invalid type "%s" provided. Allowed values are: %s', $type, implode(', ', array_map(fn ($t) => $t->value, DolibarrDocTypeEnum::cases()))));
+        }
+
+        $route = 'documents/download?modulepart='.$type.'&original_file='.urlencode("$docRef/$docRef.pdf");
+
+        return $this->getJsonContent($route);
+    }
 }

+ 54 - 0
src/State/Provider/Dolibarr/DolibarrDocDownloadProvider.php

@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\State\Provider\Dolibarr;
+
+use ApiPlatform\Metadata\GetCollection;
+use ApiPlatform\Metadata\Operation;
+use ApiPlatform\State\ProviderInterface;
+use App\Service\Dolibarr\DolibarrApiService;
+use Symfony\Component\HttpFoundation\HeaderUtils;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Custom provider pour les DolibarrAccounts récupérés via l'api dolibarr.
+ */
+final readonly class DolibarrDocDownloadProvider implements ProviderInterface
+{
+    public function __construct(
+        private DolibarrApiService $dolibarrApiService,
+    ) {
+    }
+
+    /**
+     * @param mixed[] $uriVariables
+     * @param mixed[] $context
+     */
+    public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
+    {
+        if ($operation instanceof GetCollection) {
+            throw new \RuntimeException('not supported', Response::HTTP_METHOD_NOT_ALLOWED);
+        }
+
+        $data = $this->dolibarrApiService->downloadBillingDocPdf(
+            $uriVariables['dolibarrDocType'],
+            $uriVariables['ref']
+        );
+
+        // Build the response and attach the file to it
+        // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
+        $response = new Response(base64_decode($data['content']));
+
+        $response->headers->set('Charset', 'UTF-8');
+        $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition');
+        $response->headers->set('Content-Type', $data['content-type']);
+
+        $response->headers->set(
+            'Content-Disposition',
+            HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $data['filename'])
+        );
+
+        return $response;
+    }
+}