first(); if (!$invoice) { return response()->json(['message' => 'Invoice Not Found'], 404); } $lines = InvoiceDetails::where('invoice_id', $invoice['id'])->orderBy('order', 'asc')->get(); $status = InvoiceStatuses::where('invoice_id', $invoice['id'])->orderBy('created_at', 'asc')->get(); $invoice->lines = $lines; $invoice->status = $status; return response()->json($invoice, 200); } public function create(Request $request, $id) { $user = $request->user(); // validate $id $validatedData = $request->validate([ 'address' => 'required', 'buyer_company' => 'required', 'contact_no' => 'required', 'marking' => 'required', 'lines.*.order' => 'required|numeric', 'lines.*.stock_code' => 'required', 'lines.*.description' => 'required', 'lines.*.quantity' => 'required|numeric', 'lines.*.unit_price_rm' => 'required|numeric', 'lines.*.unit_price_rmb' => '', 'lines.*.total' => 'required|numeric', ]); // booking_id belongs to user $booking = Booking::where('id', $id)->first(); if (!$booking) { return response()->json(['message' => 'Unable to find booking'], 403); } // user_id in booking does not match if ($booking->user_id !== $user->id) { return response()->json([ 'message' => 'Booking does not belongs to you' ], 403); } // Amount match with total $subtotalArray = array_map( function ($line) { return $line['total']; }, $validatedData['lines'] ); $total = array_reduce($subtotalArray, function ($v1, $v2) { return $v1 + $v2; }); if ($total !== $booking->amount) { return response()->json([ 'message' => 'Booking amount expected is '.$booking->amount.'. Your Invoice amount is '.$total ], 400); } // Write to database if does not exist $exist = Invoice::where('booking_id', $id)->first(); if ($exist) { return response() ->json(['message' => 'Invoice exist. Cannot create duplicate invoice. Try edit.'], 400); } // Generate PO Number - po20200810-001(PO Format) $dt = Carbon::now(); $po_number = 'po'.$dt->format('Ymmdd').'-'.$id; $invoice = new Invoice; $invoice->amount = $total; $invoice->booking_id = (int)$id; $invoice->buyer_company = $validatedData['buyer_company']; $invoice->address = $validatedData['address']; $invoice->contact_no = $validatedData['contact_no']; $invoice->po_number = $po_number; $invoice->save(); if (!$invoice) { return response() ->json(['message' => 'Unable to Save Data'], 500); } // Insert invoice_id into lines foreach( $validatedData['lines'] as $key => $line) { $invoice_details = new InvoiceDetails; $invoice_details->order = $line['order']; $invoice_details->description = $line['description']; $invoice_details->quantity = $line['quantity']; $invoice_details->stock_code = $line['stock_code']; $invoice_details->invoice_id = $invoice->id; $invoice_details->unit_price_rmb = $line['unit_price_rmb']; $invoice_details->unit_price_rm = $line['unit_price_rm']; $invoice_details->total = $line['total']; $invoice_details->save(); } unset($line); $invoice->lines = $invoice_details; // Post status as pending $status = new InvoiceStatuses; $status->status = 'pending'; $status->comment = ''; $status->invoice_id = $invoice->id; $status->save(); if($invoice_details) { return $this->show($id); } else { return response(500); } } public function edit(Request $request, $id) { $user = $request->user(); // validate $id $validatedData = $request->validate([ 'address' => 'required', 'buyer_company' => 'required', 'contact_no' => 'required', 'marking' => 'required', 'lines.*.order' => 'required|numeric', 'lines.*.stock_code' => 'required', 'lines.*.description' => 'required', 'lines.*.quantity' => 'required|numeric', 'lines.*.unit_price_rm' => 'required|numeric', 'lines.*.unit_price_rmb' => '', 'lines.*.total' => 'required|numeric', ]); // booking_id belongs to user $booking = Booking::where('id', $id)->first(); if (!$booking) { return response()->json(['message' => 'Unable to find booking'], 403); } $invoice = Invoice::where('booking_id', $id)->first(); if (!$invoice) { return response()->json(['message' => 'Invoice Not Found'], 404); } // role === 'member' && $booking->user_id !== user()->id && $currentstatus !== 'request_change') if ($request->user()->role === 'member') { if ($booking->user_id !== $request->user()->id) { return response()->json([ 'message' => 'Booking does not belongs to you' ], 403); } $currentstatus = InvoiceStatuses::where('invoice_id', $invoice['id'])->latest('created_at')->first()->status; if ($currentstatus !== 'request_change') { return response()->json(['message' => 'Submitted PO can only be changed when status is request_change'], 403); } } // Amount match with total $subtotalArray = array_map( function ($line) { return $line['total']; }, $validatedData['lines'] ); $total = array_reduce($subtotalArray, function ($v1, $v2) { return $v1 + $v2; }); if ($total != $booking->amount) { return response()->json([ 'message' => 'Booking amount expected is '.$booking->amount.'. Your Invoice amount is '.$total ], 400); } // Generate PO Number - po20200810-001(PO Format) $dt = Carbon::now(); $po_number = 'po'.$dt->format('Ymmdd').'-'.$id; $invoice->amount = $total; $invoice->booking_id = (int)$id; $invoice->buyer_company = $validatedData['buyer_company']; $invoice->address = $validatedData['address']; $invoice->contact_no = $validatedData['contact_no']; $invoice->po_number = $po_number; $invoice->save(); if (!$invoice) { return response() ->json(['message' => 'Unable to Save Data'], 500); } // Remove all invoice_details corresponding to invoice_id $invoice_details = InvoiceDetails::where('invoice_id', $invoice->id); $invoice_details->delete(); // Insert invoice_id into lines foreach( $validatedData['lines'] as $key => $line) { $invoice_details = new InvoiceDetails; $invoice_details->order = $line['order']; $invoice_details->description = $line['description']; $invoice_details->quantity = $line['quantity']; $invoice_details->stock_code = $line['stock_code']; $invoice_details->invoice_id = $invoice->id; $invoice_details->unit_price_rmb = $line['unit_price_rmb']; $invoice_details->unit_price_rm = $line['unit_price_rm']; $invoice_details->total = $line['total']; $invoice_details->save(); } unset($line); // Post status as pending $status = new InvoiceStatuses; $status->status = 'pending'; if ($request->user()->role === 'admin') { $status->comment = 'Edited by Admin.'; } else { $status->comment = 'Edited by Member.'; } $status->invoice_id = $invoice->id; $status->save(); if($invoice_details) { return $this->show($id); } else { return response(500); } } public function postStatus(Request $request, $id) { // validate $id is integer $validatedData = $request->validate([ 'status' => ['required', Rule::in('request_change', 'approve')], 'comment' => Rule::requiredIf($request->status === 'request_change') ]); // Save to database $status = new InvoiceStatuses; $status->status = $validatedData['status']; $status->comment = $validatedData['comment']; $status->invoice_id = Invoice::where('booking_id', $id)->first()['id']; $status->save(); // Response return response()->json($status, 201); } public function getPO($id) { } public function getDO($id) { } public function getSupplierDO($id) { } }