浏览代码

add DolibarrDocDownload api resource and provider

Olivier Massot 10 月之前
父节点
当前提交
65bc39926f

+ 1 - 0
config/opentalent/products.yaml

@@ -18,6 +18,7 @@ parameters:
           - LicenceCmfOrganizationER
           - UploadRequest
           - SubdomainAvailability
+          - 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: [
+                'dolibarrDocType' => DolibarrDocTypeEnum::VALIDATION_REGEX,
+                '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
+     * @var string
+     */
+    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;
+    }
+}

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

@@ -0,0 +1,21 @@
+<?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
+
+    public const VALIDATION_REGEX = '^' . self::ORDER->value . '|' . self::INVOICE->value . '|' . self::CONTRACT->value . '$';
+}

+ 28 - 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,31 @@ class DolibarrApiService extends ApiRequestService
             throw new HttpException($res->getStatusCode(), 'Error while updating the society in Dolibarr');
         }
     }
+
+    /**
+     * @param $type
+     * @param $docRef
+     * @return array<mixed>|null  The resulting document. Ex :
+     *                      {
+     *                          "filename": "CO2502-0380.pdf",
+     *                          "content-type": "application/pdf",
+     *                          "filesize": 10660,
+     *                          "content": "JVBERi0xLjcKJeLjz9MKNyAwIG9iago8PCAvV...",
+     *                          "encoding": "base64"
+     *                      }
+     */
+    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\Enum\Dolibarr\DolibarrDocTypeEnum;
+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($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;
+    }
+}