From 85ecf8b0bc90b3295653788a9a9d35916e0124a1 Mon Sep 17 00:00:00 2001
From: "a.shamavov" <a.shamavov@iqdev.digital>
Date: Tue, 7 May 2024 10:11:50 +0500
Subject: [PATCH] =?UTF-8?q?STA-1047=20|=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?=
 =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20POST,=20PUT,=20PATCH,=20DELETE=20?=
 =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB?=
 =?UTF-8?q?=D0=BB=D0=B5=D1=80=D0=BE=D0=B2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../RequestBodyArgumentResolver.php           |  46 +++
 src/Attribute/RequestBody.php                 |  11 +
 src/Controller/NewsController.php             |  33 +++
 src/Controller/RestaurantController.php       |  33 +++
 src/Entity/News.php                           |   2 +-
 src/Entity/Restaurant.php                     |   8 +-
 src/Exception/ErrorCodeEnum.php               |  12 +
 src/Exception/FileNotFoundException.php       |  13 +
 src/Exception/NewsExceptionEnum.php           |  10 -
 src/Exception/NewsNotFoundException.php       |   6 +-
 src/Exception/NewsTypeNotFoundException.php   |  13 +
 src/Exception/RequestBodyConvertException.php |  13 +
 src/Exception/RestaurantExceptionEnum.php     |  10 -
 src/Exception/RestaurantNotFoundException.php |   2 +-
 .../RestaurantTypeNotFoundException.php       |  13 +
 src/Exception/SeoNotFoundException.php        |  13 +
 src/Exception/SettlementNotFoundException.php |  13 +
 src/Exception/ValidationException.php         |  13 +
 src/Mapper/NewsMapper.php                     |  61 ++++
 src/Mapper/RestaurantMapper.php               |  88 +++++-
 src/Repository/FileRepository.php             |  29 +-
 .../Interface/NewsRepositoryInterface.php     |   7 +
 .../RestaurantRepositoryInterface.php         |   6 +
 src/Repository/NewsRepository.php             |  41 +++
 src/Repository/NewsTypeRepository.php         |  29 +-
 src/Repository/RestaurantRepository.php       |  31 ++
 src/Repository/RestaurantTypeRepository.php   |   6 +
 src/Repository/SeoRepository.php              |  29 +-
 src/Repository/SettlementRepository.php       |  29 +-
 src/Requests/CreateNewsRequest.php            | 164 +++++++++++
 src/Requests/CreateRestaurantRequest.php      | 272 ++++++++++++++++++
 src/Requests/EditNewsRequest.php              | 164 +++++++++++
 src/Requests/EditRestaurantRequest.php        | 272 ++++++++++++++++++
 src/Service/NewsService.php                   |  99 ++++++-
 src/Service/RestaurantService.php             | 108 +++++++
 35 files changed, 1573 insertions(+), 126 deletions(-)
 create mode 100644 src/ArgumentResolver/RequestBodyArgumentResolver.php
 create mode 100644 src/Attribute/RequestBody.php
 create mode 100644 src/Exception/ErrorCodeEnum.php
 create mode 100644 src/Exception/FileNotFoundException.php
 delete mode 100644 src/Exception/NewsExceptionEnum.php
 create mode 100644 src/Exception/NewsTypeNotFoundException.php
 create mode 100644 src/Exception/RequestBodyConvertException.php
 delete mode 100644 src/Exception/RestaurantExceptionEnum.php
 create mode 100644 src/Exception/RestaurantTypeNotFoundException.php
 create mode 100644 src/Exception/SeoNotFoundException.php
 create mode 100644 src/Exception/SettlementNotFoundException.php
 create mode 100644 src/Exception/ValidationException.php
 create mode 100644 src/Requests/CreateNewsRequest.php
 create mode 100644 src/Requests/CreateRestaurantRequest.php
 create mode 100644 src/Requests/EditNewsRequest.php
 create mode 100644 src/Requests/EditRestaurantRequest.php

diff --git a/src/ArgumentResolver/RequestBodyArgumentResolver.php b/src/ArgumentResolver/RequestBodyArgumentResolver.php
new file mode 100644
index 0000000..9e86ed0
--- /dev/null
+++ b/src/ArgumentResolver/RequestBodyArgumentResolver.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace App\ArgumentResolver;
+
+use App\Exception\RequestBodyConvertException;
+use App\Exception\ValidationException;
+use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+use App\Attribute\RequestBody;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
+use Symfony\Component\Serializer\Encoder\JsonEncoder;
+use Symfony\Component\Serializer\SerializerInterface;
+
+class RequestBodyArgumentResolver implements ValueResolverInterface
+{
+
+    public function __construct(
+        private SerializerInterface $serializer,
+        private ValidatorInterface $validator,
+    ) {}
+
+    public function resolve(Request $request, ArgumentMetadata $argument): iterable
+    {
+        if (!$argument->getAttributesOfType(RequestBody::class, ArgumentMetadata::IS_INSTANCEOF)) {
+            return [];
+        }
+
+        try {
+            $model = $this->serializer->deserialize(
+                $request->getContent(),
+                $argument->getType(),
+                JsonEncoder::FORMAT
+            );
+        } catch (\Throwable $throwable) {
+            throw new RequestBodyConvertException($throwable->getMessage());
+        }
+
+        $errors = $this->validator->validate($model);
+        if (count($errors) > 0) {
+            throw new ValidationException($errors);
+        }
+
+        return [$model];
+    }
+}
\ No newline at end of file
diff --git a/src/Attribute/RequestBody.php b/src/Attribute/RequestBody.php
new file mode 100644
index 0000000..34dc62c
--- /dev/null
+++ b/src/Attribute/RequestBody.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Attribute;
+
+use Attribute;
+
+#[Attribute(Attribute::TARGET_PARAMETER)]
+class RequestBody
+{
+
+}
\ No newline at end of file
diff --git a/src/Controller/NewsController.php b/src/Controller/NewsController.php
index 12d0a6e..27ee418 100644
--- a/src/Controller/NewsController.php
+++ b/src/Controller/NewsController.php
@@ -4,7 +4,10 @@ declare(strict_types=1);
 
 namespace App\Controller;
 
+use App\Attribute\RequestBody;
 use App\Exception\NewsNotFoundException;
+use App\Requests\CreateNewsRequest;
+use App\Requests\EditNewsRequest;
 use App\Requests\NewsListRequest;
 use App\Service\NewsService;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -55,4 +58,34 @@ class NewsController extends AbstractController
             ], $e->getCode());
         }
     }
+
+    #[Route('/news', name: 'addNews', methods: ['POST'])]
+    public function addNews(
+        #[RequestBody] CreateNewsRequest $request
+    ): Response {
+        return $this->json($this->newsService->addNewsByRequest($request));
+    }
+
+    #[Route('/news/{id}', name: 'putNews', methods: ['PUT'])]
+    public function putNews(
+        string $id,
+        #[RequestBody] EditNewsRequest $request
+    ): Response {
+        return $this->json($this->newsService->putNewsByRequest($id, $request));
+    }
+
+    #[Route('/news/{id}', name: 'patchNews', methods: ['PATCH'])]
+    public function patchNews(
+        string $id,
+        #[RequestBody] EditNewsRequest $request
+    ): Response {
+        return $this->json($this->newsService->patchNewsByRequest($id, $request));
+    }
+
+    #[Route('/news/{id}', name: 'deleteNews', methods: ['DELETE'])]
+    public function deleteNews(string $id): Response
+    {
+        $this->newsService->deleteNews($id);
+        return $this->json(null);
+    }
 }
diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php
index 8f842cb..7761231 100644
--- a/src/Controller/RestaurantController.php
+++ b/src/Controller/RestaurantController.php
@@ -4,7 +4,10 @@ declare(strict_types=1);
 
 namespace App\Controller;
 
+use App\Attribute\RequestBody;
 use App\Exception\RestaurantNotFoundException;
+use App\Requests\CreateRestaurantRequest;
+use App\Requests\EditRestaurantRequest;
 use App\Requests\RestaurantListRequest;
 use App\Service\RestaurantService;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -39,4 +42,34 @@ class RestaurantController extends AbstractController
             ], $e->getCode());
         }
     }
+
+    #[Route('/restaurant', name: 'addRestaurant', methods: ['POST'])]
+    public function addRestaurant(
+        #[RequestBody] CreateRestaurantRequest $request
+    ): Response {
+        return $this->json($this->restaurantService->addRestaurantByRequest($request));
+    }
+
+    #[Route('/restaurant/{id}', name: 'putRestaurant', methods: ['PUT'])]
+    public function putRestaurant(
+        string $id,
+        #[RequestBody] EditRestaurantRequest $request
+    ): Response {
+        return $this->json($this->restaurantService->putRestaurantByRequest($id, $request));
+    }
+
+    #[Route('/restaurant/{id}', name: 'patchRestaurant', methods: ['PATCH'])]
+    public function patchRestaurant(
+        string $id,
+        #[RequestBody] EditRestaurantRequest $request
+    ): Response {
+        return $this->json($this->restaurantService->patchRestaurantByRequest($id, $request));
+    }
+
+    #[Route('/restaurant/{id}', name: 'deleteRestaurant', methods: ['DELETE'])]
+    public function deleteRestaurant(string $id): Response
+    {
+        $this->restaurantService->deleteRestaurant($id);
+        return $this->json(null);
+    }
 }
diff --git a/src/Entity/News.php b/src/Entity/News.php
index 1cca2ff..2458122 100644
--- a/src/Entity/News.php
+++ b/src/Entity/News.php
@@ -63,7 +63,7 @@ class News
     #[ORM\JoinColumn(nullable: false)]
     private ?Seo $seo = null;
 
-    #[ORM\OneToOne(cascade: ['persist', 'remove'])]
+    #[ORM\OneToOne]
     #[ORM\JoinColumn(nullable: false)]
     private ?File $file = null;
 
diff --git a/src/Entity/Restaurant.php b/src/Entity/Restaurant.php
index ff7d311..3783fc9 100644
--- a/src/Entity/Restaurant.php
+++ b/src/Entity/Restaurant.php
@@ -94,7 +94,7 @@ class Restaurant
     #[ORM\JoinColumn(nullable: false)]
     private ?Seo $seo = null;
 
-    #[ORM\OneToOne(cascade: ['persist', 'remove'], fetch: 'EAGER')]
+    #[ORM\OneToOne(fetch: 'EAGER')]
     #[ORM\JoinColumn(nullable: false)]
     private ?File $file = null;
 
@@ -109,6 +109,12 @@ class Restaurant
         return $this->id;
     }
 
