diff --git a/app/Classes/General/Eloquent/Filters/AnswerLikeWithUserId.php b/app/Classes/General/Eloquent/Filters/AnswerLikeWithUserId.php
new file mode 100644
index 00000000..041f2f5e
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/AnswerLikeWithUserId.php
@@ -0,0 +1,45 @@
+where(function ($query) use ($searchText) {
+ $query->where('answer', 'like', '%' . $searchText . '%')
+ ->orWhereHas('answer', function ($subquery) use ($searchText) {
+ $subquery->where('display_text', 'like', '%' . $searchText . '%');
+ });
+ })
+ ->where('user_id', $userId);
+ }
+ else if($searchText){
+ return $builder->where(function ($query) use ($searchText) {
+ $query->where('answer', 'like', '%' . $searchText . '%')
+ ->orWhereHas('answer', function ($subquery) use ($searchText) {
+ $subquery->where('display_text', 'like', '%' . $searchText . '%');
+ });
+ });
+ }
+ else{
+ return $builder->where('user_id', $userId);
+ }
+
+ // return $builder->where('answer', 'like', '%' . $value . '%')
+ // ->orWhereHas('answer', function ($subquery) use($value){
+ // $subquery->where('display_text', 'like', '%' . $value . '%');
+ // });
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/EndDate.php b/app/Classes/General/Eloquent/Filters/EndDate.php
new file mode 100644
index 00000000..b6fb0d43
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/EndDate.php
@@ -0,0 +1,20 @@
+whereDate('created_at', '<=', Carbon::parse($value)->format('Y-m-d'));
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php b/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php
new file mode 100644
index 00000000..ae4e6787
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php
@@ -0,0 +1,24 @@
+whereHas('question', function ($subquery) use($value){
+ $subquery->whereHas('questionnaire', function ($subsubquery) use($value){
+ $subsubquery->where('id', $value);
+ });
+ });
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/IdAfter.php b/app/Classes/General/Eloquent/Filters/IdAfter.php
new file mode 100644
index 00000000..3273a1a3
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/IdAfter.php
@@ -0,0 +1,37 @@
+', $id)
+ ->where('reference', $reference)
+ ->whereIn('answer', $questionGroups)
+ ->orderBy('id', 'asc')
+ ->limit(1)
+ ->value('id');
+
+ if ($nextId) {
+ return $builder->where('id', '>', $id)
+ ->where('id', '<', $nextId)->withTrashed();
+ }
+
+ return $builder->where('id', '>', $id)->withTrashed();
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/IsAdminFilter.php b/app/Classes/General/Eloquent/Filters/IsAdminFilter.php
new file mode 100644
index 00000000..2cc18c03
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/IsAdminFilter.php
@@ -0,0 +1,20 @@
+where('is_admin_filter', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/IsPrevious.php b/app/Classes/General/Eloquent/Filters/IsPrevious.php
new file mode 100644
index 00000000..feeb8a0a
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/IsPrevious.php
@@ -0,0 +1,21 @@
+where('is_previous', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/QuestionGroupIn.php b/app/Classes/General/Eloquent/Filters/QuestionGroupIn.php
new file mode 100644
index 00000000..bc955ad8
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/QuestionGroupIn.php
@@ -0,0 +1,21 @@
+whereHas('question', function ($query) use ($value) {
+ $query->whereIn('group', $value);
+ });
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/QuestionId.php b/app/Classes/General/Eloquent/Filters/QuestionId.php
new file mode 100644
index 00000000..9c78f51a
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/QuestionId.php
@@ -0,0 +1,20 @@
+where('question_id', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/QuestionIn.php b/app/Classes/General/Eloquent/Filters/QuestionIn.php
new file mode 100644
index 00000000..ad1911fb
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/QuestionIn.php
@@ -0,0 +1,21 @@
+whereHas('question', function ($query) use ($value) {
+ $query->whereIn('question_number', $value);
+ });
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/QuestionNumber.php b/app/Classes/General/Eloquent/Filters/QuestionNumber.php
new file mode 100644
index 00000000..02d67343
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/QuestionNumber.php
@@ -0,0 +1,20 @@
+where('question_number', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/QuestionnaireSetId.php b/app/Classes/General/Eloquent/Filters/QuestionnaireSetId.php
new file mode 100644
index 00000000..aa9efe19
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/QuestionnaireSetId.php
@@ -0,0 +1,20 @@
+where('questionnaire_set_id', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/StartDate.php b/app/Classes/General/Eloquent/Filters/StartDate.php
new file mode 100644
index 00000000..ce2281b8
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/StartDate.php
@@ -0,0 +1,20 @@
+whereDate('created_at', '>=', Carbon::parse($value)->format('Y-m-d'));
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/WithAnswers.php b/app/Classes/General/Eloquent/Filters/WithAnswers.php
new file mode 100644
index 00000000..1cce3d2a
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/WithAnswers.php
@@ -0,0 +1,21 @@
+where(function ($query) use($value){
+ $query->whereIn('answer', $value);
+ });
+ }
+}
diff --git a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php
index d102a763..9033c594 100644
--- a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php
+++ b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php
@@ -30,13 +30,10 @@ class CanUpdateBankMetadata extends AbstractRule
*/
protected function authorized($object): bool
{
- //cief todo: 66 - temporary workaround
// if (!Auth::user()->can('update bank_metadata')) {
// return false;
// }
- // return true;
-
if (in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)) {
return true;
}
diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php
index f7d1d775..57406e1f 100644
--- a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php
+++ b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php
@@ -4,15 +4,8 @@ namespace App\Classes\Modules\Bookings\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
+use App\Classes\Modules\Bookings\Processors\ApprovePurchaseOrderProcessor;
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 Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -32,23 +25,18 @@ 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, FetchesBooking $fetchesBooking)
{
+ $this->approvePurchaseOrderProcessor = $approvePurchaseOrderProcessor;
$this->fetchesBooking = $fetchesBooking;
- $this->updatesTransactionStatus = $updatesTransactionStatus;
- $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
}
/**
@@ -58,18 +46,10 @@ 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($booking);
return $this->response([]);
}
-
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php
index 478c71a4..48f1fd21 100644
--- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php
+++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php
@@ -5,31 +5,11 @@ namespace App\Classes\Modules\Bookings\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
-use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
-use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
-use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
-use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
-use App\Classes\Modules\Transactions\Services\CreatesTransaction;
-use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
-use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill;
-use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
-use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
-use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
-use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
-use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
-use App\Classes\Modules\Vouchers\Processors\Voucherify\BookingToVoucherifyProcessor;
-use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance;
-use App\Classes\ValueObjects\Constants\ApprovalStatus;
-use App\Classes\ValueObjects\Constants\PaymentMethodType;
-use App\Classes\ValueObjects\Constants\TransactionType;
use App\Http\Resources\TransactionResource;
use App\Models\Booking;
-use App\Models\Transaction;
-use App\Models\Wallet;
-use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
+use App\Classes\Modules\Bookings\Processors\CreateBookingPaymentProcessor;
class CreateBookingPaymentLogic extends AbstractControllerLogic
{
@@ -44,71 +24,18 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
];
}
- /** @var FetchesBookingQuotation */
- private $fetchBookingQuotation;
+ /** @var CreateBookingPaymentProcessor */
+ private $createBookingPaymentProcessor;
- /** @var FetchesCompanyPaymentAttemptLimit */
- private $fetchesCompanyPaymentAttemptLimit;
- /** @var GeneratesTransactionBillNumber */
- private $generatesTransactionBillNumber;
-
- /** @var CreatesTransaction */
- private $createsTransaction;
-
- /** @var CalculatesBookingOutstanding */
- private $calculatesBookingOutstanding;
-
- /** @var CreatesBillplzBill */
- private $createsBillplzBill;
-
- /** @var UpdatesWalletBalance */
- private $updatesWalletBalance;
-
- /** @var UpdatesTransactionStatus */
- private $updatesTransactionStatus;
-
- /** @var CreateCashBackTransactionProcessor */
- private $createCashBackTransactionProcessor;
-
- /** @var RecalculatesWalletBalance */
- private $recalculatesWalletBalance;
-
- /** @var BookingToVoucherifyProcessor */
- private $bookingToVoucherifyProcessor;
-
- /** @var CalculatesBookingRefundAmount */
- private $calculatesBookingRefundAmount;
/**
* CreateBookingPaymentLogic constructor.
- * @param FetchesBookingQuotation $fetchBookingQuotation
- * @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
- * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
- * @param CreatesTransaction $createsTransaction
- * @param CalculatesBookingOutstanding $calculatesBookingOutstanding
- * @param CreatesBillplzBill $createsBillplzBill
- * @param UpdatesWalletBalance $updatesWalletBalance
- * @param UpdatesTransactionStatus $updatesTransactionStatus
- * @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor
- * @param RecalculatesWalletBalance $recalculatesWalletBalance
- * @param BookingToVoucherifyProcessor $bookingToVoucherifyProcessor
- * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
+ * @param CreateBookingPaymentProcessor $createBookingPaymentProcessor
*/
- public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
+ public function __construct(CreateBookingPaymentProcessor $createBookingPaymentProcessor)
{
- $this->fetchBookingQuotation = $fetchBookingQuotation;
- $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
- $this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
- $this->createsTransaction = $createsTransaction;
- $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
- $this->createsBillplzBill = $createsBillplzBill;
- $this->updatesWalletBalance = $updatesWalletBalance;
- $this->updatesTransactionStatus = $updatesTransactionStatus;
- $this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
- $this->recalculatesWalletBalance = $recalculatesWalletBalance;
- $this->bookingToVoucherifyProcessor = $bookingToVoucherifyProcessor;
- $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
+ $this->createBookingPaymentProcessor = $createBookingPaymentProcessor;
}
/**
@@ -122,61 +49,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$booking = Booking::find($request->route('id'));
- $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]);
-
- $outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
-
- if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.');
-
- $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $voucherCode, null, $booking);
-
- $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
-
- $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
-
- $paymentReference = null;
-
- $amount = $configurations->getTotal();
-
- if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){
- $billPlzBill = $this->createsBillplzBill->execute($booking->company->name, $request->user()->email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $request->input('bank_code'));
- $paymentReference = $billPlzBill->id;
- }
-
- if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){
- /** @var Wallet $wallet */
- $wallet = $booking->company->wallets()->first();
-
- if((float) number_format(($wallet->amount - $amount),2) < 0){
- throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.');
- }
-
- $transaction_object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], '');
- $transaction = $this->createsTransaction->execute($wallet, $transaction_object);
-
- $paymentReference = $billNumber;
-
- $walletBalance = $this->recalculatesWalletBalance->execute($wallet);
- $this->updatesWalletBalance->execute($wallet, $walletBalance);
- }
-
- $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
-
- $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id,
- $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(),
- $configurations->getTotal(), $configurations->getForeignTotal(), 1,
- $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(),
- $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference);
-
- /** @var Transaction $transaction */
- $transaction = $this->createsTransaction->execute($booking, $object);
-// $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction);
-
- $this->bookingToVoucherifyProcessor->execute($booking->company->employees()->first(), $transaction, $booking->company->id, $configurations->getSubTotal(), $configurations->getServiceCharge(), $configurations->getVoucherDiscountAmount(), $voucherCode);
-
- if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){
- $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
- }
+ $transaction = $this->createBookingPaymentProcessor->execute($booking, $request->input('amount'), $request->input('payment_method'), $voucherCode, $request->input('bank_code'), $request->user()->email);
return $this->resourceResponse(new TransactionResource($transaction));
}
diff --git a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php
index d1f2286e..711ae1cb 100644
--- a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php
+++ b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php
@@ -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
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php
index e40a947d..b75b0d11 100644
--- a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php
+++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php
@@ -1,31 +1,20 @@
canUpdateBooking = $canUpdateBooking;
- $this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
$this->fetchesBooking = $fetchesBooking;
- $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
- $this->updatesTransactionStatus = $updatesTransactionStatus;
+ $this->updateBookingAmountProcessor = $updateBookingAmountProcessor;
}
/**
@@ -76,25 +55,11 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
+ $fixAmount = floatval(str_replace(',', '', $request->input('fix_amount', $booking->fix_amount)));
- $input_amount = number_format( floatval(str_replace(',', '', $request->input('fix_amount', $booking->fix_amount))), 5, '.', '');
-
- $minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking);
-
- if (((float)$input_amount + 0.01) < (float)$minimum_amount) {
- throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
- }
-
- $poTransaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
- $booking->transactions()->where('type', TransactionType::PROFORMA)->delete();
-
- if($poTransaction) {
- $this->updatesTransactionStatus->execute($poTransaction, ApprovalStatus::PENDING_SUBMISSION);
- }
-
- $booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount);
+ $this->updateBookingAmountProcessor->execute($booking, $fixAmount);
return $this->resourceResponse(new BookingResource($booking));
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UploadPurchaseOrderLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UploadPurchaseOrderLogic.php
index ef6124cf..ab183a1f 100644
--- a/app/Classes/Modules/Bookings/ControllersLogic/UploadPurchaseOrderLogic.php
+++ b/app/Classes/Modules/Bookings/ControllersLogic/UploadPurchaseOrderLogic.php
@@ -4,25 +4,8 @@ namespace App\Classes\Modules\Bookings\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
-use App\Classes\Modules\Bookings\Processors\CreatePurchaseOrderFor1688OrderProcessor;
+use App\Classes\Modules\Bookings\Processors\UploadPurchaseOrderProcessor;
use App\Classes\Modules\Bookings\Services\FetchesBooking;
-use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
-use App\Classes\Modules\Documents\Services\ApprovesDocument;
-use App\Classes\Modules\Documents\Services\CreatesDocument;
-use App\Classes\Modules\Documents\Services\CreatesFiles;
-use App\Classes\Modules\Documents\Services\FetchesDocument;
-use App\Classes\Modules\Documents\Services\RejectsDocument;
-use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
-use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
-use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
-use App\Classes\Modules\Transactions\Services\FetchesTransaction;
-use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
-use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
-use App\Classes\ValueObjects\Constants\ApprovalStatus;
-use App\Classes\ValueObjects\Constants\DocumentType;
-use App\Classes\ValueObjects\Constants\PaymentMethodType;
-use App\Classes\ValueObjects\Constants\TransactionType;
-use App\Models\Document;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -42,29 +25,19 @@ class UploadPurchaseOrderLogic extends AbstractControllerLogic
/** @var FetchesBooking */
private $fetchesBooking;
- /** @var CreatesDocument */
- private $createsDocument;
-
- /** @var CreatesFiles */
- private $createsFile;
-
- /** @var CreatePurchaseOrderFor1688OrderProcessor */
- private $createPurchaseOrderFor1688OrderProcessor;
+ /** @var UploadPurchaseOrderProcessor */
+ private $uploadPurchaseOrderProcessor;
/**
* UploadPurchaseOrderLogic constructor.
* @param FetchesBooking $fetchesBooking
- * @param CreatesDocument $createsDocument
- * @param CreatesFiles $createsFile
- * @param CreatePurchaseOrderFor1688OrderProcessor $createPurchaseOrderFor1688OrderProcessor
+ * @param UploadPurchaseOrderProcessor $uploadPurchaseOrderProcessor
*/
- public function __construct(FetchesBooking $fetchesBooking, CreatesDocument $createsDocument, CreatesFiles $createsFile, CreatePurchaseOrderFor1688OrderProcessor $createPurchaseOrderFor1688OrderProcessor)
+ public function __construct(FetchesBooking $fetchesBooking, UploadPurchaseOrderProcessor $uploadPurchaseOrderProcessor)
{
$this->fetchesBooking = $fetchesBooking;
- $this->createsDocument = $createsDocument;
- $this->createsFile = $createsFile;
- $this->createPurchaseOrderFor1688OrderProcessor = $createPurchaseOrderFor1688OrderProcessor;
+ $this->uploadPurchaseOrderProcessor = $uploadPurchaseOrderProcessor;
}
/**
@@ -74,19 +47,8 @@ class UploadPurchaseOrderLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
-
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
-
- $object = new DocumentObject(DocumentType::ECOMMERCE_PURCHASE_ORDER, $request->input('files'), '', ApprovalStatus::APPROVED, '1688_purchase_orders');
-
- /** @var Document $document */
- $document = $this->createsDocument->execute($booking, $object);
-
- $this->createsFile->execute($document, $object);
-
- if(!in_array($booking->company->id, [199, 510])){
- $this->createPurchaseOrderFor1688OrderProcessor->execute($booking);
- }
+ $this->uploadPurchaseOrderProcessor->execute($booking, $request->input('files'));
return $this->response([]);
}
diff --git a/app/Classes/Modules/Bookings/Processors/ApprovePurchaseOrderProcessor.php b/app/Classes/Modules/Bookings/Processors/ApprovePurchaseOrderProcessor.php
new file mode 100644
index 00000000..e5021c06
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Processors/ApprovePurchaseOrderProcessor.php
@@ -0,0 +1,53 @@
+fetchesBooking = $fetchesBooking;
+ $this->updatesTransactionStatus = $updatesTransactionStatus;
+ $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
+ }
+
+ /**
+ * @param Booking $booking
+ * @return void
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ */
+ public function execute(Booking $booking) {
+
+ $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);
+ }
+}
diff --git a/app/Classes/Modules/Bookings/Processors/CreateBookingPaymentProcessor.php b/app/Classes/Modules/Bookings/Processors/CreateBookingPaymentProcessor.php
new file mode 100644
index 00000000..ec1233ee
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Processors/CreateBookingPaymentProcessor.php
@@ -0,0 +1,174 @@
+fetchBookingQuotation = $fetchBookingQuotation;
+ $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
+ $this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
+ $this->createsTransaction = $createsTransaction;
+ $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
+ $this->createsBillplzBill = $createsBillplzBill;
+ $this->updatesWalletBalance = $updatesWalletBalance;
+ $this->updatesTransactionStatus = $updatesTransactionStatus;
+ $this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
+ $this->recalculatesWalletBalance = $recalculatesWalletBalance;
+ $this->bookingToVoucherifyProcessor = $bookingToVoucherifyProcessor;
+ $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
+ }
+
+ /**
+ * Process booking payment.
+ *
+ * @param Booking $booking
+ * @param float $amount
+ * @param string $paymentMethod
+ * @param string|null $voucherCode
+ * @param string|null $bankCode
+ * @param string $email
+ * @return Transaction
+ * @throws MalformedRequestException
+ */
+ public function execute(Booking $booking, string $amount, string $paymentMethod, ?string $voucherCode, ?string $bankCode, string $email, bool $checkSysRecordedOutstanding = true)
+ {
+ $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $amount)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$paymentMethod]);
+
+ $outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
+
+ if($checkSysRecordedOutstanding){
+ if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.');
+ }
+
+ $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $voucherCode);
+
+ $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
+
+ $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
+
+ $paymentReference = null;
+
+ $amount = $configurations->getTotal();
+
+ if(PaymentMethodType::PAYMENT_METHODS[$paymentMethod] == PaymentMethodType::PAYMENT_GATEWAY){
+ $billPlzBill = $this->createsBillplzBill->execute($booking->company->name, $email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $bankCode);
+ $paymentReference = $billPlzBill->id;
+ }
+
+ if(PaymentMethodType::PAYMENT_METHODS[$paymentMethod] == PaymentMethodType::WALLET){
+ /** @var Wallet $wallet */
+ $wallet = $booking->company->wallets()->first();
+
+ if((float) number_format(($wallet->amount - $amount), 2) < 0){
+ throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.');
+ }
+
+ $transaction_object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], '');
+ $transaction = $this->createsTransaction->execute($wallet, $transaction_object);
+
+ $paymentReference = $billNumber;
+
+ $walletBalance = $this->recalculatesWalletBalance->execute($wallet);
+ $this->updatesWalletBalance->execute($wallet, $walletBalance);
+ }
+
+ $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
+
+ $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id,
+ $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(),
+ $configurations->getTotal(), $configurations->getForeignTotal(), 1,
+ $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(),
+ $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference);
+
+ /** @var Transaction $transaction */
+ $transaction = $this->createsTransaction->execute($booking, $object);
+// $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction);
+
+ $this->bookingToVoucherifyProcessor->execute($booking->company->employees()->first(), $transaction, $booking->company->id, $configurations->getSubTotal(), $configurations->getVoucherDiscountAmount(), $voucherCode);
+
+ if(PaymentMethodType::PAYMENT_METHODS[$paymentMethod] == PaymentMethodType::WALLET){
+ $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
+ }
+
+ return $transaction;
+ }
+}
diff --git a/app/Classes/Modules/Bookings/Processors/UpdateBookingAmountProcessor.php b/app/Classes/Modules/Bookings/Processors/UpdateBookingAmountProcessor.php
new file mode 100644
index 00000000..57b2531d
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Processors/UpdateBookingAmountProcessor.php
@@ -0,0 +1,65 @@
+updatesBookingFixedAmount = $updatesBookingFixedAmount;
+ $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
+ $this->updatesTransactionStatus = $updatesTransactionStatus;
+ }
+
+ /**
+ * @param Booking $booking
+ * @return Booking $booking
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ */
+ public function execute(Booking $booking, float $fixAmount)
+ {
+ $input_amount = number_format($fixAmount, 5, '.', '');
+
+ $minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking);
+
+ if (((float)$input_amount + 0.01) < (float)$minimum_amount) {
+ throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
+ }
+
+ $poTransaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
+ $booking->transactions()->where('type', TransactionType::PROFORMA)->delete();
+
+ if($poTransaction) {
+ $this->updatesTransactionStatus->execute($poTransaction, ApprovalStatus::PENDING_SUBMISSION);
+ }
+
+ $booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount);
+
+ return $booking;
+ }
+
+}
diff --git a/app/Classes/Modules/Bookings/Processors/UploadPurchaseOrderProcessor.php b/app/Classes/Modules/Bookings/Processors/UploadPurchaseOrderProcessor.php
new file mode 100644
index 00000000..85203e86
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Processors/UploadPurchaseOrderProcessor.php
@@ -0,0 +1,60 @@
+createsDocument = $createsDocument;
+ $this->createsFile = $createsFile;
+ $this->createPurchaseOrderFor1688OrderProcessor = $createPurchaseOrderFor1688OrderProcessor;
+ }
+
+ /**
+ * @param Booking $booking
+ * @param array $files
+ * @return void
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ */
+ public function execute(Booking $booking, array $files)
+ {
+ $object = new DocumentObject(DocumentType::ECOMMERCE_PURCHASE_ORDER, $files, '', ApprovalStatus::APPROVED, '1688_purchase_orders');
+
+ /** @var Document $document */
+ $document = $this->createsDocument->execute($booking, $object);
+
+ $this->createsFile->execute($document, $object);
+
+ if(!in_array($booking->company->id, [199, 510])){
+ $this->createPurchaseOrderFor1688OrderProcessor->execute($booking);
+ }
+ }
+
+}
diff --git a/app/Classes/Modules/Documents/Processors/UploadDocumentProcessor.php b/app/Classes/Modules/Documents/Processors/UploadDocumentProcessor.php
new file mode 100644
index 00000000..d6cd77e7
--- /dev/null
+++ b/app/Classes/Modules/Documents/Processors/UploadDocumentProcessor.php
@@ -0,0 +1,51 @@
+createsDocument = $createsDocument;
+ $this->createsFiles = $createsFiles;
+ }
+
+
+ /**
+ * @param QAUserAnswerSelected qaUserAnswerSelected
+ * @param array $filesUpload
+ * @param string $path
+ * @param string $documentType
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ */
+ public function execute(QAUserAnswerSelected $qaUserAnswerSelected, $filesUpload, string $path, string $documentType = DocumentType::ADMIN_WORK_FLOW) {
+ $object = new DocumentObject($documentType, $filesUpload, '', ApprovalStatus::PENDING_VERIFICATION, $path);
+
+ /** @var Document $document */
+ $document = $this->createsDocument->execute($qaUserAnswerSelected, $object);
+
+ $result = $this->createsFiles->execute($document, $object);
+ return $result;
+ }
+}
diff --git a/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithGroupsLogic.php b/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithGroupsLogic.php
new file mode 100644
index 00000000..1f8d0ffb
--- /dev/null
+++ b/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithGroupsLogic.php
@@ -0,0 +1,64 @@
+ 'Export Questions & Answers',
+ 'message' => 'You have successfully exported data'
+ ];
+ }
+
+ /** @var ExportsQAWithGroups */
+ private $exportsQAWithGroups;
+
+ /** @var CanExportQuestionsAnswers */
+ private $canExport;
+
+ /**
+ * ExportQAWithGroupsLogic constructor.
+ * @param ExportsQAWithGroups $exportsQAWithGroups
+ * @param CanExportQuestionsAnswers $canExport
+ */
+ public function __construct(ExportsQAWithGroups $exportsQAWithGroups, CanExportQuestionsAnswers $canExport)
+ {
+ $this->exportsQAWithGroups = $exportsQAWithGroups;
+ $this->canExport = $canExport;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return Response
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canExport->passes();
+
+ $this->exportsQAWithGroups->setFilters(Helper::deserializeFilters($request->input('filters')));
+
+ $exportFileName = 'qas.xls';
+ $filesystemDriver = Storage::getDefaultDriver();
+ if($filesystemDriver === 's3'){
+ return $this->response([ 'src' => AWSS3Helper::S3Exportable($exportFileName, $this->exportsQAWithGroups) ]);
+ }
+
+ return $this->response([ 'src' => null ]);
+ }
+
+}
diff --git a/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithoutGroupsLogic.php b/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithoutGroupsLogic.php
new file mode 100644
index 00000000..b67f1098
--- /dev/null
+++ b/app/Classes/Modules/Exports/ControllersLogic/ExportQAWithoutGroupsLogic.php
@@ -0,0 +1,64 @@
+ 'Export Questions & Answers',
+ 'message' => 'You have successfully exported data'
+ ];
+ }
+
+ /** @var ExportsQAWithoutGroups */
+ private $exportsQAWithoutGroups;
+
+ /** @var CanExportQuestionsAnswers */
+ private $canExport;
+
+ /**
+ * ExportQAWithoutGroupsLogic constructor.
+ * @param ExportsQAWithoutGroups $exportsQAWithoutGroups
+ * @param CanExportQuestionsAnswers $canExport
+ */
+ public function __construct(ExportsQAWithoutGroups $exportsQAWithoutGroups, CanExportQuestionsAnswers $canExport)
+ {
+ $this->exportsQAWithoutGroups = $exportsQAWithoutGroups;
+ $this->canExport = $canExport;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return Response
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canExport->passes();
+
+ $this->exportsQAWithoutGroups->setFilters(Helper::deserializeFilters($request->input('filters')));
+
+ $exportFileName = 'qas.xls';
+ $filesystemDriver = Storage::getDefaultDriver();
+ if($filesystemDriver === 's3'){
+ return $this->response([ 'src' => AWSS3Helper::S3Exportable($exportFileName, $this->exportsQAWithoutGroups) ]);
+ }
+
+ return $this->response([ 'src' => null ]);
+ }
+}
diff --git a/app/Classes/Modules/Exports/Services/ExportsQAWithGroups.php b/app/Classes/Modules/Exports/Services/ExportsQAWithGroups.php
new file mode 100644
index 00000000..90efd5b8
--- /dev/null
+++ b/app/Classes/Modules/Exports/Services/ExportsQAWithGroups.php
@@ -0,0 +1,137 @@
+filters = $filters;
+ }
+
+ /**
+ * @return \Illuminate\Support\Collection|mixed
+ */
+ public function query()
+ {
+ $data = (new ApplyFiltersToQuery())->execute(QAUserAnswerSelected::query(), $this->filters, true);
+
+ return $data;
+ }
+
+ /**
+ * @param QAUserAnswerSelected $userAnswer
+ *
+ * @return array
+ */
+ public function map($userAnswer): array
+ {
+ $source = $userAnswer->userSource;
+ $user = $userAnswer->source_id === 0 ? $userAnswer->user : null;
+ $answer = $userAnswer->answer()->first();
+ $answerValue = $answer ? $answer->value : null;
+ if($userAnswer->is_previous === 1){
+ $answerValue ='go_back';
+ }
+ $questionGroups = explode(',', $userAnswer->question->questionnaire->group);
+ $metadata = json_decode($userAnswer->question_metadata);
+ $rows = [[
+ $userAnswer->id,
+ $userAnswer->question->questionnaire->version,
+ $userAnswer->question->questionnaire->description,
+ $userAnswer->question->question_title,
+ $answer ? $answer->display_text : null,
+ $answerValue,
+ $user ? $user->email : $source->email,
+ $userAnswer->time_used_seconds,
+ $metadata->marking ?? null,
+ isset($metadata->company) ? $metadata->company->reference: null,
+ isset($metadata->payment_history[0]) ? $metadata->payment_history[0]->currency_rate : null,
+ isset($metadata->payment_history[0]) ? $metadata->payment_history[0]->currency->short_code . " " . round($metadata->payment_history[0]->amount, 2): null,
+ Carbon::parse($userAnswer->created_at)->format('d-m-Y h:i:s A'),
+ "YES"
+ ]];
+
+ $nextId = QAUserAnswerSelected::where('id', '>', $userAnswer->id)
+ ->where('reference', $userAnswer->reference)
+ ->whereIn('answer', $questionGroups)
+ ->orderBy('id', 'asc')
+ ->limit(1)
+ ->value('id');
+
+ if ($nextId) {
+ $temp = QAUserAnswerSelected::where('reference', '=', $userAnswer->reference)->where('id', '>', $userAnswer->id)
+ ->where('id', '<', $nextId)->withTrashed()->get();
+ }
+ else{
+ $temp = QAUserAnswerSelected::where('reference', '=', $userAnswer->reference)->where('id', '>', $userAnswer->id)->withTrashed()->get();
+ }
+
+ foreach ($temp as $relatedAnswer) {
+ $source = $relatedAnswer->userSource;
+ $user = $relatedAnswer->source_id === 0 ? $relatedAnswer->user : null;
+ $answer = $relatedAnswer->answer()->first();
+ $answerValue = $answer ? $answer->value : null;
+ if($relatedAnswer->is_previous === 1){
+ $answerValue ='go_back';
+ }
+ $md = json_decode($relatedAnswer->question_metadata);
+
+ $rows[] = [
+ $relatedAnswer->id,
+ $relatedAnswer->question->questionnaire->version,
+ $relatedAnswer->question->questionnaire->description,
+ $relatedAnswer->question->question_title,
+ $answer ? $answer->display_text : null,
+ $answerValue,
+ $user ? $user->email : $source->email,
+ $relatedAnswer->time_used_seconds,
+ $md->marking ?? null,
+ isset($md->company) ? $md->company->reference: null,
+ isset($md->payment_history[0]) ? $md->payment_history[0]->currency_rate : null,
+ isset($md->payment_history[0]) ? $md->payment_history[0]->currency->short_code . " " . round($md->payment_history[0]->amount, 2): null,
+ Carbon::parse($userAnswer->created_at)->format('d-m-Y h:i:s A'),
+ ];
+ }
+
+ return $rows;
+ }
+}
diff --git a/app/Classes/Modules/Exports/Services/ExportsQAWithoutGroups.php b/app/Classes/Modules/Exports/Services/ExportsQAWithoutGroups.php
new file mode 100644
index 00000000..a35845cc
--- /dev/null
+++ b/app/Classes/Modules/Exports/Services/ExportsQAWithoutGroups.php
@@ -0,0 +1,93 @@
+filters = $filters;
+ }
+
+ /**
+ * @return \Illuminate\Support\Collection|mixed
+ */
+ public function query()
+ {
+ $data = (new ApplyFiltersToQuery())->execute(QAUserAnswerSelected::query()->withTrashed(), $this->filters, true);
+
+ return $data;
+ }
+
+ /**
+ * @param QAUserAnswerSelected $userAnswer
+ *
+ * @return array
+ */
+ public function map($userAnswer): array
+ {
+ $source = $userAnswer->userSource;
+ $user = $userAnswer->source_id === 0 ? $userAnswer->user : null;
+ $answer = $userAnswer->answer()->first();
+ $answerValue = $answer ? $answer->value : null;
+ if($userAnswer->is_previous === 1){
+ $answerValue ='go_back';
+ }
+ $questionGroups = explode(',', $userAnswer->question->questionnaire->group);
+ $metadata = json_decode($userAnswer->question_metadata);
+ $rows = [[
+ $userAnswer->id,
+ $userAnswer->question->questionnaire->version,
+ $userAnswer->question->questionnaire->description,
+ $userAnswer->question->question_title,
+ $answer ? $answer->display_text : null,
+ $answerValue,
+ $user ? $user->email : $source->email,
+ $userAnswer->time_used_seconds,
+ $metadata->marking ?? null,
+ isset($metadata->company) ? $metadata->company->reference: null,
+ isset($metadata->payment_history[0]) ? $metadata->payment_history[0]->currency_rate : null,
+ isset($metadata->payment_history[0]) ? $metadata->payment_history[0]->currency->short_code . " " . round($metadata->payment_history[0]->amount, 2): null,
+ Carbon::parse($userAnswer->created_at)->format('d-m-Y h:i:s A'),
+ $answer ? in_array($answer->value, $questionGroups) : false,
+ ]];
+
+ return $rows;
+ }
+}
diff --git a/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php b/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php
new file mode 100644
index 00000000..5072a6b3
--- /dev/null
+++ b/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php
@@ -0,0 +1,48 @@
+user()){
+ $roleToCheck = Auth()->user()->type;
+ if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function validators($object): bool
+ {
+ return true;
+ }
+
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ return true;
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWF1688BookingLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWF1688BookingLogic.php
new file mode 100644
index 00000000..205b6dbe
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWF1688BookingLogic.php
@@ -0,0 +1,111 @@
+ 'Retrieved Booking for Admin Workflow ',
+ 'message' => 'You have successfully retrieved a Booking for Admin Workflow'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ private $canFetchQuestion;
+
+ /** @var FetchesBooking */
+ private $fetchesBooking;
+
+ /**
+ * FetchAdminWFBookingLogic 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', '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);
+ }
+
+ $booking = $this->fetchesBooking->execute(['id' => $booking->id, 'with_transactions' => true, 'order_by_id_desc' => true]);
+
+ 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));
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFModelAttributesLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFModelAttributesLogic.php
new file mode 100644
index 00000000..ed7151e0
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFModelAttributesLogic.php
@@ -0,0 +1,82 @@
+ 'Retrieved Model Attributes for Admin Workflow ',
+ 'message' => 'You have successfully retrieved Model Attributes for Admin Workflow'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ private $canFetchQuestion;
+
+ /** @var FetchesBooking */
+ private $fetchesBooking;
+
+ /**
+ * FetchAdminWFModelAttributesLogic 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();
+
+ // $booking = Booking::find($request->route('booking_id'));
+ $booking = $this->fetchesBooking->execute(['id' => $request->route('booking_id'), 'with_transactions' => true, 'order_by_id_desc' => true]);
+
+ 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));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingApprovalPOLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingApprovalPOLogic.php
new file mode 100644
index 00000000..7006bdc0
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingApprovalPOLogic.php
@@ -0,0 +1,99 @@
+ 'Retrieved Pending Approval PO for Admin Workflow ',
+ 'message' => 'You have successfully retrieved Pending Approval PO for Admin Workflow'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ 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()->subMinutes(30));
+ });
+ })
+ ->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 BookingBaseResource($booking));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingFillPOLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingFillPOLogic.php
new file mode 100644
index 00000000..001838ce
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchAdminWFPendingFillPOLogic.php
@@ -0,0 +1,96 @@
+ 'Retrieved Pending Fill PO for Admin Workflow ',
+ 'message' => 'You have successfully retrieved Pending Fill PO for Admin Workflow'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ 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 BookingBaseResource($booking));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/FetchQuestionV1AdminWFLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchQuestionV1AdminWFLogic.php
new file mode 100644
index 00000000..0b6bfdd8
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/FetchQuestionV1AdminWFLogic.php
@@ -0,0 +1,62 @@
+ 'Retrieved Admin Workflow First Question',
+ 'message' => 'You have successfully retrieved a Admin Workflow First Question'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ private $canFetchQuestion;
+
+ /** @var FetchFirstQuestionV1AdminWFProcessor */
+ private $fetchFirstQuestionQAProcessor;
+
+ /**
+ * FetchQuestionV1AdminWFLogic constructor.
+ * @param CanFetchQuestion $canFetchQuestion
+ * @param FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor
+ */
+ public function __construct(CanFetchQuestion $canFetchQuestion, FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor)
+ {
+ $this->canFetchQuestion = $canFetchQuestion;
+ $this->fetchFirstQuestionQAProcessor = $fetchFirstQuestionQAProcessor;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws ErrorException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canFetchQuestion->passes();
+
+ $userId = Auth::user()->id;
+
+ $query = $this->fetchFirstQuestionQAProcessor->execute($request);
+
+ return $this->resourceResponse(new QuestionResource($query, $userId));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php
new file mode 100644
index 00000000..d8fe5667
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php
@@ -0,0 +1,60 @@
+ 'Retrieved Questionnaire Sets',
+ 'message' => 'You have successfully retrieved a list of questionnaire sets'
+ ];
+ }
+
+ /** @var CanListQuestions */
+ private $canListQuestions;
+
+ /** @var ListsQuestionnaireSet */
+ private $listsQuestionnaireSet;
+
+ /**
+ * ListQuestionnaireSetLogic constructor.
+ * @param CanListQuestions $canListQuestions
+ * @param ListsQuestionnaireSet $listsQuestionnaires
+ */
+ public function __construct(CanListQuestions $canListQuestions, ListsQuestionnaireSet $listsQuestionnaireSet)
+ {
+ $this->canListQuestions = $canListQuestions;
+ $this->listsQuestionnaireSet = $listsQuestionnaireSet;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ // $this->canListQuestions->passes(); //cief todo: 74
+
+ $query = $this->listsQuestionnaireSet->execute($this->listsQuestionnaireSet->deserializeFilters($request->input('filters')));
+
+ return $this->collectionResponse(QuestionnaireSetsResource::collection($query));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php
new file mode 100644
index 00000000..d1912b1a
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php
@@ -0,0 +1,60 @@
+ 'Retrieved Questions Answers',
+ 'message' => 'You have successfully retrieved a list of questions and answers'
+ ];
+ }
+
+ /** @var CanListQuestions */
+ private $canListQuestions;
+
+ /** @var ListsQuestionUserAnswerSelected */
+ private $listsQuestionUserAnswerSelected;
+
+ /**
+ * ListQuestionsAnswersLogic constructor.
+ * @param CanListQuestions $canListQuestions
+ * @param ListsQuestionUserAnswerSelected $listsQuestionUserAnswerSelected
+ */
+ public function __construct(CanListQuestions $canListQuestions, ListsQuestionUserAnswerSelected $listsQuestionUserAnswerSelected)
+ {
+ $this->canListQuestions = $canListQuestions;
+ $this->listsQuestionUserAnswerSelected = $listsQuestionUserAnswerSelected;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canListQuestions->passes();
+
+ $query = $this->listsQuestionUserAnswerSelected->execute($this->listsQuestionUserAnswerSelected->deserializeFilters($request->input('filters')));
+
+ return $this->collectionResponse(QuestionsAnswersResource::collection($query));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsLogic.php
new file mode 100644
index 00000000..a3d7ffa1
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsLogic.php
@@ -0,0 +1,70 @@
+ 'Retrieved Questions',
+ 'message' => 'You have successfully retrieved a list of questions'
+ ];
+ }
+
+ /** @var CanListQuestions */
+ private $canListQuestions;
+
+ /** @var ListsQuestions */
+ private $listsQuestions;
+
+ /**
+ * ListQuestionsLogic constructor.
+ * @param CanListQuestions $canListQuestions
+ * @param ListsQuestions $listsQuestions
+ */
+ public function __construct(CanListQuestions $canListQuestions, ListsQuestions $listsQuestions)
+ {
+ $this->canListQuestions = $canListQuestions;
+ $this->listsQuestions = $listsQuestions;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canListQuestions->passes();
+ $setId = 0;
+ if ($request->route('set_id')) {
+ $setId = $request->route('set_id');
+ }
+
+ if($setId === 0){
+ $set = QAQuestionnaireSet::where('group', '1688,approve_po,fill_po')->latest('id')->first();
+ $setId = $set->id;
+ }
+
+ $query = $this->listsQuestions->execute(array_merge($this->listsQuestions->deserializeFilters($request->input('filters')), ['questionnaire_set_id' => $setId]));
+
+ return $this->collectionResponse(QuestionResource::collection($query));
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php
new file mode 100644
index 00000000..5395a898
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php
@@ -0,0 +1,185 @@
+ 'Retrieved Admin Workflow Next Question',
+ 'message' => 'You have successfully retrieved a Admin Workflow Next Question'
+ ];
+ }
+
+ /** @var CanFetchQuestion */
+ private $canFetchQuestion;
+
+ /** @var SaveAnswerV1AdminWFProcessor */
+ private $saveAnswerProcessor;
+
+ /** @var SaveAnswerActionV1AdminWFProcessor */
+ private $saveAnswerActionProcessor;
+
+ /** @var FetchNextQuestionV1AdminWFProcessor */
+ private $fetchNextQuestionV1AdminWFProcessor;
+
+ /** @var FetchNextQuestionMetadataV1AdminWFProcessor */
+ private $fetchNextQuestionMetadataProcessor;
+
+ /** @var FetchFirstQuestionV1AdminWFProcessor */
+ private $fetchFirstQuestionQAProcessor;
+
+ /** @var ListsQuestionUserAnswerSelected */
+ private $listsUserAnswerSelected;
+
+ /** @var CreatesKeyValuePair */
+ private $createsKeyValuePair;
+
+ /**
+ * UpdateNextQuestionV1AdminWFLogic constructor.
+ * @param CanFetchQuestion $canFetchQuestion
+ * @param SaveAnswerV1AdminWFProcessor $saveAnswerProcessor
+ * @param FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionV1AdminWFProcessor
+ * @param FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor
+ * @param ListsQuestionUserAnswerSelected $listsUserAnswerSelected
+ * @param CreatesKeyValuePair $createsKeyValuePair
+ * @param SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor
+ * @param FetchNextQuestionMetadataV1AdminWFProcessor $fetchNextQuestionMetadataProcessor
+ */
+ public function __construct(CanFetchQuestion $canFetchQuestion, SaveAnswerV1AdminWFProcessor $saveAnswerProcessor, FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionV1AdminWFProcessor, FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor, ListsQuestionUserAnswerSelected $listsUserAnswerSelected, CreatesKeyValuePair $createsKeyValuePair, SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor, FetchNextQuestionMetadataV1AdminWFProcessor $fetchNextQuestionMetadataProcessor)
+ {
+ $this->canFetchQuestion = $canFetchQuestion;
+ $this->saveAnswerProcessor = $saveAnswerProcessor;
+ $this->fetchNextQuestionV1AdminWFProcessor = $fetchNextQuestionV1AdminWFProcessor;
+ $this->fetchFirstQuestionQAProcessor = $fetchFirstQuestionQAProcessor;
+ $this->listsUserAnswerSelected = $listsUserAnswerSelected;
+ $this->createsKeyValuePair = $createsKeyValuePair;
+ $this->saveAnswerActionProcessor = $saveAnswerActionProcessor;
+ $this->fetchNextQuestionMetadataProcessor = $fetchNextQuestionMetadataProcessor;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws MalformedRequestException
+ * @throws ResourceNotFoundException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $userId = Auth::user()->id;
+ $timeUsedSeconds = 0;
+ $reference = null;
+ $questionMetadata = null;
+ $booking = null;
+ $previousAnswer = null;
+
+ $this->canFetchQuestion->passes();
+
+ $currentQuestion = $request->question;
+ $filesUpload = $request->only(['files', 'filesA', 'filesB', 'filesC']);
+ if ($request->has('questionContext')) {
+ $questionMetadata = $request->questionContext['questionMetadata'] ?? null;
+ $timeUsedSeconds = intval($request->questionContext['timeUsedSeconds']) ?? 0;
+ $reference = $request->questionContext['session_id'];
+ $booking = $questionMetadata ? Booking::where('id', $questionMetadata['id'])->first() : null;
+ }
+
+ //Save answer given by user (both next and previous)
+ $answerOptionId = 0;
+ if ($request->has('answerObj')) {
+ $answerOptionId = intval($request->answerObj['id']);
+ }
+
+ $this->saveAnswerProcessor->execute($userId, 0, $currentQuestion, $questionMetadata, $request->answer, $answerOptionId, $filesUpload, $timeUsedSeconds, $request->has('isPrevious'), $reference);
+ if(!$request->has('isPrevious')){
+ $this->saveAnswerActionProcessor->execute($booking, $questionMetadata, $answerOptionId, $currentQuestion, $filesUpload);
+ }
+
+ if ($request->has('questionContext')) {
+ $previousAnswer = $this->listsUserAnswerSelected->execute(['user_id' => $userId, 'reference' => $reference, 'is_previous' => 0, 'order_by' => (object)['column' => 'id','DESC' => true]])[0];
+ }
+
+ if($booking){
+ $this->markBookingAsProcessed($booking, $request->has('isPrevious'), $currentQuestion);
+ }
+
+ //Get returned question (previous or next) and additional metadata if applicable
+ $returnQuestion = $this->fetchNextQuestionV1AdminWFProcessor->execute($currentQuestion, $request->answerObj, $request->questionContext, $previousAnswer, $booking, $request->has('isPrevious'));
+ $questionMetadata = $this->fetchNextQuestionMetadataProcessor->execute($returnQuestion, $questionMetadata);
+
+ //When a questionnaire ended, return back the first question
+ if(is_null($returnQuestion)){
+ $returnQuestion = $this->fetchFirstQuestionQAProcessor->execute($request);
+ }
+
+ return $this->resourceResponse(new QuestionResource($returnQuestion, $userId, $request->has('isPrevious'), $this->isNoGoingBack($returnQuestion), $previousAnswer, $questionMetadata));
+ }
+
+ private function markBookingAsProcessed(Booking $booking, bool $isPrevious, array $currentQuestion){
+ //Marked data that has already been processed so that it does not appear again
+ if($currentQuestion && $currentQuestion['is_end'] === 1 && !$isPrevious){
+ $key1 = "admin_workflow_processed";
+ $key2 = "admin_workflow_processing";
+ if (strpos($currentQuestion['question_number'], '1688') === 0) {
+ $key1 = '1688_'.$key1;
+ $key2 = '1688_'.$key2;
+ }
+ if (strpos($currentQuestion['question_number'], 'fill_po') === 0) {
+ $key1 = 'xfill_po_'.$key1;
+ $key2 = 'xfill_po_'.$key2;
+ }
+ if (strpos($currentQuestion['question_number'], 'approve_po') === 0) {
+ $key1 = 'xapprove_po_'.$key1;
+ $key2 = 'xapprove_po_'.$key2;
+ }
+
+ $processingRecord = $booking->attributesKVP()->where('key', $key2)->first();
+ if ($processingRecord) {
+ $processingRecord->delete();
+ }
+
+ $kvp = $booking->attributesKVP()->where('key', $key1)->first();
+
+ if(!$kvp){
+ $keyValuePairObject = new KeyValuePairObject($key1, true);
+ $this->createsKeyValuePair->execute($booking, $keyValuePairObject);
+ }
+ }
+ }
+
+ private function isNoGoingBack(QAQuestions $returnQuestion){
+
+ if($returnQuestion && ($returnQuestion->is_start || $returnQuestion->is_end)){
+ return 1;
+ }
+ else if($returnQuestion && $returnQuestion->is_start === 0 && $returnQuestion && $returnQuestion->is_end === 0){
+ return 0;
+ }
+
+ return 0;
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/DataTransferObjects/QAUserSourceObject.php b/app/Classes/Modules/Questionnaires/DataTransferObjects/QAUserSourceObject.php
new file mode 100644
index 00000000..510a945c
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/DataTransferObjects/QAUserSourceObject.php
@@ -0,0 +1,56 @@
+system = $system;
+ $this->marking = $marking;
+ $this->email = $email;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSystem(): string
+ {
+ return $this->system;
+ }
+
+ /**
+ * @return string
+ */
+ public function getMarking(): string
+ {
+ return $this->marking;
+ }
+
+ /**
+ * @return string
+ */
+ public function getEmail(): string
+ {
+ return $this->email;
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/Processors/FetchFirstQuestionV1AdminWFProcessor.php b/app/Classes/Modules/Questionnaires/Processors/FetchFirstQuestionV1AdminWFProcessor.php
new file mode 100644
index 00000000..2bebe260
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Processors/FetchFirstQuestionV1AdminWFProcessor.php
@@ -0,0 +1,39 @@
+fetchesQuestion = $fetchesQuestion;
+ }
+
+ public function execute(Request $request){
+ try {
+ $setId = $request->route('set_id');
+ if($setId === '0'){
+ $set = QAQuestionnaireSet::where('group', '1688,approve_po,fill_po')->latest('id')->first();
+ $setId = $set->id;
+ }
+ $query = $this->fetchesQuestion->execute(['questionnaire_set_id' => $setId]);
+ return $query;
+ } catch (\Exception $exception){
+ throw new ErrorException($exception->getMessage(), $exception->getCode());
+ }
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionMetadataV1AdminWFProcessor.php b/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionMetadataV1AdminWFProcessor.php
new file mode 100644
index 00000000..0c57b6d1
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionMetadataV1AdminWFProcessor.php
@@ -0,0 +1,19 @@
+question_number === '1688_underpaid_order_1'){
+ $amountProcessed = $questionMetadata['amount_processed'];
+ $amountPaid = $questionMetadata['paid_amount'];
+ $questionMetadata['amount_to_be_deducted'] = $amountProcessed - $amountPaid;
+ }
+
+ return $questionMetadata;
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionV1AdminWFProcessor.php b/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionV1AdminWFProcessor.php
new file mode 100644
index 00000000..bb9454e3
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Processors/FetchNextQuestionV1AdminWFProcessor.php
@@ -0,0 +1,148 @@
+fetchesQuestion = $fetchesQuestion;
+ $this->listsQuestions = $listsQuestions;
+ $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
+ $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
+ $this->fetchBookingQuotation = $fetchBookingQuotation;
+ }
+
+ public function execute(array $currentQuestion, ?array $currentQuestionAnswer, array $questionContext, QAUserAnswerSelected $previousAnswer, ?Booking $booking, bool $isPrevious){
+ $isEnd = 0;
+ $questionId = 0;
+ $nextQuestionNumber = "";
+ $nextNestedQuestion = "";
+ $nextMainQuestion= "";
+ $questionnaireSetId = 0;
+ $questionType = QAType::DEFAULT;
+ $returnQuestion = null;
+
+ if ($currentQuestion && array_key_exists('id', $currentQuestion)) {
+ $questionId = $currentQuestion['id'];
+ $isEnd = $currentQuestion['is_end'];
+ $questionType = $currentQuestion['question_type'];
+ $nextNestedQuestion = $currentQuestion['next_nested_question'];
+ $nextMainQuestion = $currentQuestion['next_main_question'];
+ $questionnaireSetId = $currentQuestion['questionnaire_set_id'];
+ }
+
+ if ($currentQuestionAnswer && $currentQuestionAnswer['next_question_number']) {
+ $nextQuestionNumber = $currentQuestionAnswer['next_question_number'];
+ }
+
+ if ($isPrevious) {
+ if($previousAnswer)
+ {
+ $previousAnswer->delete();
+ }
+ else{
+ return null;
+ }
+
+ //Get previous question
+ $previousQuestion = $this->fetchesQuestion->execute(['questionnaire_set_id' => $questionnaireSetId, 'id' => $previousAnswer['question_id']]);
+ $returnQuestion = $previousQuestion;
+ }
+ else{
+ //Get next question
+ $nextQuestion = null;
+ $question_number = "";
+ if($nextQuestionNumber !== ""){
+ $question_number = $nextQuestionNumber;
+ }
+ else if($nextNestedQuestion !== ""){
+ $question_number = $nextNestedQuestion;
+ }
+ else {
+ $question_number = $nextMainQuestion;
+ }
+
+ if($question_number !== ""){
+ //Check if question exists
+ $questions = $this->listsQuestions->execute(['questionnaire_set_id' => $questionnaireSetId, 'question_number' => $question_number]);
+ if($previousAnswer['answer'] === '1688_order_verified' && count($questions) == 0){
+ $questionMetadata = $questionContext['questionMetadata'] ?? null;
+ $amountProcessed = $questionMetadata['amount_processed'];
+ $amountPaid = $questionMetadata['paid_amount'];
+ $wallet = $booking->company->wallets()->first();
+ $walletAmount = $wallet->amount;
+
+ if ($amountProcessed === $amountPaid) {
+ $question_number = '1688_proceed_order';
+ }
+ else if ($amountProcessed > $amountPaid) {
+ $outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
+
+ $differenceUnderPayinCNY = $amountProcessed - $amountPaid;
+ $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $differenceUnderPayinCNY)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS['wallet']);
+ $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject);
+ $amountUnderpay = $configurations->getTotal();
+
+ // if($amountUnderpay > round($outstanding, 2)) {
+ // $question_number = '1688_underpaid_order_3';
+ // }
+
+ if($walletAmount > $amountUnderpay) {
+ $question_number = '1688_underpaid_order_1';
+ }
+ else {
+ $question_number = '1688_underpaid_order_2';
+ }
+ }
+ else {
+ $question_number = '1688_overpaid_order';
+ }
+ }
+
+ $nextQuestion = $this->fetchesQuestion->execute(['questionnaire_set_id' => $questionnaireSetId, 'question_number' => $question_number]);
+ $returnQuestion = $nextQuestion;
+ }
+ }
+
+ return $returnQuestion;
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Processors/SaveAnswerActionV1AdminWFProcessor.php b/app/Classes/Modules/Questionnaires/Processors/SaveAnswerActionV1AdminWFProcessor.php
new file mode 100644
index 00000000..822e7dd8
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Processors/SaveAnswerActionV1AdminWFProcessor.php
@@ -0,0 +1,113 @@
+approvePurchaseOrderProcessor = $approvePurchaseOrderProcessor;
+ $this->uploadPurchaseOrderProcessor = $uploadPurchaseOrderProcessor;
+ $this->createPaymentProofDocumentProcessor = $createPaymentProofDocumentProcessor;
+ $this->fetchesTransaction = $fetchesTransaction;
+ $this->fetchBookingQuotation = $fetchBookingQuotation;
+ $this->createBookingPaymentProcessor = $createBookingPaymentProcessor;
+ $this->updateBookingAmountProcessor = $updateBookingAmountProcessor;
+ }
+
+ /**
+ * @return
+ */
+ public function execute($booking, $questionMetadata, $answerOptionId, $currentQuestion, $filesUpload){
+ $answerOption = QAAnswerOptions::where('id', $answerOptionId)->first();
+ if($currentQuestion['question_number'] === 'approve_po' && $answerOption && $answerOption->value === "approve_po_approved"){
+ $this->approvePurchaseOrderProcessor->execute($booking);
+ }
+ else if($currentQuestion['question_number'] === '1688_submit' || $currentQuestion['question_number'] === '1688_underpaid_documents_submission' || $currentQuestion['question_number'] === '1688_overpaid_documents_submission')
+ {
+ if($filesUpload){
+ if ($booking && isset($filesUpload['filesA']) && isset($filesUpload['filesB']))
+ {
+ $mergedFilesUpload = array_merge(
+ $filesUpload['filesA'] ?? [],
+ $filesUpload['filesB'] ?? []
+ );
+ $this->uploadPurchaseOrderProcessor->execute($booking, $mergedFilesUpload);
+ }
+
+ if (isset($filesUpload['filesC']) && isset($questionMetadata['payment_history'][0]['transaction_bill']['id']))
+ {
+ $transaction = $this->fetchesTransaction->execute(['id' =>$questionMetadata['payment_history'][0]['transaction_bill']['id']]);
+ $this->createPaymentProofDocumentProcessor->execute($transaction, $filesUpload['filesC']);
+ }
+ }
+ }
+ else if($currentQuestion['question_number'] === '1688_underpaid_order_1')
+ {
+ $wallet = $booking->company->wallets()->first();
+ $amountProcessed = $questionMetadata['amount_processed'];
+ $amountPaid = $questionMetadata['paid_amount'];
+ if ($amountProcessed > $amountPaid) {
+ $differenceUnderInCNY = $amountProcessed - $amountPaid;
+ $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $differenceUnderInCNY)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS['wallet']);
+ $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject);
+ $amountUnderpay = $configurations->getTotal();
+
+ if($amountUnderpay != $differenceUnderInCNY){
+ $this->updateBookingAmountProcessor->execute($booking, $amountProcessed);
+ }
+
+ if($wallet->amount > $amountUnderpay){
+ $company = $booking->company()->first();
+ $employee = $company->employees()->first();
+ $transaction = $this->createBookingPaymentProcessor->execute($booking, (string) $differenceUnderInCNY, 'wallet', "", "", $employee->email, false);
+ }
+ }
+
+ }
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Processors/SaveAnswerV1AdminWFProcessor.php b/app/Classes/Modules/Questionnaires/Processors/SaveAnswerV1AdminWFProcessor.php
new file mode 100644
index 00000000..70ee3c36
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Processors/SaveAnswerV1AdminWFProcessor.php
@@ -0,0 +1,130 @@
+uploadDocumentForProcessor = $uploadDocumentForProcessor;
+ }
+
+ /**
+ * @return QAUserAnswerSelected|\Illuminate\Database\Eloquent\Model
+ */
+ public function execute($userId, $sourceId, $currentQuestion, $questionMetadata, $answerInText, $answerOptionId, $filesUpload, $timeUsedSeconds, $isPrevious, $reference = null){
+
+ $answer = null;
+ $attachments = [];
+ $questionId = $currentQuestion['id'];
+ $questionType = $currentQuestion['question_type'];
+ $questionNumber = $currentQuestion['question_number'];
+ if ($isPrevious){
+ $answerInText = "go_back";
+ }
+
+ if(is_null($answer))
+ {
+ $answer = new QAUserAnswerSelected;
+ }
+ $answer->user_id = $userId;
+ $answer->source_id = $sourceId;
+ $answer->question_id = $questionId;
+ $answer->question_metadata = json_encode($questionMetadata);
+ $answer->answer_option_id = $answerOptionId;
+ $answer->time_used_seconds = $timeUsedSeconds;
+ $answer->is_previous = $isPrevious;
+ if($reference){
+ $answer->reference = $reference;
+ }
+ $answer->save(); //cief todo: why 2 save() in this file, this is wrong
+
+ if($filesUpload){
+ if (isset($filesUpload['filesA']))
+ {
+ foreach ($filesUpload as $key => $files) {
+ if($key === 'filesA'){
+ $attachments[$key] = $this->saveFile($answer, $files, 'questionnaires', DocumentType::ADMIN_WORK_FLOW.'/'.DocumentType::ECOMMERCE_PURCHASE_ORDER_EN);
+ }
+ else if($key === "filesB"){
+ $attachments[$key] = $this->saveFile($answer, $files, 'questionnaires', DocumentType::ADMIN_WORK_FLOW.'/'.DocumentType::ECOMMERCE_PURCHASE_ORDER_CH);
+ }
+ else if($key === "filesC"){
+ $attachments[$key] = $this->saveFile($answer, $files, 'questionnaires', DocumentType::ADMIN_WORK_FLOW.'/'.DocumentType::CURRENCY_VENDOR_PAYMENT_PROOF);
+ }
+ }
+ }
+ else if (isset($filesUpload['files']) && $filesUpload['files'])
+ {
+ $attachments = $this->saveFile($answer, $filesUpload['files']);
+ }
+ }
+
+ if(!$isPrevious) {
+ if($questionType === QAType::SUBMIT_1688_3_TYPES_DOCUMENTS){
+ $structuredAnswer = [
+ 'text' => "3_DOCUMENTS_UPLOADED",
+ 'files' => $attachments,
+ ];
+ $answer->answer = json_encode($structuredAnswer);
+ }
+ else if($questionType === QAType::REMARKS_WITH_DOCUMENT_UPLOAD){
+ $structuredAnswer = [
+ 'text' => $answerInText,
+ 'files' => $attachments,
+ ];
+ $answer->answer = json_encode($structuredAnswer);
+ }
+ else if($questionType === QAType::DOCUMENT_UPLOAD){
+ $structuredAnswer = [
+ 'files' => $attachments,
+ ];
+ $answer->answer = json_encode($structuredAnswer);
+ }
+ else if($questionType === QAType::FLOAT_MONEY){
+ $answer->answer = floatval(str_replace(',', '', $answerInText));
+ }
+ else {
+ $answer->answer = $answerInText;
+
+ if($questionNumber === '1688_underpaid_order_1_proceed' || $questionNumber === '1688_underpaid_order_1'){
+ $answer->answer = $questionMetadata['amount_to_be_deducted'];
+ }
+ }
+ }
+ else {
+ $answer->answer = $answerInText;
+ }
+
+ $answer->save();
+
+ return $answer;
+ }
+
+ private function saveFile(QAUserAnswerSelected $answer, array $files, string $path = 'questionnaires', string $documentType = DocumentType::ADMIN_WORK_FLOW){
+ $result = $this->uploadDocumentForProcessor->execute($answer, $files, $path, $documentType);
+ $attachment = array_map(function ($item) use($documentType) {
+ return [
+ 'name' => $item->document_id,
+ 'file_id' => $item->id,
+ 'document_type'=> $documentType,
+ ];
+ }, $result);
+
+ return $attachment;
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/CreatesQAUserSource.php b/app/Classes/Modules/Questionnaires/Services/CreatesQAUserSource.php
new file mode 100644
index 00000000..2268cf7f
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/CreatesQAUserSource.php
@@ -0,0 +1,26 @@
+system = $object->getSystem();
+ $model->marking = $object->getMarking();
+ $model->email = $object->getEmail();
+
+ return $this->handler($model);
+
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/FetchesQAUserSource.php b/app/Classes/Modules/Questionnaires/Services/FetchesQAUserSource.php
new file mode 100644
index 00000000..c8b467c1
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/FetchesQAUserSource.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/FetchesQuestion.php b/app/Classes/Modules/Questionnaires/Services/FetchesQuestion.php
new file mode 100644
index 00000000..5fe948e5
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/FetchesQuestion.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/FetchesUserAnswerSelected.php b/app/Classes/Modules/Questionnaires/Services/FetchesUserAnswerSelected.php
new file mode 100644
index 00000000..34007879
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/FetchesUserAnswerSelected.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php b/app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php
new file mode 100644
index 00000000..358ab612
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php b/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php
new file mode 100644
index 00000000..fb58304b
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Services/ListsQuestions.php b/app/Classes/Modules/Questionnaires/Services/ListsQuestions.php
new file mode 100644
index 00000000..b736f454
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Services/ListsQuestions.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Questionnaires/Standards/Rules/CanFetchQuestion.php b/app/Classes/Modules/Questionnaires/Standards/Rules/CanFetchQuestion.php
new file mode 100644
index 00000000..65e46e26
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Standards/Rules/CanFetchQuestion.php
@@ -0,0 +1,43 @@
+user()->type;
+ if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function validators($object): bool
+ {
+ return true;
+ }
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ return true;
+ }
+
+}
diff --git a/app/Classes/Modules/Questionnaires/Standards/Rules/CanListQuestions.php b/app/Classes/Modules/Questionnaires/Standards/Rules/CanListQuestions.php
new file mode 100644
index 00000000..7ff92774
--- /dev/null
+++ b/app/Classes/Modules/Questionnaires/Standards/Rules/CanListQuestions.php
@@ -0,0 +1,45 @@
+user()->type;
+ if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function validators($object): bool
+ {
+ return true;
+
+ }
+
+
+ /**
+ * @param $object
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ return true;
+ }
+
+}
diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php
index 46534d77..9e619ee1 100644
--- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php
+++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php
@@ -4,24 +4,10 @@ namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
-use App\Classes\Modules\Companies\Services\FetchesCompany;
-use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus;
-use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
-use App\Classes\Modules\Documents\Services\CreatesDocument;
-use App\Classes\Modules\Documents\Services\CreatesFiles;
-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\CompanyType;
-use App\Classes\ValueObjects\Constants\DocumentType;
-use App\Classes\Jobs\SendUserPaymentProofUploadedEmail;
-use App\Models\Company;
-use App\Models\Document;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-
-use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
-
+use App\Classes\Modules\Transactions\Services\FetchesTransaction;
+use App\Classes\Modules\Transactions\Processors\CreatePaymentProofDocumentProcessor;
class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
{
@@ -39,37 +25,18 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
/** @var FetchesTransaction */
private $fetchesTransaction;
- /** @var CreatesDocument */
- private $createsDocument;
-
- /** @var CreatesFiles */
- private $createsFile;
-
- /** @var UpdatesTransactionStatus */
- private $updatesTransactionStatus;
-
- /** @var CreateInvoiceTransactionProcessor */
- private $createInvoiceTransactionProcessor;
-
- /** @var SendUserPaymentProofUploadedEmail */
- private $sendUserPaymentProofUploadedEmail;
+ /** @var CreatePaymentProofDocumentProcessor */
+ private $createPaymentProofDocumentProcessor;
/**
* CreatePaymentProofDocumentLogic constructor.
+ * @param CreatePaymentProofDocumentProcessor $createPaymentProofDocumentProcessor
* @param FetchesTransaction $fetchesTransaction
- * @param CreatesDocument $createsDocument
- * @param CreatesFiles $createsFile
- * @param UpdatesTransactionStatus $updatesTransactionStatus
- * @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
*/
- public function __construct(FetchesTransaction $fetchesTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesTransactionStatus $updatesTransactionStatus, CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor, SendUserPaymentProofUploadedEmail $sendUserPaymentProofUploadedEmail)
+ public function __construct(CreatePaymentProofDocumentProcessor $createPaymentProofDocumentProcessor, FetchesTransaction $fetchesTransaction)
{
+ $this->createPaymentProofDocumentProcessor = $createPaymentProofDocumentProcessor;
$this->fetchesTransaction = $fetchesTransaction;
- $this->createsDocument = $createsDocument;
- $this->createsFile = $createsFile;
- $this->updatesTransactionStatus = $updatesTransactionStatus;
- $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
- $this->sendUserPaymentProofUploadedEmail = $sendUserPaymentProofUploadedEmail;
}
/**
@@ -79,30 +46,10 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
-
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
-
- $object = new DocumentObject(DocumentType::CURRENCY_VENDOR_PAYMENT_PROOF, $request->input('files'), '', ApprovalStatus::APPROVED, 'china_bank_slip');
-
- /** @var Document $document */
- $document = $this->createsDocument->execute($transaction, $object);
-
- $file = $this->createsFile->execute($document, $object);
-
- $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
-
- $this->createInvoiceTransactionProcessor->execute($transaction->owner->booking);
-
- // send email to customer
- // todo: a function to send a proof to the receipiant, they have to give us a email of the receipiant and also need to submiited purchase order
- $companyEmployee = $transaction->owner->booking->company->employees;
- foreach ($companyEmployee as $employee) {
- if (app()->environment('production') || in_array($employee->email, ['cief.enquirycntr@gmail.com', 'tech.ciefmalaysia@gmail.com'])) {
- $this->sendUserPaymentProofUploadedEmail::dispatch($employee, $transaction->owner->booking, $file[0]);
- }
- }
+ $this->createPaymentProofDocumentProcessor->execute($transaction, $request->input('files'));
return $this->response([]);
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DownloadMockUpWhiteFormPdfLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DownloadMockUpWhiteFormPdfLogic.php
index 4d80785f..7c68536d 100644
--- a/app/Classes/Modules/Transactions/ControllersLogic/DownloadMockUpWhiteFormPdfLogic.php
+++ b/app/Classes/Modules/Transactions/ControllersLogic/DownloadMockUpWhiteFormPdfLogic.php
@@ -48,7 +48,7 @@ class DownloadMockUpWhiteFormPdfLogic
return ['id' => $value];
}, json_decode($request->input('payments')));
- DB::beginTransaction();
+ DB::beginTransaction(); //cief todo: 74
$this->createSupplierTransactionProcessor->execute($supplier, $rate, $payments);
@@ -56,7 +56,7 @@ class DownloadMockUpWhiteFormPdfLogic
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $this->createSupplierTransactionProcessor->getBills(), 'transferFeeTransactions' => $this->createSupplierTransactionProcessor->getTransferTransactions(), 'supplier' => $supplier]);
- DB::rollBack();
+ DB::rollBack(); //cief todo: 74
$exportFileName = 'MockUpWhiteForm.pdf';
$filesystemDriver = Storage::getDefaultDriver();
diff --git a/app/Classes/Modules/Transactions/Processors/CreatePaymentProofDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreatePaymentProofDocumentProcessor.php
new file mode 100644
index 00000000..29dc8e5d
--- /dev/null
+++ b/app/Classes/Modules/Transactions/Processors/CreatePaymentProofDocumentProcessor.php
@@ -0,0 +1,81 @@
+createsDocument = $createsDocument;
+ $this->createsFile = $createsFile;
+ $this->updatesTransactionStatus = $updatesTransactionStatus;
+ $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
+ $this->sendUserPaymentProofUploadedEmail = $sendUserPaymentProofUploadedEmail;
+ }
+
+ /**
+ * @param Transaction $transaction
+ * @param array $files
+ * @return void
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ */
+ public function execute(Transaction $transaction, array $files)
+ {
+ $object = new DocumentObject(DocumentType::CURRENCY_VENDOR_PAYMENT_PROOF, $files, '', ApprovalStatus::APPROVED, 'china_bank_slip');
+
+ /** @var Document $document */
+ $document = $this->createsDocument->execute($transaction, $object);
+
+ $file = $this->createsFile->execute($document, $object);
+
+ $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
+
+ $this->createInvoiceTransactionProcessor->execute($transaction->owner->booking);
+
+ // send email to customer
+ // todo: a function to send a proof to the receipiant, they have to give us a email of the receipiant and also need to submiited purchase order
+ $companyEmployee = $transaction->owner->booking->company->employees;
+ foreach ($companyEmployee as $employee) {
+ if (app()->environment('production') || in_array($employee->email, ['cief.enquirycntr@gmail.com', 'tech.ciefmalaysia@gmail.com'])) {
+ $this->sendUserPaymentProofUploadedEmail::dispatch($employee, $transaction->owner->booking, $file[0]);
+ }
+ }
+ }
+
+}
diff --git a/app/Classes/ValueObjects/Constants/DocumentType.php b/app/Classes/ValueObjects/Constants/DocumentType.php
index 42f8222b..f2fe0b09 100644
--- a/app/Classes/ValueObjects/Constants/DocumentType.php
+++ b/app/Classes/ValueObjects/Constants/DocumentType.php
@@ -2,6 +2,7 @@
namespace App\Classes\ValueObjects\Constants;
+
final class DocumentType {
public const PROFILE_PICTURE = 'PROFILE_PICTURE';
@@ -27,4 +28,8 @@ final class DocumentType {
public const BULK_PURCHASE_ORDER = 'BULK_PURCHASE_ORDER';
public const BILL_GROUP_PAYMENT_PROOF = 'BILL_GROUP_PAYMENT_PROOF';
+
+ public const ADMIN_WORK_FLOW = 'ADMIN_WORK_FLOW';
+ public const ECOMMERCE_PURCHASE_ORDER_EN = 'ECOMMERCE_PURCHASE_ORDER_EN';
+ public const ECOMMERCE_PURCHASE_ORDER_CH = 'ECOMMERCE_PURCHASE_ORDER_CH';
}
diff --git a/app/Classes/ValueObjects/Constants/QAType.php b/app/Classes/ValueObjects/Constants/QAType.php
new file mode 100644
index 00000000..43f5b7c5
--- /dev/null
+++ b/app/Classes/ValueObjects/Constants/QAType.php
@@ -0,0 +1,27 @@
+ '1688', 'id' => QuestionGroup::_1688],
+ // ['text' => 'approve_po', 'id' => QuestionGroup::APPROVE_PO],
+ // ['text' => 'fill_po', 'id' => QuestionGroup::FILL_PO],
+ // ];
+
+ // const QUESTION_GROUPS = [
+ // QuestionGroup::_1688,
+ // QuestionGroup::APPROVE_PO,
+ // QuestionGroup::FILL_PO,
+ // ];
+}
diff --git a/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php b/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php
new file mode 100644
index 00000000..92262915
--- /dev/null
+++ b/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php
@@ -0,0 +1,33 @@
+execute($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param ExportQAWithoutGroupsLogic $logic
+ * @return BinaryFileResponse
+ * @return JsonResponse
+ */
+ public function exportWithoutGroups(Request $request, ExportQAWithoutGroupsLogic $logic) {
+ return $logic->execute($request);
+ }
+}
diff --git a/app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php b/app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php
new file mode 100644
index 00000000..c94cbe6b
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php
@@ -0,0 +1,50 @@
+execute($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param FetchAdminWFModelAttributesLogic $logic
+ * @return JsonResponse
+ */
+ public function fetchModelAttributes(Request $request, FetchAdminWFModelAttributesLogic $logic): JsonResponse {
+ return $logic->execute($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param FetchAdminWFPendingApprovalPOLogic $logic
+ * @return JsonResponse
+ */
+ public function fetchPendingApprovalPO(Request $request, FetchAdminWFPendingApprovalPOLogic $logic): JsonResponse {
+ return $logic->execute($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param FetchAdminWFPendingFillPOLogic $logic
+ * @return JsonResponse
+ */
+ public function fetchPendingFillPO(Request $request, FetchAdminWFPendingFillPOLogic $logic): JsonResponse {
+ return $logic->execute($request);
+ }
+}
diff --git a/app/Http/Controllers/Questionnaires/FetchQuestionV1AdminWFController.php b/app/Http/Controllers/Questionnaires/FetchQuestionV1AdminWFController.php
new file mode 100644
index 00000000..2e047aca
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/FetchQuestionV1AdminWFController.php
@@ -0,0 +1,21 @@
+execute($request);
+ }
+
+}
diff --git a/app/Http/Controllers/Questionnaires/ListQuestionnaireSetController.php b/app/Http/Controllers/Questionnaires/ListQuestionnaireSetController.php
new file mode 100644
index 00000000..8fac21a0
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/ListQuestionnaireSetController.php
@@ -0,0 +1,21 @@
+execute($request);
+ }
+
+}
diff --git a/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php b/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php
new file mode 100644
index 00000000..091eba5e
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php
@@ -0,0 +1,21 @@
+execute($request);
+ }
+
+}
diff --git a/app/Http/Controllers/Questionnaires/ListQuestionsController.php b/app/Http/Controllers/Questionnaires/ListQuestionsController.php
new file mode 100644
index 00000000..3fc4d75f
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/ListQuestionsController.php
@@ -0,0 +1,21 @@
+execute($request);
+ }
+
+}
diff --git a/app/Http/Controllers/Questionnaires/UpdateNextQuestionV1AdminWFController.php b/app/Http/Controllers/Questionnaires/UpdateNextQuestionV1AdminWFController.php
new file mode 100644
index 00000000..87ed672b
--- /dev/null
+++ b/app/Http/Controllers/Questionnaires/UpdateNextQuestionV1AdminWFController.php
@@ -0,0 +1,31 @@
+question;
+ // $questionnaireSetId = $currentQuestion['questionnaire_set_id'];
+ // $questionnaireSet = QAQuestionnaireSet::where('id', $questionnaireSetId)->first();
+ // $group = '';
+ // $version = 0;
+ // if($questionnaireSet){
+ // $group = $questionnaireSet->group;
+ // $version = $questionnaireSet->version;
+ // }
+ return $logic->execute($request);
+ }
+}
diff --git a/app/Http/Resources/AnswerOptionsResource.php b/app/Http/Resources/AnswerOptionsResource.php
new file mode 100644
index 00000000..6c168847
--- /dev/null
+++ b/app/Http/Resources/AnswerOptionsResource.php
@@ -0,0 +1,27 @@
+ $this->id,
+ 'display_text' => $this->display_text,
+ 'value' => $this->value,
+ 'order' => $this->order,
+ 'question_number' => $this->question_number,
+ 'next_question_number' => $this->next_question_number,
+ ];
+ }
+}
diff --git a/app/Http/Resources/BookingBaseResource.php b/app/Http/Resources/BookingBaseResource.php
new file mode 100644
index 00000000..960be05e
--- /dev/null
+++ b/app/Http/Resources/BookingBaseResource.php
@@ -0,0 +1,61 @@
+ $this->id,
+ 'company' => new CompanyResource($this->company),
+ 'bank' => new BankResource($this->bank),
+ 'service' => new ServiceTypeResource($this->service),
+ 'marking' => $this->marking,
+ // 'amount' => $this->fix_amount,
+ // 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
+ 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
+ // 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)),
+ 'fixed_currency' => new CurrencyResource($this->fixedCurrency),
+ 'order_reference_no' => $this->modelAttributes()->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)->get()->map(function ($attr) {
+ return [
+ 'id' => $attr->id,
+ 'value' => $attr->value
+ ];
+ }),
+ 'status' => $this->status,
+ 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
+ $this->mergeWhen($this->relationLoaded('transactions'), [
+ 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
+ $query->where(function($query){
+ $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED, ApprovalStatus::REFUNDED]);
+ })->orWhere(function($query){
+ $query->where(function($query){
+ $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
+ })->orWhere(function($query){
+ $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ });
+ });
+ })->latest()->get())
+ ])
+ ];
+ }
+}
diff --git a/app/Http/Resources/QuestionResource.php b/app/Http/Resources/QuestionResource.php
new file mode 100644
index 00000000..e2ad946c
--- /dev/null
+++ b/app/Http/Resources/QuestionResource.php
@@ -0,0 +1,77 @@
+question = $question;
+ $this->userId = $userId;
+ $this->isPrevious = $isPrevious;
+ $this->isNoGoingBack = $isNoGoingBack;
+ $this->previousAnswer = $previousAnswer;
+ $this->questionMetadata = $questionMetadata;
+ }
+ /**
+ * Transform the resource into an array.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return array
+ */
+ public function toArray($request)
+ {
+ if($this->question){
+ $q = (object)$this->question;
+ return [
+ 'id' => $q->id,
+ 'question_number' => $q->question_number,
+ 'question_title' => $q->question_title,
+ 'question_description' => $q->question_description,
+ 'question_type' => $q->question_type,
+ 'question_answers' => AnswerOptionsResource::collection(QAAnswerOptions::where('question_number', $q->question_number)->where('questionnaire_set_id', $q->questionnaire_set_id)->orderBy('order', 'ASC')->get()),
+ 'questionnaire_set_id' => $q->questionnaire_set_id,
+ 'question_metadata'=> $this->questionMetadata,
+ // 'questionnaire' => new QuestionnaireSetsResource($q->questionnaire),
+ // 'questionnaire_answers' => $q->is_end ? QuestionnaireAnswersResource::collection(QAUserAnswerSelected::where('user_id', $this->userId)->get()) : null,
+ 'next_nested_question' => $q->next_nested_question,
+ 'next_main_question' => $q->next_main_question,
+ 'is_start' => $q->is_start,
+ 'is_end' => $q->is_end,
+ 'end_text' => $q->end_text,
+ 'order' => $q->order,
+ 'answer' => $this->previousAnswer,
+ 'url' => $q->url,
+ 'is_no_going_back' => $this->isNoGoingBack,
+ 'is_previous' => $this->isPrevious,
+ ];
+ }
+ else{
+ return [];
+ }
+ }
+}
diff --git a/app/Http/Resources/QuestionnaireAnswersResource.php b/app/Http/Resources/QuestionnaireAnswersResource.php
new file mode 100644
index 00000000..1deda19d
--- /dev/null
+++ b/app/Http/Resources/QuestionnaireAnswersResource.php
@@ -0,0 +1,25 @@
+question_id)->first();
+ return [
+ 'question_title' => $question ? $question->question_title : null,
+ 'answer' => $this->answer
+ ];
+ }
+}
diff --git a/app/Http/Resources/QuestionnaireSetsResource.php b/app/Http/Resources/QuestionnaireSetsResource.php
new file mode 100644
index 00000000..0865de6d
--- /dev/null
+++ b/app/Http/Resources/QuestionnaireSetsResource.php
@@ -0,0 +1,26 @@
+ $this->id,
+ 'name' => $this->name,
+ 'description' => $this->description,
+ 'group' => explode(',', $this->group),
+ 'version' => $this->version,
+ ];
+ }
+}
diff --git a/app/Http/Resources/QuestionsAnswersResource.php b/app/Http/Resources/QuestionsAnswersResource.php
new file mode 100644
index 00000000..b3ff2974
--- /dev/null
+++ b/app/Http/Resources/QuestionsAnswersResource.php
@@ -0,0 +1,50 @@
+question_id)->first();
+ $source = new UserSourceResource($this->userSource);
+ $user = $this->source_id === 0 ? new UserResource($this->user) : null;
+ $answerOption = QAAnswerOptions::where('id', $this->answer_option_id)->first();
+ $questionGroups = explode(',', $this->question->questionnaire->group);
+ $user_marking = '';
+
+ return [
+ 'id' => $this->id,
+ 'question_id' => $this->question_id,
+ 'question_groups' => $questionGroups,
+ 'questionnaire' => new QuestionnaireSetsResource($this->question->questionnaire),
+ 'question_title' => $question ? $question->question_title : null,
+ 'question_type' => $question ? $question->question_type : 0,
+ 'question_metadata' => $this->question_metadata,
+ 'answer' => $answerOption ? $answerOption->display_text : null,
+ 'answer_value' => $this->answer,
+ 'documentsList' => DocumentResource::collection($this->documents),
+ 'documents' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::ADMIN_WORK_FLOW)->first()),
+ 'reference' => $this->reference,
+ 'source_system' => null,
+ 'source_marking' => $user ? $user_marking : $source->marking,
+ 'source_email' => $user ? $user->email : $source->email,
+ 'time' => $this->time_used_seconds,
+ 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
+ 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
+ ];
+ }
+}
diff --git a/app/Http/Resources/UserSourceResource.php b/app/Http/Resources/UserSourceResource.php
new file mode 100644
index 00000000..f39fbdfe
--- /dev/null
+++ b/app/Http/Resources/UserSourceResource.php
@@ -0,0 +1,24 @@
+ $this->system,
+ 'email' => $this->email,
+ 'marking' => $this->marking,
+ ];
+ }
+}
diff --git a/app/Models/Booking.php b/app/Models/Booking.php
index 259ca01e..83b724a6 100644
--- a/app/Models/Booking.php
+++ b/app/Models/Booking.php
@@ -2,11 +2,13 @@
namespace App\Models;
+
use App\Classes\General\Interfaces\Documentable;
use App\Classes\General\Interfaces\Transactionable;
use App\Classes\General\Interfaces\Voucherifiable;
use App\Classes\General\Traits\LogData;
use App\Classes\ValueObjects\Constants\RoleTypes;
+use App\Classes\General\Interfaces\KeyValueInterface;
use App\Scopes\CustomerBookingsScope;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
@@ -26,7 +28,7 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships;
* @property int convertible_currency_id
* @property int conversion_currency_id
*/
-class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable
+class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable, KeyValueInterface
{
use HasRelationships;
use SoftDeletes;
@@ -130,4 +132,11 @@ class Booking extends AbstractModel implements Documentable, Transactionable, Vo
return $this->morphMany(VoucherEntityMapping::class, 'owner');
}
+ /**
+ * @return MorphMany
+ */
+ public function attributesKVP(): MorphMany
+ {
+ return $this->morphMany(KeyValuePair::class, 'owner');
+ }
}
diff --git a/app/Models/QAAnswerOptions.php b/app/Models/QAAnswerOptions.php
new file mode 100644
index 00000000..cd2eca79
--- /dev/null
+++ b/app/Models/QAAnswerOptions.php
@@ -0,0 +1,9 @@
+BelongsTo(QAQuestionnaireSet::class, 'questionnaire_set_id', 'id');
+ }
+
+ /**
+ * @return HasMany
+ */
+ public function userAnswers()
+ {
+ return $this->hasMany(QAUserAnswerSelected::class, 'question_id', 'id');
+ }
+}
diff --git a/app/Models/QAUserAnswerSelected.php b/app/Models/QAUserAnswerSelected.php
new file mode 100644
index 00000000..56515d31
--- /dev/null
+++ b/app/Models/QAUserAnswerSelected.php
@@ -0,0 +1,71 @@
+morphMany(Document::class, 'owner');
+ }
+
+ /**
+ * @return BelongsTo
+ */
+ public function userSource(): BelongsTo
+ {
+ return $this->BelongsTo(QAUserSource::class, 'source_id', 'id');
+ }
+
+ /**
+ * @return BelongsTo
+ */
+ public function user(): BelongsTo
+ {
+ return $this->BelongsTo(User::class, 'user_id', 'id');
+ }
+
+ /**
+ * @return BelongsTo
+ */
+ public function question(): BelongsTo
+ {
+ return $this->BelongsTo(QAQuestions::class, 'question_id', 'id');
+ }
+
+
+ /**
+ * @return BelongsTo
+ */
+ public function answer(): BelongsTo
+ {
+ return $this->BelongsTo(QAAnswerOptions::class, 'answer_option_id', 'id');
+ }
+
+ /**
+ * @return MorphMany
+ */
+ public function attributesKVP(): MorphMany
+ {
+ return $this->morphMany(KeyValuePair::class, 'owner');
+ }
+
+}
diff --git a/app/Models/QAUserSource.php b/app/Models/QAUserSource.php
new file mode 100644
index 00000000..21401df5
--- /dev/null
+++ b/app/Models/QAUserSource.php
@@ -0,0 +1,9 @@
+id();
+ $table->string('name');
+ $table->string('description')->nullable();
+ $table->string('group')->nullable();
+ $table->unsignedBigInteger('order')->default(0);
+ $table->unsignedBigInteger('next_set')->nullable();
+ $table->unsignedBigInteger('version')->default(1);
+ $table->timestamps();
+ $table->softDeletes();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('qa_questionnaire_sets');
+ }
+}
diff --git a/database/migrations/2024_11_26_015531_create_qa_questions_table.php b/database/migrations/2024_11_26_015531_create_qa_questions_table.php
new file mode 100644
index 00000000..c6811f4e
--- /dev/null
+++ b/database/migrations/2024_11_26_015531_create_qa_questions_table.php
@@ -0,0 +1,47 @@
+id();
+ $table->string('question_number');
+ $table->text('question_title');
+ $table->text('question_description')->nullable();
+ $table->unsignedBigInteger('questionnaire_set_id');
+ $table->string('next_nested_question')->nullable();
+ $table->string('next_main_question')->nullable();
+ $table->unsignedBigInteger('question_type');
+ $table->tinyInteger('is_start');
+ $table->tinyInteger('is_end');
+ $table->string('end_text')->nullable();
+ $table->unsignedBigInteger('order')->default(0);
+ $table->string('url')->nullable();
+ $table->timestamps();
+ $table->softDeletes();
+
+ $table->foreign('questionnaire_set_id')->references('id')->on('qa_questionnaire_sets');
+
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('qa_questions');
+ }
+}
diff --git a/database/migrations/2024_11_26_025531_change_value_column_to_text_in_key_value_pairs_table.php b/database/migrations/2024_11_26_025531_change_value_column_to_text_in_key_value_pairs_table.php
new file mode 100644
index 00000000..b7fe759e
--- /dev/null
+++ b/database/migrations/2024_11_26_025531_change_value_column_to_text_in_key_value_pairs_table.php
@@ -0,0 +1,32 @@
+text('value')->change();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('key_value_pairs', function (Blueprint $table) {
+ $table->string('value', 191)->change();
+ });
+ }
+}
diff --git a/database/migrations/2024_11_26_025531_create_qa_answer_options_table.php b/database/migrations/2024_11_26_025531_create_qa_answer_options_table.php
new file mode 100644
index 00000000..9198768a
--- /dev/null
+++ b/database/migrations/2024_11_26_025531_create_qa_answer_options_table.php
@@ -0,0 +1,41 @@
+id();
+ $table->text('display_text');
+ $table->string('value');
+ $table->unsignedBigInteger('order')->default(0);
+ $table->string('question_number');
+ $table->string('next_question_number')->nullable();
+ $table->unsignedBigInteger('questionnaire_set_id');
+ $table->timestamps();
+ $table->softDeletes();
+
+ $table->foreign('questionnaire_set_id')->references('id')->on('qa_questionnaire_sets');
+
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('qa_answer_options');
+ }
+}
diff --git a/database/migrations/2024_11_26_025531_create_qa_user_answer_selected_table.php b/database/migrations/2024_11_26_025531_create_qa_user_answer_selected_table.php
new file mode 100644
index 00000000..a7ce3977
--- /dev/null
+++ b/database/migrations/2024_11_26_025531_create_qa_user_answer_selected_table.php
@@ -0,0 +1,46 @@
+id();
+ $table->unsignedBigInteger('user_id')->default(0);
+ $table->unsignedBigInteger('source_id')->default(0);
+ $table->unsignedBigInteger('question_id');
+ $table->longText('question_metadata')->nullable();
+ $table->unsignedBigInteger('answer_option_id');
+ $table->text('answer')->nullable();
+ $table->string('reference')->nullable();
+ $table->integer('time_used_seconds')->nullable();
+ $table->tinyInteger('is_previous')->default(0);
+ $table->timestamps();
+ $table->softDeletes();
+
+ $table->foreign('question_id')->references('id')->on('qa_questions');
+ // $table->foreign('answer_option_id')->references('id')->on('qa_answer_options');
+ // $table->foreign('user_id')->references('id')->on('users');
+ // $table->foreign('source_id')->references('id')->on('qa_user_source');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('qa_user_answer_selected');
+ }
+}
diff --git a/database/migrations/2024_11_26_025531_create_qa_user_source_table.php b/database/migrations/2024_11_26_025531_create_qa_user_source_table.php
new file mode 100644
index 00000000..638a8d44
--- /dev/null
+++ b/database/migrations/2024_11_26_025531_create_qa_user_source_table.php
@@ -0,0 +1,34 @@
+id();
+ $table->string('system');
+ $table->string('email');
+ $table->string('marking');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('qa_user_source');
+ }
+}
diff --git a/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php b/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php
new file mode 100644
index 00000000..372874ab
--- /dev/null
+++ b/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php
@@ -0,0 +1,32 @@
+string('group')->after('questionnaire_set_id')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('qa_questions', function (Blueprint $table) {
+ $table->dropColumn('group');
+ });
+ }
+}
diff --git a/database/migrations/2025_02_17_105441_add_is_admin_filter_to_qa_questions_table.php b/database/migrations/2025_02_17_105441_add_is_admin_filter_to_qa_questions_table.php
new file mode 100644
index 00000000..b16fb12c
--- /dev/null
+++ b/database/migrations/2025_02_17_105441_add_is_admin_filter_to_qa_questions_table.php
@@ -0,0 +1,32 @@
+boolean('is_admin_filter')->after('url')->default(false);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('qa_questions', function (Blueprint $table) {
+ $table->dropColumn('is_admin_filter');
+ });
+ }
+}
diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php
index eb94b74f..a12bc52d 100644
--- a/database/seeds/DatabaseSeeder.php
+++ b/database/seeds/DatabaseSeeder.php
@@ -5,6 +5,7 @@ use Database\Seeders\CompaniesTableDevelopmentSeeder;
use Database\Seeders\CurrenciesTableDevelopmentSeeder;
use Database\Seeders\CurrencyRatesTableDevelopmentSeeder;
use Database\Seeders\DummyDataSeeder;
+use Database\Seeders\QAWorkFlowSeeder;
use Database\Seeders\SegmentConstantsTableDevelopmentSeeder;
use Database\Seeders\SegmentsTableDevelopmentSeeder;
use Database\Seeders\ServiceTypesTableDevelopmentSeeder;
@@ -20,7 +21,7 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
- DB::beginTransaction();
+ DB::beginTransaction();
//General
$this->call(CountriesTableSeeder::class);
@@ -48,6 +49,9 @@ class DatabaseSeeder extends Seeder
$this->call(DummyDataSeeder::class);
}
+ // Admin Work Flow
+ $this->call(QAWorkFlowSeeder::class);
+
// DB::commit();
}
}
diff --git a/database/seeds/QAWorkFlowSeeder.php b/database/seeds/QAWorkFlowSeeder.php
new file mode 100644
index 00000000..bc875b5a
--- /dev/null
+++ b/database/seeds/QAWorkFlowSeeder.php
@@ -0,0 +1,776 @@
+ 'Admin Work Flow',
+ 'description' => 'Admin Work Flow',
+ 'group' => '1688,approve_po,fill_po',
+ 'version' => 1,
+ 'questions' => [
+ [
+ 'question_number' => 'node_0',
+ 'question_title' => 'Are you ready to work today?',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => true,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Yes', 'value' => 'start_work', 'next_question_number' => 'start_work'],
+ ['display_text' => 'No', 'value' => 'no_work', 'next_question_number' => 'no_work'],
+ ],
+ 'group' => '',
+ ],
+ [
+ 'question_number' => 'start_work',
+ 'question_title' => 'What will you work on?',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => '1688', 'value' => '1688', 'next_question_number' => '1688'],
+ ['display_text' => 'Approve PO', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ['display_text' => 'Fill PO', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ],
+ 'group' => '',
+ ],
+ [
+ 'question_number' => 'no_work',
+ 'question_title' => 'Come back when you are ready to work',
+ 'question_type' => QAType::DEFAULT,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'group' => '',
+ ],
+ [
+ 'question_number' => '1688',
+ 'question_title' => '1688',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'url' => 'api.admin_work_flow.fetch_oldest_order', //'http://localhost:8082/api/v1/admin-work-flow/fetch-oldest-order', //this.route("api.admin_work_flow.fetch_oldest_order"),
+ 'is_start' => true,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Login Issue', 'value' => '1688_login_issue', 'btn_color' => 'warning', 'next_question_number' => '1688_login_issue'],
+ ['display_text' => 'Login Successful', 'value' => '1688_login_successful', 'next_question_number' => '1688_login_successful'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_login_issue',
+ 'question_title' => '1688_login_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Need TAC', 'value' => '1688_login_issue_need_tac', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Wrong login details', 'value' => '1688_login_issue_wrong_login_details', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Others', 'value' => '1688_login_issue_others', 'next_question_number' => '1688_login_issue_others'],
+ ['display_text' => 'Order Cancelled', 'value' => '1688_login_issue_refund_request', 'next_question_number' => '1688_login_issue_refund_request'],
+ ],
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_login_successful',
+ 'question_title' => '1688_login_successful',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ //'url' => 'api.admin_work_flow.fetch_model_attributes', //'http://localhost:8082/api/v1/admin-work-flow/{booking_id}/fetch-model-attributes',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => "Can't verify order?", 'value' => '1688_login_successful_cannot_verify', 'next_question_number' => '1688_login_successful_cannot_verify'],
+ ['display_text' => 'Order Verified', 'value' => '1688_order_verify', 'next_question_number' => '1688_order_verify'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_login_successful_cannot_verify',
+ 'question_title' => '1688_login_successful_cannot_verify',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Amount not found', 'value' => '1688_login_successful_cannot_verify_amount_not_found', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Plus Member', 'value' => '1688_login_successful_cannot_verify_plus_member', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Others', 'value' => '1688_login_successful_cannot_verify_others', 'next_question_number' => '1688_login_successful_cannot_verify_others'],
+ ['display_text' => 'Customer did not verify 1688 account', 'value' => '1688_login_successful_cannot_verify_customer_did_not_verify_account', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'WorldFirst account linked another account', 'value' => '1688_login_successful_cannot_verify_worldfirst_account_linked_another_account', 'next_question_number' => '1688_issue_submit'],
+ ],
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_login_successful_cannot_verify_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => '1688_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_order_verify',
+ 'question_title' => 'Order Amount (CNY)',
+ 'question_description' => 'Please key in the order amount',
+ 'question_' => 'Order Amount',
+ 'question_type' => QAType::FLOAT_MONEY,
+ 'next_nested_question' => '1688_order_verification',
+ //'url' => 'api.admin_work_flow.fetch_model_attributes',
+ 'is_start' => false,
+ 'is_end' => false,
+ // 'answer_options' => [
+ // ['display_text' => 'Yes', 'value' => '1688_order_verification', 'next_question_number' => '1688_order_verification'],
+ // ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_order_verification',
+ 'question_title' => 'Are You Sure this is the correct amount?',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Yes', 'value' => '1688_order_verified', 'next_question_number' => '1688_order_verified'],
+ ['display_text' => 'No', 'value' => '1688_order_verified', 'next_question_number' => '1688_order_verified'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_proceed_order',
+ 'question_title' => 'Proceed the order on 1688?',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Yes', 'value' => '1688_submit', 'next_question_number' => '1688_submit'],
+ ['display_text' => 'Got Issue', 'value' => '1688_proceed_order_issue', 'next_question_number' => '1688_proceed_order_issue'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_proceed_order_issue',
+ 'question_title' => '1688_proceed_order_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Wrong Pin Number', 'value' => '1688_proceed_order_issue_wrong_pin_number', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Not Enough Stock', 'value' => '1688_proceed_order_issue_not_enough_stock', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'Others', 'value' => '1688_proceed_order_issue_others', 'next_question_number' => '1688_proceed_order_issue_others'],
+ ['display_text' => 'No CrossBoarder', 'value' => '1688_proceed_order_issue_no_crossborder', 'next_question_number' => '1688_issue_submit'],
+ ['display_text' => 'AngPau', 'value' => '1688_proceed_order_issue_angpau', 'next_question_number' => '1688_issue_submit'],
+ ],
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_proceed_order_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => '1688_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_login_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => '1688_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_submit',
+ 'question_title' => '1688_submit',
+ 'question_type' => QAType::SUBMIT_1688_3_TYPES_DOCUMENTS,
+ 'next_nested_question' => '1688_documents_submitted',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_documents_submitted',
+ 'question_title' => 'Thank you for the hard work',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_login_issue_refund_request',
+ 'question_title' => 'Refund Request sent',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ // [
+ // 'question_number' => '1688_insufficient_order',
+ // 'question_title' => 'Are You Sure this is the correct amount?',
+ // 'question_type' => QAType::MULTIPLE_CHOICES,
+ // 'is_start' => false,
+ // 'is_end' => false,
+ // 'answer_options' => [
+ // ['display_text' => 'Underpaid Order', 'value' => 'underpaid_order_1', 'next_question_number' => '1688_issue_submit'],
+ // ['display_text' => 'Underpaid Order', 'value' => 'underpaid_order_2', 'next_question_number' => '1688_issue_submit'],
+ // ['display_text' => 'Overpaid Order', 'value' => 'underpaid_order_2', 'next_question_number' => '1688_issue_submit'],
+ // ],
+ // 'group' => '1688',
+ // ],
+ // [
+ // 'question_number' => '1688_order_paid_precisely',
+ // 'question_title' => 'Amount paid is same as recorded in system',
+ // 'question_type' => QAType::MULTIPLE_CHOICES,
+ // 'is_start' => false,
+ // 'is_end' => false,
+ // 'answer_options' => [
+ // ['display_text' => 'Done', 'value' => '1688_issue_submit', 'next_question_number' => '1688_issue_submit'],
+ // ],
+ // 'group' => '1688',
+ // ],
+ [
+ 'question_number' => '1688_underpaid_order_1',
+ 'question_title' => "This order is underpaid. Clicking 'Next' will deduct the amount short from wallet automatically. ",
+ 'question_type' => QAType::DEFAULT,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'next_nested_question' => '1688_underpaid_order_1_proceed',
+ // 'answer_options' => [
+ // ['display_text' => 'Proceed', 'value' => '1688_underpaid_order_1_proceed', 'next_question_number' => '1688_underpaid_order_1_proceed'],
+ // ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_order_1_proceed',
+ 'question_title' => "The missing amount has successfully been deducted from the customer’s wallet",
+ 'question_type' => QAType::DEFAULT,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'next_nested_question' => '1688_underpaid_proceed_order',
+ // 'answer_options' => [
+ // ['display_text' => 'Done', 'value' => '1688_issue_submit', 'next_question_number' => '1688_issue_submit'],
+ // ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_order_2',
+ 'question_title' => 'Underpaid Order',
+ 'question_description' => 'Insufficient wallet balance. Refund request to be sent',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Done', 'value' => '1688_underpaid_order_2_submitted', 'next_question_number' => '1688_underpaid_order_2_submitted'],
+ ],
+ 'group' => '1688',
+ ],
+ // [
+ // 'question_number' => '1688_underpaid_order_3',
+ // 'question_title' => 'Underpaid Order?',
+ // 'question_description' => 'There is no outstanding on record, please go back and check if the amount processed is entered correctly.',
+ // 'question_type' => QAType::MULTIPLE_CHOICES,
+ // 'is_start' => false,
+ // 'is_end' => false,
+ // 'answer_options' => [
+ // ['display_text' => 'Done', 'value' => '1688_issue_submit', 'next_question_number' => '1688_issue_submit'],
+ // ],
+ // 'group' => '1688',
+ // ],
+ [
+ 'question_number' => '1688_overpaid_order',
+ 'question_title' => 'Overpaid Order',
+ 'question_description' => 'Exceeded amount to be refunded to customer’s wallet',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Next', 'value' => '1688_overpaid_proceed_order', 'next_question_number' => '1688_overpaid_proceed_order'],
+ ],
+ 'group' => '1688',
+ ],
+
+ // 1688 underpaid - starts
+ [
+ 'question_number' => '1688_underpaid_proceed_order',
+ 'question_title' => 'Please process the order on 1688',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Yes', 'value' => '1688_underpaid_documents_submission', 'next_question_number' => '1688_underpaid_documents_submission'],
+ ['display_text' => 'Got Issue', 'value' => '1688_underpaid_proceed_order_issue', 'next_question_number' => '1688_underpaid_proceed_order_issue'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_proceed_order_issue',
+ 'question_title' => '1688_underpaid_proceed_order_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Wrong Pin Number', 'value' => '1688_underpaid_proceed_order_issue_wrong_pin_number', 'next_question_number' => '1688_underpaid_issue_submit'],
+ ['display_text' => 'Not Enough Stock', 'value' => '1688_underpaid_proceed_order_issue_not_enough_stock', 'next_question_number' => '1688_underpaid_issue_submit'],
+ ['display_text' => 'Others', 'value' => '1688_underpaid_proceed_order_issue_others', 'next_question_number' => '1688_underpaid_proceed_order_issue_others'],
+ ['display_text' => 'No CrossBoarder', 'value' => '1688_underpaid_proceed_order_issue_no_crossborder', 'next_question_number' => '1688_underpaid_issue_submit'],
+ ['display_text' => 'AngPau', 'value' => '1688_underpaid_proceed_order_issue_angpau', 'next_question_number' => '1688_underpaid_issue_submit'],
+ ],
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_underpaid_proceed_order_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => '1688_underpaid_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_underpaid_documents_submission',
+ 'question_title' => '1688_underpaid_documents_submission',
+ 'question_type' => QAType::SUBMIT_1688_3_TYPES_DOCUMENTS,
+ 'next_nested_question' => '1688_underpaid_documents_submitted',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_documents_submitted',
+ 'question_title' => 'Thank you for your hard work',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_underpaid_order_2_submitted',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ // 1688 underpaid - ends
+ // 1688 overpaid - starts
+ [
+ 'question_number' => '1688_overpaid_proceed_order',
+ 'question_title' => 'Please process the order on 1688',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Yes', 'value' => '1688_overpaid_documents_submission', 'next_question_number' => '1688_overpaid_documents_submission'],
+ ['display_text' => 'Got Issue', 'value' => '1688_overpaid_proceed_order_issue', 'next_question_number' => '1688_overpaid_proceed_order_issue'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_overpaid_proceed_order_issue',
+ 'question_title' => '1688_overpaid_proceed_order_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Wrong Pin Number', 'value' => '1688_overpaid_proceed_order_issue_wrong_pin_number', 'next_question_number' => '1688_overpaid_issue_submit'],
+ ['display_text' => 'Not Enough Stock', 'value' => '1688_overpaid_proceed_order_issue_not_enough_stock', 'next_question_number' => '1688_overpaid_issue_submit'],
+ ['display_text' => 'Others', 'value' => '1688_overpaid_proceed_order_issue_others', 'next_question_number' => '1688_overpaid_proceed_order_issue_others'],
+ ['display_text' => 'No CrossBoarder', 'value' => '1688_overpaid_proceed_order_issue_no_crossborder', 'next_question_number' => '1688_overpaid_issue_submit'],
+ ['display_text' => 'AngPau', 'value' => '1688_overpaid_proceed_order_issue_angpau', 'next_question_number' => '1688_overpaid_issue_submit'],
+ ],
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_overpaid_proceed_order_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => '1688_overpaid_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => '1688_overpaid_documents_submission',
+ 'question_title' => '1688_overpaid_documents_submission',
+ 'question_type' => QAType::SUBMIT_1688_3_TYPES_DOCUMENTS,
+ 'next_nested_question' => '1688_overpaid_documents_submitted',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_overpaid_documents_submitted',
+ 'question_title' => 'Thank you for your hard work',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ [
+ 'question_number' => '1688_overpaid_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'],
+ ],
+ 'group' => '1688',
+ ],
+ // 1688 overpaid - ends
+
+ [
+ 'question_number' => 'approve_po',
+ 'question_title' => 'approve_po',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'url' => "api.admin_work_flow.fetch_pending_approve_po",
+ 'is_start' => true,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Approve', 'value' => 'approve_po_approved', 'next_question_number' => 'approve_po_approved'],
+ ['display_text' => 'Edit PO', 'value' => 'approve_po_edit', 'next_question_number' => 'approve_po_edit'],
+ ['display_text' => 'Reject', 'value' => 'approve_po_reject', 'next_question_number' => 'approve_po_reject'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'fill_po',
+ 'question_title' => 'fill_po',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'url' => "api.admin_work_flow.fetch_pending_fill_po",
+ 'is_start' => true,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Edit PO', 'value' => 'fill_po_edit', 'next_question_number' => 'fill_po_edit'],
+ ],
+ 'group' => 'fill_po',
+ ],
+ [
+ 'question_number' => 'approve_po_filled',
+ 'question_title' => 'PO Filled',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'approve_po_approved',
+ 'question_title' => 'PO Approved',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'approve_po_edit',
+ 'question_title' => 'approve_po_edit',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'url' => "api.booking.show",
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Issue?', 'value' => 'approve_po_edit_po_issue', 'next_question_number' => 'approve_po_edit_po_issue'],
+ ['display_text' => 'Done', 'value' => 'approve_po_filled', 'next_question_number' => 'approve_po_filled'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'approve_po_reject',
+ 'question_title' => 'PO Rejected',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Sensitive Goods', 'value' => 'Sensitive Goods', 'next_question_number' => 'approve_po_reject_others_complete'],
+ ['display_text' => 'Others', 'value' => 'approve_po_reject_others', 'next_question_number' => 'approve_po_reject_others'],
+ // ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ // ['display_text' => 'Next Order', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'approve_po_reject_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => 'approve_po_reject_others_complete',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => 'approve_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'approve_po_reject_others_complete',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'approve_po_edit_po_issue',
+ 'question_title' => 'approve_po_edit_po_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Sensitive Goods', 'value' => 'Sensitive Goods', 'next_question_number' => 'approve_po_edit_po_issue_submit'],
+ ['display_text' => 'Others', 'value' => 'approve_po_edit_po_issue_others', 'next_question_number' => 'approve_po_edit_po_issue_others'],
+ ],
+ 'group' => 'approve_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'approve_po_edit_po_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'approve_po_edit_po_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => 'approve_po_edit_po_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => 'approve_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'approve_po_edit_po_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'approve_po',
+ ],
+ [
+ 'question_number' => 'fill_po_issue_others',
+ 'question_title' => 'What other issues did you encounter? Upload documents if needed',
+ 'question_type' => QAType::REMARKS_WITH_DOCUMENT_UPLOAD,
+ 'next_nested_question' => 'fill_po_issue_submit',
+ 'is_start' => false,
+ 'is_end' => false,
+ 'group' => 'fill_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'fill_po_issue_submit',
+ 'question_title' => 'Issue has been submitted',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'fill_po',
+ ],
+ [
+ 'question_number' => 'fill_po_edit',
+ 'question_title' => 'fill_po_edit',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'url' => "api.booking.show",
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Issue?', 'value' => 'fill_po_edit_issue', 'next_question_number' => 'fill_po_edit_issue'],
+ ['display_text' => 'Done', 'value' => 'fill_po_edit_filled', 'next_question_number' => 'fill_po_edit_filled'],
+ ],
+ 'group' => 'fill_po',
+ ],
+ [
+ 'question_number' => 'fill_po_edit_issue',
+ 'question_title' => 'fill_po_edit_issue',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => false,
+ 'answer_options' => [
+ ['display_text' => 'Sensitive Goods', 'value' => 'Sensitive Goods', 'next_question_number' => 'fill_po_issue_submit'],
+ ['display_text' => 'Others', 'value' => 'fill_po_issue_others', 'next_question_number' => 'fill_po_issue_others'],
+ ],
+ 'group' => 'fill_po',
+ 'is_admin_filter' => true
+ ],
+ [
+ 'question_number' => 'fill_po_edit_filled',
+ 'question_title' => 'PO Filled',
+ 'question_type' => QAType::MULTIPLE_CHOICES,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'answer_options' => [
+ ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'],
+ ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'],
+ ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'],
+ ],
+ 'group' => 'fill_po',
+ ],
+ [
+ 'question_number' => 'stop_working',
+ 'question_title' => 'Thank you. Reload page to restart.',
+ 'question_type' => QAType::DEFAULT,
+ 'is_start' => false,
+ 'is_end' => true,
+ 'group' => '',
+ ],
+ ]
+ ],
+ ];
+
+ foreach ($questionnaireSets as $set) {
+ $questionnaireSet = QAQuestionnaireSet::create([
+ 'name' => $set['name'],
+ 'description' => $set['description'],
+ 'group' => $set['group'],
+ ]);
+
+ foreach ($set['questions'] as $key => $questionData) {
+ $question = new QAQuestions;
+ $question->question_number = $questionData['question_number'];
+ $question->question_title = $questionData['question_title'];
+ if (isset($questionData['question_description'])) {
+ $question->question_description = $questionData['question_description'];
+ }
+ $question->question_type = $questionData['question_type'];
+ $question->questionnaire_set_id = $questionnaireSet->id;
+ if (isset($questionData['group']) && $questionData['group'] != '') {
+ $question->group = $questionData['group'];
+ }
+
+ if (isset($questionData['next_nested_question'])) {
+ $question->next_nested_question = $questionData['next_nested_question'];
+ }
+ if (isset($questionData['next_main_question'])) {
+ $question->next_main_question = $questionData['next_main_question'];
+ }
+
+ $question->is_start = $questionData['is_start'];
+ $question->is_end = $questionData['is_end'];
+ if (isset($questionData['end_text'])) {
+ $question->end_text = $questionData['end_text'];
+ }
+
+ if (isset($questionData['url'])) {
+ $question->url = $questionData['url'];
+ }
+
+ if (isset($questionData['is_admin_filter'])) {
+ $question->is_admin_filter = $questionData['is_admin_filter'];
+ }
+
+ $question->order = $key + 1;
+ $question->save();
+
+ if (isset($questionData['answer_options'])) {
+ foreach ($questionData['answer_options'] as $optionData) {
+ $answerOption = new QAAnswerOptions;
+ $answerOption->display_text = $optionData['display_text'];
+ $answerOption->value = $optionData['value'];
+ $answerOption->question_number = $questionData['question_number'];
+ $answerOption->next_question_number = $optionData['next_question_number'] ?? null;
+ $answerOption->questionnaire_set_id = $questionnaireSet->id;
+ $answerOption->save();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/resources/assets/vue/components/admin-workflow/elements/QuestionAnswer2Component.vue b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswer2Component.vue
new file mode 100644
index 00000000..9a25f5af
--- /dev/null
+++ b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswer2Component.vue
@@ -0,0 +1,202 @@
+
+
{{ item.created_at_with_time }}
{{ item.source_email }}
{{ item.questionnaire.description }}
Time(s): {{ item.time }} Total:
+ {{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
+
Unit Price
-{{product.unit_price}}
+{{product.unit_price.toFixed(3)}}
Quantity
@@ -144,7 +144,7 @@ }, created() { this.product = this.data; - this.product.unit_price = (Math.round((this.product.unit_price+ Number.EPSILON) * 1000) / 1000).toFixed(3) + this.product.unit_price = (Math.round((this.product.unit_price+ Number.EPSILON) * 1000) / 1000); }, computed: { productTotal(){ diff --git a/resources/assets/vue/components/companies/sections/AddVoucherOptionsSectionComponent.vue b/resources/assets/vue/components/companies/sections/AddVoucherOptionsSectionComponent.vue index f8598c69..dee98112 100644 --- a/resources/assets/vue/components/companies/sections/AddVoucherOptionsSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/AddVoucherOptionsSectionComponent.vue @@ -14,8 +14,7 @@
+ ORDER Marking:+ |
+
+ {{ externalApiResponse.data.marking + }}+ |
+
+ 1688 LOGIN ID/EMAIL/PHONE: ++ |
+
+ {{ externalApiResponse.data.bank.account_no }}+ |
+
+ 1688 LOGIN PASSWORD: ++ |
+
+ {{ externalApiResponse.data.bank.holder_name }}+ |
+
+ ALIPAY 6-DIGIT PAYMENT PIN: ++ |
+
+ {{ externalApiResponse.data.bank.bank_branch }}+ |
+
+ ORDER Marking:+ |
+
+ {{ externalApiResponse.data.booking_marking + }}+ |
+
+ 1688 LOGIN ID/EMAIL/PHONE: ++ |
+
+ {{ externalApiResponse.data.account_no }}+ |
+
+ 1688 LOGIN PASSWORD: ++ |
+
+ {{ externalApiResponse.data.holder_name }}+ |
+
+ ALIPAY 6-DIGIT PAYMENT PIN: ++ |
+
+ {{ externalApiResponse.data.pin }}+ |
+