fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; $this->createsBillplzBill = $createsBillplzBill; $this->updatesWalletBalance = $updatesWalletBalance; $this->updatesTransactionStatus = $updatesTransactionStatus; $this->recalculatesWalletBalance = $recalculatesWalletBalance; } /** * @return array */ protected function notification():array { return [ 'title' => 'Create Payment Booking', 'message' => 'You have successfully created a payment booking' ]; } /** @var FetchesBookingQuotation */ private $fetchBookingQuotation; /** @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 RecalculatesWalletBalance */ private $recalculatesWalletBalance; // // /** @var FetchesVoucher */ // private $fetchesVoucher; // // /** @var CreatesVoucher */ // private $createsVoucher; // // /** @var CreatesVoucherRedemption */ // private $createsVoucherRedemption; // // /** @var RedeemsVoucher */ // private $redeemsVoucher; public function logic(Request $request) : JsonResponse { $booking = Booking::find($request->route('id')); $conversionObject = $this->createConversionObject($request, $booking); $this->validatePayment($request, $booking, $conversionObject); $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $request->input('voucher_code')); $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); $paymentReference = $this->handlePaymentMethods($request, $booking, $configurations, $billNumber); $object = $this->createTransactionObject($booking, $configurations, $billNumber, $paymentReference); /** @var Transaction $transaction */ $transaction = $this->createsTransaction->execute($booking, $object); if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); } // $this->handleVoucherCode($request, $booking, $configurations, $transaction); //todo-important: uncomment this for voucherify return $this->resourceResponse(new TransactionResource($transaction)); } private function createConversionObject(Request $request, Booking $booking): CurrencyConversionObject { return 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')] ); } private function validatePayment(Request $request, Booking $booking, CurrencyConversionObject $conversionObject): void { $outstanding = $this->calculatesBookingOutstanding->execute($booking); if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); } private function handlePaymentMethods(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): ?string { $paymentReference = null; if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY) $paymentReference = $this->handlePaymentGateway($request, $booking, $configurations, $billNumber); if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET) $paymentReference = $this->handleWalletPayment($request, $booking, $configurations, $billNumber); return $paymentReference; } private function handlePaymentGateway(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): string { $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') ); return $billPlzBill->id; } private function handleWalletPayment(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): string { $wallet = $booking->company->wallets()->first(); $amount = $configurations->getTotal(); if((float) number_format(($wallet->amount - $amount),2) < 0) throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); $transactionObject = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], ''); $this->createsTransaction->execute($wallet, $transactionObject); $walletBalance = $this->recalculatesWalletBalance->execute($wallet); $this->updatesWalletBalance->execute($wallet, $walletBalance); return $billNumber; } private function createTransactionObject(Booking $booking, CalculationObject $configurations, string $billNumber, ?string $paymentReference): TransactionObject { return 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($this->fetchesCompanyPaymentAttemptLimit->execute($booking->company)), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference ); } // private function handleVoucherCode(Request $request, Booking $booking, CalculationObject $configurations, Transaction $transaction): void // { // $voucherCode = $request->input('voucher_code'); // if($voucherCode){ // $employee = $booking->company->employees()->first(); // // $result = $this->redeemsVoucher->execute($voucherCode, $configurations->getSubTotal(), $employee); // $voucher = $result->voucher; // $redemptionId = $result->id; // // $voucherValue = $voucher->discount->amount_off ?? ($voucher->discount->percent_off ?? 0.00); // $voucherObject = new VoucherObject($voucher->code, $voucher->metadata->name ?? "", $voucher->discount->type, $voucherValue); // $voucher = $this->createsVoucher->execute($voucherObject); // // if(!$voucher) // $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]); // // $this->createsVoucherRedemption->execute($redemptionId, $voucher->id, $employee->id, $configurations->getVoucherDiscountAmount()); // } // } }