From 7121b9d18cc8ff6e5081220fb96e958904fa9c3e Mon Sep 17 00:00:00 2001
From: AlexP <a.plohih@iqdev.digital>
Date: Thu, 9 May 2024 23:54:52 +0500
Subject: [PATCH] STA-960 | add dto and cast from entities

---
 app/src/DTO/RestaurantListDTO.php           |  10 --
 app/src/DTO/RestaurantListingElementDTO.php |  15 ---
 app/src/Dto/DtoCollection.php               |  29 +++++
 app/src/Dto/DtoInterface.php                |   6 +
 app/src/Dto/ErrorDto.php                    |  12 ++
 app/src/Dto/FileDto.php                     |  18 +++
 app/src/Dto/KitchenTypeDto.php              |  12 ++
 app/src/Dto/NewsCategoryDto.php             |  12 ++
 app/src/Dto/NewsDetailElementDto.php        |  19 ++++
 app/src/Dto/NewsFilterVariants.php          |   9 ++
 app/src/Dto/NewsListDto.php                 |  13 +++
 app/src/Dto/NewsListingElementDto.php       |  19 ++++
 app/src/Dto/PaginationDto.php               |  10 ++
 app/src/Dto/RestaurantDetailElementDto.php  |  45 ++++++++
 app/src/Dto/RestaurantFilterVariantsDto.php |  14 +++
 app/src/Dto/RestaurantListDto.php           |  15 +++
 app/src/Dto/RestaurantListingElementDto.php |  20 ++++
 app/src/Dto/RestaurantTypeDto.php           |  12 ++
 app/src/Dto/TagDto.php                      |  11 ++
 app/src/Dto/ValidateErrorDto.php            |   5 +
 app/src/Entity/File.php                     |  19 +++-
 app/src/Entity/Kitchens.php                 |  16 ++-
 app/src/Entity/News.php                     |  35 +++++-
 app/src/Entity/NewsCategories.php           |  16 ++-
 app/src/Entity/NewsType.php                 |   1 +
 app/src/Entity/PrototypeDto.php             |  11 ++
 app/src/Entity/PrototypeElementDto.php      |  14 +++
 app/src/Entity/RestaurantTypes.php          |  15 ++-
 app/src/Entity/Restaurants.php              | 120 +++++++++++++++++++-
 29 files changed, 522 insertions(+), 31 deletions(-)
 delete mode 100644 app/src/DTO/RestaurantListDTO.php
 delete mode 100644 app/src/DTO/RestaurantListingElementDTO.php
 create mode 100644 app/src/Dto/DtoCollection.php
 create mode 100644 app/src/Dto/DtoInterface.php
 create mode 100644 app/src/Dto/ErrorDto.php
 create mode 100644 app/src/Dto/FileDto.php
 create mode 100644 app/src/Dto/KitchenTypeDto.php
 create mode 100644 app/src/Dto/NewsCategoryDto.php
 create mode 100644 app/src/Dto/NewsDetailElementDto.php
 create mode 100644 app/src/Dto/NewsFilterVariants.php
 create mode 100644 app/src/Dto/NewsListDto.php
 create mode 100644 app/src/Dto/NewsListingElementDto.php
 create mode 100644 app/src/Dto/PaginationDto.php
 create mode 100644 app/src/Dto/RestaurantDetailElementDto.php
 create mode 100644 app/src/Dto/RestaurantFilterVariantsDto.php
 create mode 100644 app/src/Dto/RestaurantListDto.php
 create mode 100644 app/src/Dto/RestaurantListingElementDto.php
 create mode 100644 app/src/Dto/RestaurantTypeDto.php
 create mode 100644 app/src/Dto/TagDto.php
 create mode 100644 app/src/Dto/ValidateErrorDto.php
 create mode 100644 app/src/Entity/PrototypeDto.php
 create mode 100644 app/src/Entity/PrototypeElementDto.php

