CustomersReportTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. <?php
  2. use Webkul\Checkout\Models\Cart;
  3. use Webkul\Checkout\Models\CartAddress;
  4. use Webkul\Checkout\Models\CartItem;
  5. use Webkul\Checkout\Models\CartPayment;
  6. use Webkul\Customer\Models\Customer;
  7. use Webkul\Customer\Models\CustomerAddress;
  8. use Webkul\Faker\Helpers\Product as ProductFaker;
  9. use Webkul\Product\Models\ProductReview;
  10. use Webkul\Sales\Models\Invoice;
  11. use Webkul\Sales\Models\InvoiceItem;
  12. use Webkul\Sales\Models\Order;
  13. use Webkul\Sales\Models\OrderAddress;
  14. use Webkul\Sales\Models\OrderItem;
  15. use Webkul\Sales\Models\OrderPayment;
  16. use function Pest\Laravel\get;
  17. it('should return the index page of customers reporting', function () {
  18. // Act and Assert.
  19. $this->loginAsAdmin();
  20. get(route('admin.reporting.customers.index'))
  21. ->assertOk()
  22. ->assertSeeText(trans('admin::app.reporting.customers.index.title'))
  23. ->assertSeeText(trans('admin::app.reporting.customers.index.customers-with-most-orders'))
  24. ->assertSeeText(trans('admin::app.reporting.customers.index.customers-with-most-reviews'))
  25. ->assertSeeText(trans('admin::app.reporting.customers.index.customers-with-most-sales'))
  26. ->assertSeeText(trans('admin::app.reporting.customers.index.top-customer-groups'))
  27. ->assertSeeText(trans('admin::app.reporting.customers.index.total-customers'))
  28. ->assertSeeText(trans('admin::app.reporting.customers.index.customers-traffic'));
  29. });
  30. it('should return the customers stats report', function () {
  31. // Act and Assert.
  32. $this->loginAsAdmin();
  33. Customer::factory()->count(2)->create();
  34. get(route('admin.reporting.customers.stats', [
  35. 'type' => 'total-customers',
  36. ]))
  37. ->assertOk()
  38. ->assertJsonPath('statistics.over_time.current.30.total', 2);
  39. });
  40. it('should return the customers with most reviews stats report', function () {
  41. // Arrange.
  42. $customer = Customer::factory()->create();
  43. $product = (new ProductFaker([
  44. 'attributes' => [
  45. 5 => 'new',
  46. ],
  47. 'attribute_value' => [
  48. 'new' => [
  49. 'boolean_value' => true,
  50. ],
  51. ],
  52. ]))
  53. ->getSimpleProductFactory()
  54. ->create();
  55. $productReviews = ProductReview::factory()->count(2)->create([
  56. 'status' => 'approved',
  57. 'customer_id' => $customer->id,
  58. 'name' => $customer->name,
  59. 'product_id' => $product->id,
  60. ]);
  61. // Act and Assert.
  62. $this->loginAsAdmin();
  63. get(route('admin.reporting.customers.stats', [
  64. 'type' => 'customers-with-most-reviews',
  65. ]))
  66. ->assertOk()
  67. ->assertJsonPath('statistics.0.email', $customer->email)
  68. ->assertJsonPath('statistics.0.id', $customer->id)
  69. ->assertJsonPath('statistics.0.reviews', $productReviews->count());
  70. foreach ($productReviews as $productReview) {
  71. $this->assertDatabaseHas('product_reviews', [
  72. 'customer_id' => $productReview->customer_id,
  73. 'product_id' => $productReview->product_id,
  74. 'status' => $productReview->status,
  75. 'name' => $productReview->name,
  76. ]);
  77. }
  78. });
  79. it('should return the top customers group stats report', function () {
  80. // Arrange.
  81. $customer = Customer::factory()->create();
  82. // Act and Assert.
  83. $this->loginAsAdmin();
  84. get(route('admin.reporting.customers.stats', [
  85. 'type' => 'top-customer-groups',
  86. ]))
  87. ->assertOk()
  88. ->assertJsonPath('statistics.0.id', $customer->id)
  89. ->assertJsonPath('statistics.0.group_name', 'General');
  90. });
  91. it('should return the customers with most orders stats report', function () {
  92. // Arrange.
  93. $product = (new ProductFaker([
  94. 'attributes' => [
  95. 5 => 'new',
  96. ],
  97. 'attribute_value' => [
  98. 'new' => [
  99. 'boolean_value' => true,
  100. ],
  101. ],
  102. ]))
  103. ->getSimpleProductFactory()
  104. ->create();
  105. $customer = Customer::factory()->create();
  106. $cart = Cart::factory()->create([
  107. 'customer_id' => $customer->id,
  108. 'customer_first_name' => $customer->first_name,
  109. 'customer_last_name' => $customer->last_name,
  110. 'customer_email' => $customer->email,
  111. 'is_guest' => 0,
  112. ]);
  113. $additional = [
  114. 'product_id' => $product->id,
  115. 'rating' => '0',
  116. 'is_buy_now' => '0',
  117. 'quantity' => '1',
  118. ];
  119. $cartItem = CartItem::factory()->create([
  120. 'cart_id' => $cart->id,
  121. 'product_id' => $product->id,
  122. 'sku' => $product->sku,
  123. 'quantity' => $additional['quantity'],
  124. 'name' => $product->name,
  125. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  126. 'base_price' => $price,
  127. 'total' => $convertedPrice * $additional['quantity'],
  128. 'base_total' => $price * $additional['quantity'],
  129. 'weight' => $product->weight ?? 0,
  130. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  131. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  132. 'type' => $product->type,
  133. 'additional' => $additional,
  134. ]);
  135. $customerAddress = CustomerAddress::factory()->create([
  136. 'cart_id' => $cart->id,
  137. 'customer_id' => $customer->id,
  138. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  139. ]);
  140. $cartBillingAddress = CartAddress::factory()->create([
  141. 'cart_id' => $cart->id,
  142. 'customer_id' => $customer->id,
  143. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  144. ]);
  145. $cartShippingAddress = CartAddress::factory()->create([
  146. 'cart_id' => $cart->id,
  147. 'customer_id' => $customer->id,
  148. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  149. ]);
  150. $cartPayment = CartPayment::factory()->create([
  151. 'cart_id' => $cart->id,
  152. 'method' => $paymentMethod = 'cashondelivery',
  153. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  154. ]);
  155. $order = Order::factory()->create([
  156. 'cart_id' => $cart->id,
  157. 'customer_id' => $customer->id,
  158. 'customer_email' => $customer->email,
  159. 'customer_first_name' => $customer->first_name,
  160. 'customer_last_name' => $customer->last_name,
  161. ]);
  162. $orderItem = OrderItem::factory()->create([
  163. 'product_id' => $product->id,
  164. 'order_id' => $order->id,
  165. 'sku' => $product->sku,
  166. 'type' => $product->type,
  167. 'name' => $product->name,
  168. ]);
  169. OrderPayment::factory()->create([
  170. 'order_id' => $order->id,
  171. ]);
  172. $orderBillingAddress = OrderAddress::factory()->create([
  173. 'cart_id' => $cart->id,
  174. 'customer_id' => $customer->id,
  175. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  176. ]);
  177. $orderShippingAddress = OrderAddress::factory()->create([
  178. 'cart_id' => $cart->id,
  179. 'customer_id' => $customer->id,
  180. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  181. ]);
  182. $invoice = Invoice::factory()->create([
  183. 'order_id' => $order->id,
  184. 'state' => 'paid',
  185. ]);
  186. $invoiceItem = InvoiceItem::factory()->create([
  187. 'invoice_id' => $invoice->id,
  188. 'order_item_id' => $orderItem->id,
  189. 'name' => $orderItem->name,
  190. 'sku' => $orderItem->sku,
  191. 'qty' => 1,
  192. 'price' => $orderItem->price,
  193. 'base_price' => $orderItem->base_price,
  194. 'total' => $orderItem->price,
  195. 'base_total' => $orderItem->base_price,
  196. 'tax_amount' => (($orderItem->tax_amount / $orderItem->qty_ordered)),
  197. 'base_tax_amount' => (($orderItem->base_tax_amount / $orderItem->qty_ordered)),
  198. 'discount_amount' => (($orderItem->discount_amount / $orderItem->qty_ordered)),
  199. 'base_discount_amount' => (($orderItem->base_discount_amount / $orderItem->qty_ordered)),
  200. 'product_id' => $orderItem->product_id,
  201. 'product_type' => $orderItem->product_type,
  202. 'additional' => $orderItem->additional,
  203. ]);
  204. $orderPayment = OrderPayment::factory()->create([
  205. 'order_id' => $order->id,
  206. ]);
  207. // Act and Assert.
  208. $this->loginAsAdmin();
  209. get(route('admin.reporting.customers.stats', [
  210. 'type' => 'customers-with-most-orders',
  211. ]))
  212. ->assertOk()
  213. ->assertJsonPath('statistics.0.id', $customer->id)
  214. ->assertJsonPath('statistics.0.email', $customer->email)
  215. ->assertJsonPath('statistics.0.full_name', $customer->name)
  216. ->assertJsonPath('statistics.0.orders', $customer->orders()->count());
  217. $cart->refresh();
  218. $cartItem->refresh();
  219. $cartBillingAddress->refresh();
  220. $cartShippingAddress->refresh();
  221. $orderBillingAddress->refresh();
  222. $orderShippingAddress->refresh();
  223. $order->refresh();
  224. $orderItem->refresh();
  225. $invoiceItem->refresh();
  226. $this->assertModelWise([
  227. Cart::class => [
  228. $this->prepareCart($cart),
  229. ],
  230. CartItem::class => [
  231. $this->prepareCartItem($cartItem),
  232. ],
  233. CartPayment::class => [
  234. $this->prepareCartPayment($cartPayment),
  235. ],
  236. CartAddress::class => [
  237. $this->prepareAddress($cartBillingAddress),
  238. ],
  239. CartAddress::class => [
  240. $this->prepareAddress($cartShippingAddress),
  241. ],
  242. CustomerAddress::class => [
  243. $this->prepareAddress($customerAddress),
  244. ],
  245. Order::class => [
  246. $this->prepareOrder($order),
  247. ],
  248. OrderItem::class => [
  249. $this->prepareOrderItem($orderItem),
  250. ],
  251. OrderAddress::class => [
  252. $this->prepareAddress($orderBillingAddress),
  253. $this->prepareAddress($orderShippingAddress),
  254. ],
  255. OrderPayment::class => [
  256. $this->prepareOrderPayment($orderPayment),
  257. ],
  258. InvoiceItem::class => [
  259. $this->prepareInvoiceItem($invoiceItem),
  260. ],
  261. ]);
  262. });
  263. it('should return the customers with most sales stats report', function () {
  264. // Arrange.
  265. $product = (new ProductFaker([
  266. 'attributes' => [
  267. 5 => 'new',
  268. ],
  269. 'attribute_value' => [
  270. 'new' => [
  271. 'boolean_value' => true,
  272. ],
  273. ],
  274. ]))
  275. ->getSimpleProductFactory()
  276. ->create();
  277. $customer = Customer::factory()->create();
  278. $cart = Cart::factory()->create([
  279. 'customer_id' => $customer->id,
  280. 'customer_first_name' => $customer->first_name,
  281. 'customer_last_name' => $customer->last_name,
  282. 'customer_email' => $customer->email,
  283. 'is_guest' => 0,
  284. ]);
  285. $additional = [
  286. 'product_id' => $product->id,
  287. 'rating' => '0',
  288. 'is_buy_now' => '0',
  289. 'quantity' => '1',
  290. ];
  291. $cartItem = CartItem::factory()->create([
  292. 'cart_id' => $cart->id,
  293. 'product_id' => $product->id,
  294. 'sku' => $product->sku,
  295. 'quantity' => $additional['quantity'],
  296. 'name' => $product->name,
  297. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  298. 'base_price' => $price,
  299. 'total' => $convertedPrice * $additional['quantity'],
  300. 'base_total' => $price * $additional['quantity'],
  301. 'weight' => $product->weight ?? 0,
  302. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  303. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  304. 'type' => $product->type,
  305. 'additional' => $additional,
  306. ]);
  307. $customerAddress = CustomerAddress::factory()->create([
  308. 'cart_id' => $cart->id,
  309. 'customer_id' => $customer->id,
  310. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  311. ]);
  312. $cartBillingAddress = CartAddress::factory()->create([
  313. 'cart_id' => $cart->id,
  314. 'customer_id' => $customer->id,
  315. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  316. ]);
  317. $cartShippingAddress = CartAddress::factory()->create([
  318. 'cart_id' => $cart->id,
  319. 'customer_id' => $customer->id,
  320. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  321. ]);
  322. $cartPayment = CartPayment::factory()->create([
  323. 'cart_id' => $cart->id,
  324. 'method' => $paymentMethod = 'cashondelivery',
  325. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  326. ]);
  327. $order = Order::factory()->create([
  328. 'cart_id' => $cart->id,
  329. 'customer_id' => $customer->id,
  330. 'customer_email' => $customer->email,
  331. 'customer_first_name' => $customer->first_name,
  332. 'customer_last_name' => $customer->last_name,
  333. ]);
  334. $orderItem = OrderItem::factory()->create([
  335. 'product_id' => $product->id,
  336. 'order_id' => $order->id,
  337. 'sku' => $product->sku,
  338. 'type' => $product->type,
  339. 'name' => $product->name,
  340. ]);
  341. OrderPayment::factory()->create([
  342. 'order_id' => $order->id,
  343. ]);
  344. $orderBillingAddress = OrderAddress::factory()->create([
  345. 'cart_id' => $cart->id,
  346. 'customer_id' => $customer->id,
  347. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  348. ]);
  349. $orderShippingAddress = OrderAddress::factory()->create([
  350. 'cart_id' => $cart->id,
  351. 'customer_id' => $customer->id,
  352. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  353. ]);
  354. $invoice = Invoice::factory()->create([
  355. 'order_id' => $order->id,
  356. 'state' => 'paid',
  357. ]);
  358. $invoiceItem = InvoiceItem::factory()->create([
  359. 'invoice_id' => $invoice->id,
  360. 'order_item_id' => $orderItem->id,
  361. 'name' => $orderItem->name,
  362. 'sku' => $orderItem->sku,
  363. 'qty' => 1,
  364. 'price' => $orderItem->price,
  365. 'base_price' => $orderItem->base_price,
  366. 'total' => $orderItem->price,
  367. 'base_total' => $orderItem->base_price,
  368. 'tax_amount' => (($orderItem->tax_amount / $orderItem->qty_ordered)),
  369. 'base_tax_amount' => (($orderItem->base_tax_amount / $orderItem->qty_ordered)),
  370. 'discount_amount' => (($orderItem->discount_amount / $orderItem->qty_ordered)),
  371. 'base_discount_amount' => (($orderItem->base_discount_amount / $orderItem->qty_ordered)),
  372. 'product_id' => $orderItem->product_id,
  373. 'product_type' => $orderItem->product_type,
  374. 'additional' => $orderItem->additional,
  375. ]);
  376. $orderPayment = OrderPayment::factory()->create([
  377. 'order_id' => $order->id,
  378. ]);
  379. // Act and Assert.
  380. $this->loginAsAdmin();
  381. get(route('admin.reporting.customers.stats', [
  382. 'type' => 'customers-with-most-sales',
  383. ]))
  384. ->assertOk()
  385. ->assertJsonPath('statistics.0.id', $customer->id)
  386. ->assertJsonPath('statistics.0.email', $customer->email)
  387. ->assertJsonPath('statistics.0.full_name', $customer->name)
  388. ->assertJsonPath('statistics.0.orders', $customer->orders()->count());
  389. $cart->refresh();
  390. $cartItem->refresh();
  391. $cartBillingAddress->refresh();
  392. $cartShippingAddress->refresh();
  393. $orderBillingAddress->refresh();
  394. $orderShippingAddress->refresh();
  395. $order->refresh();
  396. $orderItem->refresh();
  397. $invoiceItem->refresh();
  398. $this->assertModelWise([
  399. Cart::class => [
  400. $this->prepareCart($cart),
  401. ],
  402. CartItem::class => [
  403. $this->prepareCartItem($cartItem),
  404. ],
  405. CartPayment::class => [
  406. $this->prepareCartPayment($cartPayment),
  407. ],
  408. CartAddress::class => [
  409. $this->prepareAddress($cartBillingAddress),
  410. ],
  411. CartAddress::class => [
  412. $this->prepareAddress($cartShippingAddress),
  413. ],
  414. CustomerAddress::class => [
  415. $this->prepareAddress($customerAddress),
  416. ],
  417. Order::class => [
  418. $this->prepareOrder($order),
  419. ],
  420. OrderItem::class => [
  421. $this->prepareOrderItem($orderItem),
  422. ],
  423. OrderAddress::class => [
  424. $this->prepareAddress($orderBillingAddress),
  425. $this->prepareAddress($orderShippingAddress),
  426. ],
  427. OrderPayment::class => [
  428. $this->prepareOrderPayment($orderPayment),
  429. ],
  430. InvoiceItem::class => [
  431. $this->prepareInvoiceItem($invoiceItem),
  432. ],
  433. ]);
  434. });