diff --git a/app/Models/Remark.php b/app/Models/Remark.php index f2de3a5c..271b4d4b 100644 --- a/app/Models/Remark.php +++ b/app/Models/Remark.php @@ -12,6 +12,14 @@ class Remark extends AbstractModel protected $table = 'remarks'; + protected $fillable = [ + 'owner_id', + 'owner_type', + 'commenter_id', + 'content', + 'type' + ]; + public function owner(): morphTo { return $this->morphTo(); diff --git a/app/Models/WorkflowTimestamp.php b/app/Models/WorkflowTimestamp.php new file mode 100644 index 00000000..5cc6a17d --- /dev/null +++ b/app/Models/WorkflowTimestamp.php @@ -0,0 +1,49 @@ + 'datetime', + ]; + + /** + * Get the user that owns the workflow timestamp. + */ + public function user() + { + return $this->belongsTo(User::class, 'userId'); + } +} diff --git a/database/migrations/2024_07_21_222302_create_workflow_timestamps_table.php b/database/migrations/2024_07_21_222302_create_workflow_timestamps_table.php new file mode 100644 index 00000000..203c58bd --- /dev/null +++ b/database/migrations/2024_07_21_222302_create_workflow_timestamps_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('current_node'); + $table->string('next_node'); + $table->integer('seconds'); + $table->unsignedBigInteger('user_id'); + $table->string('session_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('workflow_timestamps'); + } +} diff --git a/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue index c2a0bd93..a429f0f4 100644 --- a/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue +++ b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue @@ -46,6 +46,7 @@ }, methods: { submitForm() { + this.$emit('remark-submitted', this.parameters.content); this.submit(this.data ? this.route('api.remark.update', this.data.id) : this.route('api.remark.create', this.id), this.data ? 'put' : 'post', this.section, true, true); }, }, diff --git a/resources/assets/vue/components/general/sections/AdminWorkFlowSectionComponent.vue b/resources/assets/vue/components/general/sections/AdminWorkFlowSectionComponent.vue new file mode 100644 index 00000000..3ceea3f0 --- /dev/null +++ b/resources/assets/vue/components/general/sections/AdminWorkFlowSectionComponent.vue @@ -0,0 +1,665 @@ + + + diff --git a/resources/views/pages/dashboards/admin_work_flow.blade.php b/resources/views/pages/dashboards/admin_work_flow.blade.php new file mode 100644 index 00000000..4fe3ddb2 --- /dev/null +++ b/resources/views/pages/dashboards/admin_work_flow.blade.php @@ -0,0 +1,4 @@ +@extends('layouts.base_portal') +@section('inner_content') + +@endsection \ No newline at end of file diff --git a/routes/admin_work_flow.php b/routes/admin_work_flow.php new file mode 100644 index 00000000..f7767523 --- /dev/null +++ b/routes/admin_work_flow.php @@ -0,0 +1,198 @@ + 'admin-work-flow', 'as' => 'admin_work_flow.', 'namespace' => 'AdminWorkFlow'], function () { + + // Generalized JSON response function + function jsonResponse($data = null, $message = null, $status = 200) + { + $response = ['message' => $message]; + + if ($data !== null) { + $response['data'] = $data; + } + + return response()->json($response, $status); + } + + + Route::get('/fetch-oldest-order', function () { + $booking = Booking::where('service_id', 4) + ->where('status', ApprovalStatus::APPROVED) + ->first(); + + return $booking ? jsonResponse([ + 'passwords' => $booking->bank->holder_name ?? null, + 'account_no' => $booking->bank->account_no ?? null, + 'pin' => $booking->bank->bank_branch ?? null, + 'holder_name' => $booking->bank->holder_name ?? null, + 'booking_marking' => $booking->marking ?? null, + 'booking_id' => $booking->id ?? null, + ]) : jsonResponse(null, 'No booking found', 404); + })->name('fetch_oldest_order'); + + + + Route::post('/add-workflow-timestamp', function (Request $request) { + $validator = Validator::make($request->all(), [ + 'current_node' => 'required|string', + 'next_node' => 'required|string', + 'seconds' => 'required|integer', + 'user_id' => 'required|integer|exists:users,id', + 'session_id' => 'required|string', + ]); + + if ($validator->fails()) { + throw new RequestValidationException($validator->messages()->first()); + } + + $workflowTimestamp = WorkflowTimestamp::create($validator->validated()); + + return jsonResponse($workflowTimestamp, 'Workflow timestamp created successfully', 201); + })->name('add_workflow_timestamp'); + + + + Route::get('/fetch-pending-approved-po', function () { + $booking = Booking::with('transactions') + ->where('service_id', 4) + ->where('status', ApprovalStatus::APPROVED) + ->whereHas('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER)->where('status', '<', ApprovalStatus::APPROVED)) + ->first(); + + return $booking ? jsonResponse(new BookingResource($booking)) : jsonResponse(null, 'No booking found', 404); + })->name('fetch_pending_approve_po'); + + + + Route::get('/fetch-pending-fill-po', function () { + $booking = Booking::with('transactions') + ->where('service_id', 4) + ->where('status', ApprovalStatus::APPROVED) + ->whereDoesntHave('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER)) + ->first(); + + return $booking ? jsonResponse(new BookingResource($booking)) : jsonResponse(null, 'No booking found', 404); + })->name('fetch_pending_fill_po'); + + + + Route::get('{booking_id}/fetch-model-attributes', function ($bookingId) { + $booking = Booking::find($bookingId); + + if (!$booking) { + return jsonResponse(null, 'No approved booking found', 404); + } + + $attributes = $booking->modelAttributes() + ->where('name', BookingAttributeNames::ORDER_REFERENCE_NO) + ->get(['id', 'value']) + ->map(fn ($attr) => $attr->only(['id', 'value'])); + + return jsonResponse([ + 'booking' => $booking, + 'booking_attributes' => $attributes, + ]); + })->name('fetch_model_attributes'); + + + // Route::post('/create-1688-login-issue-remark', function (Request $request) { + // $validator = Validator::make($request->all(), [ + // 'booking_id' => 'required', + // 'remark' => 'required', + // 'user_id' => 'required', + // ]); + + // if ($validator->fails()) { + // throw new RequestValidationException($validator->messages()->first()); + // } + + // $booking = Booking::find($request->booking_id); + + // if (!$booking) { + // return jsonResponse(null, 'Booking not found', 404); + // } + + // $remark = new Remark([ + // 'commenter_id' => $request->user_id, + // 'content' => $request->remark, + // 'owner_type' => get_class($booking), + // 'owner_id' => $booking->id, + // ]); + + // $remark->save(); + + // return jsonResponse($remark, 'Remark created successfully', 201); + // })->name('create_1688_login_issue_remark'); + + Route::post('/create_issue_remark', function (Request $request) { + $validator = Validator::make($request->all(), [ + 'booking_id' => 'required', + 'remark' => 'required', + 'user_id' => 'required', + ]); + + if ($validator->fails()) { + throw new RequestValidationException($validator->messages()->first()); + } + + $booking = Booking::find($request->booking_id); + + + if (!$booking) { + return jsonResponse(null, 'Booking not found', 404); + } + + $remark = new Remark([ + 'commenter_id' => $request->user_id, + 'content' => $request->remark, + 'owner_type' => get_class($booking), + 'owner_id' => $booking->id, + ]); + + $remark->save(); + + return jsonResponse($remark, 'Remark created successfully', 201); + })->name('create_issue_remark'); + + Route::post('/create_po_issue_remark', function (Request $request) { + $validator = Validator::make($request->all(), [ + 'booking_id' => 'required', + 'remark' => 'required', + 'user_id' => 'required', + ]); + + if ($validator->fails()) { + return response()->json(['message' => $validator->messages()->first()], 400); // Return validation error + } + + $booking = Booking::find($request->booking_id); + + if (!$booking) { + return response()->json(['message' => 'Booking not found'], 404); + } + + $remark = new Remark([ + 'commenter_id' => $request->user_id, + 'content' => $request->remark, + 'owner_type' => get_class($booking), + 'owner_id' => $booking->id, + ]); + + $remark->save(); + + return response()->json(['data' => $remark, 'message' => 'Remark created successfully'], 201); + })->name('create_po_issue_remark'); +}); diff --git a/routes/api.php b/routes/api.php index 0af29933..e38854b2 100644 --- a/routes/api.php +++ b/routes/api.php @@ -87,5 +87,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function // require __DIR__ . '/rate.php'; // require __DIR__ . '/receipt.php'; + require __DIR__ . '/admin_work_flow.php'; + }); }); diff --git a/routes/web.php b/routes/web.php index 1f2b2a86..c358f7c3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1217,3 +1217,6 @@ Route::get('check-duplicate-refunds', function () { echo ''; }); +Route::get('/admin-work-flow', function () { + return view('pages.dashboards.admin_work_flow'); +})->name('admin-work-flow');