diff --git a/app/src/DTO/RestaurantListDTO.php b/app/src/DTO/RestaurantListDTO.php
deleted file mode 100644
index 2cd51f0..0000000
--- a/app/src/DTO/RestaurantListDTO.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-namespace App\DTO;
-
-class RestaurantListDTO
-{
-    private $pagination;
-    private $list;
-    private $filterVariants;
-}
\ No newline at end of file
diff --git a/app/src/DTO/RestaurantListingElementDTO.php b/app/src/DTO/RestaurantListingElementDTO.php
deleted file mode 100644
index c6d6a7e..0000000
--- a/app/src/DTO/RestaurantListingElementDTO.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-namespace App\DTO;
-
-class RestaurantListingElementDTO
-{
-    private $id;
-    private $name;
-    private $code;
-    private $type;
-    private $check;
-    private $image;
-    private $detailLink;
-
-}
\ No newline at end of file
diff --git a/app/src/Dto/DtoCollection.php b/app/src/Dto/DtoCollection.php
new file mode 100644
index 0000000..0e6bb08
--- /dev/null
+++ b/app/src/Dto/DtoCollection.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Dto;
+
+use JsonSerializable;
+use Ramsey\Collection\AbstractCollection;
+
+/** Переопределенная коллекция, что бы можно было сериалайзить коллекции */
+class DtoCollection extends AbstractCollection implements JsonSerializable
+{
+    public function __construct(
+        private readonly string $collectionType,
+        array $data = []
+    ) {
+        parent::__construct($data);
+    }
+
+    /** @return string */
+    public function getType(): string
+    {
+        return $this->collectionType;
+    }
+
+    /** Метод для сериализации коллекции в JSON */
+    public function jsonSerialize(): array
+    {
+        return $this->data;
+    }
+}
diff --git a/app/src/Dto/DtoInterface.php b/app/src/Dto/DtoInterface.php
new file mode 100644
index 0000000..fc79608
--- /dev/null
+++ b/app/src/Dto/DtoInterface.php
@@ -0,0 +1,6 @@
+<?php
+
+namespace App\Dto;
+
+/** Инетерфейс, необходимый для реализации протота */
+interface DtoInterface {}
diff --git a/app/src/Dto/ErrorDto.php b/app/src/Dto/ErrorDto.php
new file mode 100644
index 0000000..8ac836d
--- /dev/null
+++ b/app/src/Dto/ErrorDto.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Dto;
+
+class ErrorDto implements DtoInterface
+{
+    public string $status;
+
+    public string $message;
+
+    public string $code;
+}
diff --git a/app/src/Dto/FileDto.php b/app/src/Dto/FileDto.php
new file mode 100644
index 0000000..b480f1e
--- /dev/null
+++ b/app/src/Dto/FileDto.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Dto;
+
+class FileDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $description;
+
+    public int $size;
+
+    public string $type;
+
+    public string $url;
+}
diff --git a/app/src/Dto/KitchenTypeDto.php b/app/src/Dto/KitchenTypeDto.php
new file mode 100644
index 0000000..e7cf75b
--- /dev/null
+++ b/app/src/Dto/KitchenTypeDto.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Dto;
+
+class KitchenTypeDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $code;
+}
diff --git a/app/src/Dto/NewsCategoryDto.php b/app/src/Dto/NewsCategoryDto.php
new file mode 100644
index 0000000..8f1b7f8
--- /dev/null
+++ b/app/src/Dto/NewsCategoryDto.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Dto;
+
+class NewsCategoryDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $code;
+}
diff --git a/app/src/Dto/NewsDetailElementDto.php b/app/src/Dto/NewsDetailElementDto.php
new file mode 100644
index 0000000..224b9cc
--- /dev/null
+++ b/app/src/Dto/NewsDetailElementDto.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Dto;
+
+class NewsDetailElementDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $description;
+
+    public ?string $text;
+
+    /** @var FileDto Преаью */
+    public ?FileDto $image;
+
+    public string $create_at;
+}
diff --git a/app/src/Dto/NewsFilterVariants.php b/app/src/Dto/NewsFilterVariants.php
new file mode 100644
index 0000000..b1d55e4
--- /dev/null
+++ b/app/src/Dto/NewsFilterVariants.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace App\Dto;
+
+class NewsFilterVariants implements DtoInterface
+{
+    /** @var DtoCollection<NewsCategoryDto>  */
+    public DtoCollection $category;
+}
diff --git a/app/src/Dto/NewsListDto.php b/app/src/Dto/NewsListDto.php
new file mode 100644
index 0000000..93928bf
--- /dev/null
+++ b/app/src/Dto/NewsListDto.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Dto;
+
+class NewsListDto implements DtoInterface
+{
+    public PaginationDto $pagination;
+
+    /** @var DtoCollection<NewsListingElementDto>  */
+    public DtoCollection $list;
+
+    public NewsFilterVariants $filterVariants;
+}
diff --git a/app/src/Dto/NewsListingElementDto.php b/app/src/Dto/NewsListingElementDto.php
new file mode 100644
index 0000000..ef41fea
--- /dev/null
+++ b/app/src/Dto/NewsListingElementDto.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Dto;
+
+class NewsListingElementDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public ?string $description;
+
+    /** @var ?FileDto Превью */
+    public ?FileDto $image;
+
+    public string $create_at;
+
+    public string $detail_link;
+}
diff --git a/app/src/Dto/PaginationDto.php b/app/src/Dto/PaginationDto.php
new file mode 100644
index 0000000..7bd5a5c
--- /dev/null
+++ b/app/src/Dto/PaginationDto.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Dto;
+
+class PaginationDto implements DtoInterface
+{
+    public int $current_page = 1;
+    public int $pages;
+    public int $page_size;
+}
diff --git a/app/src/Dto/RestaurantDetailElementDto.php b/app/src/Dto/RestaurantDetailElementDto.php
new file mode 100644
index 0000000..13f29c9
--- /dev/null
+++ b/app/src/Dto/RestaurantDetailElementDto.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Dto;
+
+use Ramsey\Collection\Collection;
+
+class RestaurantDetailElementDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $code;
+
+    public string $coordinates;
+
+    public RestaurantTypeDto $type;
+
+    public ?string $check;
+
+    public ?string $check_info;
+
+    /** @var DtoCollection<KitchenTypeDto>|null  */
+    public ?DtoCollection $kitchen;
+
+    /** @var DtoCollection<string>|null */
+    public ?DtoCollection $phone;
+
+    /** @var DtoCollection<string>|null */
+    public ?DtoCollection $email;
+
+    /** @var DtoCollection<string>|null */
+    public ?DtoCollection $address;
+
+    /** @var DtoCollection<TagDto>|null */
+    public ?DtoCollection $tags;
+
+    public ?string $site;
+
+    /** @var FileDto|null Превью фото */
+    public ?FileDto $image;
+
+    /** @var DtoCollection<FileDto>|null */
+    public ?DtoCollection $gallery;
+}
diff --git a/app/src/Dto/RestaurantFilterVariantsDto.php b/app/src/Dto/RestaurantFilterVariantsDto.php
new file mode 100644
index 0000000..612cd5c
--- /dev/null
+++ b/app/src/Dto/RestaurantFilterVariantsDto.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Dto;
+
+use Ramsey\Collection\Collection;
+
+class RestaurantFilterVariantsDto implements DtoInterface
+{
+    /** @var DtoCollection<RestaurantTypeDto>  */
+    public DtoCollection $type;
+
+    /** @var DtoCollection<KitchenTypeDto>  */
+    public DtoCollection $kitchen;
+}
diff --git a/app/src/Dto/RestaurantListDto.php b/app/src/Dto/RestaurantListDto.php
new file mode 100644
index 0000000..87c6e61
--- /dev/null
+++ b/app/src/Dto/RestaurantListDto.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace App\Dto;
+
+use Ramsey\Collection\Collection;
+
+class RestaurantListDto implements DtoInterface
+{
+    public PaginationDto $pagination;
+
+    /** @var DtoCollection<RestaurantListingElementDto>  */
+    public DtoCollection $list;
+
+    public RestaurantFilterVariantsDto $filterVariants;
+}
diff --git a/app/src/Dto/RestaurantListingElementDto.php b/app/src/Dto/RestaurantListingElementDto.php
new file mode 100644
index 0000000..3b575da
--- /dev/null
+++ b/app/src/Dto/RestaurantListingElementDto.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Dto;
+
+class RestaurantListingElementDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $code;
+
+    public RestaurantTypeDto $type;
+
+    public ?string $check;
+
+    public ?FileDto $image;
+
+    public string $detail_link;
+}
diff --git a/app/src/Dto/RestaurantTypeDto.php b/app/src/Dto/RestaurantTypeDto.php
new file mode 100644
index 0000000..233bbc7
--- /dev/null
+++ b/app/src/Dto/RestaurantTypeDto.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Dto;
+
+class RestaurantTypeDto implements DtoInterface
+{
+    public string $id;
+
+    public string $name;
+
+    public string $code;
+}
diff --git a/app/src/Dto/TagDto.php b/app/src/Dto/TagDto.php
new file mode 100644
index 0000000..42dee2b
--- /dev/null
+++ b/app/src/Dto/TagDto.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Dto;
+
+class TagDto implements DtoInterface
+{
+    public string $name;
+
+    /** @var DtoCollection<string>  */
+    public DtoCollection $list;
+}
diff --git a/app/src/Dto/ValidateErrorDto.php b/app/src/Dto/ValidateErrorDto.php
new file mode 100644
index 0000000..307b43e
--- /dev/null
+++ b/app/src/Dto/ValidateErrorDto.php
@@ -0,0 +1,5 @@
+<?php
+
+namespace App\Dto;
+
+class ValidateErrorDto extends ErrorDto {}
diff --git a/app/src/Entity/File.php b/app/src/Entity/File.php
index c123f41..751cb27 100644
--- a/app/src/Entity/File.php
+++ b/app/src/Entity/File.php
@@ -2,6 +2,8 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
+use App\Dto\FileDto;
 use App\Repository\FileRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