+    public function setId(Uuid $id): self
+    {
+        $this->id = $id;
+        return $this;
+    }
+
     public function getName(): ?string
     {
         return $this->name;
diff --git a/src/Exception/ErrorCodeEnum.php b/src/Exception/ErrorCodeEnum.php
new file mode 100644
index 0000000..cc4948b
--- /dev/null
+++ b/src/Exception/ErrorCodeEnum.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Exception;
+
+use Symfony\Component\HttpFoundation\Response;
+
+enum ErrorCodeEnum: int
+{
+    case NotFound = Response::HTTP_NOT_FOUND;
+    case BadRequest = Response::HTTP_BAD_REQUEST;
+    case UnprocessableEntity = Response::HTTP_UNPROCESSABLE_ENTITY;
+}
diff --git a/src/Exception/FileNotFoundException.php b/src/Exception/FileNotFoundException.php
new file mode 100644
index 0000000..39fd330
--- /dev/null
+++ b/src/Exception/FileNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class FileNotFoundException extends RuntimeException
+{
+    public function __construct()
+    {
+        parent::__construct("File not found", ErrorCodeEnum::NotFound->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/NewsExceptionEnum.php b/src/Exception/NewsExceptionEnum.php
deleted file mode 100644
index 38c5c28..0000000
--- a/src/Exception/NewsExceptionEnum.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-namespace App\Exception;
-
-use Symfony\Component\HttpFoundation\Response;
-
-enum NewsExceptionEnum: int
-{
-    case NotFound = Response::HTTP_NOT_FOUND;
-}
diff --git a/src/Exception/NewsNotFoundException.php b/src/Exception/NewsNotFoundException.php
index 9b4dd01..5ccf6c9 100644
--- a/src/Exception/NewsNotFoundException.php
+++ b/src/Exception/NewsNotFoundException.php
@@ -2,10 +2,12 @@
 
 namespace App\Exception;
 
-class NewsNotFoundException extends \RuntimeException
+use RuntimeException;
+
+class NewsNotFoundException extends RuntimeException
 {
     public function __construct()
     {
-        parent::__construct("News not found", NewsExceptionEnum::NotFound->value);
+        parent::__construct("News not found", ErrorCodeEnum::NotFound->value);
     }
 }
\ No newline at end of file
diff --git a/src/Exception/NewsTypeNotFoundException.php b/src/Exception/NewsTypeNotFoundException.php
new file mode 100644
index 0000000..0d4505f
--- /dev/null
+++ b/src/Exception/NewsTypeNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class NewsTypeNotFoundException extends RuntimeException
+{
+    public function __construct()
+    {
+        parent::__construct("News type not found", ErrorCodeEnum::NotFound->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/RequestBodyConvertException.php b/src/Exception/RequestBodyConvertException.php
new file mode 100644
index 0000000..40a3418
--- /dev/null
+++ b/src/Exception/RequestBodyConvertException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class RequestBodyConvertException extends RuntimeException
+{
+    public function __construct($message)
+    {
+        parent::__construct("Error converting request body" . $message, ErrorCodeEnum::BadRequest->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/RestaurantExceptionEnum.php b/src/Exception/RestaurantExceptionEnum.php
deleted file mode 100644
index 6f3f8fa..0000000
--- a/src/Exception/RestaurantExceptionEnum.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-namespace App\Exception;
-
-use Symfony\Component\HttpFoundation\Response;
-
-enum RestaurantExceptionEnum: int
-{
-    case NotFound = Response::HTTP_NOT_FOUND;
-}
diff --git a/src/Exception/RestaurantNotFoundException.php b/src/Exception/RestaurantNotFoundException.php
index 25f78ab..43fb797 100644
--- a/src/Exception/RestaurantNotFoundException.php
+++ b/src/Exception/RestaurantNotFoundException.php
@@ -6,6 +6,6 @@ class RestaurantNotFoundException extends \RuntimeException
 {
     public function __construct()
     {
-        parent::__construct("Restaurant not found", RestaurantExceptionEnum::NotFound->value);
+        parent::__construct("Restaurant not found", ErrorCodeEnum::NotFound->value);
     }
 }
\ No newline at end of file
diff --git a/src/Exception/RestaurantTypeNotFoundException.php b/src/Exception/RestaurantTypeNotFoundException.php
new file mode 100644
index 0000000..6c98c9c
--- /dev/null
+++ b/src/Exception/RestaurantTypeNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class RestaurantTypeNotFoundException extends RuntimeException
+{
+    public function __construct()
+    {
+        parent::__construct("Restaurant type not found", ErrorCodeEnum::NotFound->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/SeoNotFoundException.php b/src/Exception/SeoNotFoundException.php
new file mode 100644
index 0000000..73c237c
--- /dev/null
+++ b/src/Exception/SeoNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class SeoNotFoundException extends RuntimeException
+{
+    public function __construct()
+    {
+        parent::__construct("Seo not found", ErrorCodeEnum::NotFound->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/SettlementNotFoundException.php b/src/Exception/SettlementNotFoundException.php
new file mode 100644
index 0000000..85a159e
--- /dev/null
+++ b/src/Exception/SettlementNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class SettlementNotFoundException extends RuntimeException
+{
+    public function __construct()
+    {
+        parent::__construct("Settlement not found", ErrorCodeEnum::NotFound->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Exception/ValidationException.php b/src/Exception/ValidationException.php
new file mode 100644
index 0000000..08b8e84
--- /dev/null
+++ b/src/Exception/ValidationException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Exception;
+
+use RuntimeException;
+
+class ValidationException extends RuntimeException
+{
+    public function __construct($message)
+    {
+        parent::__construct('Validation failed' . $message, ErrorCodeEnum::UnprocessableEntity->value);
+    }
+}
\ No newline at end of file
diff --git a/src/Mapper/NewsMapper.php b/src/Mapper/NewsMapper.php
index 4b06e81..679bb32 100644
--- a/src/Mapper/NewsMapper.php
+++ b/src/Mapper/NewsMapper.php
@@ -2,15 +2,22 @@
 
 namespace App\Mapper;
 
+use App\Entity\File;
 use App\Entity\News;
 use App\Entity\NewsCategory;
+use App\Entity\NewsType;
+use App\Entity\Seo;
 use App\Model\NewsDetailElement;
 use App\Model\NewsFilterVariants;
 use App\Model\NewsList;
 use App\Model\NewsListingElement;
 use App\Model\NewsCategory as NewsCategoryModel;
 use App\Model\Pagination;
+use App\Requests\CreateNewsRequest;
+use App\Requests\EditNewsRequest;
 use Ramsey\Collection\Collection;
+use DateTimeImmutable;
+use Symfony\Component\Uid\Uuid;
 
 class NewsMapper
 {
@@ -74,4 +81,58 @@ class NewsMapper
             $newsCategory->getCode(),
         );
     }
+
+    public static function createNewsEntity(
+        CreateNewsRequest|EditNewsRequest $request,
+        NewsType $newsType,
+        Seo $seo,
+        File $file,
+        string $id = null
+    ): News {
+        $news = (new News())
+            ->setCode($request->getCode())
+            ->setActive($request->isActive())
+            ->setCreateAt(new DateTimeImmutable())
+            ->setUpdateAt(new DateTimeImmutable())
+            ->setSort($request->getSort())
+            ->setPreviewImage($request->getPreviewImage())
+            ->setDetailImage($request->getDetailImage())
+            ->setPreviewText($request->getPreviewText())
+            ->setDetailText($request->getDetailText())
+            ->setType($newsType)
+            ->setMainPageRender($request->isMainPageRender())
+            ->setSeo($seo)
+            ->setFile($file);
+
+        if ($id !== null) {
+            $news->setId(new Uuid($id));
+        }
+
+        return $news;
+    }
+
+    public static function updateNewsEntity(
+        CreateNewsRequest|EditNewsRequest $request,
+        NewsType $newsType,
+        Seo $seo,
+        File $file,
+        News $news
+    ): News
+    {
+        $news->setCode($request->getCode());
+        $news->setActive($request->isActive());
+        $news->setCreateAt($news->getCreateAt());
+        $news->setUpdateAt(new DateTimeImmutable());
+        $news->setSort($request->getSort());
+        $news->setPreviewText($request->getPreviewText());
+        $news->setDetailText($request->getDetailText());
+        $news->setPreviewImage($request->getPreviewImage());
+        $news->setDetailImage($request->getDetailImage());
+        $news->setType($newsType);
+        $news->setMainPageRender($request->isMainPageRender());
+        $news->setSeo($seo);
+        $news->setFile($file);
+
+        return $news;
+    }
 }
\ No newline at end of file
diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php
index fc72b15..6674e68 100644
--- a/src/Mapper/RestaurantMapper.php
+++ b/src/Mapper/RestaurantMapper.php
@@ -6,7 +6,10 @@ use App\Entity\Gallery;
 use App\Entity\Kitchen;
 use App\Entity\Restaurant;
 use App\Entity\RestaurantType;
+use App\Entity\Seo;
+use App\Entity\Settlement;
 use App\Entity\Tags;
+use App\Entity\File;
 use App\Model\KitchenType;
 use App\Model\Pagination;
 use App\Model\RestaurantDetailElement;
@@ -15,8 +18,12 @@ use App\Model\RestaurantList;
 use App\Model\RestaurantListingElement;
 use App\Model\RestaurantType as RestaurantTypeModel;
 use App\Model\Tag;
-use App\Model\File;
+use App\Model\File as FileModel;
+use App\Requests\CreateRestaurantRequest;
+use App\Requests\EditRestaurantRequest;
 use Ramsey\Collection\Collection;
+use DateTimeImmutable;
+use Symfony\Component\Uid\Uuid;
 
 class RestaurantMapper
 {
@@ -69,7 +76,7 @@ class RestaurantMapper
 
     public static function mapToDetailElement(
         Restaurant $restaurant,
-        Collection $gallery
+        Collection|null $gallery
     ): RestaurantDetailElement {
         return new RestaurantDetailElement(
             $restaurant->getId(),
@@ -96,7 +103,9 @@ class RestaurantMapper
             ),
             $restaurant->getSite(),
             FileMapper::mapToFile($restaurant->getFile()),
-            self::mapToGallery($gallery),
+            $gallery
+                ? self::mapToGallery($gallery)
+                : new Collection(FileModel::class),
             $restaurant->getSeo()?->getTitle(),
             $restaurant->getSeo()?->getDescription(),
             $restaurant->getSeo()?->getKeywords()
@@ -135,10 +144,81 @@ class RestaurantMapper
 
     public static function mapToGallery(Collection $gallery): Collection
     {
-        return new Collection(File::class, array_map(
+        return new Collection(FileModel::class, array_map(
             function (Gallery $galleryOne) {
                 return FileMapper::mapToFile($galleryOne->getFile());
             }, $gallery->toArray())
         );
     }
+
+    public static function createRestaurantEntity(
+        CreateRestaurantRequest|EditRestaurantRequest $request,
+        RestaurantType $restaurantType,
+        Settlement $settlement,
+        Seo $seo,
+        File $file,
+        string $id = null
+    ): Restaurant {
+        $restaurant = (new Restaurant())
+            ->setName($request->getName())
+            ->setCode($request->getCode())
+            ->setActive($request->isActive())
+            ->setSort($request->getSort())
+            ->setCreateAt(new DateTimeImmutable())
+            ->setUpdateAt(new DateTimeImmutable())
+            ->setCoordinates($request->getCoordinates())
+            ->setTypeId($restaurantType)
+            ->setSettlementId($settlement)
+            ->setDescription($request->getDescription())
+            ->setCheckPrice($request->getCheck())
+            ->setCheckInfo($request->getCheckInfo())
+            ->setPhone($request->getPhone())
+            ->setEmail($request->getEmail())
+            ->setAddress($request->getAddress())
+            ->setSite($request->getSite())
+            ->setPreviewImage($request->getPreviewImage())
+            ->setDetailImage($request->getDetailImage())
+            ->setSeo($seo)
+            ->setFile($file)
+            ->setHowToFind($request->getHowToFind());
+
+        if ($id !== null) {
+            $restaurant->setId(new Uuid($id));
+        }
+
+        return $restaurant;
+    }
+
+    public static function updateRestaurantEntity(
+        EditRestaurantRequest $request,
+        RestaurantType $restaurantType,
+        Settlement $settlement,
+        Seo $seo,
+        File $file,
+        Restaurant $restaurant
+    ): Restaurant
+    {
+        $restaurant->setName($request->getName());
+        $restaurant->setCode($request->getCode());
+        $restaurant->setActive($request->isActive());
+        $restaurant->setSort($request->getSort());
+        $restaurant->setCreateAt($restaurant->getCreateAt());
+        $restaurant->setUpdateAt(new DateTimeImmutable());
+        $restaurant->setCoordinates($request->getCoordinates());
+        $restaurant->setTypeId($restaurantType);
+        $restaurant->setSettlementId($settlement);
+        $restaurant->setDescription($request->getDescription());
+        $restaurant->setCheckPrice($request->getCheck());
+        $restaurant->setCheckInfo($request->getCheckInfo());
+        $restaurant->setPhone($request->getPhone());
+        $restaurant->setEmail($request->getEmail());
+        $restaurant->setAddress($request->getAddress());
+        $restaurant->setSite($request->getSite());
+        $restaurant->setPreviewImage($request->getPreviewImage());
+        $restaurant->setHowToFind($request->getHowToFind());
+        $restaurant->setDetailImage($request->getDetailImage());
+        $restaurant->setSeo($seo);
+        $restaurant->setFile($file);
+        return $restaurant;
+    }
 }
\ No newline at end of file
diff --git a/src/Repository/FileRepository.php b/src/Repository/FileRepository.php
index 4d5449a..2253c9c 100644
--- a/src/Repository/FileRepository.php
+++ b/src/Repository/FileRepository.php
@@ -5,6 +5,7 @@ namespace App\Repository;
 use App\Entity\File;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
+use Symfony\Component\Uid\Uuid;
 
 /**
  * @extends ServiceEntityRepository<File>
@@ -21,28 +22,8 @@ class FileRepository extends ServiceEntityRepository
         parent::__construct($registry, File::class);
     }
 
-//    /**
-//     * @return File[] Returns an array of File objects
-//     */
-//    public function findByExampleField($value): array
-//    {
-//        return $this->createQueryBuilder('f')
-//            ->andWhere('f.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->orderBy('f.id', 'ASC')
-//            ->setMaxResults(10)
-//            ->getQuery()
-//            ->getResult()
-//        ;
-//    }
-
-//    public function findOneBySomeField($value): ?File
-//    {
-//        return $this->createQueryBuilder('f')
-//            ->andWhere('f.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->getQuery()
-//            ->getOneOrNullResult()
-//        ;
-//    }
+    public function getById(Uuid $id): ?File
+    {
+        return $this->find($id);
+    }
 }
diff --git a/src/Repository/Interface/NewsRepositoryInterface.php b/src/Repository/Interface/NewsRepositoryInterface.php
index 10a95f6..a27f0d8 100644
--- a/src/Repository/Interface/NewsRepositoryInterface.php
+++ b/src/Repository/Interface/NewsRepositoryInterface.php
@@ -10,4 +10,11 @@ interface NewsRepositoryInterface
     public function getCount(): int;
     public function getMainNews(): News;
     public function getNewsById(string $newsId): News|null;
+    public function getById(string $id): News|null;
+
+    public function create(News $news): News;
+
+    public function newsExists(string $id): bool;
+
+    public function delete(string $id): void;
 }
\ No newline at end of file
diff --git a/src/Repository/Interface/RestaurantRepositoryInterface.php b/src/Repository/Interface/RestaurantRepositoryInterface.php
index b23f1e2..48665b3 100644
--- a/src/Repository/Interface/RestaurantRepositoryInterface.php
+++ b/src/Repository/Interface/RestaurantRepositoryInterface.php
@@ -11,4 +11,10 @@ interface RestaurantRepositoryInterface
     public function getCount(): int;
 
     public function getById(string $id): Restaurant|null;
+
+    public function create(Restaurant $restaurant): Restaurant;
+
+    public function restaurantExists(string $id): bool;
+
+    public function delete(string $id): void;
 }
\ No newline at end of file
diff --git a/src/Repository/NewsRepository.php b/src/Repository/NewsRepository.php
index 597484e..f22f9a9 100644
--- a/src/Repository/NewsRepository.php
+++ b/src/Repository/NewsRepository.php
@@ -57,4 +57,45 @@ class NewsRepository extends ServiceEntityRepository implements NewsRepositoryIn
             return null;
         }
     }
+
+    public function getById(string $id): News|null
+    {
+        try {
+            $uuid = new Uuid($id);
+            return $this->find($uuid);
+        } catch (\Exception $e) {
+            return null;
+        }
+    }
+
+    public function create(News $news): News
+    {
+        $id = $news->getId();
+        $this->getEntityManager()->persist($news);
+
+        if ($id !== null) {
+            $news->setId($id);
+        }
+
+        $this->getEntityManager()->flush();
+        return $news;
+    }
+
+    public function update(News $news): News
+    {
+        $this->getEntityManager()->persist($news);
+        $this->getEntityManager()->flush();
+        return $news;
+    }
+
+    public function newsExists(string $id): bool
+    {
+        return null !== $this->find(new Uuid($id));
+    }
+
+    public function delete(string $id): void
+    {
+        $this->getEntityManager()->remove($this->find(new Uuid($id)));
+        $this->getEntityManager()->flush();
+    }
 }
diff --git a/src/Repository/NewsTypeRepository.php b/src/Repository/NewsTypeRepository.php
index 385998b..99181da 100644
--- a/src/Repository/NewsTypeRepository.php
+++ b/src/Repository/NewsTypeRepository.php
@@ -5,6 +5,7 @@ namespace App\Repository;
 use App\Entity\NewsType;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
+use Symfony\Component\Uid\Uuid;
 
 /**
  * @extends ServiceEntityRepository<NewsType>
@@ -21,28 +22,8 @@ class NewsTypeRepository extends ServiceEntityRepository
         parent::__construct($registry, NewsType::class);
     }
 
-//    /**
-//     * @return NewsType[] Returns an array of NewsType objects
-//     */
-//    public function findByExampleField($value): array
-//    {
-//        return $this->createQueryBuilder('n')
-//            ->andWhere('n.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->orderBy('n.id', 'ASC')
-//            ->setMaxResults(10)
-//            ->getQuery()
-//            ->getResult()
-//        ;
-//    }
-
-//    public function findOneBySomeField($value): ?NewsType
-//    {
-//        return $this->createQueryBuilder('n')
-//            ->andWhere('n.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->getQuery()
-//            ->getOneOrNullResult()
-//        ;
-//    }
+    public function getById(string $id): ?NewsType
+    {
+        return $this->find(new Uuid($id));
+    }
 }
diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php
index 3a23833..a235f54 100644
--- a/src/Repository/RestaurantRepository.php
+++ b/src/Repository/RestaurantRepository.php
@@ -62,4 +62,35 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant
             return null;
         }
     }
+
+    public function create(Restaurant $restaurant): Restaurant
+    {
+        $id = $restaurant->getId();
+        $this->getEntityManager()->persist($restaurant);
+
+        if ($id !== null) {
+            $restaurant->setId($id);
+        }
+
+        $this->getEntityManager()->flush();
+        return $restaurant;
+    }
+
+    public function update(Restaurant $restaurant): Restaurant
+    {
+        $this->getEntityManager()->persist($restaurant);
+        $this->getEntityManager()->flush();
+        return $restaurant;
+    }
+
+    public function restaurantExists(string $id): bool
+    {
+        return null !== $this->find(new Uuid($id));
+    }
+
+    public function delete(string $id): void
+    {
+        $this->getEntityManager()->remove($this->find(new Uuid($id)));
+        $this->getEntityManager()->flush();
+    }
 }
diff --git a/src/Repository/RestaurantTypeRepository.php b/src/Repository/RestaurantTypeRepository.php
index aa1f621..901e49d 100644
--- a/src/Repository/RestaurantTypeRepository.php
+++ b/src/Repository/RestaurantTypeRepository.php
@@ -6,6 +6,7 @@ use App\Entity\RestaurantType;
 use App\Repository\Interface\RestaurantTypeRepositoryInterface;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
+use Symfony\Component\Uid\Uuid;
 
 /**
  * @extends ServiceEntityRepository<RestaurantType>
@@ -26,4 +27,9 @@ class RestaurantTypeRepository extends ServiceEntityRepository implements Restau
     {
         return $this->findAll();
     }
+
+    public function getById(Uuid $id): ?RestaurantType
+    {
+        return $this->find($id);
+    }
 }
diff --git a/src/Repository/SeoRepository.php b/src/Repository/SeoRepository.php
index 09b0990..97e976a 100644
--- a/src/Repository/SeoRepository.php
+++ b/src/Repository/SeoRepository.php
@@ -5,6 +5,7 @@ namespace App\Repository;
 use App\Entity\Seo;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
+use Symfony\Component\Uid\Uuid;
 
 /**
  * @extends ServiceEntityRepository<Seo>
@@ -21,28 +22,8 @@ class SeoRepository extends ServiceEntityRepository
         parent::__construct($registry, Seo::class);
     }
 
-//    /**
-//     * @return Seo[] Returns an array of Seo objects
-//     */
-//    public function findByExampleField($value): array
-//    {
-//        return $this->createQueryBuilder('s')
-//            ->andWhere('s.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->orderBy('s.id', 'ASC')
-//            ->setMaxResults(10)
-//            ->getQuery()
-//            ->getResult()
-//        ;
-//    }
-
-//    public function findOneBySomeField($value): ?Seo
-//    {
-//        return $this->createQueryBuilder('s')
-//            ->andWhere('s.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->getQuery()
-//            ->getOneOrNullResult()
-//        ;
-//    }
+    public function getById(Uuid $id): ?Seo
+    {
+        return $this->find($id);
+    }
 }
diff --git a/src/Repository/SettlementRepository.php b/src/Repository/SettlementRepository.php
index 1b5e100..d191d81 100644
--- a/src/Repository/SettlementRepository.php
+++ b/src/Repository/SettlementRepository.php
@@ -5,6 +5,7 @@ namespace App\Repository;
 use App\Entity\Settlement;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
+use Symfony\Component\Uid\Uuid;
 
 /**
  * @extends ServiceEntityRepository<Settlement>
@@ -21,28 +22,8 @@ class SettlementRepository extends ServiceEntityRepository
         parent::__construct($registry, Settlement::class);
     }
 
-//    /**
-//     * @return Settlement[] Returns an array of Settlement objects
-//     */
-//    public function findByExampleField($value): array
-//    {
-//        return $this->createQueryBuilder('s')
-//            ->andWhere('s.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->orderBy('s.id', 'ASC')
-//            ->setMaxResults(10)
-//            ->getQuery()
-//            ->getResult()
-//        ;
-//    }
-
-//    public function findOneBySomeField($value): ?Settlement
-//    {
-//        return $this->createQueryBuilder('s')
-//            ->andWhere('s.exampleField = :val')
-//            ->setParameter('val', $value)
-//            ->getQuery()
-//            ->getOneOrNullResult()
-//        ;
-//    }
+    public function getById(Uuid $id): ?Settlement
+    {
+        return $this->find($id);
+    }
 }
diff --git a/src/Requests/CreateNewsRequest.php b/src/Requests/CreateNewsRequest.php
new file mode 100644
index 0000000..25653b6
--- /dev/null
+++ b/src/Requests/CreateNewsRequest.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace App\Requests;
+
+use Symfony\Component\Uid\Uuid;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class CreateNewsRequest
+{
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $typeId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $seoId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $fileId;
+
+    #[Assert\NotBlank]
+    private string $code;
+
+    #[Assert\NotBlank]
+    #[Assert\Type('bool')]
+    private bool $active;
+
+    #[Assert\NotBlank]
+    #[Assert\Type('int')]
+    private int $sort;
+
+    private string $previewImage;
+
+    private string $detailImage;
+
+    private string $previewText;
+
+    private string $detailText;
+
+    #[Assert\Type('bool')]
+    private bool $mainPageRender;
+
+    public function getTypeId(): Uuid
+    {
+        return $this->typeId;
+    }
+
+    public function setTypeId(Uuid $typeId): self
+    {
+        $this->typeId = $typeId;
+        return $this;
+    }
+
+    public function getSeoId(): Uuid
+    {
+        return $this->seoId;
+    }
+
+    public function setSeoId(Uuid $seoId): self
+    {
+        $this->seoId = $seoId;
+        return $this;
+    }
+
+    public function getFileId(): Uuid
+    {
+        return $this->fileId;
+    }
+
+    public function setFileId(Uuid $fileId): self
+    {
+        $this->fileId = $fileId;
+        return $this;
+    }
+
+    public function getCode(): string
+    {
+        return $this->code;
+    }
+
+    public function setCode(string $code): self
+    {
+        $this->code = $code;
+        return $this;
+    }
+
+    public function isActive(): bool
+    {
+        return $this->active;
+    }
+
+    public function setActive(bool $active): self
+    {
+        $this->active = $active;
+        return $this;
+    }
+
+    public function getSort(): int
+    {
+        return $this->sort;
+    }
+
+    public function setSort(int $sort): self
+    {
+        $this->sort = $sort;
+        return $this;
+    }
+
+    public function getPreviewImage(): string
+    {
+        return $this->previewImage;
+    }
+
+    public function setPreviewImage(string $previewImage): self
+    {
+        $this->previewImage = $previewImage;
+        return $this;
+    }
+
+    public function getDetailImage(): string
+    {
+        return $this->detailImage;
+    }
+
+    public function setDetailImage(string $detailImage): self
+    {
+        $this->detailImage = $detailImage;
+        return $this;
+    }
+
+    public function getPreviewText(): string
+    {
+        return $this->previewText;
+    }
+
+    public function setPreviewText(string $previewText): self
+    {
+        $this->previewText = $previewText;
+        return $this;
+    }
+
+    public function getDetailText(): string
+    {
+        return $this->detailText;
+    }
+
+    public function setDetailText(string $detailText): self
+    {
+        $this->detailText = $detailText;
+        return $this;
+    }
+
+    public function isMainPageRender(): bool
+    {
+        return $this->mainPageRender;
+    }
+
+    public function setMainPageRender(bool $mainPageRender): self
+    {
+        $this->mainPageRender = $mainPageRender;
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/src/Requests/CreateRestaurantRequest.php b/src/Requests/CreateRestaurantRequest.php
new file mode 100644
index 0000000..bc2e761
--- /dev/null
+++ b/src/Requests/CreateRestaurantRequest.php
@@ -0,0 +1,272 @@
+<?php
+
+namespace App\Requests;
+
+use Symfony\Component\Uid\Uuid;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class CreateRestaurantRequest
+{
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $typeId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $settlementId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $seoId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $fileId;
+
+    #[Assert\NotBlank]
+    private string $name;
+
+    #[Assert\NotBlank]
+    private string $code;
+
+    #[Assert\Type('bool')]
+    private bool $active;
+
+    #[Assert\Type('int')]
+    private int $sort;
+
+    #[Assert\Type('array')]
+    private array $coordinates;
+
+    private string $description;
+
+    private string $check;
+
+    private string $checkInfo;
+
+    #[Assert\Type('array')]
+    private array $phone;
+
+    #[Assert\Type('array')]
+    private array $email;
+
+    #[Assert\Type('array')]
+    private array $address;
+
+    private string $site;
+
+    private string $previewImage;
+
+    private string $detailImage;
+
+    private string $howToFind;
+
+    public function getTypeId(): Uuid
+    {
+        return $this->typeId;
+    }
+
+    public function setTypeId(Uuid $typeId): self
+    {
+        $this->typeId = $typeId;
+        return $this;
+    }
+
+    public function getSettlementId(): Uuid
+    {
+        return $this->settlementId;
+    }
+
+    public function setSettlementId(Uuid $settlementId): self
+    {
+        $this->settlementId = $settlementId;
+        return $this;
+    }
+
+    public function getSeoId(): Uuid
+    {
+        return $this->seoId;
+    }
+
+    public function setSeoId(Uuid $seoId): self
+    {
+        $this->seoId = $seoId;
+        return $this;
+    }
+
+    public function getFileId(): Uuid
+    {
+        return $this->fileId;
+    }
+
+    public function setFileId(Uuid $fileId): self
+    {
+        $this->fileId = $fileId;
+        return $this;
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+
+    public function setName(string $name): self
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    public function getCode(): string
+    {
+        return $this->code;
+    }
+
+    public function setCode(string $code): self
+    {
+        $this->code = $code;
+        return $this;
+    }
+
+    public function isActive(): bool
+    {
+        return $this->active;
+    }
+
+    public function setActive(bool $active): self
+    {
+        $this->active = $active;
+        return $this;
+    }
+
+    public function getSort(): int
+    {
+        return $this->sort;
+    }
+
+    public function setSort(int $sort): self
+    {
+        $this->sort = $sort;
+        return $this;
+    }
+
+    public function getCoordinates(): array
+    {
+        return $this->coordinates;
+    }
+
+    public function setCoordinates(array $coordinates): self
+    {
+        $this->coordinates = $coordinates;
+        return $this;
+    }
+
+    public function getDescription(): string
+    {
+        return $this->description;
+    }
+
+    public function setDescription(string $description): self
+    {
+        $this->description = $description;
+        return $this;
+    }
+
+    public function getCheck(): string
+    {
+        return $this->check;
+    }
+
+    public function setCheck(string $check): self
+    {
+        $this->check = $check;
+        return $this;
+    }
+
+    public function getCheckInfo(): string
+    {
+        return $this->checkInfo;
+    }
+
+    public function setCheckInfo(string $checkInfo): self
+    {
+        $this->checkInfo = $checkInfo;
+        return $this;
+    }
+
+    public function getPhone(): array
+    {
+        return $this->phone;
+    }
+
+    public function setPhone(array $phone): self
+    {
+        $this->phone = $phone;
+        return $this;
+    }
+
+    public function getEmail(): array
+    {
+        return $this->email;
+    }
+
+    public function setEmail(array $email): self
+    {
+        $this->email = $email;
+        return $this;
+    }
+
+    public function getAddress(): array
+    {
+        return $this->address;
+    }
+
+    public function setAddress(array $address): self
+    {
+        $this->address = $address;
+        return $this;
+    }
+
+    public function getSite(): string
+    {
+        return $this->site;
+    }
+
+    public function setSite(string $site): self
+    {
+        $this->site = $site;
+        return $this;
+    }
+
+    public function getPreviewImage(): string
+    {
+        return $this->previewImage;
+    }
+
+    public function setPreviewImage(string $previewImage): self
+    {
+        $this->previewImage = $previewImage;
+        return $this;
+    }
+
+    public function getDetailImage(): string
+    {
+        return $this->detailImage;
+    }
+
+    public function setDetailImage(string $detailImage): self
+    {
+        $this->detailImage = $detailImage;
+        return $this;
+    }
+
+    public function getHowToFind(): string
+    {
+        return $this->howToFind;
+    }
+
+    public function setHowToFind(string $howToFind): self
+    {
+        $this->howToFind = $howToFind;
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/src/Requests/EditNewsRequest.php b/src/Requests/EditNewsRequest.php
new file mode 100644
index 0000000..e78432c
--- /dev/null
+++ b/src/Requests/EditNewsRequest.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace App\Requests;
+
+use Symfony\Component\Uid\Uuid;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class EditNewsRequest
+{
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $typeId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $seoId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $fileId;
+
+    #[Assert\NotBlank]
+    private string $code;
+
+    #[Assert\NotBlank]
+    #[Assert\Type('bool')]
+    private bool $active;
+
+    #[Assert\NotBlank]
+    #[Assert\Type('int')]
+    private int $sort;
+
+    private string $previewImage;
+
+    private string $detailImage;
+
+    private string $previewText;
+
+    private string $detailText;
+
+    #[Assert\Type('bool')]
+    private bool $mainPageRender;
+
+    public function getTypeId(): Uuid
+    {
+        return $this->typeId;
+    }
+
+    public function setTypeId(Uuid $typeId): self
+    {
+        $this->typeId = $typeId;
+        return $this;
+    }
+
+    public function getSeoId(): Uuid
+    {
+        return $this->seoId;
+    }
+
+    public function setSeoId(Uuid $seoId): self
+    {
+        $this->seoId = $seoId;
+        return $this;
+    }
+
+    public function getFileId(): Uuid
+    {
+        return $this->fileId;
+    }
+
+    public function setFileId(Uuid $fileId): self
+    {
+        $this->fileId = $fileId;
+        return $this;
+    }
+
+    public function getCode(): string
+    {
+        return $this->code;
+    }
+
+    public function setCode(string $code): self
+    {
+        $this->code = $code;
+        return $this;
+    }
+
+    public function isActive(): bool
+    {
+        return $this->active;
+    }
+
+    public function setActive(bool $active): self
+    {
+        $this->active = $active;
+        return $this;
+    }
+
+    public function getSort(): int
+    {
+        return $this->sort;
+    }
+
+    public function setSort(int $sort): self
+    {
+        $this->sort = $sort;
+        return $this;
+    }
+
+    public function getPreviewImage(): string
+    {
+        return $this->previewImage;
+    }
+
+    public function setPreviewImage(string $previewImage): self
+    {
+        $this->previewImage = $previewImage;
+        return $this;
+    }
+
+    public function getDetailImage(): string
+    {
+        return $this->detailImage;
+    }
+
+    public function setDetailImage(string $detailImage): self
+    {
+        $this->detailImage = $detailImage;
+        return $this;
+    }
+
+    public function getPreviewText(): string
+    {
+        return $this->previewText;
+    }
+
+    public function setPreviewText(string $previewText): self
+    {
+        $this->previewText = $previewText;
+        return $this;
+    }
+
+    public function getDetailText(): string
+    {
+        return $this->detailText;
+    }
+
+    public function setDetailText(string $detailText): self
+    {
+        $this->detailText = $detailText;
+        return $this;
+    }
+
+    public function isMainPageRender(): bool
+    {
+        return $this->mainPageRender;
+    }
+
+    public function setMainPageRender(bool $mainPageRender): self
+    {
+        $this->mainPageRender = $mainPageRender;
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/src/Requests/EditRestaurantRequest.php b/src/Requests/EditRestaurantRequest.php
new file mode 100644
index 0000000..956c9db
--- /dev/null
+++ b/src/Requests/EditRestaurantRequest.php
@@ -0,0 +1,272 @@
+<?php
+
+namespace App\Requests;
+
+use Symfony\Component\Uid\Uuid;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class EditRestaurantRequest
+{
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $typeId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $settlementId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $seoId;
+
+    #[Assert\NotBlank]
+    #[Assert\Uuid]
+    private Uuid $fileId;
+
+    #[Assert\NotBlank]
+    private string $name;
+
+    #[Assert\NotBlank]
+    private string $code;
+
+    #[Assert\Type('bool')]
+    private bool $active;
+
+    #[Assert\Type('int')]
+    private int $sort;
+
+    #[Assert\Type('array')]
+    private array $coordinates;
+
+    private string $description;
+
+    private string $check;
+
+    private string $checkInfo;
+
+    #[Assert\Type('array')]
+    private array $phone;
+
+    #[Assert\Type('array')]
+    private array $email;
+
+    #[Assert\Type('array')]
+    private array $address;
+
+    private string $site;
+
+    private string $previewImage;
+
+    private string $detailImage;
+
+    private string $howToFind;
+
+    public function getTypeId(): Uuid
+    {
+        return $this->typeId;
+    }
+
+    public function setTypeId(Uuid $typeId): self
+    {
+        $this->typeId = $typeId;
+        return $this;
+    }
+
+    public function getSettlementId(): Uuid
+    {
+        return $this->settlementId;
+    }
+
+    public function setSettlementId(Uuid $settlementId): self
+    {
+        $this->settlementId = $settlementId;
+        return $this;
+    }
+
+    public function getSeoId(): Uuid
+    {
+        return $this->seoId;
+    }
+
+    public function setSeoId(Uuid $seoId): self
+    {
+        $this->seoId = $seoId;
+        return $this;
+    }
+
+    public function getFileId(): Uuid
+    {
+        return $this->fileId;
+    }
+
+    public function setFileId(Uuid $fileId): self
+    {
+        $this->fileId = $fileId;
+        return $this;
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+
+    public function setName(string $name): self
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    public function getCode(): string
+    {
+        return $this->code;
+    }
+
+    public function setCode(string $code): self
+    {
+        $this->code = $code;
+        return $this;
+    }
+
+    public function isActive(): bool
+    {
+        return $this->active;
+    }
+
+    public function setActive(bool $active): self
+    {
+        $this->active = $active;
+        return $this;
+    }
+
+    public function getSort(): int
+    {
+        return $this->sort;
+    }
+
+    public function setSort(int $sort): self
+    {
+        $this->sort = $sort;
+        return $this;
+    }
+
+    public function getCoordinates(): array
+    {
+        return $this->coordinates;
+    }
+
+    public function setCoordinates(array $coordinates): self
+    {
+        $this->coordinates = $coordinates;
+        return $this;
+    }
+
+    public function getDescription(): string
+    {
+        return $this->description;
+    }
+
+    public function setDescription(string $description): self
+    {
+        $this->description = $description;
+        return $this;
+    }
+
+    public function getCheck(): string
+    {
+        return $this->check;
+    }
+
+    public function setCheck(string $check): self
+    {
+        $this->check = $check;
+        return $this;
+    }
+
+    public function getCheckInfo(): string
+    {
+        return $this->checkInfo;
+    }
+
+    public function setCheckInfo(string $checkInfo): self
+    {
+        $this->checkInfo = $checkInfo;
+        return $this;
+    }
+
+    public function getPhone(): array
+    {
+        return $this->phone;
+    }
+
+    public function setPhone(array $phone): self
+    {
+        $this->phone = $phone;
+        return $this;
+    }
+
+    public function getEmail(): array
+    {
+        return $this->email;
+    }
+
+    public function setEmail(array $email): self
+    {
+        $this->email = $email;
+        return $this;
+    }
+
+    public function getAddress(): array
+    {
+        return $this->address;
+    }
+
+    public function setAddress(array $address): self
+    {
+        $this->address = $address;
+        return $this;
+    }
+
+    public function getSite(): string
+    {
+        return $this->site;
+    }
+
+    public function setSite(string $site): self
+    {
+        $this->site = $site;
+        return $this;
+    }
+
+    public function getPreviewImage(): string
+    {
+        return $this->previewImage;
+    }
+
+    public function setPreviewImage(string $previewImage): self
+    {
+        $this->previewImage = $previewImage;
+        return $this;
+    }
+
+    public function getDetailImage(): string
+    {
+        return $this->detailImage;
+    }
+
+    public function setDetailImage(string $detailImage): self
+    {
+        $this->detailImage = $detailImage;
+        return $this;
+    }
+
+    public function getHowToFind(): string
+    {
+        return $this->howToFind;
+    }
+
+    public function setHowToFind(string $howToFind): self
+    {
+        $this->howToFind = $howToFind;
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/src/Service/NewsService.php b/src/Service/NewsService.php
index 52bdd28..1f1923e 100644
--- a/src/Service/NewsService.php
+++ b/src/Service/NewsService.php
@@ -2,15 +2,26 @@
 
 namespace App\Service;
 
+use App\Entity\File;
 use App\Entity\News;
 use App\Entity\NewsCategory;
+use App\Entity\NewsType;
+use App\Entity\Seo;
+use App\Exception\FileNotFoundException;
 use App\Exception\NewsNotFoundException;
+use App\Exception\NewsTypeNotFoundException;
+use App\Exception\SeoNotFoundException;
 use App\Mapper\NewsMapper;
 use App\Model\NewsDetailElement;
 use App\Model\NewsList;
 use App\Model\NewsListingElement;
+use App\Repository\FileRepository;
 use App\Repository\Interface\NewsCategoryRepositoryInterface;
 use App\Repository\Interface\NewsRepositoryInterface;
+use App\Repository\NewsTypeRepository;
+use App\Repository\SeoRepository;
+use App\Requests\CreateNewsRequest;
+use App\Requests\EditNewsRequest;
 use App\Requests\NewsListRequest;
 use Ramsey\Collection\Collection;
 use Symfony\Component\HttpFoundation\Request;
@@ -22,7 +33,10 @@ class NewsService
 
     public function __construct(
         private NewsRepositoryInterface $newsRepository,
-        private NewsCategoryRepositoryInterface $newsCategoryRepository
+        private NewsCategoryRepositoryInterface $newsCategoryRepository,
+        private NewsTypeRepository $newsTypeRepository,
+        private SeoRepository $seoRepository,
+        private FileRepository $fileRepository
     ) {}
 
     public function getNewsByRequest(NewsListRequest $request): NewsList
@@ -83,4 +97,87 @@ class NewsService
 
         return NewsMapper::mapToDetailElement($news);
     }
+
+    public function addNewsByRequest(
+        CreateNewsRequest|EditNewsRequest $request,
+        string $id = null
+    ): NewsDetailElement {
+        $newsType = $this->newsTypeRepository->getById($request->getTypeId());
+        $seo = $this->seoRepository->getById($request->getSeoId());
+        $file = $this->fileRepository->getById($request->getFileId());
+        $this->checkForNulls($newsType, $seo, $file);
+
+        $news = $this->newsRepository->create(
+            NewsMapper::createNewsEntity(
+                $request,
+                $newsType,
+                $seo,
+                $file,
+                $id
+            ));
+
+        return NewsMapper::mapToDetailElement($news);
+    }
+
+    public function putNewsByRequest(
+        string $id,
+        EditNewsRequest $request
+    ): NewsDetailElement {
+        if ($this->newsRepository->newsExists($id)) {
+            return $this->patchNewsByRequest($id, $request);
+        }
+
+        return $this->addNewsByRequest($request, $id);
+    }
+
+    public function patchNewsByRequest(
+        string $id,
+        EditNewsRequest $request
+    ): NewsDetailElement {
+        $newsType = $this->newsTypeRepository->getById($request->getTypeId());
+        $seo = $this->seoRepository->getById($request->getSeoId());
+        $file = $this->fileRepository->getById($request->getFileId());
+        $this->checkForNulls($newsType, $seo, $file);
+
+        if (!$this->newsRepository->newsExists($id)) {
+            throw new NewsNotFoundException();
+        }
+
+        $newNews = NewsMapper::updateNewsEntity(
+            $request,
+            $newsType,
+            $seo,
+            $file,
+            $this->newsRepository->getById($id)
+        );
+
+        return NewsMapper::mapToDetailElement(
+            $this->newsRepository->update($newNews),
+        );
+    }
+
+    public function deleteNews(string $id): void
+    {
+        if (!$this->newsRepository->newsExists($id)) {
+            throw new NewsNotFoundException();
+        }
+
+        $this->newsRepository->delete($id);
+    }
+
+    private function checkForNulls(
+        ?NewsType $type,
+        ?Seo $seo,
+        ?File $file
+    ): void {
+        if ($type === null) {
+            throw new NewsTypeNotFoundException();
+        }
+        if ($seo === null) {
+            throw new SeoNotFoundException;
+        }
+        if ($file === null) {
+            throw new FileNotFoundException();
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Service/RestaurantService.php b/src/Service/RestaurantService.php
index 23ade59..1b49e39 100644
--- a/src/Service/RestaurantService.php
+++ b/src/Service/RestaurantService.php
@@ -2,12 +2,24 @@
 
 namespace App\Service;
 
+use App\Entity\File;
 use App\Entity\Gallery;
 use App\Entity\Kitchen;
 use App\Entity\Restaurant;
 use App\Entity\RestaurantType;
+use App\Entity\Seo;
+use App\Entity\Settlement;
+use App\Exception\FileNotFoundException;
 use App\Exception\RestaurantNotFoundException;
+use App\Exception\RestaurantTypeNotFoundException;
+use App\Exception\SeoNotFoundException;
+use App\Exception\SettlementNotFoundException;
+use App\Repository\FileRepository;
 use App\Repository\Interface\GalleryRepositoryInterface;
+use App\Repository\SeoRepository;
+use App\Repository\SettlementRepository;
+use App\Requests\CreateRestaurantRequest;
+use App\Requests\EditRestaurantRequest;
 use App\Requests\RestaurantListRequest;
 use App\Mapper\RestaurantMapper;
 use App\Model\RestaurantDetailElement;
@@ -17,6 +29,7 @@ use App\Repository\Interface\RestaurantRepositoryInterface;
 use App\Repository\Interface\RestaurantTypeRepositoryInterface;
 use Ramsey\Collection\Collection;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Uid\Uuid;
 
 class RestaurantService
 {
@@ -28,6 +41,9 @@ class RestaurantService
         private RestaurantTypeRepositoryInterface $restaurantTypeRepository,
         private KitchenRepositoryInterface $kitchenRepository,
         private GalleryRepositoryInterface $galleryRepository,
+        private SettlementRepository $settlementRepository,
+        private SeoRepository $seoRepository,
+        private FIleRepository $fileRepository,
     ) {}
 
     public function getRestaurantsByRequest(
@@ -99,4 +115,96 @@ class RestaurantService
 
         return RestaurantMapper::mapToDetailElement($restaurant, $gallery);
     }
+
+    public function addRestaurantByRequest(
+        CreateRestaurantRequest|EditRestaurantRequest $request,
+        string $id = null
+    ): RestaurantDetailElement {
+        $restaurantType = $this->restaurantTypeRepository->getById($request->getTypeId());
+        $settlement = $this->settlementRepository->getById($request->getSettlementId());
+        $seo = $this->seoRepository->getById($request->getSeoId());
+        $file = $this->fileRepository->getById($request->getFileId());
+        $this->checkForNulls($restaurantType, $settlement, $seo, $file);
+
+        $restaurant = $this->restaurantRepository->create(
+            RestaurantMapper::createRestaurantEntity(
+                $request,
+                $restaurantType,
+                $settlement,
+                $seo,
+                $file,
+                $id
+        ));
+
+        return RestaurantMapper::mapToDetailElement($restaurant, null);
+    }
+
+    public function putRestaurantByRequest(
+        string $id,
+        EditRestaurantRequest $request
+    ): RestaurantDetailElement {
+        if ($this->restaurantRepository->restaurantExists($id)) {
+            return $this->patchRestaurantByRequest($id, $request);
+        }
+
+        return $this->addRestaurantByRequest($request, $id);
+    }
+
+    public function patchRestaurantByRequest(
+        string $id,
+        EditRestaurantRequest $request
+    ): RestaurantDetailElement {
+        $restaurantType = $this->restaurantTypeRepository->getById($request->getTypeId());
+        $settlement = $this->settlementRepository->getById($request->getSettlementId());
+        $seo = $this->seoRepository->getById($request->getSeoId());
+        $file = $this->fileRepository->getById($request->getFileId());
+        $this->checkForNulls($restaurantType, $settlement, $seo, $file);
+
+        if (!$this->restaurantRepository->restaurantExists($id)) {
+            throw new RestaurantNotFoundException();
+        }
+
+        $newRestaurant = RestaurantMapper::updateRestaurantEntity(
+            $request,
+            $restaurantType,
+            $settlement,
+            $seo,
+            $file,
+            $this->restaurantRepository->getById($id)
+        );
+
+        return RestaurantMapper::mapToDetailElement(
+            $this->restaurantRepository->update($newRestaurant),
+            null
+        );
+    }
+
+    public function deleteRestaurant(string $id): void
+    {
+        if (!$this->restaurantRepository->restaurantExists($id)) {
+            throw new RestaurantNotFoundException();
+        }
+
+        $this->restaurantRepository->delete($id);
+    }
+
+    private function checkForNulls(
+        ?RestaurantType $type,
+        ?Settlement $settlement,
+        ?Seo $seo,
+        ?File $file
+    ): void {
+        if ($type === null) {
+            throw new RestaurantTypeNotFoundException();
+        }
+        if ($settlement === null) {
+            throw new SettlementNotFoundException();
+        }
+        if ($seo === null) {
+            throw new SeoNotFoundException;
+        }
+        if ($file === null) {
+            throw new FileNotFoundException();
+        }
+    }
 }
\ No newline at end of file
-- 
GitLab