OrderRepository.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. namespace App\Shop\Orders\Repositories;
  3. use App\Shop\Carts\Repositories\CartRepository;
  4. use App\Shop\Carts\ShoppingCart;
  5. use Gloudemans\Shoppingcart\Facades\Cart;
  6. use Jsdecena\Baserepo\BaseRepository;
  7. use App\Shop\Employees\Employee;
  8. use App\Shop\Employees\Repositories\EmployeeRepository;
  9. use App\Events\OrderCreateEvent;
  10. use App\Mail\sendEmailNotificationToAdminMailable;
  11. use App\Mail\SendOrderToCustomerMailable;
  12. use App\Shop\Orders\Exceptions\OrderInvalidArgumentException;
  13. use App\Shop\Orders\Exceptions\OrderNotFoundException;
  14. use App\Shop\Addresses\Address;
  15. use App\Shop\Couriers\Courier;
  16. use App\Shop\Orders\Order;
  17. use App\Shop\Orders\Repositories\Interfaces\OrderRepositoryInterface;
  18. use App\Shop\Orders\Transformers\OrderTransformable;
  19. use App\Shop\Products\Product;
  20. use App\Shop\Products\Repositories\ProductRepository;
  21. use Illuminate\Database\Eloquent\ModelNotFoundException;
  22. use Illuminate\Database\QueryException;
  23. use Illuminate\Support\Collection;
  24. use Illuminate\Support\Facades\Mail;
  25. class OrderRepository extends BaseRepository implements OrderRepositoryInterface
  26. {
  27. use OrderTransformable;
  28. /**
  29. * OrderRepository constructor.
  30. * @param Order $order
  31. */
  32. public function __construct(Order $order)
  33. {
  34. parent::__construct($order);
  35. $this->model = $order;
  36. }
  37. /**
  38. * Create the order
  39. *
  40. * @param array $params
  41. * @return Order
  42. * @throws OrderInvalidArgumentException
  43. */
  44. public function createOrder(array $params) : Order
  45. {
  46. try {
  47. $order = $this->create($params);
  48. $orderRepo = new OrderRepository($order);
  49. $orderRepo->buildOrderDetails(Cart::content());
  50. event(new OrderCreateEvent($order));
  51. return $order;
  52. } catch (QueryException $e) {
  53. throw new OrderInvalidArgumentException($e->getMessage(), 500, $e);
  54. }
  55. }
  56. /**
  57. * @param array $params
  58. *
  59. * @return bool
  60. * @throws OrderInvalidArgumentException
  61. */
  62. public function updateOrder(array $params) : bool
  63. {
  64. try {
  65. return $this->update($params);
  66. } catch (QueryException $e) {
  67. throw new OrderInvalidArgumentException($e->getMessage());
  68. }
  69. }
  70. /**
  71. * @param int $id
  72. * @return Order
  73. * @throws OrderNotFoundException
  74. */
  75. public function findOrderById(int $id) : Order
  76. {
  77. try {
  78. return $this->findOneOrFail($id);
  79. } catch (ModelNotFoundException $e) {
  80. throw new OrderNotFoundException($e);
  81. }
  82. }
  83. /**
  84. * Return all the orders
  85. *
  86. * @param string $order
  87. * @param string $sort
  88. * @param array $columns
  89. * @return Collection
  90. */
  91. public function listOrders(string $order = 'id', string $sort = 'desc', array $columns = ['*']) : Collection
  92. {
  93. return $this->all($columns, $order, $sort);
  94. }
  95. /**
  96. * @param Order $order
  97. * @return mixed
  98. */
  99. public function findProducts(Order $order) : Collection
  100. {
  101. return $order->products;
  102. }
  103. /**
  104. * @param Product $product
  105. * @param int $quantity
  106. * @param array $data
  107. */
  108. public function associateProduct(Product $product, int $quantity = 1, array $data = [])
  109. {
  110. $this->model->products()->attach($product, [
  111. 'quantity' => $quantity,
  112. 'product_name' => $product->name,
  113. 'product_sku' => $product->sku,
  114. 'product_description' => $product->description,
  115. 'product_price' => $product->price,
  116. 'product_attribute_id' => isset($data['product_attribute_id']) ? $data['product_attribute_id']: null,
  117. ]);
  118. $product->quantity = ($product->quantity - $quantity);
  119. $product->save();
  120. }
  121. /**
  122. * Send email to customer
  123. */
  124. public function sendEmailToCustomer()
  125. {
  126. Mail::to($this->model->customer)
  127. ->send(new SendOrderToCustomerMailable($this->findOrderById($this->model->id)));
  128. }
  129. /**
  130. * Send email notification to the admin
  131. */
  132. public function sendEmailNotificationToAdmin()
  133. {
  134. $employeeRepo = new EmployeeRepository(new Employee);
  135. $employee = $employeeRepo->findEmployeeById(1);
  136. Mail::to($employee)
  137. ->send(new sendEmailNotificationToAdminMailable($this->findOrderById($this->model->id)));
  138. }
  139. /**
  140. * @param string $text
  141. * @return mixed
  142. */
  143. public function searchOrder(string $text) : Collection
  144. {
  145. if (!empty($text)) {
  146. return $this->model->searchForOrder($text)->get();
  147. } else {
  148. return $this->listOrders();
  149. }
  150. }
  151. /**
  152. * @return Order
  153. */
  154. public function transform()
  155. {
  156. return $this->transformOrder($this->model);
  157. }
  158. /**
  159. * @return Collection
  160. */
  161. public function listOrderedProducts() : Collection
  162. {
  163. return $this->model->products->map(function (Product $product) {
  164. $product->name = $product->pivot->product_name;
  165. $product->sku = $product->pivot->product_sku;
  166. $product->description = $product->pivot->product_description;
  167. $product->price = $product->pivot->product_price;
  168. $product->quantity = $product->pivot->quantity;
  169. $product->product_attribute_id = $product->pivot->product_attribute_id;
  170. return $product;
  171. });
  172. }
  173. /**
  174. * @param Collection $items
  175. */
  176. public function buildOrderDetails(Collection $items)
  177. {
  178. $items->each(function ($item) {
  179. $productRepo = new ProductRepository(new Product);
  180. $product = $productRepo->find($item->id);
  181. if ($item->options->has('product_attribute_id')) {
  182. $this->associateProduct($product, $item->qty, [
  183. 'product_attribute_id' => $item->options->product_attribute_id
  184. ]);
  185. } else {
  186. $this->associateProduct($product, $item->qty);
  187. }
  188. });
  189. }
  190. /**
  191. * @return Collection $addresses
  192. */
  193. public function getAddresses() : Collection
  194. {
  195. return $this->model->address()->get();
  196. }
  197. /**
  198. * @return Collection $couriers
  199. */
  200. public function getCouriers() : Collection
  201. {
  202. return $this->model->courier()->get();
  203. }
  204. }