@@ -9,7 +11,7 @@ use Doctrine\DBAL\Types\Types;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: FileRepository::class)]
-class File
+class File implements PrototypeDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -288,4 +290,19 @@ class File
 
         return $this;
     }
+
+    /** @inheritDoc */
+    public function getDto(): FileDto
+    {
+        $dto =  new FileDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->description = $this->getDescription();
+        $dto->size = $this->getSize();
+        $dto->type = $this->getType();
+        $dto->url = $this->getUrl();
+
+        return $dto;
+    }
 }
diff --git a/app/src/Entity/Kitchens.php b/app/src/Entity/Kitchens.php
index c5dc4aa..d45bf0a 100644
--- a/app/src/Entity/Kitchens.php
+++ b/app/src/Entity/Kitchens.php
@@ -2,6 +2,8 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
+use App\Dto\KitchenTypeDto;
 use App\Repository\KitchensRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
@@ -9,7 +11,7 @@ use Doctrine\DBAL\Types\Types;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: KitchensRepository::class)]
-class Kitchens
+class Kitchens implements PrototypeDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -94,4 +96,16 @@ class Kitchens
 
         return $this;
     }
+
+    /** @inheritDoc */
+    public function getDto(): DtoInterface
+    {
+        $dto = new KitchenTypeDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->code = $this->getCode();
+
+        return $dto;
+    }
 }
