AddProductInCart.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php
  2. namespace Webkul\BagistoApi\Models;
  3. use ApiPlatform\Metadata\ApiProperty;
  4. use ApiPlatform\Metadata\ApiResource;
  5. use ApiPlatform\Metadata\GraphQl\Mutation;
  6. use ApiPlatform\Metadata\Post;
  7. use ApiPlatform\OpenApi\Model;
  8. use Webkul\BagistoApi\Dto\CartData;
  9. use Webkul\BagistoApi\Dto\CartInput;
  10. use Webkul\BagistoApi\State\CartTokenMutationProvider;
  11. use Webkul\BagistoApi\State\CartTokenProcessor;
  12. use ApiPlatform\OpenApi\Model\Operation;
  13. /**
  14. * AddProductInCart - GraphQL & REST API Resource for Adding Products to Cart
  15. *
  16. * Provides mutation for adding products to an existing shopping cart.
  17. * Uses token-based authentication for guest users or bearer token for authenticated users.
  18. */
  19. #[ApiResource(
  20. routePrefix: '/api/shop',
  21. shortName: 'AddProductInCart',
  22. uriTemplate: '/add-product-in-cart',
  23. operations: [
  24. new Post(
  25. name: 'addProduct',
  26. uriTemplate: '/add-product-in-cart',
  27. input: CartInput::class,
  28. output: CartData::class,
  29. provider: CartTokenMutationProvider::class,
  30. processor: CartTokenProcessor::class,
  31. deserialize: false,
  32. denormalizationContext: [
  33. 'allow_extra_attributes' => true,
  34. 'groups' => ['mutation'],
  35. ],
  36. normalizationContext: [
  37. 'groups' => ['mutation'],
  38. ],
  39. description: 'Add product to cart. Can be used for both authenticated users and guests.',
  40. openapi: new Operation(
  41. tags: ['Cart'],
  42. summary: 'Add product to cart',
  43. description: 'Add a product to the shopping cart with quantity and optional product options.',
  44. requestBody: new Model\RequestBody(
  45. description: 'Product to add to cart',
  46. required: true,
  47. content: new \ArrayObject([
  48. 'application/json' => [
  49. 'schema' => [
  50. 'type' => 'object',
  51. 'properties' => [
  52. 'productId' => [
  53. 'type' => 'integer',
  54. 'example' => 1,
  55. 'description' => 'Product ID',
  56. ],
  57. 'quantity' => [
  58. 'type' => 'integer',
  59. 'example' => 1,
  60. 'description' => 'Quantity',
  61. ],
  62. 'options' => [
  63. 'type' => 'object',
  64. 'example' => ['size' => 'M', 'color' => 'blue'],
  65. 'description' => 'Product options (optional)',
  66. ],
  67. 'bundleOptions' => [
  68. 'type' => 'string',
  69. 'example' => '{"1":[1],"2":[2],"3":[3],"4":[4]}',
  70. 'description' => 'Bundle options JSON (optional)',
  71. ],
  72. 'bundleOptionQty' => [
  73. 'type' => 'string',
  74. 'example' => '{"1":1,"2":2,"3":1,"4":2}',
  75. 'description' => 'Bundle option quantities JSON (optional)',
  76. ],
  77. 'groupedQty' => [
  78. 'type' => 'string',
  79. 'example' => '{"101":2,"102":1}',
  80. 'description' => 'Grouped product associated quantities JSON (optional, required for grouped products)',
  81. ],
  82. 'booking' => [
  83. 'type' => 'string',
  84. 'example' => '{"type":"appointment","date":"2026-03-12","slot":"10:00 AM - 11:00 AM"}',
  85. 'description' => 'Booking options JSON string (optional, required for booking products)',
  86. ],
  87. 'specialNote' => [
  88. 'type' => 'string',
  89. 'example' => 'This is a special note',
  90. 'description' => 'Special request / note (optional; merged into booking.note)',
  91. ],
  92. 'variantId' => [
  93. 'type' => 'integer',
  94. 'example' => 1001,
  95. 'description' => 'Selected flexible variant ID (required for flexible_variant products unless superAttribute is provided)',
  96. ],
  97. 'superAttribute' => [
  98. 'type' => 'object',
  99. 'example' => ['12' => 34, '13' => 56],
  100. 'description' => 'Map of optionId => optionValueId; used to resolve flexible variant when variantId is omitted',
  101. ],
  102. ],
  103. ],
  104. 'examples' => [
  105. 'simple_product' => [
  106. 'summary' => 'Add Simple Product',
  107. 'description' => 'Add a simple product to cart',
  108. 'value' => [
  109. 'productId' => 1,
  110. 'quantity' => 1,
  111. ],
  112. ],
  113. 'product_with_options' => [
  114. 'summary' => 'Add Product with Options',
  115. 'description' => 'Add a product with size and color options',
  116. 'value' => [
  117. 'productId' => 2,
  118. 'quantity' => 2,
  119. 'options' => ['size' => 'M', 'color' => 'blue'],
  120. ],
  121. ],
  122. 'bundle_product' => [
  123. 'summary' => 'Add Bundle Product',
  124. 'description' => 'Add a bundle product with selected bundle options',
  125. 'value' => [
  126. 'productId' => 6,
  127. 'quantity' => 1,
  128. 'bundleOptions' => '{"1":[1],"2":[2],"3":[3],"4":[4]}',
  129. 'bundleOptionQty' => '{"1":1,"2":2,"3":1,"4":2}',
  130. ],
  131. ],
  132. 'grouped_product' => [
  133. 'summary' => 'Add Grouped Product',
  134. 'description' => 'Add a grouped product by specifying quantities for associated simple products',
  135. 'value' => [
  136. 'productId' => 5,
  137. 'quantity' => 1,
  138. 'groupedQty' => '{"101":2,"102":1}',
  139. ],
  140. ],
  141. 'booking_product' => [
  142. 'summary' => 'Add Booking Product',
  143. 'description' => 'Add a booking product (appointment/default/table/rental/event) to cart by passing booking options as JSON string',
  144. 'value' => [
  145. 'productId' => 2555,
  146. 'quantity' => 1,
  147. 'booking' => '{"type":"appointment","date":"2026-03-12","slot":"10:00 AM - 11:00 AM"}',
  148. ],
  149. ],
  150. 'event_booking_product' => [
  151. 'summary' => 'Add Event Booking',
  152. 'description' => 'Add an event booking product by selecting one or more ticket quantities (at least one ticket qty > 0 required)',
  153. 'value' => [
  154. 'productId' => 2564,
  155. 'quantity' => 1,
  156. 'booking' => '{"type":"event","qty":{"501":1,"502":2}}',
  157. ],
  158. ],
  159. 'flexible_variant_product' => [
  160. 'summary' => 'Add Flexible Variant Product',
  161. 'description' => 'Add a Longyi flexible_variant product by passing the selected variantId',
  162. 'value' => [
  163. 'productId' => 7,
  164. 'variantId' => 1001,
  165. 'quantity' => 1,
  166. ],
  167. ],
  168. 'flexible_variant_by_super_attribute' => [
  169. 'summary' => 'Add Flexible Variant via super_attribute',
  170. 'description' => 'Resolve a flexible variant from a {optionId: valueId} map when variantId is unknown',
  171. 'value' => [
  172. 'productId' => 7,
  173. 'quantity' => 1,
  174. 'superAttribute' => [
  175. '12' => 34,
  176. '13' => 56,
  177. ],
  178. ],
  179. ],
  180. 'table_booking_product_with_note' => [
  181. 'summary' => 'Add Table Booking (with note)',
  182. 'description' => 'Add a table booking product and send special request/note separately',
  183. 'value' => [
  184. 'productId' => 2563,
  185. 'quantity' => 1,
  186. 'booking' => '{"type":"table","date":"2026-03-25","slot":"12:00 PM - 12:45 PM"}',
  187. 'specialNote' => 'This is a special note',
  188. ],
  189. ],
  190. ],
  191. ],
  192. ]),
  193. ),
  194. ),
  195. ),
  196. ],
  197. graphQlOperations: [
  198. new Mutation(
  199. name: 'create',
  200. input: CartInput::class,
  201. output: CartData::class,
  202. provider: CartTokenMutationProvider::class,
  203. processor: CartTokenProcessor::class,
  204. denormalizationContext: [
  205. 'allow_extra_attributes' => true,
  206. 'groups' => ['mutation'],
  207. ],
  208. normalizationContext: [
  209. 'groups' => ['mutation'],
  210. ],
  211. description: 'Add product to cart. Can be used for both authenticated users and guests.',
  212. ),
  213. ]
  214. )]
  215. class AddProductInCart
  216. {
  217. #[ApiProperty(readable: true, writable: false)]
  218. public ?int $id = null;
  219. #[ApiProperty(readable: true, writable: false)]
  220. public ?string $cartToken = null;
  221. #[ApiProperty(readable: true, writable: false)]
  222. public ?int $customerId = null;
  223. #[ApiProperty(readable: true, writable: false)]
  224. public ?int $channelId = null;
  225. #[ApiProperty(readable: true, writable: false)]
  226. public ?int $itemsCount = null;
  227. #[ApiProperty(readable: true, writable: false)]
  228. public ?array $items = null;
  229. #[ApiProperty(readable: true, writable: false)]
  230. public ?float $subtotal = null;
  231. #[ApiProperty(readable: true, writable: false)]
  232. public ?float $baseSubtotal = null;
  233. #[ApiProperty(readable: true, writable: false)]
  234. public ?float $discountAmount = null;
  235. #[ApiProperty(readable: true, writable: false)]
  236. public ?float $baseDiscountAmount = null;
  237. #[ApiProperty(readable: true, writable: false)]
  238. public ?float $taxAmount = null;
  239. #[ApiProperty(readable: true, writable: false)]
  240. public ?float $baseTaxAmount = null;
  241. #[ApiProperty(readable: true, writable: false)]
  242. public ?float $shippingAmount = null;
  243. #[ApiProperty(readable: true, writable: false)]
  244. public ?float $baseShippingAmount = null;
  245. #[ApiProperty(readable: true, writable: false)]
  246. public ?float $grandTotal = null;
  247. #[ApiProperty(readable: true, writable: false)]
  248. public ?float $baseGrandTotal = null;
  249. #[ApiProperty(readable: true, writable: false)]
  250. public ?string $formattedSubtotal = null;
  251. #[ApiProperty(readable: true, writable: false)]
  252. public ?string $formattedDiscountAmount = null;
  253. #[ApiProperty(readable: true, writable: false)]
  254. public ?string $formattedTaxAmount = null;
  255. #[ApiProperty(readable: true, writable: false)]
  256. public ?string $formattedShippingAmount = null;
  257. #[ApiProperty(readable: true, writable: false)]
  258. public ?string $formattedGrandTotal = null;
  259. #[ApiProperty(readable: true, writable: false)]
  260. public ?string $couponCode = null;
  261. #[ApiProperty(readable: true, writable: false)]
  262. public ?bool $success = null;
  263. #[ApiProperty(readable: true, writable: false)]
  264. public ?string $message = null;
  265. #[ApiProperty(readable: true, writable: false)]
  266. public ?array $carts = null;
  267. #[ApiProperty(readable: true, writable: false)]
  268. public ?string $sessionToken = null;
  269. #[ApiProperty(readable: true, writable: false)]
  270. public ?bool $isGuest = null;
  271. }