src/Entity/PhotoUploadErrorReport.php line 40

  1. <?php
  2. /*
  3.  * This file is part of the Pellipop project.
  4.  *
  5.  * (c) Mobizel
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace App\Entity;
  12. use App\Entity\IdentifiableTrait;
  13. use App\Entity\Order\Order;
  14. use App\Entity\Order\OrderItemPhoto;
  15. use App\Repository\PhotoUploadErrorReportRepository;
  16. use Doctrine\DBAL\Types\Types;
  17. use Doctrine\ORM\Mapping as ORM;
  18. use Gedmo\Timestampable\Traits\TimestampableEntity;
  19. use Sylius\Component\Resource\Annotation\SyliusCrudRoutes;
  20. use Sylius\Component\Resource\Model\ResourceInterface;
  21. #[ORM\Entity(repositoryClass: PhotoUploadErrorReportRepository::class)]
  22. #[ORM\Table(name: 'app_photo_upload_error_report')]
  23. #[SyliusCrudRoutes(alias: 'app.photo_upload_error_report', path: '/admin/photo-upload-errors', section: 'backend', templates: 'backend/photo_upload_error_report', grid: 'app_backend_photo_upload_error_report', only: ['index', 'show'], vars: [
  24.     'all' => [
  25.         'subheader' => 'app.ui.photo_upload_errors',
  26.     ],
  27.     'index' => [
  28.         'icon' => 'exclamation triangle',
  29.     ],
  30. ])]
  31. #[ORM\Index(columns: ['order_id'], name: 'idx_order_id')]
  32. #[ORM\Index(columns: ['photo_id'], name: 'idx_photo_id')]
  33. #[ORM\Index(columns: ['error_type'], name: 'idx_error_type')]
  34. #[ORM\Index(columns: ['resolved'], name: 'idx_resolved')]
  35. class PhotoUploadErrorReport implements ResourceInterface
  36. {
  37.     use IdentifiableTrait;
  38.     use TimestampableEntity;
  39.     public const ERROR_TYPE_FILE_MISSING = 'file_missing';
  40.     public const ERROR_TYPE_FILE_CORRUPTED = 'file_corrupted';
  41.     public const ERROR_TYPE_STATE_TRANSITION = 'state_transition';
  42.     public const ERROR_TYPE_FUJI_SERVER = 'fuji_server';
  43.     public const ERROR_TYPE_NETWORK = 'network';
  44.     public const ERROR_TYPE_COMPRESSION = 'compression';
  45.     public const ERROR_TYPE_UNKNOWN = 'unknown';
  46.     public const SOURCE_API = 'api';
  47.     public const SOURCE_COMMAND = 'command';
  48.     public const SOURCE_APP = 'app';
  49.     /**
  50.      * Types conservés par Vanguard : fatal/critique (fichier définitivement inexploitable) ou
  51.      * fonctionnel (règle métier violée). Les autres types (réseau, compression, inconnu, Fuji
  52.      * serveur tiers) sont transitoires ou déjà couverts par un fallback applicatif — ils ne sont
  53.      * pas persistés (voir PhotoUploadErrorReporter::reportError()).
  54.      */
  55.     public const KEPT_ERROR_TYPES = [
  56.         self::ERROR_TYPE_FILE_MISSING,
  57.         self::ERROR_TYPE_FILE_CORRUPTED,
  58.         self::ERROR_TYPE_STATE_TRANSITION,
  59.     ];
  60.     public static function isKeptSeverity(string $errorType): bool
  61.     {
  62.         return \in_array($errorType, self::KEPT_ERROR_TYPES, true);
  63.     }
  64.     #[ORM\ManyToOne(targetEntity: Order::class)]
  65.     #[ORM\JoinColumn(name: 'order_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
  66.     private ?Order $order = null;
  67.     #[ORM\ManyToOne(targetEntity: OrderItemPhoto::class)]
  68.     #[ORM\JoinColumn(name: 'photo_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
  69.     private ?OrderItemPhoto $photo = null;
  70.     #[ORM\Column(length: 50)]
  71.     private string $errorType;
  72.     #[ORM\Column(length: 20)]
  73.     private string $source;
  74.     #[ORM\Column(type: Types::TEXT)]
  75.     private string $errorMessage;
  76.     #[ORM\Column(type: Types::TEXT, nullable: true)]
  77.     private ?string $stackTrace = null;
  78.     #[ORM\Column(type: Types::JSON, nullable: true)]
  79.     private ?array $context = null;
  80.     #[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])]
  81.     private bool $resolved = false;
  82.     #[ORM\Column(type: Types::TEXT, nullable: true)]
  83.     private ?string $resolutionNote = null;
  84.     #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
  85.     private ?\DateTimeImmutable $resolvedAt = null;
  86.     public function getId(): ?int
  87.     {
  88.         return $this->id;
  89.     }
  90.     public function getOrder(): ?Order
  91.     {
  92.         return $this->order;
  93.     }
  94.     public function setOrder(?Order $order): self
  95.     {
  96.         $this->order = $order;
  97.         return $this;
  98.     }
  99.     public function getOrderId(): ?int
  100.     {
  101.         return $this->order?->getId();
  102.     }
  103.     public function getPhoto(): ?OrderItemPhoto
  104.     {
  105.         return $this->photo;
  106.     }
  107.     public function getPhotoId(): ?int
  108.     {
  109.         return $this->photo?->getId();
  110.     }
  111.     public function setPhoto(?OrderItemPhoto $photo): self
  112.     {
  113.         $this->photo = $photo;
  114.         return $this;
  115.     }
  116.     public function getErrorType(): string
  117.     {
  118.         return $this->errorType;
  119.     }
  120.     public function setErrorType(string $errorType): self
  121.     {
  122.         $this->errorType = $errorType;
  123.         return $this;
  124.     }
  125.     public function getSource(): string
  126.     {
  127.         return $this->source;
  128.     }
  129.     public function setSource(string $source): self
  130.     {
  131.         $this->source = $source;
  132.         return $this;
  133.     }
  134.     public function getErrorMessage(): string
  135.     {
  136.         return $this->errorMessage;
  137.     }
  138.     public function setErrorMessage(string $errorMessage): self
  139.     {
  140.         $this->errorMessage = $errorMessage;
  141.         return $this;
  142.     }
  143.     public function getStackTrace(): ?string
  144.     {
  145.         return $this->stackTrace;
  146.     }
  147.     public function setStackTrace(?string $stackTrace): self
  148.     {
  149.         $this->stackTrace = $stackTrace;
  150.         return $this;
  151.     }
  152.     public function getContext(): ?array
  153.     {
  154.         return $this->context;
  155.     }
  156.     public function setContext(?array $context): self
  157.     {
  158.         $this->context = $context;
  159.         return $this;
  160.     }
  161.     public function isResolved(): bool
  162.     {
  163.         return $this->resolved;
  164.     }
  165.     public function setResolved(bool $resolved): self
  166.     {
  167.         $this->resolved = $resolved;
  168.         if ($resolved && $this->resolvedAt === null) {
  169.             $this->resolvedAt = new \DateTimeImmutable();
  170.         } elseif (!$resolved) {
  171.             $this->resolvedAt = null;
  172.         }
  173.         return $this;
  174.     }
  175.     public function getResolutionNote(): ?string
  176.     {
  177.         return $this->resolutionNote;
  178.     }
  179.     public function setResolutionNote(?string $resolutionNote): self
  180.     {
  181.         $this->resolutionNote = $resolutionNote;
  182.         return $this;
  183.     }
  184.     public function getResolvedAt(): ?\DateTimeImmutable
  185.     {
  186.         return $this->resolvedAt;
  187.     }
  188.     public function setResolvedAt(?\DateTimeImmutable $resolvedAt): self
  189.     {
  190.         $this->resolvedAt = $resolvedAt;
  191.         return $this;
  192.     }
  193.     public static function getErrorTypeChoices(): array
  194.     {
  195.         return [
  196.             self::ERROR_TYPE_FILE_MISSING => 'Fichier manquant',
  197.             self::ERROR_TYPE_FILE_CORRUPTED => 'Fichier corrompu',
  198.             self::ERROR_TYPE_STATE_TRANSITION => 'Transition d\'état impossible',
  199.             self::ERROR_TYPE_FUJI_SERVER => 'Erreur serveur Fuji',
  200.             self::ERROR_TYPE_NETWORK => 'Erreur réseau',
  201.             self::ERROR_TYPE_UNKNOWN => 'Erreur inconnue',
  202.         ];
  203.     }
  204.     public static function getSourceChoices(): array
  205.     {
  206.         return [
  207.             self::SOURCE_API => 'API',
  208.             self::SOURCE_COMMAND => 'Commande',
  209.             self::SOURCE_APP => 'Application mobile',
  210.         ];
  211.     }
  212. }