diff --git a/app/src/Entity/News.php b/app/src/Entity/News.php
index 5011c6d..e84bdc8 100644
--- a/app/src/Entity/News.php
+++ b/app/src/Entity/News.php
@@ -2,6 +2,9 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
+use App\Dto\NewsDetailElementDto;
+use App\Dto\NewsListingElementDto;
 use App\Repository\NewsRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
@@ -9,7 +12,7 @@ use Doctrine\DBAL\Types\Types;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: NewsRepository::class)]
-class News
+class News implements PrototypeElementDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -242,4 +245,34 @@ class News
 
         return $this;
     }
+
+    /** @inheritDoc */
+    public function getDto(): DtoInterface
+    {
+        $entity = new NewsListingElementDto();
+
+        $entity->id = $this->getId();
+        $entity->name = $this->getName();
+        $entity->description = $this->getDetailText();
+        $entity->image = $this->getPreviewImage()?->getDto();
+        $entity->create_at = $this->getCreatedAt();
+        $entity->detail_link = "api/v1/restaurants/" . $this->getId();
+
+        return $entity;
+    }
+
+    /** @inheritDoc */
+    public function getExtendedDto(): DtoInterface
+    {
+        $entity = new NewsDetailElementDto();
+
+        $entity->id = $this->getId();
+        $entity->name = $this->getName();
+        $entity->description = $this->getPreviewText();
+        $entity->text = $this->getDetailText();
+        $entity->image = $this->getPreviewImage()?->getDto();
+        $entity->create_at = $this->getCreatedAt();
+
+        return $entity;
+    }
 }
