RefundTest.php 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. <?php
  2. use Illuminate\Support\Facades\Mail;
  3. use Webkul\Admin\Mail\Order\RefundedNotification as AdminRefundedNotification;
  4. use Webkul\Checkout\Models\Cart;
  5. use Webkul\Checkout\Models\CartAddress;
  6. use Webkul\Checkout\Models\CartItem;
  7. use Webkul\Checkout\Models\CartPayment;
  8. use Webkul\Checkout\Models\CartShippingRate;
  9. use Webkul\Core\Models\CoreConfig;
  10. use Webkul\Customer\Models\Customer;
  11. use Webkul\Customer\Models\CustomerAddress;
  12. use Webkul\Faker\Helpers\Product as ProductFaker;
  13. use Webkul\Sales\Models\Order;
  14. use Webkul\Sales\Models\OrderAddress;
  15. use Webkul\Sales\Models\OrderItem;
  16. use Webkul\Sales\Models\OrderPayment;
  17. use Webkul\Sales\Models\Refund;
  18. use Webkul\Shop\Mail\Order\RefundedNotification as ShopRefundedNotification;
  19. use function Pest\Laravel\get;
  20. use function Pest\Laravel\postJson;
  21. it('should return the refund index page', function () {
  22. // Act and Assert.
  23. $this->loginAsAdmin();
  24. get(route('admin.sales.refunds.index'))
  25. ->assertOk()
  26. ->assertSeeText(trans('admin::app.sales.refunds.index.title'));
  27. });
  28. it('should fails the validation error when refund items data not provided', function () {
  29. // Arrange.
  30. $product = (new ProductFaker([
  31. 'attributes' => [
  32. 5 => 'new',
  33. ],
  34. 'attribute_value' => [
  35. 'new' => [
  36. 'boolean_value' => true,
  37. ],
  38. ],
  39. ]))
  40. ->getSimpleProductFactory()
  41. ->create();
  42. $customer = Customer::factory()->create();
  43. $cart = Cart::factory()->create([
  44. 'customer_id' => $customer->id,
  45. 'customer_first_name' => $customer->first_name,
  46. 'customer_last_name' => $customer->last_name,
  47. 'customer_email' => $customer->email,
  48. 'is_guest' => 0,
  49. ]);
  50. $additional = [
  51. 'product_id' => $product->id,
  52. 'rating' => '0',
  53. 'is_buy_now' => '0',
  54. 'quantity' => '1',
  55. ];
  56. $cartItem = CartItem::factory()->create([
  57. 'cart_id' => $cart->id,
  58. 'product_id' => $product->id,
  59. 'sku' => $product->sku,
  60. 'quantity' => $additional['quantity'],
  61. 'name' => $product->name,
  62. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  63. 'price_incl_tax' => $convertedPrice,
  64. 'base_price' => $price,
  65. 'base_price_incl_tax' => $price,
  66. 'total' => $total = $convertedPrice * $additional['quantity'],
  67. 'total_incl_tax' => $total,
  68. 'base_total' => $price * $additional['quantity'],
  69. 'weight' => $product->weight ?? 0,
  70. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  71. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  72. 'type' => $product->type,
  73. 'additional' => $additional,
  74. ]);
  75. $customerAddress = CustomerAddress::factory()->create([
  76. 'cart_id' => $cart->id,
  77. 'customer_id' => $customer->id,
  78. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  79. ]);
  80. $cartBillingAddress = CartAddress::factory()->create([
  81. 'cart_id' => $cart->id,
  82. 'customer_id' => $customer->id,
  83. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  84. ]);
  85. $cartShippingAddress = CartAddress::factory()->create([
  86. 'cart_id' => $cart->id,
  87. 'customer_id' => $customer->id,
  88. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  89. ]);
  90. $cartPayment = CartPayment::factory()->create([
  91. 'cart_id' => $cart->id,
  92. 'method' => $paymentMethod = 'cashondelivery',
  93. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  94. ]);
  95. $cartShippingRate = CartShippingRate::factory()->create([
  96. 'carrier' => 'free',
  97. 'carrier_title' => 'Free shipping',
  98. 'method' => 'free_free',
  99. 'method_title' => 'Free Shipping',
  100. 'method_description' => 'Free Shipping',
  101. 'cart_address_id' => $cartShippingAddress->id,
  102. ]);
  103. $order = Order::factory()->create([
  104. 'cart_id' => $cart->id,
  105. 'customer_id' => $customer->id,
  106. 'customer_email' => $customer->email,
  107. 'customer_first_name' => $customer->first_name,
  108. 'customer_last_name' => $customer->last_name,
  109. ]);
  110. $orderItem = OrderItem::factory()->create([
  111. 'product_id' => $product->id,
  112. 'order_id' => $order->id,
  113. 'sku' => $product->sku,
  114. 'type' => $product->type,
  115. 'name' => $product->name,
  116. ]);
  117. $orderBillingAddress = OrderAddress::factory()->create([
  118. 'cart_id' => $cart->id,
  119. 'customer_id' => $customer->id,
  120. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  121. ]);
  122. $orderShippingAddress = OrderAddress::factory()->create([
  123. 'cart_id' => $cart->id,
  124. 'customer_id' => $customer->id,
  125. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  126. ]);
  127. $orderPayment = OrderPayment::factory()->create([
  128. 'order_id' => $order->id,
  129. ]);
  130. // Act and Assert.
  131. $this->loginAsAdmin();
  132. postJson(route('admin.sales.refunds.store', $order->id), [
  133. 'refund' => [
  134. 'items' => [
  135. 'INVALID_DATA',
  136. ],
  137. 'shipping' => '0',
  138. 'adjustment_refund' => '0',
  139. 'adjustment_fee' => '0',
  140. ],
  141. ])
  142. ->assertJsonValidationErrorFor('refund.items.0')
  143. ->assertUnprocessable();
  144. $cart->refresh();
  145. $cartItem->refresh();
  146. $cartBillingAddress->refresh();
  147. $cartShippingAddress->refresh();
  148. $orderBillingAddress->refresh();
  149. $orderShippingAddress->refresh();
  150. $order->refresh();
  151. $orderItem->refresh();
  152. $this->assertModelWise([
  153. Cart::class => [
  154. $this->prepareCart($cart),
  155. ],
  156. CartItem::class => [
  157. $this->prepareCartItem($cartItem),
  158. ],
  159. CartPayment::class => [
  160. $this->prepareCartPayment($cartPayment),
  161. ],
  162. CartAddress::class => [
  163. $this->prepareAddress($cartBillingAddress),
  164. ],
  165. CartAddress::class => [
  166. $this->prepareAddress($cartShippingAddress),
  167. ],
  168. CartShippingRate::class => [
  169. $this->prepareCartShippingRate($cartShippingRate),
  170. ],
  171. CustomerAddress::class => [
  172. $this->prepareAddress($customerAddress),
  173. ],
  174. Order::class => [
  175. $this->prepareOrder($order),
  176. ],
  177. OrderItem::class => [
  178. $this->prepareOrderItem($orderItem),
  179. ],
  180. OrderAddress::class => [
  181. $this->prepareAddress($orderBillingAddress),
  182. $this->prepareAddress($orderShippingAddress),
  183. ],
  184. OrderPayment::class => [
  185. $this->prepareOrderPayment($orderPayment),
  186. ],
  187. ]);
  188. });
  189. it('should fails the validation error when refund items data provided with wrong way', function () {
  190. // Arrange.
  191. $product = (new ProductFaker([
  192. 'attributes' => [
  193. 5 => 'new',
  194. ],
  195. 'attribute_value' => [
  196. 'new' => [
  197. 'boolean_value' => true,
  198. ],
  199. ],
  200. ]))
  201. ->getSimpleProductFactory()
  202. ->create();
  203. $customer = Customer::factory()->create();
  204. $cart = Cart::factory()->create([
  205. 'customer_id' => $customer->id,
  206. 'customer_first_name' => $customer->first_name,
  207. 'customer_last_name' => $customer->last_name,
  208. 'customer_email' => $customer->email,
  209. 'is_guest' => 0,
  210. ]);
  211. $additional = [
  212. 'product_id' => $product->id,
  213. 'rating' => '0',
  214. 'is_buy_now' => '0',
  215. 'quantity' => '1',
  216. ];
  217. $cartItem = CartItem::factory()->create([
  218. 'cart_id' => $cart->id,
  219. 'product_id' => $product->id,
  220. 'sku' => $product->sku,
  221. 'quantity' => $additional['quantity'],
  222. 'name' => $product->name,
  223. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  224. 'price_incl_tax' => $convertedPrice,
  225. 'base_price' => $price,
  226. 'base_price_incl_tax' => $price,
  227. 'total' => $total = $convertedPrice * $additional['quantity'],
  228. 'total_incl_tax' => $total,
  229. 'base_total' => $price * $additional['quantity'],
  230. 'weight' => $product->weight ?? 0,
  231. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  232. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  233. 'type' => $product->type,
  234. 'additional' => $additional,
  235. ]);
  236. $customerAddress = CustomerAddress::factory()->create([
  237. 'cart_id' => $cart->id,
  238. 'customer_id' => $customer->id,
  239. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  240. ]);
  241. $cartBillingAddress = CartAddress::factory()->create([
  242. 'cart_id' => $cart->id,
  243. 'customer_id' => $customer->id,
  244. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  245. ]);
  246. $cartShippingAddress = CartAddress::factory()->create([
  247. 'cart_id' => $cart->id,
  248. 'customer_id' => $customer->id,
  249. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  250. ]);
  251. $cartPayment = CartPayment::factory()->create([
  252. 'cart_id' => $cart->id,
  253. 'method' => $paymentMethod = 'cashondelivery',
  254. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  255. ]);
  256. $cartShippingRate = CartShippingRate::factory()->create([
  257. 'carrier' => 'free',
  258. 'carrier_title' => 'Free shipping',
  259. 'method' => 'free_free',
  260. 'method_title' => 'Free Shipping',
  261. 'method_description' => 'Free Shipping',
  262. 'cart_address_id' => $cartShippingAddress->id,
  263. ]);
  264. $order = Order::factory()->create([
  265. 'cart_id' => $cart->id,
  266. 'customer_id' => $customer->id,
  267. 'customer_email' => $customer->email,
  268. 'customer_first_name' => $customer->first_name,
  269. 'customer_last_name' => $customer->last_name,
  270. ]);
  271. $orderItem = OrderItem::factory()->create([
  272. 'product_id' => $product->id,
  273. 'order_id' => $order->id,
  274. 'sku' => $product->sku,
  275. 'type' => $product->type,
  276. 'name' => $product->name,
  277. ]);
  278. $orderBillingAddress = OrderAddress::factory()->create([
  279. 'cart_id' => $cart->id,
  280. 'customer_id' => $customer->id,
  281. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  282. ]);
  283. $orderShippingAddress = OrderAddress::factory()->create([
  284. 'cart_id' => $cart->id,
  285. 'customer_id' => $customer->id,
  286. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  287. ]);
  288. $orderPayment = OrderPayment::factory()->create([
  289. 'order_id' => $order->id,
  290. ]);
  291. // Act and Assert.
  292. $this->loginAsAdmin();
  293. postJson(route('admin.sales.refunds.store', $order->id), [
  294. 'refund' => [
  295. 'items' => [
  296. fake()->word(),
  297. ],
  298. ],
  299. ])
  300. ->assertJsonValidationErrorFor('refund.items.0')
  301. ->assertUnprocessable();
  302. $cart->refresh();
  303. $cartItem->refresh();
  304. $cartBillingAddress->refresh();
  305. $cartShippingAddress->refresh();
  306. $orderBillingAddress->refresh();
  307. $orderShippingAddress->refresh();
  308. $order->refresh();
  309. $orderItem->refresh();
  310. $this->assertModelWise([
  311. Cart::class => [
  312. $this->prepareCart($cart),
  313. ],
  314. CartItem::class => [
  315. $this->prepareCartItem($cartItem),
  316. ],
  317. CartPayment::class => [
  318. $this->prepareCartPayment($cartPayment),
  319. ],
  320. CartAddress::class => [
  321. $this->prepareAddress($cartBillingAddress),
  322. ],
  323. CartAddress::class => [
  324. $this->prepareAddress($cartShippingAddress),
  325. ],
  326. CartShippingRate::class => [
  327. $this->prepareCartShippingRate($cartShippingRate),
  328. ],
  329. CustomerAddress::class => [
  330. $this->prepareAddress($customerAddress),
  331. ],
  332. Order::class => [
  333. $this->prepareOrder($order),
  334. ],
  335. OrderItem::class => [
  336. $this->prepareOrderItem($orderItem),
  337. ],
  338. OrderAddress::class => [
  339. $this->prepareAddress($orderBillingAddress),
  340. $this->prepareAddress($orderShippingAddress),
  341. ],
  342. OrderPayment::class => [
  343. $this->prepareOrderPayment($orderPayment),
  344. ],
  345. ]);
  346. });
  347. it('should store the order refund', function () {
  348. // Arrange.
  349. $product = (new ProductFaker([
  350. 'attributes' => [
  351. 5 => 'new',
  352. ],
  353. 'attribute_value' => [
  354. 'new' => [
  355. 'boolean_value' => true,
  356. ],
  357. ],
  358. ]))
  359. ->getSimpleProductFactory()
  360. ->create();
  361. $customer = Customer::factory()->create();
  362. $cart = Cart::factory()->create([
  363. 'customer_id' => $customer->id,
  364. 'customer_first_name' => $customer->first_name,
  365. 'customer_last_name' => $customer->last_name,
  366. 'customer_email' => $customer->email,
  367. 'is_guest' => 0,
  368. ]);
  369. $additional = [
  370. 'product_id' => $product->id,
  371. 'rating' => '0',
  372. 'is_buy_now' => '0',
  373. 'quantity' => '1',
  374. ];
  375. $cartItem = CartItem::factory()->create([
  376. 'cart_id' => $cart->id,
  377. 'product_id' => $product->id,
  378. 'sku' => $product->sku,
  379. 'quantity' => $additional['quantity'],
  380. 'name' => $product->name,
  381. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  382. 'price_incl_tax' => $convertedPrice,
  383. 'base_price' => $price,
  384. 'base_price_incl_tax' => $price,
  385. 'total' => $total = $convertedPrice * $additional['quantity'],
  386. 'total_incl_tax' => $total,
  387. 'base_total' => $price * $additional['quantity'],
  388. 'weight' => $product->weight ?? 0,
  389. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  390. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  391. 'type' => $product->type,
  392. 'additional' => $additional,
  393. ]);
  394. $customerAddress = CustomerAddress::factory()->create([
  395. 'cart_id' => $cart->id,
  396. 'customer_id' => $customer->id,
  397. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  398. ]);
  399. $cartBillingAddress = CartAddress::factory()->create([
  400. 'cart_id' => $cart->id,
  401. 'customer_id' => $customer->id,
  402. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  403. ]);
  404. $cartShippingAddress = CartAddress::factory()->create([
  405. 'cart_id' => $cart->id,
  406. 'customer_id' => $customer->id,
  407. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  408. ]);
  409. $cartPayment = CartPayment::factory()->create([
  410. 'cart_id' => $cart->id,
  411. 'method' => $paymentMethod = 'cashondelivery',
  412. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  413. ]);
  414. $cartShippingRate = CartShippingRate::factory()->create([
  415. 'carrier' => 'free',
  416. 'carrier_title' => 'Free shipping',
  417. 'method' => 'free_free',
  418. 'method_title' => 'Free Shipping',
  419. 'method_description' => 'Free Shipping',
  420. 'cart_address_id' => $cartShippingAddress->id,
  421. ]);
  422. $order = Order::factory()->create([
  423. 'cart_id' => $cart->id,
  424. 'customer_id' => $customer->id,
  425. 'customer_email' => $customer->email,
  426. 'customer_first_name' => $customer->first_name,
  427. 'customer_last_name' => $customer->last_name,
  428. ]);
  429. $orderItem = OrderItem::factory()->create([
  430. 'product_id' => $product->id,
  431. 'order_id' => $order->id,
  432. 'sku' => $product->sku,
  433. 'type' => $product->type,
  434. 'name' => $product->name,
  435. 'qty_shipped' => 1,
  436. 'qty_invoiced' => 1,
  437. 'qty_canceled' => 1,
  438. ]);
  439. $orderBillingAddress = OrderAddress::factory()->create([
  440. 'cart_id' => $cart->id,
  441. 'customer_id' => $customer->id,
  442. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  443. ]);
  444. $orderShippingAddress = OrderAddress::factory()->create([
  445. 'cart_id' => $cart->id,
  446. 'customer_id' => $customer->id,
  447. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  448. ]);
  449. $orderPayment = OrderPayment::factory()->create([
  450. 'order_id' => $order->id,
  451. ]);
  452. foreach ($order->items as $item) {
  453. foreach ($order->channel->inventory_sources as $inventorySource) {
  454. $items[$item->id] = $inventorySource->id;
  455. }
  456. }
  457. // Act and Assert.
  458. $this->loginAsAdmin();
  459. postJson(route('admin.sales.refunds.store', $order->id), [
  460. 'refund' => [
  461. 'items' => $items,
  462. 'shipping' => 0,
  463. 'adjustment_refund' => '0',
  464. 'adjustment_fee' => '0',
  465. ],
  466. ])
  467. ->assertRedirect(route('admin.sales.orders.view', $order->id))
  468. ->isRedirection();
  469. $cart->refresh();
  470. $cartItem->refresh();
  471. $cartBillingAddress->refresh();
  472. $cartShippingAddress->refresh();
  473. $orderBillingAddress->refresh();
  474. $orderShippingAddress->refresh();
  475. $order->refresh();
  476. $orderItem->refresh();
  477. $this->assertModelWise([
  478. Cart::class => [
  479. $this->prepareCart($cart),
  480. ],
  481. CartItem::class => [
  482. $this->prepareCartItem($cartItem),
  483. ],
  484. CartPayment::class => [
  485. $this->prepareCartPayment($cartPayment),
  486. ],
  487. CartAddress::class => [
  488. $this->prepareAddress($cartBillingAddress),
  489. ],
  490. CartAddress::class => [
  491. $this->prepareAddress($cartShippingAddress),
  492. ],
  493. CartShippingRate::class => [
  494. $this->prepareCartShippingRate($cartShippingRate),
  495. ],
  496. CustomerAddress::class => [
  497. $this->prepareAddress($customerAddress),
  498. ],
  499. Order::class => [
  500. $this->prepareOrder($order),
  501. ],
  502. OrderItem::class => [
  503. $this->prepareOrderItem($orderItem),
  504. ],
  505. OrderAddress::class => [
  506. $this->prepareAddress($orderBillingAddress),
  507. $this->prepareAddress($orderShippingAddress),
  508. ],
  509. OrderPayment::class => [
  510. $this->prepareOrderPayment($orderPayment),
  511. ],
  512. Refund::class => [
  513. [
  514. 'state' => 'refunded',
  515. 'order_id' => $order->id,
  516. ],
  517. ],
  518. ]);
  519. });
  520. it('should store the order refund and send email to the customer and admin', function () {
  521. // Arrange.
  522. Mail::fake();
  523. CoreConfig::where('code', 'emails.general.notifications.emails.general.notifications.new_refund_mail_to_admin')->update([
  524. 'value' => 1,
  525. ]);
  526. $product = (new ProductFaker([
  527. 'attributes' => [
  528. 5 => 'new',
  529. ],
  530. 'attribute_value' => [
  531. 'new' => [
  532. 'boolean_value' => true,
  533. ],
  534. ],
  535. ]))
  536. ->getSimpleProductFactory()
  537. ->create();
  538. $customer = Customer::factory()->create();
  539. $cart = Cart::factory()->create([
  540. 'customer_id' => $customer->id,
  541. 'customer_first_name' => $customer->first_name,
  542. 'customer_last_name' => $customer->last_name,
  543. 'customer_email' => $customer->email,
  544. 'is_guest' => 0,
  545. ]);
  546. $additional = [
  547. 'product_id' => $product->id,
  548. 'rating' => '0',
  549. 'is_buy_now' => '0',
  550. 'quantity' => '1',
  551. ];
  552. $cartItem = CartItem::factory()->create([
  553. 'cart_id' => $cart->id,
  554. 'product_id' => $product->id,
  555. 'sku' => $product->sku,
  556. 'quantity' => $additional['quantity'],
  557. 'name' => $product->name,
  558. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  559. 'price_incl_tax' => $convertedPrice,
  560. 'base_price' => $price,
  561. 'base_price_incl_tax' => $price,
  562. 'total' => $total = $convertedPrice * $additional['quantity'],
  563. 'total_incl_tax' => $total,
  564. 'base_total' => $price * $additional['quantity'],
  565. 'weight' => $product->weight ?? 0,
  566. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  567. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  568. 'type' => $product->type,
  569. 'additional' => $additional,
  570. ]);
  571. $customerAddress = CustomerAddress::factory()->create([
  572. 'cart_id' => $cart->id,
  573. 'customer_id' => $customer->id,
  574. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  575. ]);
  576. $cartBillingAddress = CartAddress::factory()->create([
  577. 'cart_id' => $cart->id,
  578. 'customer_id' => $customer->id,
  579. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  580. ]);
  581. $cartShippingAddress = CartAddress::factory()->create([
  582. 'cart_id' => $cart->id,
  583. 'customer_id' => $customer->id,
  584. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  585. ]);
  586. $cartPayment = CartPayment::factory()->create([
  587. 'cart_id' => $cart->id,
  588. 'method' => $paymentMethod = 'cashondelivery',
  589. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  590. ]);
  591. $cartShippingRate = CartShippingRate::factory()->create([
  592. 'carrier' => 'free',
  593. 'carrier_title' => 'Free shipping',
  594. 'method' => 'free_free',
  595. 'method_title' => 'Free Shipping',
  596. 'method_description' => 'Free Shipping',
  597. 'cart_address_id' => $cartShippingAddress->id,
  598. ]);
  599. $order = Order::factory()->create([
  600. 'cart_id' => $cart->id,
  601. 'customer_id' => $customer->id,
  602. 'customer_email' => $customer->email,
  603. 'customer_first_name' => $customer->first_name,
  604. 'customer_last_name' => $customer->last_name,
  605. ]);
  606. $orderItem = OrderItem::factory()->create([
  607. 'product_id' => $product->id,
  608. 'order_id' => $order->id,
  609. 'sku' => $product->sku,
  610. 'type' => $product->type,
  611. 'name' => $product->name,
  612. 'qty_shipped' => 1,
  613. 'qty_invoiced' => 1,
  614. 'qty_canceled' => 1,
  615. ]);
  616. $orderBillingAddress = OrderAddress::factory()->create([
  617. 'cart_id' => $cart->id,
  618. 'customer_id' => $customer->id,
  619. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  620. ]);
  621. $orderShippingAddress = OrderAddress::factory()->create([
  622. 'cart_id' => $cart->id,
  623. 'customer_id' => $customer->id,
  624. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  625. ]);
  626. $orderPayment = OrderPayment::factory()->create([
  627. 'order_id' => $order->id,
  628. ]);
  629. foreach ($order->items as $item) {
  630. foreach ($order->channel->inventory_sources as $inventorySource) {
  631. $items[$item->id] = $inventorySource->id;
  632. }
  633. }
  634. // Act and Assert.
  635. $this->loginAsAdmin();
  636. postJson(route('admin.sales.refunds.store', $order->id), [
  637. 'refund' => [
  638. 'items' => $items,
  639. 'shipping' => 0,
  640. 'adjustment_refund' => '0',
  641. 'adjustment_fee' => '0',
  642. ],
  643. ])
  644. ->assertRedirect(route('admin.sales.orders.view', $order->id))
  645. ->isRedirection();
  646. $cart->refresh();
  647. $cartItem->refresh();
  648. $cartBillingAddress->refresh();
  649. $cartShippingAddress->refresh();
  650. $orderBillingAddress->refresh();
  651. $orderShippingAddress->refresh();
  652. $order->refresh();
  653. $orderItem->refresh();
  654. $this->assertModelWise([
  655. Cart::class => [
  656. $this->prepareCart($cart),
  657. ],
  658. CartItem::class => [
  659. $this->prepareCartItem($cartItem),
  660. ],
  661. CartPayment::class => [
  662. $this->prepareCartPayment($cartPayment),
  663. ],
  664. CartAddress::class => [
  665. $this->prepareAddress($cartBillingAddress),
  666. ],
  667. CartAddress::class => [
  668. $this->prepareAddress($cartShippingAddress),
  669. ],
  670. CartShippingRate::class => [
  671. $this->prepareCartShippingRate($cartShippingRate),
  672. ],
  673. CustomerAddress::class => [
  674. $this->prepareAddress($customerAddress),
  675. ],
  676. Order::class => [
  677. $this->prepareOrder($order),
  678. ],
  679. OrderItem::class => [
  680. $this->prepareOrderItem($orderItem),
  681. ],
  682. OrderAddress::class => [
  683. $this->prepareAddress($orderBillingAddress),
  684. $this->prepareAddress($orderShippingAddress),
  685. ],
  686. OrderPayment::class => [
  687. $this->prepareOrderPayment($orderPayment),
  688. ],
  689. Refund::class => [
  690. [
  691. 'state' => 'refunded',
  692. 'order_id' => $order->id,
  693. ],
  694. ],
  695. ]);
  696. Mail::assertQueued(AdminRefundedNotification::class);
  697. Mail::assertQueued(ShopRefundedNotification::class);
  698. Mail::assertQueuedCount(2);
  699. });
  700. it('should return the order refunded data', function () {
  701. // Arrange.
  702. $product = (new ProductFaker([
  703. 'attributes' => [
  704. 5 => 'new',
  705. ],
  706. 'attribute_value' => [
  707. 'new' => [
  708. 'boolean_value' => true,
  709. ],
  710. ],
  711. ]))
  712. ->getSimpleProductFactory()
  713. ->create();
  714. $customer = Customer::factory()->create();
  715. $cart = Cart::factory()->create([
  716. 'customer_id' => $customer->id,
  717. 'customer_first_name' => $customer->first_name,
  718. 'customer_last_name' => $customer->last_name,
  719. 'customer_email' => $customer->email,
  720. 'is_guest' => 0,
  721. ]);
  722. $additional = [
  723. 'product_id' => $product->id,
  724. 'rating' => '0',
  725. 'is_buy_now' => '0',
  726. 'quantity' => '1',
  727. ];
  728. $cartItem = CartItem::factory()->create([
  729. 'cart_id' => $cart->id,
  730. 'product_id' => $product->id,
  731. 'sku' => $product->sku,
  732. 'quantity' => $additional['quantity'],
  733. 'name' => $product->name,
  734. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  735. 'price_incl_tax' => $convertedPrice,
  736. 'base_price' => $price,
  737. 'base_price_incl_tax' => $price,
  738. 'total' => $total = $convertedPrice * $additional['quantity'],
  739. 'total_incl_tax' => $total,
  740. 'base_total' => $price * $additional['quantity'],
  741. 'weight' => $product->weight ?? 0,
  742. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  743. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  744. 'type' => $product->type,
  745. 'additional' => $additional,
  746. ]);
  747. $customerAddress = CustomerAddress::factory()->create([
  748. 'cart_id' => $cart->id,
  749. 'customer_id' => $customer->id,
  750. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  751. ]);
  752. $cartBillingAddress = CartAddress::factory()->create([
  753. 'cart_id' => $cart->id,
  754. 'customer_id' => $customer->id,
  755. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  756. ]);
  757. $cartShippingAddress = CartAddress::factory()->create([
  758. 'cart_id' => $cart->id,
  759. 'customer_id' => $customer->id,
  760. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  761. ]);
  762. $cartPayment = CartPayment::factory()->create([
  763. 'cart_id' => $cart->id,
  764. 'method' => $paymentMethod = 'cashondelivery',
  765. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  766. ]);
  767. $cartShippingRate = CartShippingRate::factory()->create([
  768. 'carrier' => 'free',
  769. 'carrier_title' => 'Free shipping',
  770. 'method' => 'free_free',
  771. 'method_title' => 'Free Shipping',
  772. 'method_description' => 'Free Shipping',
  773. 'cart_address_id' => $cartShippingAddress->id,
  774. ]);
  775. $order = Order::factory()->create([
  776. 'cart_id' => $cart->id,
  777. 'customer_id' => $customer->id,
  778. 'customer_email' => $customer->email,
  779. 'customer_first_name' => $customer->first_name,
  780. 'customer_last_name' => $customer->last_name,
  781. ]);
  782. $orderItem = OrderItem::factory()->create([
  783. 'product_id' => $product->id,
  784. 'order_id' => $order->id,
  785. 'sku' => $product->sku,
  786. 'type' => $product->type,
  787. 'name' => $product->name,
  788. ]);
  789. $orderBillingAddress = OrderAddress::factory()->create([
  790. 'cart_id' => $cart->id,
  791. 'customer_id' => $customer->id,
  792. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  793. ]);
  794. $orderShippingAddress = OrderAddress::factory()->create([
  795. 'cart_id' => $cart->id,
  796. 'customer_id' => $customer->id,
  797. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  798. ]);
  799. $orderPayment = OrderPayment::factory()->create([
  800. 'order_id' => $order->id,
  801. ]);
  802. $summary = [
  803. 'subtotal' => ['price' => 0],
  804. 'discount' => ['price' => 0],
  805. 'tax' => ['price' => 0],
  806. 'shipping' => ['price' => 0],
  807. 'grand_total' => ['price' => 0],
  808. ];
  809. $items = [];
  810. foreach ($order->items as $item) {
  811. if ($item->qty_to_refund) {
  812. $items[$item->id] = rand(1, $item->qty_to_refund);
  813. }
  814. }
  815. foreach ($items as $orderItemId => $qty) {
  816. $orderItem = OrderItem::find($orderItemId);
  817. $summary['subtotal']['price'] += $orderItem->base_price * $qty;
  818. $summary['discount']['price'] += ($orderItem->base_discount_amount / $orderItem->qty_ordered) * $qty;
  819. $summary['tax']['price'] += ($orderItem->tax_amount / $orderItem->qty_ordered) * $qty;
  820. }
  821. $summary['shipping']['price'] += $order->base_shipping_invoiced - $order->base_shipping_refunded - $order->base_shipping_discount_amount;
  822. $summary['grand_total']['price'] += $summary['subtotal']['price'] + $summary['tax']['price'] + $summary['shipping']['price'] - $summary['discount']['price'];
  823. $refund = [
  824. 'items' => $items,
  825. 'shipping' => $order->base_shipping_invoiced - $order->base_shipping_refunded - $order->base_shipping_discount_amount,
  826. 'adjustment_refund' => 0,
  827. 'adjustment_fee' => 0,
  828. ];
  829. // Act and Assert.
  830. $this->loginAsAdmin();
  831. postJson(route('admin.sales.refunds.update_totals', $order->id), $refund)
  832. ->assertOk()
  833. ->assertJsonPath('grand_total.price', $summary['grand_total']['price']);
  834. $cart->refresh();
  835. $cartItem->refresh();
  836. $cartBillingAddress->refresh();
  837. $cartShippingAddress->refresh();
  838. $orderBillingAddress->refresh();
  839. $orderShippingAddress->refresh();
  840. $order->refresh();
  841. $orderItem->refresh();
  842. $this->assertModelWise([
  843. Cart::class => [
  844. $this->prepareCart($cart),
  845. ],
  846. CartItem::class => [
  847. $this->prepareCartItem($cartItem),
  848. ],
  849. CartPayment::class => [
  850. $this->prepareCartPayment($cartPayment),
  851. ],
  852. CartAddress::class => [
  853. $this->prepareAddress($cartBillingAddress),
  854. ],
  855. CartAddress::class => [
  856. $this->prepareAddress($cartShippingAddress),
  857. ],
  858. CartShippingRate::class => [
  859. $this->prepareCartShippingRate($cartShippingRate),
  860. ],
  861. CustomerAddress::class => [
  862. $this->prepareAddress($customerAddress),
  863. ],
  864. Order::class => [
  865. $this->prepareOrder($order),
  866. ],
  867. OrderItem::class => [
  868. $this->prepareOrderItem($orderItem),
  869. ],
  870. OrderAddress::class => [
  871. $this->prepareAddress($orderBillingAddress),
  872. $this->prepareAddress($orderShippingAddress),
  873. ],
  874. OrderPayment::class => [
  875. $this->prepareOrderPayment($orderPayment),
  876. ],
  877. ]);
  878. });
  879. it('should return the view page of refund', function () {
  880. // Arrange.
  881. $product = (new ProductFaker([
  882. 'attributes' => [
  883. 5 => 'new',
  884. ],
  885. 'attribute_value' => [
  886. 'new' => [
  887. 'boolean_value' => true,
  888. ],
  889. ],
  890. ]))
  891. ->getSimpleProductFactory()
  892. ->create();
  893. $customer = Customer::factory()->create();
  894. $cart = Cart::factory()->create([
  895. 'customer_id' => $customer->id,
  896. 'customer_first_name' => $customer->first_name,
  897. 'customer_last_name' => $customer->last_name,
  898. 'customer_email' => $customer->email,
  899. 'is_guest' => 0,
  900. ]);
  901. $additional = [
  902. 'product_id' => $product->id,
  903. 'rating' => '0',
  904. 'is_buy_now' => '0',
  905. 'quantity' => '1',
  906. ];
  907. $cartItem = CartItem::factory()->create([
  908. 'cart_id' => $cart->id,
  909. 'product_id' => $product->id,
  910. 'sku' => $product->sku,
  911. 'quantity' => $additional['quantity'],
  912. 'name' => $product->name,
  913. 'price' => $convertedPrice = core()->convertPrice($price = $product->price),
  914. 'price_incl_tax' => $convertedPrice,
  915. 'base_price' => $price,
  916. 'base_price_incl_tax' => $price,
  917. 'total' => $total = $convertedPrice * $additional['quantity'],
  918. 'total_incl_tax' => $total,
  919. 'base_total' => $price * $additional['quantity'],
  920. 'weight' => $product->weight ?? 0,
  921. 'total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  922. 'base_total_weight' => ($product->weight ?? 0) * $additional['quantity'],
  923. 'type' => $product->type,
  924. 'additional' => $additional,
  925. ]);
  926. $customerAddress = CustomerAddress::factory()->create([
  927. 'cart_id' => $cart->id,
  928. 'customer_id' => $customer->id,
  929. 'address_type' => CustomerAddress::ADDRESS_TYPE,
  930. ]);
  931. $cartBillingAddress = CartAddress::factory()->create([
  932. 'cart_id' => $cart->id,
  933. 'customer_id' => $customer->id,
  934. 'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
  935. ]);
  936. $cartShippingAddress = CartAddress::factory()->create([
  937. 'cart_id' => $cart->id,
  938. 'customer_id' => $customer->id,
  939. 'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
  940. ]);
  941. $cartPayment = CartPayment::factory()->create([
  942. 'cart_id' => $cart->id,
  943. 'method' => $paymentMethod = 'cashondelivery',
  944. 'method_title' => core()->getConfigData('sales.payment_methods.'.$paymentMethod.'.title'),
  945. ]);
  946. $cartShippingRate = CartShippingRate::factory()->create([
  947. 'carrier' => 'free',
  948. 'carrier_title' => 'Free shipping',
  949. 'method' => 'free_free',
  950. 'method_title' => 'Free Shipping',
  951. 'method_description' => 'Free Shipping',
  952. 'cart_address_id' => $cartShippingAddress->id,
  953. ]);
  954. $order = Order::factory()->create([
  955. 'cart_id' => $cart->id,
  956. 'customer_id' => $customer->id,
  957. 'customer_email' => $customer->email,
  958. 'customer_first_name' => $customer->first_name,
  959. 'customer_last_name' => $customer->last_name,
  960. ]);
  961. $orderItem = OrderItem::factory()->create([
  962. 'product_id' => $product->id,
  963. 'order_id' => $order->id,
  964. 'sku' => $product->sku,
  965. 'type' => $product->type,
  966. 'name' => $product->name,
  967. 'qty_shipped' => 1,
  968. 'qty_invoiced' => 1,
  969. 'qty_canceled' => 1,
  970. ]);
  971. $orderBillingAddress = OrderAddress::factory()->create([
  972. 'cart_id' => $cart->id,
  973. 'customer_id' => $customer->id,
  974. 'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
  975. ]);
  976. $orderShippingAddress = OrderAddress::factory()->create([
  977. 'cart_id' => $cart->id,
  978. 'customer_id' => $customer->id,
  979. 'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
  980. ]);
  981. $orderPayment = OrderPayment::factory()->create([
  982. 'order_id' => $order->id,
  983. ]);
  984. $refund = Refund::factory()->create([
  985. 'order_id' => $order->id,
  986. ]);
  987. // Act and Assert.
  988. $this->loginAsAdmin();
  989. get(route('admin.sales.refunds.view', $refund->id))
  990. ->assertOk()
  991. ->assertSeeText(trans('admin::app.sales.refunds.view.title', ['refund_id' => $refund->id]))
  992. ->assertSeeText(trans('admin::app.sales.refunds.view.product-ordered'));
  993. $cart->refresh();
  994. $cartItem->refresh();
  995. $cartBillingAddress->refresh();
  996. $cartShippingAddress->refresh();
  997. $orderBillingAddress->refresh();
  998. $orderShippingAddress->refresh();
  999. $order->refresh();
  1000. $orderItem->refresh();
  1001. $this->assertModelWise([
  1002. Cart::class => [
  1003. $this->prepareCart($cart),
  1004. ],
  1005. CartItem::class => [
  1006. $this->prepareCartItem($cartItem),
  1007. ],
  1008. CartPayment::class => [
  1009. $this->prepareCartPayment($cartPayment),
  1010. ],
  1011. CartAddress::class => [
  1012. $this->prepareAddress($cartBillingAddress),
  1013. ],
  1014. CartAddress::class => [
  1015. $this->prepareAddress($cartShippingAddress),
  1016. ],
  1017. CartShippingRate::class => [
  1018. $this->prepareCartShippingRate($cartShippingRate),
  1019. ],
  1020. CustomerAddress::class => [
  1021. $this->prepareAddress($customerAddress),
  1022. ],
  1023. Order::class => [
  1024. $this->prepareOrder($order),
  1025. ],
  1026. OrderItem::class => [
  1027. $this->prepareOrderItem($orderItem),
  1028. ],
  1029. OrderAddress::class => [
  1030. $this->prepareAddress($orderBillingAddress),
  1031. $this->prepareAddress($orderShippingAddress),
  1032. ],
  1033. OrderPayment::class => [
  1034. $this->prepareOrderPayment($orderPayment),
  1035. ],
  1036. ]);
  1037. });