CustomerOrder.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. namespace Webkul\BagistoApi\Models;
  3. use ApiPlatform\Metadata\ApiProperty;
  4. use ApiPlatform\Metadata\ApiResource;
  5. use ApiPlatform\Metadata\Get;
  6. use ApiPlatform\Metadata\GetCollection;
  7. use ApiPlatform\Metadata\GraphQl\Query;
  8. use ApiPlatform\Metadata\GraphQl\QueryCollection;
  9. use Illuminate\Database\Eloquent\Model;
  10. use Illuminate\Database\Eloquent\Relations\HasMany;
  11. use Illuminate\Database\Eloquent\Relations\HasOne;
  12. use Webkul\BagistoApi\State\CustomerOrderProvider;
  13. use ApiPlatform\OpenApi\Model\Operation;
  14. /**
  15. * Customer Order API Resource
  16. *
  17. * Standalone model pointing to the `orders` table with explicit field casts
  18. * and hand-picked relationships. Follows the same pattern as CustomerInvoice
  19. * to avoid inheriting unwanted relationships from the base Order model
  20. * (morphTo fields, proxy relationships) that can break API Platform serialization.
  21. *
  22. * This is a read-only, customer-scoped resource.
  23. */
  24. #[ApiResource(
  25. routePrefix: '/api/shop',
  26. shortName: 'CustomerOrder',
  27. uriTemplate: '/customer-orders',
  28. operations: [
  29. new GetCollection(
  30. uriTemplate: '/customer-orders',
  31. provider: CustomerOrderProvider::class,
  32. output: \Webkul\BagistoApi\Dto\CustomerOrder\CustomerOrderListDto::class,
  33. normalizationContext: ['skip_null_values' => false],
  34. openapi: new Operation(tags: ['Customer Order']),
  35. ),
  36. new Get(
  37. uriTemplate: '/customer-orders/{id}',
  38. provider: CustomerOrderProvider::class,
  39. output: \Webkul\BagistoApi\Dto\CustomerOrder\CustomerOrderDetailDto::class,
  40. normalizationContext: ['skip_null_values' => false],
  41. openapi: new Operation(tags: ['Customer Order']),
  42. ),
  43. ],
  44. graphQlOperations: [
  45. new Query(
  46. provider: CustomerOrderProvider::class,
  47. ),
  48. new QueryCollection(
  49. provider: CustomerOrderProvider::class,
  50. paginationType: 'cursor',
  51. args: [
  52. 'status' => ['type' => 'String', 'description' => 'Filter orders by status (pending, processing, completed, canceled, closed, fraud)'],
  53. 'first' => ['type' => 'Int', 'description' => 'Number of items to return from the start'],
  54. 'last' => ['type' => 'Int', 'description' => 'Number of items to return from the end'],
  55. 'after' => ['type' => 'String', 'description' => 'Cursor to start pagination after'],
  56. 'before' => ['type' => 'String', 'description' => 'Cursor to start pagination before'],
  57. ],
  58. ),
  59. ],
  60. )]
  61. class CustomerOrder extends Model
  62. {
  63. /** @var string */
  64. protected $table = 'orders';
  65. /** @var array */
  66. protected $casts = [
  67. 'id' => 'int',
  68. 'increment_id' => 'string',
  69. 'status' => 'string',
  70. 'channel_name' => 'string',
  71. 'is_guest' => 'boolean',
  72. 'customer_email' => 'string',
  73. 'customer_first_name' => 'string',
  74. 'customer_last_name' => 'string',
  75. 'shipping_method' => 'string',
  76. 'shipping_title' => 'string',
  77. 'shipping_description' => 'string',
  78. 'coupon_code' => 'string',
  79. 'is_gift' => 'boolean',
  80. 'total_item_count' => 'int',
  81. 'total_qty_ordered' => 'int',
  82. 'base_currency_code' => 'string',
  83. 'channel_currency_code' => 'string',
  84. 'order_currency_code' => 'string',
  85. 'grand_total' => 'float',
  86. 'base_grand_total' => 'float',
  87. 'grand_total_invoiced' => 'float',
  88. 'base_grand_total_invoiced' => 'float',
  89. 'grand_total_refunded' => 'float',
  90. 'base_grand_total_refunded' => 'float',
  91. 'sub_total' => 'float',
  92. 'base_sub_total' => 'float',
  93. 'sub_total_invoiced' => 'float',
  94. 'base_sub_total_invoiced' => 'float',
  95. 'sub_total_refunded' => 'float',
  96. 'base_sub_total_refunded' => 'float',
  97. 'discount_percent' => 'float',
  98. 'discount_amount' => 'float',
  99. 'base_discount_amount' => 'float',
  100. 'discount_invoiced' => 'float',
  101. 'base_discount_invoiced' => 'float',
  102. 'discount_refunded' => 'float',
  103. 'base_discount_refunded' => 'float',
  104. 'tax_amount' => 'float',
  105. 'base_tax_amount' => 'float',
  106. 'tax_amount_invoiced' => 'float',
  107. 'base_tax_amount_invoiced' => 'float',
  108. 'tax_amount_refunded' => 'float',
  109. 'base_tax_amount_refunded' => 'float',
  110. 'shipping_amount' => 'float',
  111. 'base_shipping_amount' => 'float',
  112. 'shipping_invoiced' => 'float',
  113. 'base_shipping_invoiced' => 'float',
  114. 'shipping_refunded' => 'float',
  115. 'base_shipping_refunded' => 'float',
  116. 'shipping_discount_amount' => 'float',
  117. 'base_shipping_discount_amount' => 'float',
  118. 'shipping_tax_amount' => 'float',
  119. 'base_shipping_tax_amount' => 'float',
  120. 'shipping_tax_refunded' => 'float',
  121. 'base_shipping_tax_refunded' => 'float',
  122. 'sub_total_incl_tax' => 'float',
  123. 'base_sub_total_incl_tax' => 'float',
  124. 'shipping_amount_incl_tax' => 'float',
  125. 'base_shipping_amount_incl_tax' => 'float',
  126. 'customer_id' => 'int',
  127. 'channel_id' => 'int',
  128. 'applied_cart_rule_ids' => 'string',
  129. 'created_at' => 'datetime',
  130. 'updated_at' => 'datetime',
  131. ];
  132. /**
  133. * API Platform identifier
  134. */
  135. #[ApiProperty(identifier: true, writable: false)]
  136. public function getId(): int
  137. {
  138. return $this->id;
  139. }
  140. /**
  141. * Customer full name computed from first + last name.
  142. */
  143. #[ApiProperty(writable: false, description: 'Customer full name')]
  144. public function getCustomerFullNameAttribute(): string
  145. {
  146. return $this->customer_first_name . ' ' . $this->customer_last_name;
  147. }
  148. /**
  149. * Get the top-level order items (excludes child items).
  150. */
  151. #[ApiProperty(writable: false)]
  152. public function items(): HasMany
  153. {
  154. return $this->hasMany(CustomerOrderItem::class, 'order_id')
  155. ->whereNull('parent_id');
  156. }
  157. /**
  158. * Get the order addresses (billing + shipping).
  159. */
  160. public function addresses(): HasMany
  161. {
  162. return $this->hasMany(CustomerOrderAddress::class, 'order_id')
  163. ->whereIn('address_type', ['order_billing', 'order_shipping']);
  164. }
  165. /**
  166. * Get the payment record for the order.
  167. */
  168. public function payment(): HasOne
  169. {
  170. return $this->hasOne(CustomerOrderPayment::class, 'order_id');
  171. }
  172. /**
  173. * Get the shipments for this order.
  174. */
  175. #[ApiProperty(writable: false)]
  176. public function shipments(): HasMany
  177. {
  178. return $this->hasMany(CustomerOrderShipment::class, 'order_id');
  179. }
  180. }