json(["message" => "Invalid id. Id needs to be a number"], 400); } // only allow if belongs or is admin if ($request->user()->role === 'member') { if (!$this->isUser($id, $request->user()->id)) { return response()->json(['message' => 'The Invoice Does not belongs to you.'], 403); } } $invoice = Invoice::where('booking_id', $id)->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 if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } $validatedData = $request->validate([ 'address' => 'required', 'buyer_company' => 'required', 'contact_no' => 'required', 'marking' => 'required', 'reg_no' => 'required', 'adjustment' => 'required|numeric', 'lines.*.order' => 'required|numeric', 'lines.*.stock_code' => 'required', 'lines.*.description' => 'max:256', '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'] ); $subtotal = array_reduce($subtotalArray, function ($v1, $v2) { return $v1 + $v2; }); $adjustment = $request->adjustment; $billing_charges = $booking->billing_charge; $total = $subtotal + $adjustment + $billing_charges; if (abs($total-$booking->bia) > 0.01) { return response()->json([ 'message' => 'Booking amount expected is '.$booking->bia.'. 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->reg_no = $validatedData['reg_no']; $invoice->buyer_company = $validatedData['buyer_company']; $invoice->address = $validatedData['address']; $invoice->contact_no = $validatedData['contact_no']; $invoice->po_number = $po_number; $invoice->adjustment = $adjustment; $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($request, $id); } else { return response(500); } } public function edit(Request $request, $id) { $user = $request->user(); // validate $id if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } $validatedData = $request->validate([ 'address' => 'required', 'buyer_company' => 'required', 'contact_no' => 'required', 'marking' => 'required', 'reg_no' => 'required', 'adjustment' => 'required|numeric', 'lines.*.order' => 'required|numeric', 'lines.*.stock_code' => 'required', 'lines.*.description' => 'max:256', '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'] ); $subtotal = array_reduce($subtotalArray, function ($v1, $v2) { return $v1 + $v2; }); $adjustment = $request->adjustment; $billing_charges = $booking->billing_charge; $total = $subtotal + $adjustment + $billing_charges; if (abs($total-$booking->bia) > 0.01) { return response()->json([ 'message' => 'Booking amount expected is '.gettype($booking->bia).'. Your Invoice amount is '.gettype($total) ], 400); } // Generate PO Number - po20200810-001(PO Format) $dt = Carbon::now(); $po_number = 'po'.$dt->format('Ymd').'-'.$id; $invoice->amount = $total; $invoice->booking_id = (int)$id; $invoice->reg_no = $validatedData['reg_no']; $invoice->buyer_company = $validatedData['buyer_company']; $invoice->address = $validatedData['address']; $invoice->contact_no = $validatedData['contact_no']; $invoice->po_number = $po_number; $invoice->adjustment = $adjustment; $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($request, $id); } else { return response(500); } } public function postStatus(Request $request, $id) { // validate $id is integer if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } $validatedData = $request->validate([ 'status' => ['required', Rule::in('request_change', 'approve')], 'comment' => Rule::requiredIf($request->status === 'request_change') ]); // Save status 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(); $booking = Booking::find($id); // Generate EI and EDO only if not exist $invoice = Invoice::where('booking_id', $id)->first(); var_dump($invoice->ei); if (!$invoice->ei && !$invoice->edo) { $monthlycount = Invoice::where('ei', 'like', 'EI-'.Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'%')->count() + 1; $generatednumber = Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'-'.sprintf("%05d", $monthlycount); $invoice->ei = 'EI-'.$generatednumber; $invoice->edo = 'EDO-'.$generatednumber; // Skip to next count if already exist while (Invoice::where('ei', $invoice->ei)->exists() || Invoice::where('edo', $invoice->edo)->exists()) { $monthlycount = $monthlycount + 1; $generatednumber = Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'-'.sprintf("%05d", $monthlycount); $invoice->ei = 'EI-'.$generatednumber; $invoice->edo = 'EDO-'.$generatednumber; } $invoice->save(); } if(!$status) { return response()->json(['message' => 'Unable to Update Status'], 500); } // Change Status to 7 if approve // Add email event here if ($validatedData['status'] === 'approve') { $booking = Booking::findOrFail($id); $booking->status = 7; $booking->admin_status = 7; $booking->save(); if(!$booking) { return response()->json(['message' => 'Unable to Complete Booking. Please Approve Again'], 500); } } // Response return response()->json($status, 201); } public function customerToCIEFPO(Request $request, $id) { if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } // Booking Exist and Belongs to User or is Admin if ($request->user()->role === 'member') { if (!$this->isUser($id, $request->user()->id)) { return response()->json(['message' => 'The PO Does not belongs to you.'], 403); } } // Generate PO $booking = Booking::where('id', $id)->first(); $invoice = Invoice::where('booking_id', $booking['id'])->first(); $lines = InvoiceDetails::where('invoice_id', $invoice->id)->get(); $marking = User::find($booking->user_id)->marking; $subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total'); $adjustment = $invoice->adjustment; $billing_charges = $booking->billing_charge; $total = $subtotal + $adjustment + $billing_charges; $data = [ 'title' => 'Purchase Order', 'detail' => [ 'date' => Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('d-m-Y'), 'po' => $invoice->po_number, 'do' => '', 'ref' => $booking->id ], 'buyer' => [ 'buyer_company' => $invoice->buyer_company, 'reg_no' => $invoice->reg_no, 'address' => $invoice->address, 'gst' => '', 'phone' => $invoice->contact_no, 'marking_no' => $marking ], 'seller' => [ 'seller_company' => 'CIEF Worldwide Sdn Bhd (1134596-M)', 'address' => 'Malaysia Global Innovation & Creativity Centre, Level 1 CWS, Block 3730, Persiaran APEC 63000 Cyberjaya.', 'phone' => '018 2909252', ], 'lines' => $lines, 'subtotal' => $subtotal, 'adjustment' => $adjustment, 'billingcharges' => $billing_charges, 'total' => $total ]; $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults(); $fontData = $defaultFontConfig['fontdata']; $mpdf = new \Mpdf\Mpdf([ 'fontDir' => array_merge($fontDirs, [ __DIR__ . '/custom/font/directory', ]), ]); $mpdf->shrink_tables_to_fit=1; $mpdf->keep_table_proportions = true; $mpdf->SetTitle('Invoice'); $html = view('pdf/po', $data); $mpdf->Bookmark('Start of the document'); $mpdf->SetHTMLFooter('
This is generated by computer. No signature required. Page {PAGENO} of {nbpg}
'); $mpdf->setHeader($invoice->po_number); $mpdf->WriteHTML($html); $mpdf->Output(); } public function CIEFToSupplierDO(Request $request, $id) { if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } // Booking Exist and Belongs to User or is Admin if ($request->user()->role === 'member') { if (!$this->isUser($id, $request->user()->id)) { return response()->json(['message' => 'The PO Does not belongs to you.'], 403); } } // Ensure Invoice Status is Approve // if ($this->invoiceStatus($id) !== 'approve') { // return response()->json(['message' => 'Invoice must and exist and approve status.'], 403); // } // Generate PO $booking = Booking::where('id', $id)->first(); $invoice = Invoice::where('booking_id', $booking['id'])->first(); $supplierbooking = SupplierBooking::where('booking_id', $id)->first(); $lines = DB::table('invoices') ->join('invoice_details', function ($join) use ($id) { $join->where('invoices.booking_id', '=', $id); $join->on('invoice_details.invoice_id', '=', 'invoices.id'); }) ->join('supplier_bookings', 'invoices.booking_id', '=', 'supplier_bookings.booking_id') ->select( 'order', 'stock_code', 'description', 'quantity', DB::raw('ROUND((invoice_details.unit_price_rmb / supplier_bookings.rate), 2) as unit_price_rm'), DB::raw('ROUND((invoice_details.quantity * ROUND((invoice_details.unit_price_rmb / supplier_bookings.rate), 2)), 2) as total'), // subtotal // adjustment // total )->get(); $supplierbooking = SupplierBooking::where('booking_id', $id)->first(); $supplier = SettingSupplier::where('id', $supplierbooking->supplier_id)->first(); $subtotal = $lines->sum('total'); $billing_charges = null; $total = $supplierbooking->amount_after_tax; $adjustment = $total - $subtotal; $data = [ 'title' => 'Delivery Order', 'detail' => [ 'date' => Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('d-m-Y'), 'po' => $invoice->po_number, 'do' => '', 'ref' => $booking->id ], 'buyer' => [ 'buyer_company' => 'CIEF Worldwide Sdn Bhd', 'reg_no' => '1134596-M', 'address' => 'Malaysia Global Innovation & Creativity Centre, Level 1 CWS, Block 3730, Persiaran APEC 63000 Cyberjaya.', 'gst' => '', 'phone' => '018 2909252', 'marking_no' => '' ], 'seller' => [ 'seller_company' => $supplier->company_name, 'address' => '', 'phone' => '', ], 'lines' => $lines, 'subtotal' => $subtotal, 'adjustment' => $adjustment, 'billingcharges' => $billing_charges, 'total' => $total ]; $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults(); $fontData = $defaultFontConfig['fontdata']; $mpdf = new \Mpdf\Mpdf([ 'fontDir' => array_merge($fontDirs, [ __DIR__ . '/custom/font/directory', ]), ]); $mpdf->shrink_tables_to_fit=1; $mpdf->keep_table_proportions = true; $mpdf->SetTitle('Invoice'); $html = view('pdf/po', $data); $mpdf->Bookmark('Start of the document'); $mpdf->SetHTMLFooter('
This is generated by computer. No signature required. Page {PAGENO} of {nbpg}
'); $mpdf->setHeader($invoice->po_number); $mpdf->WriteHTML($html); $mpdf->Output(); } public function CIEFToCustomerInvoice(Request $request, $id) { if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } // only allow if belongs or is admin if ($request->user()->role === 'member') { if (!$this->isUser($id, $request->user()->id)) { return response()->json(['message' => 'The Invoice Does not belongs to you.'], 403); } } $booking = Booking::where('id', $id)->first(); $invoice = Invoice::where('booking_id', $booking['id'])->first(); $lines = InvoiceDetails::where('invoice_id', $invoice->id)->get(); $subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total'); $adjustment = $invoice->adjustment; $billing_charges = $booking->billing_charge; $total = $subtotal + $adjustment + $billing_charges; $data = [ 'title' => 'Invoice', 'detail' => [ 'date' => Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('d-m-Y'), 'ei' => $invoice->ei, 'edo' => null, 'ref' => $booking->id ], 'billto' => [ 'buyer_company' => $invoice->buyer_company, 'reg_no' => $invoice->reg_no, 'address' => $invoice->address, 'gst' => '', 'phone' => $invoice->contact_no, 'marking_no' => '' ], 'total_page' => (count($lines) / 10), 'lines' => $lines, 'subtotal' => $subtotal, 'adjustment' => $adjustment, 'billingcharges' => $billing_charges, 'total' => $total ]; $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults(); $fontData = $defaultFontConfig['fontdata']; $mpdf = new \Mpdf\Mpdf([ 'fontDir' => array_merge($fontDirs, [ __DIR__ . '/custom/font/directory', ]), ]); $mpdf->shrink_tables_to_fit=1; $mpdf->keep_table_proportions = true; $mpdf->SetTitle('Invoice'); $html = view('pdf/invoice', $data); $mpdf->Bookmark('Start of the document'); $mpdf->SetHTMLFooter('
This is generated by computer. No signature required. Page {PAGENO} of {nbpg}
'); $mpdf->setHeader($invoice->ei); $mpdf->WriteHTML($html); $mpdf->Output(); } public function CIEFToCustomerDO(Request $request, $id) { if (!is_numeric($id)) { return response()->json(["message" => "Invalid id. Id needs to be a number"], 400); } // only allow if belongs or is admin if ($request->user()->role === 'member') { if (!$this->isUser($id, $request->user()->id)) { return response()->json(['message' => 'The Invoice Does not belongs to you.'], 403); } } // Generate PO $booking = Booking::where('id', $id)->first(); $invoice = Invoice::where('booking_id', $booking['id'])->first(); $lines = InvoiceDetails::where('invoice_id', $invoice->id)->get(); $subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total'); $adjustment = $invoice->adjustment; $billing_charges = $booking->billing_charge; $total = $subtotal + $adjustment + $billing_charges; $data = [ 'title' => 'Delivery Order', 'detail' => [ 'date' => Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('d-m-Y'), 'ei' => '', 'edo' => $invoice->edo, 'ref' => $booking->id ], 'billto' => [ 'buyer_company' => $invoice->buyer_company, 'reg_no' => $invoice->reg_no, 'address' => $invoice->address, 'gst' => '', 'phone' => $invoice->contact_no, 'marking_no' => '' ], 'lines' => $lines, 'subtotal' => $subtotal, 'adjustment' => $adjustment, 'billingcharges' => $billing_charges, 'total' => $total ]; $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults(); $fontData = $defaultFontConfig['fontdata']; $mpdf = new \Mpdf\Mpdf([ 'fontDir' => array_merge($fontDirs, [ __DIR__ . '/custom/font/directory', ]), ]); $mpdf->shrink_tables_to_fit=1; $mpdf->keep_table_proportions = true; $mpdf->SetTitle('do'); $html = view('pdf/invoice', $data); $mpdf->Bookmark('Start of the document'); $mpdf->SetHTMLFooter('
This is generated by computer. No signature required. Page {PAGENO} of {nbpg}
'); $mpdf->setHeader($invoice->edo); $mpdf->WriteHTML($html); $mpdf->Output(); } private function isUser($booking_id, $user_id) { $booking = Booking::where([ ['id', '=', $booking_id], ['user_id', '=', $user_id] ])->first(); if ($booking) { return true; } else { return false; } } private function invoiceStatus($booking_id) { $invoice = Invoice::where('booking_id', $booking_id)->first(); if (!$invoice) { return; } $currentstatus = InvoiceStatuses::where('invoice_id', $invoice['id'])->latest('created_at')->first()->status; return $currentstatus; } }