diff --git a/app/src/Entity/NewsCategories.php b/app/src/Entity/NewsCategories.php
index fb41930..0f77fd1 100644
--- a/app/src/Entity/NewsCategories.php
+++ b/app/src/Entity/NewsCategories.php
@@ -2,6 +2,8 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
+use App\Dto\NewsCategoryDto;
 use App\Repository\NewsCategoriesRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
@@ -9,7 +11,7 @@ use Doctrine\DBAL\Types\Types;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: NewsCategoriesRepository::class)]
-class NewsCategories
+class NewsCategories implements PrototypeDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -94,4 +96,16 @@ class NewsCategories
 
         return $this;
     }
+
+    /** @inheritDoc */
+    public function getDto(): DtoInterface
+    {
+        $dto = new NewsCategoryDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->code = $this->getCode();
+
+        return $dto;
+    }
 }
diff --git a/app/src/Entity/NewsType.php b/app/src/Entity/NewsType.php
index 493fff0..8331456 100644
--- a/app/src/Entity/NewsType.php
+++ b/app/src/Entity/NewsType.php
@@ -2,6 +2,7 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
 use App\Repository\NewsTypeRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
diff --git a/app/src/Entity/PrototypeDto.php b/app/src/Entity/PrototypeDto.php
new file mode 100644
index 0000000..19c8822
--- /dev/null
+++ b/app/src/Entity/PrototypeDto.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Entity;
+
+use App\Dto\DtoInterface;
+/** Интерфейс прототипа */
+interface PrototypeDto
+{
+    /** Породить dto из сущности */
+    public function getDto(): DtoInterface;
+}
diff --git a/app/src/Entity/PrototypeElementDto.php b/app/src/Entity/PrototypeElementDto.php
new file mode 100644
index 0000000..7c6a79f
--- /dev/null
+++ b/app/src/Entity/PrototypeElementDto.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Entity;
+
+use App\Dto\DtoInterface;
+
+interface PrototypeElementDto
+{
+    /** Породить dto элемента листинга */
+    public function getDto(): DtoInterface;
+
+    /** Породить dto детальной информации */
+    public function getExtendedDto(): DtoInterface;
+}
diff --git a/app/src/Entity/RestaurantTypes.php b/app/src/Entity/RestaurantTypes.php
index 12d132e..59f87c8 100644
--- a/app/src/Entity/RestaurantTypes.php
+++ b/app/src/Entity/RestaurantTypes.php
@@ -2,6 +2,8 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoInterface;
+use App\Dto\RestaurantTypeDto;
 use App\Repository\RestaurantTypesRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
@@ -10,7 +12,7 @@ use Doctrine\ORM\Mapping as ORM;
 use Doctrine\ORM\Mapping\GeneratedValue;
 
 #[ORM\Entity(repositoryClass: RestaurantTypesRepository::class)]
-class RestaurantTypes
+class RestaurantTypes implements PrototypeDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -98,4 +100,15 @@ class RestaurantTypes
 
         return $this;
     }
+
+    public function getDto(): DtoInterface
+    {
+        $dto = new RestaurantTypeDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->code = $this->getCode();
+
+        return $dto;
+    }
 }
