PurchaseController.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Exports\PurchaseDetailsExport;
  4. use App\Models\Ppn;
  5. use Inertia\Inertia;
  6. use App\Models\Product;
  7. use App\Models\Purchase;
  8. use App\Models\Supplier;
  9. use App\Models\StockProduct;
  10. use App\Models\PurchaseDetail;
  11. use Barryvdh\DomPDF\Facade\Pdf;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Database\QueryException;
  14. use App\Http\Requests\Purchase\StorePurchaseRequest;
  15. use App\Http\Requests\Purchase\UpdatePurchaseRequest;
  16. use App\Models\Company;
  17. use App\Services\FunctionService;
  18. use App\Services\PurchaseService;
  19. class PurchaseController extends Controller
  20. {
  21. public function __construct()
  22. {
  23. $this->authorizeResource(Purchase::class);
  24. }
  25. /**
  26. * Display a listing of the resource.
  27. *
  28. * @return \Illuminate\Http\Response
  29. */
  30. public function index()
  31. {
  32. return inertia("Purchases/Index", [
  33. "initialFilters" => request()->only("search"),
  34. "purchases" => Purchase::search(request()->only("search"))
  35. ->latest()
  36. ->paginate(10)
  37. ->withQueryString()
  38. ->through(
  39. fn($purchase) => [
  40. "id" => $purchase->id,
  41. "updatedAt" => $purchase->updated_at,
  42. "name" => $purchase->supplier->name,
  43. "phone" => $purchase->supplier->phone,
  44. "email" => $purchase->supplier->email,
  45. "price" => FunctionService::rupiahFormat(
  46. PurchaseService::totalPrice($purchase)
  47. ),
  48. "status" => $purchase->status,
  49. ]
  50. ),
  51. ]);
  52. }
  53. /**
  54. * Show the form for creating a new resource.
  55. *
  56. * @return \Illuminate\Http\Response
  57. */
  58. public function create()
  59. {
  60. return inertia("Purchases/Create", [
  61. "number" => "PBN" . now()->format("YmdHis"),
  62. "ppn" => Ppn::first()->ppn,
  63. "productNumber" => "PDK" . now()->format("YmdHis"),
  64. "suppliers" => Inertia::lazy(
  65. fn() => Supplier::search([
  66. "search" => request("supplier"),
  67. ])->get()
  68. ),
  69. "products" => Inertia::lazy(
  70. fn() => Product::search(["search" => request("product")])->get()
  71. ),
  72. "productPurchase" => Inertia::lazy(
  73. fn() => PurchaseDetail::historyProductPurchase(
  74. request()->only("product_number", "supplier_id")
  75. )
  76. ->orderBy("price", "desc")
  77. ->get()
  78. ->transform(
  79. fn($purchaseDetail) => [
  80. "number" => $purchaseDetail->product_number,
  81. "price" => $purchaseDetail->getRawOriginal("price"),
  82. "qty" => $purchaseDetail->qty,
  83. "ppn" => $purchaseDetail->purchase->ppn,
  84. ]
  85. )
  86. ->first()
  87. ),
  88. ]);
  89. }
  90. /**
  91. * Store a newly created resource in storage.
  92. *
  93. * @param \Illuminate\Http\Request $request
  94. * @return \Illuminate\Http\Response
  95. */
  96. public function store(StorePurchaseRequest $request)
  97. {
  98. DB::beginTransaction();
  99. try {
  100. $validated = $request
  101. ->safe()
  102. ->merge([
  103. "user_id" => auth()->user()->id,
  104. "ppn" => $request->ppn ? true : false,
  105. ])
  106. ->all();
  107. $purchase = Purchase::create($validated);
  108. foreach ($request->products as $product) {
  109. $validated = [
  110. "product_number" => $product["number"],
  111. "price" => $product["price"],
  112. "qty" => $product["qty"],
  113. ];
  114. $purchase->purchaseDetail()->create($validated);
  115. }
  116. DB::commit();
  117. return back()->with(
  118. "success",
  119. __("messages.success.store.purchase")
  120. );
  121. } catch (QueryException $e) {
  122. DB::rollBack();
  123. return back()->with("error", __("messages.error.store.purchase"));
  124. }
  125. }
  126. /**
  127. * Display the specified resource.
  128. *
  129. * @param Purchase $purchase
  130. * @return \Illuminate\Http\Response
  131. */
  132. public function show(Purchase $purchase)
  133. {
  134. return inertia("Purchases/Show", [
  135. "id" => $purchase->id,
  136. "number" => $purchase->number,
  137. "ppn" => Ppn::first()->ppn,
  138. "status" => $purchase->status,
  139. "ppnChecked" => $purchase->ppn ? true : false,
  140. "supplier" => $purchase->supplier,
  141. "purchaseDetail" => $purchase->purchaseDetail->transform(
  142. fn($purchase) => [
  143. "id" => $purchase->id,
  144. "number" => $purchase->product_number,
  145. "name" => $purchase->product->name,
  146. "price" => $purchase->getRawOriginal("price"),
  147. "qty" => $purchase->qty,
  148. "unit" => $purchase->product->unit,
  149. ]
  150. ),
  151. ]);
  152. }
  153. /**
  154. * Show the form for editing the specified resource.
  155. *
  156. * @param Purchase $purchase
  157. * @return \Illuminate\Http\Response
  158. */
  159. public function edit(Purchase $purchase)
  160. {
  161. return inertia("Purchases/Edit", [
  162. "id" => $purchase->id,
  163. "number" => $purchase->number,
  164. "ppn" => Ppn::first()->ppn,
  165. "status" => $purchase->status,
  166. "productNumber" => "PDK" . now()->format("YmdHis"),
  167. "ppnChecked" => $purchase->ppn ? true : false,
  168. "supplier" => $purchase->supplier,
  169. "products" => Inertia::lazy(
  170. fn() => Product::search(["search" => request("product")])->get()
  171. ),
  172. "purchaseDetail" => $purchase->purchaseDetail->transform(
  173. fn($purchase) => [
  174. "id" => $purchase->id,
  175. "number" => $purchase->product_number,
  176. "name" => $purchase->product->name,
  177. "price" => $purchase->getRawOriginal("price"),
  178. "qty" => $purchase->qty,
  179. "unit" => $purchase->product->unit,
  180. ]
  181. ),
  182. "productPurchase" => Inertia::lazy(
  183. fn() => PurchaseDetail::historyProductPurchase(
  184. request()->only("product_number", "supplier_id")
  185. )
  186. ->orderBy("price", "desc")
  187. ->get()
  188. ->transform(
  189. fn($purchaseDetail) => [
  190. "number" => $purchaseDetail->product_number,
  191. "price" => $purchaseDetail->getRawOriginal("price"),
  192. "qty" => $purchaseDetail->qty,
  193. "ppn" => $purchaseDetail->purchase->ppn,
  194. ]
  195. )
  196. ->first()
  197. ),
  198. ]);
  199. }
  200. /**
  201. * Update the specified resource in storage.
  202. *
  203. * @param \Illuminate\Http\Request $request
  204. * @param Purchase $purchase
  205. * @return \Illuminate\Http\Response
  206. */
  207. public function update(UpdatePurchaseRequest $request, Purchase $purchase)
  208. {
  209. DB::beginTransaction();
  210. try {
  211. $validated = $request
  212. ->safe()
  213. ->merge([
  214. "ppn" => $request->ppn ? true : false,
  215. ])
  216. ->all();
  217. $purchase->update($validated);
  218. foreach ($request->products as $product) {
  219. $validated = [
  220. "product_number" => $product["number"],
  221. "price" => $product["price"],
  222. "qty" => $product["qty"],
  223. ];
  224. if (!empty($product["label"])) {
  225. if ($product["label"] == "add") {
  226. $purchase->purchaseDetail()->create($validated);
  227. }
  228. if ($product["label"] == "edit") {
  229. $purchase->purchaseDetail
  230. ->find($product["id"])
  231. ->update($validated);
  232. }
  233. if ($product["label"] == "delete") {
  234. $purchase->purchaseDetail
  235. ->find($product["id"])
  236. ->delete();
  237. }
  238. }
  239. if ($request->status == "success") {
  240. $stockProduct = StockProduct::where(
  241. "product_number",
  242. $product["number"]
  243. );
  244. if ($stockProduct->exists()) {
  245. $validated = [
  246. "price" =>
  247. $stockProduct
  248. ->first()
  249. ->getRawOriginal("price") >=
  250. $product["price"]
  251. ? $stockProduct
  252. ->first()
  253. ->getRawOriginal("price")
  254. : $product["price"],
  255. "ppn" => $request->ppn ? true : false,
  256. ];
  257. $stockProduct->increment(
  258. "qty",
  259. $product["qty"],
  260. $validated
  261. );
  262. } else {
  263. $validated = [
  264. "price" => $product["price"],
  265. "ppn" => $request->ppn ? true : false,
  266. "qty" => $product["qty"],
  267. "product_number" => $product["number"],
  268. ];
  269. StockProduct::create($validated);
  270. }
  271. }
  272. }
  273. DB::commit();
  274. if ($request->status == "success") {
  275. return to_route("purchases.show", $purchase)->with(
  276. "success",
  277. __("messages.success.update.purchase")
  278. );
  279. } else {
  280. return back()->with(
  281. "success",
  282. __("messages.success.update.purchase")
  283. );
  284. }
  285. } catch (QueryException $e) {
  286. DB::rollBack();
  287. return back()->with("error", __("messages.error.update.purchase"));
  288. }
  289. }
  290. /**
  291. * Remove the specified resource from storage.
  292. *
  293. * @param Purchase $purchase
  294. * @return \Illuminate\Http\Response
  295. */
  296. public function destroy(Purchase $purchase)
  297. {
  298. //
  299. }
  300. public function invoice(Purchase $purchase)
  301. {
  302. $ppn = Ppn::first()->ppn;
  303. $company = Company::first();
  304. $pdf = Pdf::loadView(
  305. "PDF.Purchases.Invoice",
  306. compact("purchase", "company", "ppn")
  307. );
  308. return $pdf->stream();
  309. }
  310. public function deliveryOrder(Purchase $purchase)
  311. {
  312. $company = Company::first();
  313. $pdf = Pdf::loadView(
  314. "PDF.Purchases.Do",
  315. compact("purchase", "company")
  316. );
  317. $pdf->setPaper("a3", "landscape");
  318. return $pdf->stream();
  319. }
  320. public function report()
  321. {
  322. return inertia("Purchases/Report", [
  323. "initialFilters" => request()->only(
  324. "start_date",
  325. "end_date",
  326. "status"
  327. ),
  328. "purchases" => PurchaseDetail::filter(
  329. request()->only("start_date", "end_date", "status")
  330. )
  331. ->latest()
  332. ->paginate(10)
  333. ->withQueryString()
  334. ->through(
  335. fn($purchaseDetail) => [
  336. "updatedAt" => $purchaseDetail->updated_at,
  337. "totalPrice" => FunctionService::rupiahFormat(
  338. $purchaseDetail->price * $purchaseDetail->qty
  339. ),
  340. "qty" => $purchaseDetail->qty,
  341. "status" => $purchaseDetail->purchase->status,
  342. ]
  343. ),
  344. ]);
  345. }
  346. public function reportExcel()
  347. {
  348. return new PurchaseDetailsExport([
  349. "purchases" => PurchaseDetail::filter(
  350. request()->only("start_date", "end_date", "status")
  351. )
  352. ->latest()
  353. ->get()
  354. ->map(
  355. fn($purchaseDetail) => [
  356. "updatedAt" => $purchaseDetail->updated_at,
  357. "qty" => $purchaseDetail->qty,
  358. "status" => $purchaseDetail->purchase->status,
  359. "price" =>
  360. $purchaseDetail->price * $purchaseDetail->qty,
  361. ]
  362. ),
  363. ]);
  364. }
  365. }