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) { $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($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(), 0, $voucherCode); if(PaymentMethodType::PAYMENT_METHODS[$paymentMethod] == PaymentMethodType::WALLET){ $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); } return $transaction; } }