src/Controller/API/WhiteMark/CatalogueController.php line 142

Open in your IDE?
  1. <?php
  2. namespace App\Controller\API\WhiteMark;
  3. use App\Exception\CatalogueException;
  4. use App\Model\Product;
  5. use App\Services\API\VersioningService;
  6. use App\Services\Common\StockService;
  7. use App\Services\DTV\YamlConfig\YamlReader;
  8. use App\Services\Front\Catalogue\JsonCatalogueService;
  9. use App\Services\ProductService;
  10. use DateTime;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use JMS\Serializer\SerializerInterface;
  13. use JsonException;
  14. use Nelmio\ApiDocBundle\Annotation\Model;
  15. use OpenApi\Annotations as OA;
  16. use Psr\Cache\InvalidArgumentException;
  17. use Symfony\Component\HttpFoundation\JsonResponse;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\HttpKernel\KernelInterface;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  23. use Symfony\Component\Validator\Validator\ValidatorInterface;
  24. use Symfony\Contracts\Cache\ItemInterface;
  25. use Symfony\Contracts\Cache\TagAwareCacheInterface;
  26. /**
  27. * @Route("/catalogues")
  28. */
  29. class CatalogueController extends ApiController
  30. {
  31. private JsonCatalogueService $catalogueService;
  32. private YamlReader $yamlReader;
  33. private ProductService $productService;
  34. private StockService $stockService;
  35. public function __construct(
  36. EntityManagerInterface $em,
  37. SerializerInterface $serializer,
  38. UrlGeneratorInterface $urlGenerator,
  39. ValidatorInterface $validator,
  40. TagAwareCacheInterface $cache,
  41. KernelInterface $kernel,
  42. VersioningService $versioningService,
  43. JsonCatalogueService $catalogueService,
  44. ProductService $productService,
  45. YamlReader $yamlReader,
  46. StockService $stockService
  47. ) {
  48. parent::__construct($em, $serializer, $urlGenerator, $validator, $cache, $kernel, $versioningService);
  49. $this->catalogueService = $catalogueService;
  50. $this->yamlReader = $yamlReader;
  51. $this->productService = $productService;
  52. $this->stockService = $stockService;
  53. $this->cacheTagSlug = 'cataloguesCache';
  54. }
  55. /**
  56. * Récupérer l'ensemble des catalogues disponibles.
  57. *
  58. * @OA\Response(
  59. * response=200,
  60. * description="Retourne la liste des catalogues",
  61. * @OA\MediaType(
  62. * mediaType="application/json",
  63. * @OA\Schema(
  64. * type="array",
  65. * @OA\Items(
  66. * type="string",
  67. * ),
  68. * )
  69. * )
  70. * )
  71. *
  72. * @OA\Tag(name="Catalogues")
  73. *
  74. * @Route("/", name="api_list_catalogue", methods={"GET"})
  75. *
  76. * @return JsonResponse
  77. */
  78. public function listCatalogue(): JsonResponse
  79. {
  80. $slugs = [];
  81. $catalogues = $this->yamlReader->getShop()['catalogues'];
  82. foreach ($catalogues as $k => $catalogue) {
  83. $catalogueType = $catalogue['slug'] ?? $k;
  84. // Modification des catalogues depuis la version 1.4.0 : pub.json devient obj_pub.json
  85. if ($catalogueType === 'pub') {
  86. $catalogueType = 'obj_pub';
  87. }
  88. if ($catalogue['enabled']) {
  89. $slugs[] = $catalogueType;
  90. }
  91. }
  92. return new JsonResponse(['catalogues' => $slugs], Response::HTTP_OK, []);
  93. }
  94. /**
  95. * Récupérer l'ensemble des produits d'un catalogue.
  96. *
  97. * @OA\Response(
  98. * response=200,
  99. * description="Retourne la liste des produits.<br>Pour afficher les images, il faut les préfixer avec
  100. * https://cdn.37deux.com/pictures suivis du format (150, 400, large).<br>Exemple :
  101. * https://cdn.37deux.com/pictures/150/pic6076bc07b0620.jpg",
  102. * @OA\JsonContent(
  103. * type="array",
  104. * @OA\Items(ref=@Model(type=Product::class, groups={"api_product:list"}))
  105. * )
  106. * )
  107. * @OA\Parameter(
  108. * name="page",
  109. * in="query",
  110. * description="La page que l'on veut récupérer",
  111. * @OA\Schema(type="int")
  112. * )
  113. *
  114. * @OA\Parameter(
  115. * name="limit",
  116. * in="query",
  117. * description="Le nombre d'éléments que l'on veut récupérer",
  118. * @OA\Schema(type="int")
  119. * )
  120. *
  121. * @OA\Parameter(
  122. * name="slug",
  123. * in="path",
  124. * description="Le nom du catalogue",
  125. * @OA\Schema(type="string")
  126. * )
  127. *
  128. * @OA\Tag(name="Catalogues")
  129. *
  130. * @Route("/{slug}/products", name="api_list_product", methods={"GET"})
  131. *
  132. * @throws InvalidArgumentException
  133. */
  134. public function listProduct(string $slug, Request $request): JsonResponse
  135. {
  136. $page = $request->get('page', 1);
  137. $limit = $request->get('limit', 15);
  138. $context = $this->getContext(["api_product:list"]);
  139. $idCache = "listProduct-" . $slug . '-' . $page . "-" . $limit;
  140. $jsonProducts = $this->cache->get($idCache, function (ItemInterface $item) use (
  141. $page,
  142. $limit,
  143. $slug,
  144. $context
  145. ) {
  146. $item->tag($this->cacheTagSlug);
  147. $products = $this->catalogueService->getProductsFromCatalogueWithPagination($slug, $page, $limit);
  148. $formattedProducts = [];
  149. foreach ($products['products'] as $product) {
  150. $formattedProducts[] = $this->catalogueService->getProductBySkuFromCatalogue($product['sku'], $slug);
  151. }
  152. $json = $this->serializer->serialize($formattedProducts, 'json', $context);
  153. $jsonProducts = [
  154. 'totalProducts' => $products['totalProducts'],
  155. 'products' => '{{json_products_data}}',
  156. ];
  157. $jsonProducts = json_encode($jsonProducts);
  158. return str_replace('"{{json_products_data}}"', $json, $jsonProducts);
  159. });
  160. return new JsonResponse($jsonProducts, Response::HTTP_OK, [], true);
  161. }
  162. /**
  163. * Récupérer un produit depuis son sku.
  164. *
  165. * @OA\Response(
  166. * response=200,
  167. * description="Retourne un produit",
  168. * @OA\JsonContent(
  169. * type="array",
  170. * @OA\Items(ref=@Model(type=Product::class, groups={"api_product:item"}))
  171. * )
  172. * )
  173. * @OA\Tag(name="Catalogues")
  174. *
  175. * @Route("/{slug}/products/{sku}", name="api_show_product", methods={"GET"})
  176. *
  177. * @throws JsonException
  178. * @throws CatalogueException
  179. */
  180. public function showProduct(string $slug, string $sku): JsonResponse
  181. {
  182. $product = $this->catalogueService->findProductBySku($sku);
  183. $json = $this->serializer->serialize($product, 'json', $this->getContext(["api_product:item"]));
  184. return new JsonResponse($json, Response::HTTP_OK, [], true);
  185. }
  186. /**
  187. * Récupérer le stock en temps réel d'un produit
  188. *
  189. * @OA\Response(
  190. * response=200,
  191. * description="Retourne un stock",
  192. * @OA\MediaType(
  193. * mediaType="application/json",
  194. * @OA\Schema(
  195. * @OA\Property(
  196. * property="sku",
  197. * type="string"
  198. * ),
  199. * @OA\Property(
  200. * property="quantity",
  201. * type="integer"
  202. * ),
  203. * example={"sku": "12345678Z9", "quantity": 3}
  204. * )
  205. * )
  206. * )
  207. * @OA\Tag(name="Catalogues")
  208. *
  209. * @Route("/{slug}/products/{sku}/stocks", name="api_show_product_stocks", methods={"GET"})
  210. * @throws JsonException
  211. */
  212. public function showProductStock(string $slug, string $sku): JsonResponse
  213. {
  214. $response = $this->stockService->getProductStockFromBO($sku);
  215. return new JsonResponse(json_encode([
  216. 'stock' => $response - $this->productService->getStockPending($sku),
  217. 'date' => (new DateTime('now'))->format('d-m-Y H:i:s'),
  218. ],), Response::HTTP_OK, [], true,);
  219. }
  220. }