From de56c2173410836fac551706fc716fa0278a50ae Mon Sep 17 00:00:00 2001 From: glovetleong Date: Tue, 8 Mar 2022 16:55:31 +0800 Subject: [PATCH 01/11] payment transaction --- .../ControllersLogic/CallbackBillplzLogic.php | 105 +++++++++++++++ .../CreateBillplzBillLogic.php | 54 ++++++++ .../BillplzXSignatureObject.php | 120 +++++++++++++++++ .../Billplzs/Services/CreatesBillplzBill.php | 57 +++++++++ .../Billplzs/Services/GetBillplzBill.php | 31 +++++ .../CreatePaymentTransactionLogic.php | 121 ++++++++++++++++++ .../CreateShippingInvoiceTransactionLogic.php | 32 ----- .../DataTransferObjects/TransactionObject.php | 17 ++- .../Services/CreatesPaymentTransaction.php | 37 ++++++ .../Constants/TransactionType.php | 3 +- .../Billplz/CallbackBillplzController.php | 22 ++++ .../Billplz/CreateBillplzBillController.php | 20 +++ .../CreatePaymentTransactionController.php | 19 +++ app/Models/CompanyModule.php | 2 +- app/Models/Transaction.php | 11 +- config/billplz.php | 13 ++ routes/api.php | 2 + routes/transaction.php | 1 + routes/web.php | 4 +- 19 files changed, 631 insertions(+), 40 deletions(-) create mode 100644 app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php create mode 100644 app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php create mode 100644 app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php create mode 100644 app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php create mode 100644 app/Classes/Modules/Billplzs/Services/GetBillplzBill.php create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php create mode 100644 app/Classes/Modules/Transactions/Services/CreatesPaymentTransaction.php create mode 100644 app/Http/Controllers/Billplz/CallbackBillplzController.php create mode 100644 app/Http/Controllers/Billplz/CreateBillplzBillController.php create mode 100644 app/Http/Controllers/Transactions/CreatePaymentTransactionController.php create mode 100644 config/billplz.php diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php new file mode 100644 index 00000000..2230343f --- /dev/null +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -0,0 +1,105 @@ +getBillplzBill = $getBillplzBill; + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->updatesWalletBalance = $updatesWalletBalance; + } + + + /** + * @param Request $request + * @return bool|\Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws MalformedRequestException + * @throws ResourceNotFoundException + */ + public function execute(Request $request) + { + $billplzXSignatureObject = new BillplzXSignatureObject($request); + + if(!$billplzXSignatureObject->isValidSignature()){ + throw new MalformedRequestException('Billplz Payment validation failed.'); + } + + $billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId()); + + if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.'); + + $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]); + + if($billPlz->state === 'paid') { + $status = ApprovalStatus::APPROVED; + } + + if($billPlz->state === 'due') { + $status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION; + } + + if($transaction->status !== ApprovalStatus::COMPLETED){ + + if($transaction->owner instanceof Wallet && $transaction->status !== ApprovalStatus::APPROVED && $status === ApprovalStatus::APPROVED) { + $this->updatesWalletBalance->execute($transaction->owner, $transaction->amount); + } + $this->updatesTransactionStatus->execute($transaction, $status); + + } + + + $token = Auth::fromUser(User::find(1)); + $request->headers->set('Authorization', 'Bearer '.$token); + + $marking = $transaction->owner instanceof Booking ? $transaction->booking->marking : $transaction->owner->owner->bookings()->orderBy('id', 'DESC')->first()->marking; + + return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking, 'transaction' => $transaction, 'status' => $status]); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php new file mode 100644 index 00000000..a7069841 --- /dev/null +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php @@ -0,0 +1,54 @@ + 'Created Billplz Bill', + 'message' => 'You have successfully created a new Bill' + ]; + } + + /** @var CreatesBillplzBill */ + private $createsBillplzBill; + + /** + * CreateBookingLogic constructor. + * @param CreatesBillplzBill $createsBillplzBill + */ + public function __construct(CreatesBillplzBill $createsBillplzBill) + { + $this->createsBillplzBill = $createsBillplzBill; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $billPlz = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, $request->input('description'), 200, $request->input('bankName')); + + if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.'); + + return $this->response(['data' => $billPlz]); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php new file mode 100644 index 00000000..c1295886 --- /dev/null +++ b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php @@ -0,0 +1,120 @@ +type = $request->exists('billplz') ? 'redirect' : 'callback'; + + $this->request = $this->type === 'redirect' ? $request->input('billplz') : $request; + + $this->billPlzId = $this->request['id']; + + $this->status = $this->request['transaction_status']; + + $this->requestXSignature = $this->request['x_signature']; + + $this->_constructBillplzArray()->_natSortBillplzArray()->_constructBillplzString()->_computeBillplzXSignature(); + } + + private function _constructBillplzArray(){ + + $this->billPlzConstructArray = collect($this->request)->forget('x_signature')->map(function($item, $key){ + return $this->type === 'redirect' ? 'billplz'.$key.$item : $key.$item; + })->toArray(); + + return $this; + } + + private function _natCaseSortBillplzArray(){ + natcasesort($this->billPlzConstructArray); + return $this; + } + + private function _natSortBillplzArray(){ + natsort($this->billPlzConstructArray); + return $this; + } + + private function _constructBillplzString(){ + $this->billPlzConstructString = implode('|', $this->billPlzConstructArray); + return $this; + } + + private function _computeBillplzXSignature(){ + $this->billPlzComputedXSignature = hash_hmac('sha256', $this->billPlzConstructString, config('billplz.x_signature_key')); + return $this; + } + + public function getBillPlzId(): string + { + return $this->billPlzId; + } + + public function getStatus(): string + { + return $this->status; + } + + /** + * @return array + */ + public function getBillPlzConstructArray(): array + { + return $this->billPlzConstructArray; + } + + /** + * @return string + */ + public function getBillPlzConstructString(): string + { + return $this->billPlzConstructString; + } + + /** + * @return string + */ + public function getBillPlzComputedXSignature(): string + { + return $this->billPlzComputedXSignature; + } + + public function isValidSignature(): bool + { + return $this->billPlzComputedXSignature === $this->requestXSignature ? true : false; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php new file mode 100644 index 00000000..5b331fca --- /dev/null +++ b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php @@ -0,0 +1,57 @@ +post(config('billplz.base_url').'/api/v3/bills', [ + 'collection_id' => $wallet ? config('billplz.wallet_collection_id') : config('billplz.collection_id'), + 'name' => $name, + 'email' => $email, + 'description' => $description, + 'amount' => $this->finalizeAmount($amount), + 'redirect_url' => route('online_payment.redirect'), + 'callback_url' => route('api.online_payment.callback'), + 'reference_1_label' => 'Bank Code', + 'reference_1' => $bankCode ? $bankCode : '', + 'reference_2_label' => 'Bill Number', + 'reference_2' => $billNumber + ]); + + if($response->successful()){ + $data = $response->json(); + + $data['url'] = $data['url'].'?auto_submit=true'; + + return (object) $data; + }else{ + return null; + } + }catch(\Exception $exception){ + throw new MalformedRequestException('Unable to get correct response from billplz server' . $exception->getMessage()); + } + } + + protected function finalizeAmount($amount){ + $number = round($amount, 2) * 100; + return (string) $number; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php b/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php new file mode 100644 index 00000000..2a86b403 --- /dev/null +++ b/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php @@ -0,0 +1,31 @@ +get(config('billplz.base_url').'/api/v3/bills/'.$billPlzId); + + if($response->successful()){ + $data = $response->json(); + + return (object) $data; + }else{ + return null; + } + }catch(\Exception $exception){ + throw new MalformedRequestException('Unable to get correct response from billplz server'); + } + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php new file mode 100644 index 00000000..bd99d86d --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php @@ -0,0 +1,121 @@ + 'Create Payment Transactions', + 'message' => 'You have successfully created currency supplier transactions' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var FetchesSegmentConstant */ + private $fetchesSegmentConstant; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatesPaymentTransaction */ + private $createsPaymentTransaction; + + /** @var CreatesBillplzBill */ + private $createsBillplzBill; + + /** @var CreatesTransactionDetail */ + private $createsTransactionDetail; + + public function __construct( + FetchesTransaction $fetchesTransaction, + GeneratesTransactionBillNumber $generatesTransactionBillNumber, + CreatesPaymentTransaction $createsPaymentTransaction, + CreatesTransactionDetail $createsTransactionDetail, + CreatesBillplzBill $createsBillplzBill + ) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createsPaymentTransaction = $createsPaymentTransaction; + $this->createsTransactionDetail = $createsTransactionDetail; + $this->createsBillplzBill = $createsBillplzBill; + } + + public function logic(Request $request) : JsonResponse + { + $invoice_transaction = $this->fetchesTransaction->execute(['id' => $request->input('transaction_id')]); + $amount = $request->input('amount'); + $company_module = $invoice_transaction->owner()->first()->owner()->first()->companyModule()->first(); + + $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + $payment_reference = null; + if ($request->input('payment_method') == 5) { + $payment_method = PaymentMethodType::PAYMENT_GATEWAY; + $billPlzBill = $this->createsBillplzBill->execute( + $company_module->name, + $company_module->employees()->first()->email, + 'This payment is credit topup for company ref. ' . $company_module->reference, $amount, $billNumber, + $request->input('bank_code'), true + ); + + $payment_reference = $billPlzBill->id; + } + else { + $payment_method = PaymentMethodType::CASH; + } + + $object = new TransactionObject( + $billNumber, + TransactionType::PAYMENT, + $company_module->id, + 1, + 1, + $payment_method, + $request->input('amount'), + $request->input('amount'), + 1, + 1, + 0, + 0, + 0, + null, + ApprovalStatus::PENDING_SUBMISSION, + null, + $payment_reference + ); + + $payment_transaction = $this->createsPaymentTransaction->execute($invoice_transaction, $object); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateShippingInvoiceTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateShippingInvoiceTransactionLogic.php index e4729533..4da640a0 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateShippingInvoiceTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateShippingInvoiceTransactionLogic.php @@ -21,23 +21,10 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\DocumentType; -// use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; -// use App\Classes\Modules\Transactions\Services\FetchesTransaction; -// use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; - -// use App\Models\Document; -// use App\Models\Transaction; -// use Barryvdh\DomPDF\PDF; -// use Carbon\Carbon; - - - use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; - -// use Meneses\LaravelLaravelMpdf\Facades\LaravelLaravelMpdf; use Meneses\LaravelMpdf\Facades\LaravelMpdf; class CreateShippingInvoiceTransactionLogic extends AbstractControllerLogic @@ -74,16 +61,6 @@ class CreateShippingInvoiceTransactionLogic extends AbstractControllerLogic /** @var CreatesFiles */ private $createsFile; - - // /** @var FetchesTransaction */ - // /** @var UpdatesTransactionStatus */ - // private $updatesTransactionStatus; - // /** @var CreatesDocument */ - // private $createsDocument; - // /** @var CreatesFiles */ - // private $createsFile; - // /** @var PDF */ - // private $pdf; public function __construct( FetchesPackingList $fetchesPackingList, @@ -93,10 +70,6 @@ class CreateShippingInvoiceTransactionLogic extends AbstractControllerLogic CreatesTransactionDetail $createsTransactionDetail, CreatesDocument $createsDocument, CreatesFiles $createsFile - - // CreatesDocument $createsDocument, - // CreatesFiles $createsFile, - // PDF $pdf ) { @@ -107,11 +80,6 @@ class CreateShippingInvoiceTransactionLogic extends AbstractControllerLogic $this->createsTransactionDetail = $createsTransactionDetail; $this->createsDocument = $createsDocument; $this->createsFile = $createsFile; - - // $this->updatesTransactionStatus = $updatesTransactionStatus; - // $this->createsDocument = $createsDocument; - // $this->createsFile = $createsFile; - // $this->pdf = $pdf; } public function logic(Request $request) : JsonResponse diff --git a/app/Classes/Modules/Transactions/DataTransferObjects/TransactionObject.php b/app/Classes/Modules/Transactions/DataTransferObjects/TransactionObject.php index b4153751..5e943e29 100644 --- a/app/Classes/Modules/Transactions/DataTransferObjects/TransactionObject.php +++ b/app/Classes/Modules/Transactions/DataTransferObjects/TransactionObject.php @@ -57,6 +57,9 @@ class TransactionObject implements DataTransferObject /** @var array|null */ private $details; + /** @var string */ + private $paymentReference; + /** * TransactionObject constructor. * @param string $billNo @@ -92,7 +95,8 @@ class TransactionObject implements DataTransferObject float $serviceCharge, ?Carbon $expiresOn, ?int $status = ApprovalStatus::PENDING_SUBMISSION, - ?array $details = [] + ?array $details = [], + ?string $paymentReference = null ) { $this->billNo = $billNo; @@ -111,6 +115,7 @@ class TransactionObject implements DataTransferObject $this->expiresOn = $expiresOn; $this->status = $status; $this->details = $details; + $this->paymentReference = $paymentReference; } /** @@ -243,7 +248,11 @@ class TransactionObject implements DataTransferObject }, $this->details); } - - - + /** + * @return string|null + */ + public function getPaymentReference(): ?string + { + return $this->paymentReference; + } } \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/Services/CreatesPaymentTransaction.php b/app/Classes/Modules/Transactions/Services/CreatesPaymentTransaction.php new file mode 100644 index 00000000..54afd914 --- /dev/null +++ b/app/Classes/Modules/Transactions/Services/CreatesPaymentTransaction.php @@ -0,0 +1,37 @@ +bill_no = $object->getBillNo(); + $model->type = $object->getTransactionType(); + $model->issuer = $object->getIssuer(); + $model->receiver = $object->getReceiver(); + $model->recipient_bank_account_id = $object->getRecipientBankAccountId(); + $model->payment_method = $object->getPaymentMethod(); + $model->amount = $object->getAmount(); + $model->original_amount = $object->getOriginalAmount(); + $model->currency_id = $object->getCurrencyId(); + $model->original_currency_id = $object->getOriginalCurrencyId(); + $model->currency_rate = $object->getCurrencyRate(); + $model->tax = $object->getTax(); + $model->service_charge = $object->getServiceCharge(); + $model->expires_on = $object->getExpiresOn(); + $model->status = $object->getStatus(); + + return $this->handler($transaction->transactions(), $model); + } +} \ No newline at end of file diff --git a/app/Classes/ValueObjects/Constants/TransactionType.php b/app/Classes/ValueObjects/Constants/TransactionType.php index d61589fa..07277b64 100644 --- a/app/Classes/ValueObjects/Constants/TransactionType.php +++ b/app/Classes/ValueObjects/Constants/TransactionType.php @@ -6,9 +6,10 @@ final class TransactionType { public const SHIPPING_INVOICE = 1; + public const PAYMENT = 2; + // public const PAYMENT_ATTEMPT = 0; - // public const PAYMENT = 1; // public const INVOICE = 2; diff --git a/app/Http/Controllers/Billplz/CallbackBillplzController.php b/app/Http/Controllers/Billplz/CallbackBillplzController.php new file mode 100644 index 00000000..9ee281e6 --- /dev/null +++ b/app/Http/Controllers/Billplz/CallbackBillplzController.php @@ -0,0 +1,22 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Billplz/CreateBillplzBillController.php b/app/Http/Controllers/Billplz/CreateBillplzBillController.php new file mode 100644 index 00000000..c10bad79 --- /dev/null +++ b/app/Http/Controllers/Billplz/CreateBillplzBillController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Transactions/CreatePaymentTransactionController.php b/app/Http/Controllers/Transactions/CreatePaymentTransactionController.php new file mode 100644 index 00000000..7636b16e --- /dev/null +++ b/app/Http/Controllers/Transactions/CreatePaymentTransactionController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Models/CompanyModule.php b/app/Models/CompanyModule.php index 180d8286..615df813 100644 --- a/app/Models/CompanyModule.php +++ b/app/Models/CompanyModule.php @@ -139,7 +139,7 @@ class CompanyModule extends AbstractModel implements Addressable, Documentable, */ public function banks(): HasMany { - return $this->HasMany(Bank::class, 'company_id'); + return $this->HasMany(BankAccount::class, 'company_id'); } /** diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 9ca9c24f..d2432941 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\General\Interfaces\Documentable; +use App\Classes\General\Interfaces\Transactionable; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; use Carbon\Carbon; @@ -12,7 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphTo; -class Transaction extends AbstractModel implements Documentable +class Transaction extends AbstractModel implements Documentable, Transactionable { protected $table = 'transactions'; @@ -29,6 +30,14 @@ class Transaction extends AbstractModel implements Documentable return $this->morphMany(Order::class, 'owner'); } + /** + * @return MorphMany + */ + public function transactions(): MorphMany + { + return $this->MorphMany(Transaction::class, 'owner'); + } + /** * @return MorphMany */ diff --git a/config/billplz.php b/config/billplz.php new file mode 100644 index 00000000..904cea31 --- /dev/null +++ b/config/billplz.php @@ -0,0 +1,13 @@ + env('BILLPLZ_BASE_URL', 'https://www.billplz.com'), + 'api_key' => env('BILLPLZ_API_KEY', '0fa4c710-761b-4a7a-a501-c2c2d02643d5'), + 'x_signature_key' => env('BILLPLZ_X_SIGNATURE_KEY', 'S-pbNVthVRsvnPfZlgLwqqOg'), + 'collection_id' => env('BILLPLZ_COLLECTION_ID', 'hev2wdjy'), + 'wallet_collection_id' => env('BILLPLZ_WALLET_COLLECTION_ID', 'hev2wdjy'), + 'redirect_url' => env('BILLPLZ_REDIRECT_URL', 'localhost'), + 'callback_url' => env('BILLPLZ_CALLBACK_URL', 'localhost'), + 'maybank' => 'MB2U0227', + 'cimb' => 'BCBB0235' +]; \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index c8f886e1..3c541439 100644 --- a/routes/api.php +++ b/routes/api.php @@ -26,6 +26,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function Route::get('/storage/{fileName}/fetch', 'Documents\RenderDocumentController@fileStorageServe')->where(['fileName' => '.*'])->name('storage.document.file'); + Route::post('online_payment/callback', 'Billplz\CallbackBillplzController@callback')->name('online_payment.callback'); + require __DIR__ . '/company.php'; require __DIR__ . '/document.php'; diff --git a/routes/transaction.php b/routes/transaction.php index 7b4f7fd0..15504e97 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -7,6 +7,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => Route::get('/list', 'ListTransactionsController@list')->name('list'); // Route::delete('/suspend/{id}', 'SuspendTransactionController@suspend')->name('suspend'); + route::post('/payment/create', 'CreatePaymentTransactionController@create')->name('payment.create'); route::post('/shipping-invoice/create', 'CreateShippingInvoiceTransactionController@create')->name('supplier.create'); diff --git a/routes/web.php b/routes/web.php index 4c3077fe..bd7d2e01 100644 --- a/routes/web.php +++ b/routes/web.php @@ -260,4 +260,6 @@ Route::get('/customers/active/{active_start}/{active_end}/{inactive_start?}/{ina echo $key + 1 .'. '.$marking.'

'; } -}); \ No newline at end of file +}); + +Route::get('/online_payment/redirect', 'Billplz\CallbackBillplzController@callback')->name('online_payment.redirect'); \ No newline at end of file From 5d9e621920d60e0f15c88c957381c855bce1e1dc Mon Sep 17 00:00:00 2001 From: glovetleong Date: Sat, 12 Mar 2022 20:06:10 +0800 Subject: [PATCH 02/11] payment document approve --- .../ApprovePaymentTransactionLogic.php | 81 +++++++++++++++++ ...UploadPaymentVerificationDocumentLogic.php | 87 +++++++++++++++++++ .../ApprovePaymentTransactionController.php | 15 ++++ ...dPaymentVerificationDocumentController.php | 20 +++++ routes/transaction.php | 13 ++- 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/ApprovePaymentTransactionLogic.php create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/UploadPaymentVerificationDocumentLogic.php create mode 100644 app/Http/Controllers/Transactions/ApprovePaymentTransactionController.php create mode 100644 app/Http/Controllers/Transactions/UploadPaymentVerificationDocumentController.php diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ApprovePaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ApprovePaymentTransactionLogic.php new file mode 100644 index 00000000..5db49ddf --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/ApprovePaymentTransactionLogic.php @@ -0,0 +1,81 @@ +fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->approvesDocument = $approvesDocument; + $this->rejectsDocument = $rejectsDocument; + } + + /** + * @return array + */ + protected function notification():array { + return [ + 'title' => 'Payment Status', + 'message' => 'You have successfully updated the payment status' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** @var ApprovesDocument */ + private $approvesDocument; + + /** @var RejectsDocument */ + private $rejectsDocument; + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + + $status = $request->route('status'); + + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('transaction_id')]); + + $status === 'approve' ? $this->approvesDocument->execute($transaction->documents()->first()) : $this->rejectsDocument->execute($transaction->documents()->first()); + + $this->updatesTransactionStatus->execute($transaction, $status === 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED); + + // $this->createInvoiceTransactionProcessor->execute($transaction->booking); + return $this->response([]); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UploadPaymentVerificationDocumentLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UploadPaymentVerificationDocumentLogic.php new file mode 100644 index 00000000..3ea3b667 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/UploadPaymentVerificationDocumentLogic.php @@ -0,0 +1,87 @@ + 'Payment Verify Document', + 'message' => 'You have successfully submitted your payment verify document' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var CreatesDocument */ + private $createsDocument; + + /** @var CreatesFiles */ + private $createsFile; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** + * CreatePaymentVerificationDocumentLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param CreatesDocument $createsDocument + * @param CreatesFiles $createsFile + * @param UpdatesTransactionStatus $updatesTransactionStatus + */ + public function __construct(FetchesTransaction $fetchesTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesTransactionStatus $updatesTransactionStatus) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->createsDocument = $createsDocument; + $this->createsFile = $createsFile; + $this->updatesTransactionStatus = $updatesTransactionStatus; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('transaction_id')]); + + $object = new DocumentObject( + DocumentType::CUSTOMER_PAYMENT_PROOF, + $request->input('files'), + '', + ApprovalStatus::PENDING_VERIFICATION, + 'payments' + ); + + /** @var Document $document */ + $document = $this->createsDocument->execute($transaction, $object); + + $this->createsFile->execute($document, $object); + + $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); + + return $this->response([]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Transactions/ApprovePaymentTransactionController.php b/app/Http/Controllers/Transactions/ApprovePaymentTransactionController.php new file mode 100644 index 00000000..cbb00610 --- /dev/null +++ b/app/Http/Controllers/Transactions/ApprovePaymentTransactionController.php @@ -0,0 +1,15 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Transactions/UploadPaymentVerificationDocumentController.php b/app/Http/Controllers/Transactions/UploadPaymentVerificationDocumentController.php new file mode 100644 index 00000000..6c32a34d --- /dev/null +++ b/app/Http/Controllers/Transactions/UploadPaymentVerificationDocumentController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/routes/transaction.php b/routes/transaction.php index 15504e97..c3e1b2f2 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -7,9 +7,20 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => Route::get('/list', 'ListTransactionsController@list')->name('list'); // Route::delete('/suspend/{id}', 'SuspendTransactionController@suspend')->name('suspend'); - route::post('/payment/create', 'CreatePaymentTransactionController@create')->name('payment.create'); + Route::post('/payment/create', 'CreatePaymentTransactionController@create')->name('payment.create'); + Route::post('/payment/upload-verification-document/{transaction_id}', 'UploadPaymentVerificationDocumentController@upload')->name('verification.create'); + Route::put('/payment/approve/{transaction_id}/{status}', 'ApprovePaymentTransactionController@approve')->where('status', 'approve|reject')->name('approval'); + + route::post('/shipping-invoice/create', 'CreateShippingInvoiceTransactionController@create')->name('supplier.create'); + // Route::group(['prefix' => '{id}/payment', 'as' => 'payment.'], function () { + // Route::post('quotation', 'FetchBookingPaymentQuotationController@fetch')->name('quotation'); + // Route::post('create', 'CreateBookingPaymentController@create')->name('create'); + // Route::post('{payment_id}/verification/create', 'CreatePaymentVerificationController@create')->name('verification.create'); + // Route::put('/{payment_id}/approval/{status}', 'ApprovePaymentVerificationController@approve')->where('status', 'approve|reject')->name('approval'); + // }); + // route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification'); From bea9507daeb26a69aa05dff36f461b61c2fa48e3 Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 10:57:43 +0800 Subject: [PATCH 03/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 4f316148..bda5b871 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -17,12 +17,12 @@ class PackingListDeliveryStatus implements Filter public static function apply(Builder $builder, $value) { return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { - $query->whereDoesntHave('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '>', Carbon::now()); + $query->whereHas('schedules', function (Builder $query) use ($value) { + $query->where('status', ApprovalStatus::APPROVED)->where('eta', '>', Carbon::now()); }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<', Carbon::now()); + $query->where('status', ApprovalStatus::APPROVED)->where('eta', '=<', Carbon::now()); }); })); } From 0a69faeb3baaa8e243ce961399c3ce72593e899b Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 10:58:48 +0800 Subject: [PATCH 04/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index bda5b871..c5efa51a 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -18,11 +18,11 @@ class PackingListDeliveryStatus implements Filter { return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', ApprovalStatus::APPROVED)->where('eta', '>', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '>', Carbon::now()); }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', ApprovalStatus::APPROVED)->where('eta', '=<', Carbon::now()); + $query->where('status', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); }); })); } From 8902a09337b3964429b6853880b091af54dbd81d Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 10:59:44 +0800 Subject: [PATCH 05/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index c5efa51a..5e811c97 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -22,7 +22,7 @@ class PackingListDeliveryStatus implements Filter }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); }); })); } From 56fb250e6ff8ee39206b508f448a950b17f3f654 Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:14:14 +0800 Subject: [PATCH 06/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 5e811c97..9445e578 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -17,8 +17,8 @@ class PackingListDeliveryStatus implements Filter public static function apply(Builder $builder, $value) { return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { - $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '>', Carbon::now()); + $query->whereDoesntHave('schedules', function (Builder $query) use ($value) { + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { From 91feb5b8fab08a334eb0cc53391cc12295be3a02 Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:19:45 +0800 Subject: [PATCH 07/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 9445e578..9c0f92a3 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -18,7 +18,7 @@ class PackingListDeliveryStatus implements Filter { return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereDoesntHave('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '>', Carbon::now()); }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { From 5fb7ddb0ec00b900f88f1a51044c3cecefe9a8dd Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:20:16 +0800 Subject: [PATCH 08/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 9c0f92a3..4f316148 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -22,7 +22,7 @@ class PackingListDeliveryStatus implements Filter }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '=<', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<', Carbon::now()); }); })); } From eb6b2943af9a1c87e321729bcf40ef9a3fa60d83 Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:21:20 +0800 Subject: [PATCH 09/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 4f316148..3f4b454c 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -18,11 +18,11 @@ class PackingListDeliveryStatus implements Filter { return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereDoesntHave('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '>', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<=', Carbon::now()); }); }) : $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereHas('schedules', function (Builder $query) use ($value) { - $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<', Carbon::now()); + $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<=', Carbon::now()); }); })); } From 6389fc6600c9cfafa129662351241028cc5fe1cf Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:24:33 +0800 Subject: [PATCH 10/11] fix delivery list filter --- resources/views/pages/delivery_list.blade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/views/pages/delivery_list.blade.php b/resources/views/pages/delivery_list.blade.php index ff4a407e..284da34e 100644 --- a/resources/views/pages/delivery_list.blade.php +++ b/resources/views/pages/delivery_list.blade.php @@ -85,7 +85,7 @@
Delivery Date
Action
- + @@ -103,7 +103,7 @@
status
Delivery Date
- + @@ -121,7 +121,7 @@
status
Delivery Date
- + From f2007b25e44fdfacfc09ea0fb776b18cdfa921c2 Mon Sep 17 00:00:00 2001 From: omair saleh Date: Mon, 14 Mar 2022 11:32:22 +0800 Subject: [PATCH 11/11] fix delivery list filter --- .../General/Eloquent/Filters/PackingListDeliveryStatus.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php index 3f4b454c..3cc41510 100644 --- a/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php +++ b/app/Classes/General/Eloquent/Filters/PackingListDeliveryStatus.php @@ -16,7 +16,9 @@ class PackingListDeliveryStatus implements Filter */ public static function apply(Builder $builder, $value) { - return $value == 1 ? $builder->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { + return $value == 1 ? $builder->whereHas('containers', function ($query){ + $query->where('containers.status', ApprovalStatus::COMPLETED); + })->whereDoesntHave('transports') : ($value == 2 ? $builder->whereHas('transports', function (Builder $query) use ($value) { $query->whereDoesntHave('schedules', function (Builder $query) use ($value) { $query->where('status', '!=', ApprovalStatus::EXPIRED)->where('eta', '<=', Carbon::now()); });