Merge branch 'dillon/74-admin-workflow' into vapor/development

This commit is contained in:
Dillon Ngo
2025-01-05 02:14:03 +08:00
15 changed files with 588 additions and 233 deletions
@@ -4,15 +4,7 @@ namespace App\Classes\Modules\Bookings\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Bookings\Services\FetchesBooking;
use App\Classes\Modules\Documents\Services\ApprovesDocument;
use App\Classes\Modules\Documents\Services\FetchesDocument;
use App\Classes\Modules\Documents\Services\RejectsDocument;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Bookings\Processors\ApprovePurchaseOrderProcessor;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -29,26 +21,16 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic
];
}
/** @var FetchesBooking */
private $fetchesBooking;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreateInvoiceTransactionProcessor */
private $createInvoiceTransactionProcessor;
/** @var ApprovePurchaseOrderProcessor */
private $approvePurchaseOrderProcessor;
/**
* ApprovePurchaseOrderLogic constructor.
* @param FetchesBooking $fetchesBooking
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
* @param ApprovePurchaseOrderProcessor $approvePurchaseOrderProcessor
*/
public function __construct(FetchesBooking $fetchesBooking, UpdatesTransactionStatus $updatesTransactionStatus, CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor)
public function __construct(ApprovePurchaseOrderProcessor $approvePurchaseOrderProcessor)
{
$this->fetchesBooking = $fetchesBooking;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
$this->approvePurchaseOrderProcessor = $approvePurchaseOrderProcessor;
}
/**
@@ -58,18 +40,7 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
$purchaseOrder = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
$booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('id', '!=', $purchaseOrder->id)->delete();
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
$this->createInvoiceTransactionProcessor->execute($booking);
$this->approvePurchaseOrderProcessor->execute($request->route('id'));
return $this->response([]);
}
}
}
@@ -19,7 +19,7 @@ class FetchBookingLogic extends AbstractControllerLogic
protected function notification():array {
return [
'title' => 'Retrieved Booking',
'message' => 'You have successfully retrieved a Address'
'message' => 'You have successfully retrieved a Booking'
];
}
@@ -58,4 +58,4 @@ class FetchBookingLogic extends AbstractControllerLogic
}
}
}
@@ -0,0 +1,55 @@
<?php
namespace App\Classes\Modules\Bookings\Processors;
use App\Classes\Modules\Bookings\Services\FetchesBooking;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
class ApprovePurchaseOrderProcessor
{
/** @var FetchesBooking */
private $fetchesBooking;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreateInvoiceTransactionProcessor */
private $createInvoiceTransactionProcessor;
/**
* ApprovePurchaseOrderProcessor constructor.
* @param FetchesBooking $fetchesBooking
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
*/
public function __construct(FetchesBooking $fetchesBooking, UpdatesTransactionStatus $updatesTransactionStatus, CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor)
{
$this->fetchesBooking = $fetchesBooking;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
}
/**
* @param int $bookingId
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
*/
public function execute(int $bookingId) {
$booking = $this->fetchesBooking->execute(['id' => $bookingId]);
$purchaseOrder = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
$booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('id', '!=', $purchaseOrder->id)->delete();
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
$this->createInvoiceTransactionProcessor->execute($booking);
}
}
@@ -0,0 +1,105 @@
<?php
namespace App\Classes\Modules\Questionnaires\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Questionnaires\Standards\Rules\CanFetchQuestion;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Http\Resources\BookingBaseResource;
use App\Models\Booking;
use App\Models\KeyValuePair;
use Carbon\Carbon;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchAdminWFBookingLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Booking for Admin Workflow ',
'message' => 'You have successfully retrieved a Booking for Admin Workflow'
];
}
/** @var CanFetchQuestion */
private $canFetchQuestion;
/**
* FetchAdminWFBookingLogic constructor.
* @param CanFetchQuestion $canFetchQuestion
*/
public function __construct(CanFetchQuestion $canFetchQuestion)
{
$this->canFetchQuestion = $canFetchQuestion;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$this->canFetchQuestion->passes();
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', '1688_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', '1688_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
$timeAgo = Carbon::now()->subMonths(6);
$serviceId = 4;
$booking = Booking::where('service_id', $serviceId)
->where('status', ApprovalStatus::APPROVED)
->whereNotIn('id', $excludedBookingIds)
->whereHas('bills', function ($query) {
$query->whereHas('groupTransaction', function ($query) {
$query->whereHas('group', function ($query) {
$query->whereDoesntHave('billGroup')->whereIn('issuer', [2]);
});
});
})
->where('created_at', '>=', $timeAgo)
->latest()
->first();
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, '1688_admin_workflow_processing');
// return responseJson([
// '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' => $booking
// ]);
// return responseJson([
// 'booking' => new BookingBaseResource($booking)
// ]);
return $this->resourceResponse(new BookingBaseResource($booking));
}
}
@@ -0,0 +1,75 @@
<?php
namespace App\Classes\Modules\Questionnaires\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Questionnaires\Standards\Rules\CanFetchQuestion;
use App\Classes\ValueObjects\Constants\BookingAttributeNames;
use App\Http\Resources\BookingBaseResource;
use App\Models\Booking;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchAdminWFModelAttributesLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Model Attributes for Admin Workflow ',
'message' => 'You have successfully retrieved Model Attributes for Admin Workflow'
];
}
/** @var CanFetchQuestion */
private $canFetchQuestion;
/**
* FetchAdminWFModelAttributesLogic constructor.
* @param CanFetchQuestion $canFetchQuestion
*/
public function __construct(CanFetchQuestion $canFetchQuestion)
{
$this->canFetchQuestion = $canFetchQuestion;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$this->canFetchQuestion->passes();
$booking = Booking::find($request->route('booking_id'));
if (!$booking) {
return responseJson(null, 'No booking found', 404);
}
$attributes = $booking->modelAttributes()
->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)
->get(['id', 'value'])
->map(fn ($attr) => $attr->only(['id', 'value']));
$transaction = $booking->bills()->first(); //cief todo: 74 - more than 1 record?
return responseJson([
'booking' => $booking,
'booking_attributes' => $attributes,
'reference' =>$transaction->owner->owner->marking,
'marking' => $transaction->owner->owner->company->reference,
'currency_rate' => $transaction->currency_rate,
'total_amount' =>$transaction->currency->short_code . ' ' . number_format((float)$transaction->amount, 2, '.', '')
]);
return $this->resourceResponse(new BookingBaseResource($booking));
}
}
@@ -0,0 +1,99 @@
<?php
namespace App\Classes\Modules\Questionnaires\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Questionnaires\Standards\Rules\CanFetchQuestion;
use App\Classes\Modules\Bookings\Services\FetchesBooking;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Http\Resources\BookingBaseResource;
use App\Http\Resources\BookingResource;
use App\Models\KeyValuePair;
use Carbon\Carbon;
use App\Models\Booking;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class FetchAdminWFPendingApprovalPOLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Pending Approval PO for Admin Workflow ',
'message' => 'You have successfully retrieved Pending Approval PO for Admin Workflow'
];
}
/** @var CanFetchQuestion */ //cief todo: permission update
private $canFetchQuestion;
/** @var FetchesBooking */
private $fetchesBooking;
/**
* FetchAdminWFPendingApprovalPOLogic constructor.
* @param CanFetchQuestion $canFetchQuestion
* @param FetchesBooking $fetchesBooking
*/
public function __construct(CanFetchQuestion $canFetchQuestion, FetchesBooking $fetchesBooking)
{
$this->canFetchQuestion = $canFetchQuestion;
$this->fetchesBooking = $fetchesBooking;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$this->canFetchQuestion->passes();
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', 'approve_po_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', 'approve_po_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
// $booking = Booking::with('transactions')
// ->where('service_id', 4)
// ->where('status', ApprovalStatus::APPROVED)
// ->whereNotIn('id', $excludedBookingIds)
// ->whereHas('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER)->where('status', '<', ApprovalStatus::APPROVED))
// ->first();
$booking = $this->fetchesBooking->execute(['purchase_order_approval' => true, 'status_in' => [2], 'id_not_in' => $excludedBookingIds, 'with_transactions' => true, 'order_by_id_desc' => true]);
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, 'approve_po_admin_workflow_processing');
// $result = new BookingBaseResource($booking);
// return responseJson([
// 'booking' => $result,
// ]);
// return $booking ? responseJson(new BookingBaseResource($booking)) : responseJson(null, 'No booking found', 404);
return $this->resourceResponse(new BookingResource($booking));
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Classes\Modules\Questionnaires\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Questionnaires\Standards\Rules\CanFetchQuestion;
use App\Classes\Modules\Bookings\Services\FetchesBooking;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Http\Resources\BookingResource;
use App\Models\KeyValuePair;
use Carbon\Carbon;
use App\Models\Booking;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchAdminWFPendingFillPOLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Pending Fill PO for Admin Workflow ',
'message' => 'You have successfully retrieved Pending Fill PO for Admin Workflow'
];
}
/** @var CanFetchQuestion */ //cief todo: 74 - permission update
private $canFetchQuestion;
/** @var FetchesBooking */
private $fetchesBooking;
/**
* FetchAdminWFPendingFillPOLogic constructor.
* @param CanFetchQuestion $canFetchQuestion
* @param FetchesBooking $fetchesBooking
*/
public function __construct(CanFetchQuestion $canFetchQuestion, FetchesBooking $fetchesBooking)
{
$this->canFetchQuestion = $canFetchQuestion;
$this->fetchesBooking = $fetchesBooking;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$this->canFetchQuestion->passes();
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', 'fill_po_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', 'fill_po_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
// $booking = Booking::with('transactions')
// ->where('service_id', 4)
// ->where('status', ApprovalStatus::APPROVED)
// ->whereNotIn('id', $excludedBookingIds)
// ->whereDoesntHave('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER))
// ->first();
$booking = $this->fetchesBooking->execute(['pending_purchase_order' => true, 'has_payment_status_in' => [2, 3], 'id_not_in' => $excludedBookingIds, 'with_transactions' => true, 'order_by_id_desc' => true]);
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, 'fill_po_admin_workflow_processing');
// $result = new BookingBaseResource($booking);
// return responseJson([
// 'booking' => $result,
// ]);
// return $booking ? responseJson(new BookingResource($booking)) : responseJson(null, 'No booking found', 404);
return $this->resourceResponse(new BookingResource($booking));
}
}
@@ -121,7 +121,7 @@ class UpdateNextQuestionV1AdminWFLogic extends AbstractControllerLogic
//Marked data that has already been processed so that it does not appear again
$isNoGoingBack = null;
if($currentQuestion && $currentQuestion['is_end'] === 1){
$booking = Booking::where('id', $questionMetadata['booking']['id'])->first();
$booking = Booking::where('id', $questionMetadata['id'])->first();
$key1 = "admin_workflow_processed";
$key2 = "admin_workflow_processing";
@@ -0,0 +1,31 @@
<?php
namespace App\Classes\Modules\Questionnaires\Processors;
use App\Classes\Modules\Bookings\Processors\ApprovePurchaseOrderProcessor;
use Illuminate\Support\Facades\Log;
class SaveAnswerActionV1AdminWFProcessor
{
/** @var ApprovePurchaseOrderProcessor */
private $approvePurchaseOrderProcessor;
/**
* SaveAnswerActionV1AdminWFProcessor constructor.
* @param ApprovePurchaseOrderProcessor $approvePurchaseOrderProcessor
*/
public function __construct(ApprovePurchaseOrderProcessor $approvePurchaseOrderProcessor)
{
$this->approvePurchaseOrderProcessor = $approvePurchaseOrderProcessor;
}
/**
* @return
*/
public function execute($questionMetadata, $answerInText){
if($answerInText === "approve_po_approved"){
$this->approvePurchaseOrderProcessor->execute($questionMetadata['id']);
}
}
}
@@ -4,28 +4,27 @@ namespace App\Classes\Modules\Questionnaires\Processors;
use App\Models\QAUserAnswerSelected;
use App\Classes\Modules\Questionnaires\Services\FetchesUserAnswerSelected;
use App\Classes\Modules\Questionnaires\Processors\SaveAnswerActionV1AdminWFProcessor;
use App\Classes\Modules\Documents\Processors\UploadDocumentProcessor;
use App\Classes\ValueObjects\Constants\QAType;
class SaveAnswerV1AdminWFProcessor
{
/** @var FetchesUserAnswerSelected */
private $fetchesUserAnswerSelected;
/** @var UploadDocumentProcessor */
private $uploadDocumentForProcessor;
/** @var SaveAnswerActionV1AdminWFProcessor */
private $saveAnswerActionProcessor;
/**
* SaveAnswerV1AdminWFProcessor constructor.
* @param FetchesUserAnswerSelected $fetchesUserAnswerSelected
* @param UploadDocumentProcessor $uploadDocumentForProcessor
* @param SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor
*/
public function __construct(FetchesUserAnswerSelected $fetchesUserAnswerSelected, UploadDocumentProcessor $uploadDocumentForProcessor)
public function __construct(UploadDocumentProcessor $uploadDocumentForProcessor, SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor)
{
$this->fetchesUserAnswerSelected = $fetchesUserAnswerSelected;
$this->uploadDocumentForProcessor = $uploadDocumentForProcessor;
$this->saveAnswerActionProcessor = $saveAnswerActionProcessor;
}
/**
@@ -80,6 +79,8 @@ class SaveAnswerV1AdminWFProcessor
}
$answer->save();
$this->saveAnswerActionProcessor->execute($questionMetadata, $answerInText);
return $answer;
}
}
@@ -1,61 +1,50 @@
<?php
namespace App\Http\Controllers\Questionnaires;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Booking;
use App\Models\KeyValuePair;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Questionnaires\ControllersLogic\FetchAdminWFBookingLogic;
use App\Classes\Modules\Questionnaires\ControllersLogic\FetchAdminWFModelAttributesLogic;
use App\Classes\Modules\Questionnaires\ControllersLogic\FetchAdminWFPendingApprovalPOLogic;
use App\Classes\Modules\Questionnaires\ControllersLogic\FetchAdminWFPendingFillPOLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AdminWorkflowBaseController
{
public function fetchOldestOrder()
{
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', '1688_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', '1688_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
/**
* @param Request $request
* @param FetchAdminWFBookingLogic $logic
* @return JsonResponse
*/
public function fetchBooking(Request $request, FetchAdminWFBookingLogic $logic): JsonResponse {
return $logic->execute($request);
}
/**
* @param Request $request
* @param FetchAdminWFModelAttributesLogic $logic
* @return JsonResponse
*/
public function fetchModelAttributes(Request $request, FetchAdminWFModelAttributesLogic $logic): JsonResponse {
return $logic->execute($request);
}
$timeAgo = Carbon::now()->subMonths(6);
$serviceId = 4;
$booking = Booking::where('service_id', $serviceId)
->where('status', ApprovalStatus::APPROVED)
->whereNotIn('id', $excludedBookingIds)
->whereHas('bills', function ($query) {
$query->whereHas('groupTransaction', function ($query) {
$query->whereHas('group', function ($query) {
$query->whereDoesntHave('billGroup')->whereIn('issuer', [2]);
});
});
})
->where('created_at', '>=', $timeAgo)
->latest()
->first();
/**
* @param Request $request
* @param FetchAdminWFPendingApprovalPOLogic $logic
* @return JsonResponse
*/
public function fetchPendingApprovalPO(Request $request, FetchAdminWFPendingApprovalPOLogic $logic): JsonResponse {
return $logic->execute($request);
}
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, '1688_admin_workflow_processing');
return responseJson([
'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' => $booking
]);
/**
* @param Request $request
* @param FetchAdminWFPendingFillPOLogic $logic
* @return JsonResponse
*/
public function fetchPendingFillPO(Request $request, FetchAdminWFPendingFillPOLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BookingBaseResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function toArray($request)
{
return [
'id' => $this->id,
'company' => new CompanyResource($this->company),
'bank' => new BankResource($this->bank),
'marking' => $this->marking,
'fixed_currency' => new CurrencyResource($this->fixedCurrency),
];
}
}
@@ -3,8 +3,8 @@
<div class="col-1">{{ item.id }}</div>
<div class="col-2">{{ item.question_title }}</div>
<div class="col-1">
<a :href="route('booking.details', JSON.parse(item.question_metadata).booking.marking)"
target="_blank">{{ JSON.parse(item.question_metadata).booking.marking }}
<a :href="route('booking.details', JSON.parse(item.question_metadata).marking)"
target="_blank">{{ JSON.parse(item.question_metadata).marking }}
</a>
</div>
<div class="col-1">{{ parsedAnswer === 'go_back' ? '' : item.answer }}</div>
@@ -19,7 +19,7 @@
<h4>{{question.question_description}}</h4>
<div v-if="question.question_number === '1688'">
<h1>Login Information</h1>
<div v-if="externalApiResponse.data.booking"
<div v-if="externalApiResponse"
class="row bg-master-light m-t-15 m-b-15 rounded padding-30 justify-content-center">
<div class="col-auto text-left">
<table>
@@ -28,8 +28,8 @@
<h3><span class="bold d-inline-block m-r-15">ORDER Marking: </span></h3>
</td>
<td>
<h3><a :href="route('booking.details', externalApiResponse.data.booking.marking)"
target="_blank">{{ externalApiResponse.data.booking.marking
<h3><a :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">{{ externalApiResponse.data.marking
}}</a></h3>
</td>
</tr>
@@ -39,7 +39,7 @@
</span></h3>
</td>
<td>
<h3>{{ externalApiResponse.data.account_no }}</h3>
<h3>{{ externalApiResponse.data.bank.account_no }}</h3>
</td>
</tr>
<tr>
@@ -48,7 +48,7 @@
</span></h3>
</td>
<td>
<h3>{{ externalApiResponse.data.holder_name }}</h3>
<h3>{{ externalApiResponse.data.bank.holder_name }}</h3>
</td>
</tr>
<tr>
@@ -57,7 +57,7 @@
</span></h3>
</td>
<td>
<h3>{{ externalApiResponse.data.pin }}</h3>
<h3>{{ externalApiResponse.data.bank.bank_branch }}</h3>
</td>
</tr>
</table>
@@ -68,9 +68,9 @@
<div v-if="question.question_number === '1688_login_successful'">
<h3>
<span class="bold d-inline-block m-r-15">ORDER Marking: </span>
<a v-if="externalApiResponse.data.booking" :href="route('booking.details', externalApiResponse.data.booking.marking)"
<a v-if="externalApiResponse" :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">
{{ externalApiResponse.data.booking.marking }}
{{ externalApiResponse.data.marking }}
</a>
</h3>
<div v-if="externalApiResponse.data.reference" class="row bg-master-light m-t-15 m-b-15 rounded padding-30 justify-content-center">
@@ -112,14 +112,14 @@
</div>
<div v-if="question.question_number === '1688_order_verify'">
<h3 v-if="externalApiResponse.data.booking">
<h3 v-if="externalApiResponse">
<span class="bold d-inline-block m-r-15">ORDER Marking: </span>
<a :href="route('booking.details', externalApiResponse.data.booking.marking)"
<a :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">
{{ externalApiResponse.data.booking.marking }}
{{ externalApiResponse.data.marking }}
</a>
</h3>
<div v-if="externalApiResponse.data.booking" class="row bg-master-light m-t-15 m-b-15 rounded padding-30 justify-content-center">
<div v-if="externalApiResponse" class="row bg-master-light m-t-15 m-b-15 rounded padding-30 justify-content-center">
<div class="col-auto text-left">
<h3>
<span class="bold d-inline-block m-r-15">ORDER Reference(s): </span>
@@ -140,16 +140,16 @@
</div>
<div v-if="question.question_number === 'approve_po'">
<div v-if="externalApiResponse.data.booking" class="row">
<div v-if="externalApiResponse && externalApiResponse.data" class="row">
<div class="col">
<h3>
<span class="bold d-inline-block m-r-15">ORDER Marking: </span>
<a :href="route('booking.details', externalApiResponse.data.booking.marking)"
target="_blank">{{ externalApiResponse.data.booking.marking }}</a>
<a :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">{{ externalApiResponse.data.marking }}</a>
</h3>
<div class="row b-a b-primary padding-30 bg-white m-t-25">
<div class="col">
<purchase-order-form-read-only-component :data="externalApiResponse.data.booking" :companySegmentIds="companySegmentIds" :section="section"></purchase-order-form-read-only-component>
<purchase-order-form-read-only-component :data="externalApiResponse.data" :companySegmentIds="companySegmentIds" :section="section"></purchase-order-form-read-only-component>
</div>
</div>
</div>
@@ -157,16 +157,16 @@
</div>
<div v-if="question.question_number === 'fill_po'">
<div v-if="externalApiResponse.data.booking" class="row">
<div v-if="externalApiResponse && externalApiResponse.data" class="row">
<div class="col">
<h3>
<span class="bold d-inline-block m-r-15">ORDER Marking: </span>
<a :href="route('booking.details', externalApiResponse.data.booking.marking)"
target="_blank">{{ externalApiResponse.data.booking.marking }}</a>
<a :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">{{ externalApiResponse.data.marking }}</a>
</h3>
<div class="row b-a b-primary padding-30 bg-white m-t-25">
<div class="col">
<purchase-order-form-read-only-component :data="externalApiResponse.data.booking" :companySegmentIds="companySegmentIds" :section="section"></purchase-order-form-read-only-component>
<purchase-order-form-read-only-component :data="externalApiResponse.data" :companySegmentIds="companySegmentIds" :section="section"></purchase-order-form-read-only-component>
</div>
</div>
</div>
@@ -174,16 +174,16 @@
</div>
<div v-if="question.question_number === 'approve_po_edit' || question.question_number === 'fill_po_edit'">
<div v-if="externalApiResponse.data.booking" class="row">
<div v-if="externalApiResponse && externalApiResponse.data" class="row">
<div class="col">
<h3>
<span class="bold d-inline-block m-r-15">ORDER Marking: </span>
<a :href="route('booking.details', externalApiResponse.data.booking.marking)"
target="_blank">{{ externalApiResponse.data.booking.marking }}</a>
<a :href="route('booking.details', externalApiResponse.data.marking)"
target="_blank">{{ externalApiResponse.data.marking }}</a>
</h3>
<div class="row b-a b-primary padding-30 bg-white m-t-25">
<div class="col">
<purchase-order-form-component :data="externalApiResponse.data.booking" :companySegmentIds="companySegmentIds" :section="section + 'GetExternalApiResponse'"
<purchase-order-form-component :data="externalApiResponse.data" :companySegmentIds="companySegmentIds" :section="section + 'GetExternalApiResponse'"
@update-parameters="handleParametersUpdate"></purchase-order-form-component>
</div>
</div>
@@ -201,7 +201,7 @@
<h2>
Upload the English PO
</h2>
<!-- <file-upload-component :data="externalApiResponse.data" section="section"></file-upload-component> -->
<!-- <file-upload-component :data="externalApiResponse" section="section"></file-upload-component> -->
<file-input-component :validator="$v.files" v-model="files">
<template slot="label">
<div class="font-heading fs-11 all-caps">Photo or File</div>
@@ -262,7 +262,7 @@
<div class="row b-a b-primary padding-30 bg-white m-t-25">
<div class="col">
<div class="m-t-25">
<!-- <remark-comment-form-component :data="externalApiResponse.data" :id="externalApiResponse.data.booking_id" :section="section" module_type="Booking"></remark-comment-form-component> -->
<!-- <remark-comment-form-component :data="externalApiResponse" :id="externalApiResponse.data.booking_id" :section="section" module_type="Booking"></remark-comment-form-component> -->
<validation-wrapper-component :validator="$v.answer">
<label>Answer</label>
<input type="text" class="form-control" v-model="answer" @input="formTouched = true">
@@ -382,7 +382,7 @@
<!-- Debug box -->
<div class="debug-box" v-if="question">
<div id="debug-meta">
{{question.question_number}}<span v-if="externalApiResponse && externalApiResponse.data && externalApiResponse.data.booking">, Booking Id: {{externalApiResponse.data.booking.id}}</span><br>
{{question.question_number}}<span v-if="externalApiResponse && externalApiResponse.data">, Booking Id: {{ externalApiResponse.data.id }}</span><br>
</div>
</div>
</div>
@@ -406,7 +406,7 @@
// From AdminWorkFlowSectionComponent
sessionId: null,
externalApiResponse: { data: null },
externalApiResponse: null,
externalApiUrl: "",
timer: null,
elapsedTime: 0,
@@ -445,7 +445,7 @@
return `${hours}:${minutes}:${seconds}`;
},
companySegmentIds() {
return this.externalApiResponse.data?.booking?.company?.segments?.map(obj => parseInt(obj.id)) ?? [];
return (this.externalApiResponse && this.externalApiResponse.data)?.booking?.company?.segments?.map(obj => parseInt(obj.id)) ?? [];
},
hidePrevious(){
// return (this.question && this.question.is_start) || (this.question && this.question.is_no_going_back && this.question.is_no_going_back === 1)
@@ -482,7 +482,7 @@
// console.log('fetchAdditionalQuestionInfo: ', JSON.stringify(this.question));
if(this.externalApiUrl){
this.isFetching = true;
this.externalApiResponse.data = {};
this.externalApiResponse = null;
this.submit(this.externalApiUrl, 'get', this.section + 'GetExternalApiResponse', false, false);
}
},
@@ -492,11 +492,11 @@
this.$store.dispatch('completeList', {'name': this.section + 'GetExternalApiResponse', 'data': []});
if(response.data)
{
this.externalApiResponse.data = response.data;
this.externalApiResponse = { data: response.data };
}
else if(response.payload.data)
{
this.externalApiResponse.data.booking = response.payload.data;
this.externalApiResponse = { data: response.payload.data } ;
}
this.isFetching = false;
}
@@ -518,17 +518,17 @@
}
if(this.question.is_previous && this.question.answer){
this.externalApiResponse.data = JSON.parse(this.question.answer.question_metadata);
this.externalApiResponse = { data: JSON.parse(this.question.answer.question_metadata) };
}
else {
if(this.question && this.question.url){
let url = this.question.url;
if(!this.isURL(this.question.url)){
if(this.question.url === 'api.admin_work_flow.fetch_model_attributes'){
url = this.route(this.question.url, this.externalApiResponse.data.booking.id);
url = this.route(this.question.url, this.externalApiResponse.data.id);
}
else if(this.question.url === 'api.booking.show'){
url = this.route(this.question.url, this.externalApiResponse.data.booking.marking);
url = this.route(this.question.url, this.externalApiResponse.data.marking);
}
else{
url = this.route(this.question.url);
@@ -579,7 +579,7 @@
}
this.parameters.extra.timeUsedSeconds = this.stepTime;
this.parameters.extra.questionMetadata = this.externalApiResponse.data;
this.parameters.extra.questionMetadata = this.externalApiResponse?.data;
this.parameters.extra.user_id = this.$store.getters.getUserId;
this.parameters.extra.session_id = this.sessionId;
+4 -98
View File
@@ -46,104 +46,10 @@ if (!function_exists('markedProcessing')) {
Route::group(['prefix' => 'admin-work-flow', 'as' => 'admin_work_flow.', 'namespace' => 'Questionnaires'], function () {
Route::get('/fetch-oldest-order', [AdminWorkflowBaseController::class, 'fetchOldestOrder'])->name('fetch_oldest_order');
Route::get('/fetch-pending-approved-po', function () {
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', 'approve_po_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', 'approve_po_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
$booking = Booking::with('transactions')
->where('service_id', 4)
->where('status', ApprovalStatus::APPROVED)
->whereNotIn('id', $excludedBookingIds)
->whereHas('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER)->where('status', '<', ApprovalStatus::APPROVED))
->first();
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, 'approve_po_admin_workflow_processing');
$result = new BookingResource($booking);
return responseJson([
'booking' => $result,
]);
// return $booking ? responseJson(new BookingResource($booking)) : responseJson(null, 'No booking found', 404);
})->name('fetch_pending_approve_po');
Route::get('/fetch-pending-fill-po', function () {
$excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking')
->where(function ($query) {
$query->where('key', 'fill_po_admin_workflow_processed')
->orWhere(function ($query) {
$query->where('key', 'fill_po_admin_workflow_processing')
->where('updated_at', '>', Carbon::now()->subHour());
});
})
->pluck('owner_id')
->filter(function ($value) {
return is_numeric($value);
})
->toArray();
$booking = Booking::with('transactions')
->where('service_id', 4)
->where('status', ApprovalStatus::APPROVED)
->whereNotIn('id', $excludedBookingIds)
->whereDoesntHave('transactions', fn ($query) => $query->where('type', TransactionType::PURCHASE_ORDER))
->first();
if(!$booking){
return responseJson(null, 'No booking found', 404);
}
markedProcessing($booking, 'fill_po_admin_workflow_processing');
$result = new BookingResource($booking);
return responseJson([
'booking' => $result,
]);
// return $booking ? responseJson(new BookingResource($booking)) : responseJson(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 responseJson(null, 'No booking found', 404);
}
$attributes = $booking->modelAttributes()
->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)
->get(['id', 'value'])
->map(fn ($attr) => $attr->only(['id', 'value']));
$transaction = $booking->bills()->first(); //cief todo: 74 - more than 1 record?
return responseJson([
'booking' => $booking,
'booking_attributes' => $attributes,
'reference' =>$transaction->owner->owner->marking,
'marking' => $transaction->owner->owner->company->reference,
'currency_rate' => $transaction->currency_rate,
'total_amount' =>$transaction->currency->short_code . ' ' . number_format((float)$transaction->amount, 2, '.', '')
]);
})->name('fetch_model_attributes');
Route::get('/fetch-booking', [AdminWorkflowBaseController::class, 'fetchBooking'])->name('fetch_oldest_order');
Route::get('{booking_id}/fetch-model-attributes', [AdminWorkflowBaseController::class, 'fetchModelAttributes'])->name('fetch_model_attributes');
Route::get('/fetch-pending-approved-po', [AdminWorkflowBaseController::class, 'fetchPendingApprovalPO'])->name('fetch_pending_approve_po');
Route::get('/fetch-pending-fill-po', [AdminWorkflowBaseController::class, 'fetchPendingFillPO'])->name('fetch_pending_fill_po');
// Route::post('/add-workflow-timestamp', function (Request $request) {