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

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