diff --git a/app/src/Entity/Restaurants.php b/app/src/Entity/Restaurants.php
index 8f3380d..ec816f7 100644
--- a/app/src/Entity/Restaurants.php
+++ b/app/src/Entity/Restaurants.php
@@ -2,14 +2,22 @@
 
 namespace App\Entity;
 
+use App\Dto\DtoCollection;
+use App\Dto\DtoInterface;
+use App\Dto\FileDto;
+use App\Dto\KitchenTypeDto;
+use App\Dto\RestaurantDetailElementDto;
+use App\Dto\RestaurantListingElementDto;
+use App\Dto\TagDto;
 use App\Repository\RestaurantsRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
+use Ramsey\Collection\Collection as RamseyCollection;
 use Doctrine\DBAL\Types\Types;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: RestaurantsRepository::class)]
-class Restaurants
+class Restaurants implements PrototypeElementDto
 {
     #[ORM\Id]
     #[ORM\Column(type: Types::GUID)]
@@ -392,4 +400,114 @@ class Restaurants
 
         return $this;
     }
+
+    /** @inheritDoc */
+    public function getDto(): DtoInterface
+    {
+        $dto = new RestaurantListingElementDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->code = $this->getCode();
+        $dto->type = $this->getType()->getDto();
+        $dto->check = $this->getReceipt();
+        $dto->image = $this->getPreviewImage()?->getDto();
+        $dto->detail_link = 'api/v1/restaurants/' . $this->getId();
+
+        return $dto;
+    }
+
+    /** @inheritDoc
+     * @throws \JsonException Если получен неправильный json с бд
+     */
+    public function getExtendedDto(): DtoInterface
+    {
+        $dto = new RestaurantDetailElementDto();
+
+        $dto->id = $this->getId();
+        $dto->name = $this->getName();
+        $dto->code = $this->getCode();
+        $dto->coordinates = $this->getCoordinates();
+        $dto->type = $this->getType()->getDto();
+        $dto->check = $this->getReceipt();
+        $dto->check_info = $this->getReceiptInfo();
+
+        $dto->kitchen = new DtoCollection(
+            KitchenTypeDto::class,
+            $this->getKitchens()
+                ->map(function(Kitchens $kitchen) {
+                return $kitchen->getDto();
+                })
+                ->toArray()
+        );
+
+        $dto->phone = $this->decode($this->getPhone(), 'phone');
+        $dto->email = $this->decode($this->getEmail(), 'email');
+        $dto->address = $this->decode($this->getAddress(), 'address');
+        $dto->tags = $this->decodeTags($this->getTags());
+        $dto->site = $this->getSite();
+        $dto->image = $this->getPreviewImage()?->getDto();
+        $dto->gallery = new DtoCollection(
+            FileDto::class,
+            $this->getGallery()
+                ->map(function(File $file) {
+                    return $file->getDto();
+                })
+                ->toArray()
+        );
+
+        return $dto;
+    }
+
+    /**
+     * @throws \JsonException Если получен неправильный json с бд
+     * @return ?DtoCollection<string>
+     */
+    private function decode(?string $jsonString, string $name): ?DtoCollection
+    {
+        if ($jsonString === null) {
+            return null;
+        }
+        return new DtoCollection(
+            'string|null',
+            json_decode(
+                $jsonString,
+                true,
+                512,
+                JSON_THROW_ON_ERROR
+            )[$name]
+        );
+    }
+
+    private function decodeTags(?string $jsonString): ?DtoCollection
+    {
+        if ($jsonString === null) {
+            return null;
+        }
+
+        $jsonCollection = new RamseyCollection(
+            'array',
+            json_decode(
+                $jsonString,
+                true,
+                512,
+                JSON_THROW_ON_ERROR
+            )
+        );
+
+        return new DtoCollection(
+            TagDto::class,
+            $jsonCollection
+                ->map(function(array $tag) {
+                    $tagDto = new TagDto();
+                    $tagDto->name = key($tag);
+                    $tagDto->list = new DtoCollection(
+                    'string',
+                    $tag
+                    );
+                    return $tagDto;
+                })
+                ->toArray()
+        );
+    }
 }
-- 
GitLab