SalesController.php 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Exports\SaleDetailsExport;
  4. use App\Models\Ppn;
  5. use App\Models\Sale;
  6. use Inertia\Inertia;
  7. use App\Models\Customer;
  8. use App\Models\StockProduct;
  9. use Illuminate\Support\Facades\DB;
  10. use Illuminate\Database\QueryException;
  11. use App\Http\Requests\Sales\StoreSaleRequest;
  12. use App\Http\Requests\Sales\UpdateSaleRequest;
  13. use App\Models\Company;
  14. use App\Models\HistoryStock;
  15. use App\Models\HistoryStockProduct;
  16. use App\Models\SaleDetail;
  17. use App\Services\FunctionService;
  18. use App\Services\SaleService;
  19. use Barryvdh\DomPDF\Facade\Pdf;
  20. class SalesController extends Controller
  21. {
  22. public function __construct()
  23. {
  24. $this->authorizeResource(Sale::class);
  25. }
  26. /**
  27. * Display a listing of the resource.
  28. *
  29. * @return \Illuminate\Http\Response
  30. */
  31. public function index()
  32. {
  33. return inertia("Sales/Index", [
  34. "initialFilters" => request()->only("search"),
  35. "sales" => Sale::search(request()->only("search"))
  36. ->latest()
  37. ->paginate(10)
  38. ->withQueryString()
  39. ->through(
  40. fn($sale) => [
  41. "id" => $sale->id,
  42. "createdAt" => $sale->created_at,
  43. "name" => $sale->customer->name,
  44. "phone" => $sale->customer->phone,
  45. "email" => $sale->customer->email,
  46. "price" => FunctionService::rupiahFormat(
  47. SaleService::totalPrice($sale)
  48. ),
  49. "status" => $sale->status,
  50. ]
  51. ),
  52. ]);
  53. }
  54. /**
  55. * Show the form for creating a new resource.
  56. *
  57. * @return \Illuminate\Http\Response
  58. */
  59. public function create()
  60. {
  61. return inertia("Sales/Create", [
  62. "number" => "PJN" . now()->format("YmdHis"),
  63. "ppn" => Ppn::first()->ppn,
  64. "customers" => Inertia::lazy(
  65. fn() => Customer::search([
  66. "search" => request("customer"),
  67. ])->get()
  68. ),
  69. "stockProducts" => Inertia::lazy(
  70. fn() => StockProduct::search([
  71. "search" => request("stock_product"),
  72. ])
  73. ->get()
  74. ->transform(
  75. fn($stockProduct) => [
  76. "number" => $stockProduct->product_number,
  77. "name" => $stockProduct->product->name,
  78. "price" => $stockProduct->getRawOriginal("price"),
  79. "ppn" => $stockProduct->ppn,
  80. "qty" => $stockProduct->qty,
  81. "unit" => $stockProduct->product->unit,
  82. "profit" => $stockProduct->product->profit,
  83. ]
  84. )
  85. ),
  86. ]);
  87. }
  88. /**
  89. * Store a newly created resource in storage.
  90. *
  91. * @param \Illuminate\Http\Request $request
  92. * @return \Illuminate\Http\Response
  93. */
  94. public function store(StoreSaleRequest $request)
  95. {
  96. DB::beginTransaction();
  97. try {
  98. $ppn = Ppn::first()->ppn;
  99. $validated = $request
  100. ->safe()
  101. ->merge([
  102. "user_id" => auth()->user()->id,
  103. "ppn" => $request->ppn ? $ppn : 0,
  104. ])
  105. ->all();
  106. $sale = Sale::create($validated);
  107. foreach ($request->products as $product) {
  108. $validated = [
  109. "product_number" => $product["number"],
  110. "price" => $product["price"],
  111. "qty" => $product["qty"],
  112. ];
  113. $sale->saleDetail()->create($validated);
  114. if ($request->status == "success") {
  115. StockProduct::where(
  116. "product_number",
  117. $product["number"]
  118. )->decrement("qty", $product["qty"]);
  119. $validated = [
  120. "price" => $product["price"],
  121. "qty" => $product["qty"],
  122. "ppn" => $request->ppn ? true : false,
  123. "product_number" => $product["number"],
  124. "sale_number" => $sale->number,
  125. ];
  126. HistoryStockProduct::create($validated);
  127. }
  128. }
  129. DB::commit();
  130. return to_route("sales.show", $sale)->with(
  131. "success",
  132. __("messages.success.store.sale")
  133. );
  134. } catch (QueryException $e) {
  135. DB::rollBack();
  136. return back()->with("error", __("messages.error.store.sale"));
  137. }
  138. }
  139. /**
  140. * Display the specified resource.
  141. *
  142. * @param Sale $sale
  143. * @return \Illuminate\Http\Response
  144. */
  145. public function show(Sale $sale)
  146. {
  147. return inertia("Sales/Show", [
  148. "id" => $sale->id,
  149. "number" => $sale->number,
  150. "ppn" => Ppn::first()->ppn,
  151. "status" => $sale->status,
  152. "ppnChecked" => $sale->ppn ? true : false,
  153. "customer" => $sale->customer,
  154. "saleDetail" => $sale->saleDetail->transform(
  155. fn($sale) => [
  156. "id" => $sale->id,
  157. "number" => $sale->product_number,
  158. "name" => $sale->product->name,
  159. "price" => $sale->getRawOriginal("price"),
  160. "qty" => $sale->qty,
  161. "unit" => $sale->product->unit,
  162. ]
  163. ),
  164. ]);
  165. }
  166. /**
  167. * Show the form for editing the specified resource.
  168. *
  169. * @param Sale $sale
  170. * @return \Illuminate\Http\Response
  171. */
  172. public function edit(Sale $sale)
  173. {
  174. //
  175. }
  176. /**
  177. * Update the specified resource in storage.
  178. *
  179. * @param \Illuminate\Http\Request $request
  180. * @param Sale $sale
  181. * @return \Illuminate\Http\Response
  182. */
  183. public function update(UpdateSaleRequest $request, Sale $sale)
  184. {
  185. //
  186. }
  187. /**
  188. * Remove the specified resource from storage.
  189. *
  190. * @param Sale $sale
  191. * @return \Illuminate\Http\Response
  192. */
  193. public function destroy(Sale $sale)
  194. {
  195. //
  196. }
  197. public function invoice(Sale $sale)
  198. {
  199. $this->authorize("viewAny", Sale::class);
  200. $ppn = Ppn::first()->ppn;
  201. $company = Company::first();
  202. $pdf = Pdf::loadView(
  203. "PDF.Sales.Invoice",
  204. compact("sale", "company", "ppn")
  205. );
  206. return $pdf->stream();
  207. }
  208. public function deliveryOrder(Sale $sale)
  209. {
  210. $this->authorize("viewAny", Sale::class);
  211. $company = Company::first();
  212. $pdf = Pdf::loadView("PDF.Sales.Do", compact("sale", "company"));
  213. $pdf->setPaper("a3", "landscape");
  214. return $pdf->stream();
  215. }
  216. public function report()
  217. {
  218. $this->authorize("viewAny", User::class);
  219. return inertia("Sales/Report", [
  220. "initialFilters" => request()->only("start_date", "end_date"),
  221. "sales" => SaleDetail::filter(
  222. request()->only("start_date", "end_date")
  223. )
  224. ->latest()
  225. ->paginate(10)
  226. ->withQueryString()
  227. ->through(
  228. fn($saleDetail) => [
  229. "createdAt" => $saleDetail->created_at,
  230. "totalPrice" => FunctionService::rupiahFormat(
  231. $saleDetail->price * $saleDetail->qty
  232. ),
  233. "qty" => $saleDetail->qty,
  234. "status" => $saleDetail->sale->status,
  235. ]
  236. ),
  237. ]);
  238. }
  239. public function reportExcel()
  240. {
  241. $this->authorize("viewAny", User::class);
  242. return new SaleDetailsExport([
  243. "sales" => SaleDetail::filter(
  244. request()->only("start_date", "end_date")
  245. )
  246. ->latest()
  247. ->get()
  248. ->map(
  249. fn($saleDetail) => [
  250. "createdAt" => $saleDetail->created_at,
  251. "qty" => $saleDetail->qty,
  252. "status" => $saleDetail->sale->status,
  253. "price" => $saleDetail->price * $saleDetail->qty,
  254. ]
  255. ),
  256. ]);
  257. }
  258. }