'Create Group Transaction', 'message' => 'You have successfully created a group transaction' ]; } /** @var FetchesTransaction */ private $fetchesTransaction; /** @var GeneratesTransactionBillNumber */ private $generatesTransactionBillNumber; /** @var FetchesCompanyModule */ private $fetchesCompanyModule; /** @var CreateWalletTopUpTransactionProcessor */ private $createWalletTopUpTransactionProcessor; /** @var CreatePaymentTransactionProcessor */ private $createPaymentTransactionProcessor; /** @var CreatesGroup */ private $createsGroup; /** @var ReleaseGoodsToCustomerProcessor */ private $releaseGoodsToCustomerProcessor; public function __construct( FetchesTransaction $fetchesTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesCompanyModule $fetchesCompanyModule, CreateWalletTopUpTransactionProcessor $createWalletTopUpTransactionProcessor, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, CreatesGroup $createsGroup, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor ) { $this->fetchesTransaction = $fetchesTransaction; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->fetchesCompanyModule = $fetchesCompanyModule; $this->createWalletTopUpTransactionProcessor = $createWalletTopUpTransactionProcessor; $this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor; $this->createsGroup = $createsGroup; $this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor; } public function logic(Request $request) : JsonResponse { $invoice_ids = json_decode($request->route('transaction_ids')); // todo-new: check why is this not working // $invoices = $this->fetchesTransaction->execute(['id_in' => $invoice_ids]); $invoices = Transaction::whereIn('id', $invoice_ids)->get(); $isInvoicesApprove = $this->checkIfInvoicesAreApprove($invoices); if(!$isInvoicesApprove){ $response = ['message' => 'One of the transactions might be suspended; please check if there are any disputes in progress.']; return $this->response(['data' => $response]); } else{ $paymentMethodStr = $request->input('payment_method'); $paymentMethod = PaymentMethodType::PAYMENT_METHODS[$paymentMethodStr]; $amount = $request->input('amount'); $bankCode = $request->input('bank_code'); $result = $this->processInvoices($invoices, $paymentMethodStr, $amount, $bankCode); if ($paymentMethod === PaymentMethodType::PAYMENT_GATEWAY) { return $this->resourceResponse(new WalletTransactionResource($result)); } } return $this->response([]); } private function processInvoices($invoices, $reqPaymentMethod, $reqAmount, $reqBankCode){ $result = []; $payment_method = PaymentMethodType::PAYMENT_METHODS[$reqPaymentMethod]; $groupPyamentStatus = ApprovalStatus::PENDING_VERIFICATION; $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); foreach ($invoices as $invoice) { $order = null; if ($invoice->owner instanceof Transaction) { if ($invoice->owner) { if ($invoice->owner->owner) { $order = $invoice->owner->owner->owner; } } } else if (!($invoice->owner instanceof Transaction) && !($invoice->owner instanceof Wallet)) { if ($invoice->owner) { $order = $invoice->owner->owner; } } if (!$order) { throw new MalformedRequestException("There is an error while paying for invoice {$invoice->bill_no}"); } } if ($payment_method == PaymentMethodType::WALLET) { $companyModuleId = $invoices->first()->receiver; $wallet = Wallet::where('owner_id', $companyModuleId)->first(); // todo-new: verify currently checking wallet amount based on 'amount' value passed by frontend if((float) number_format(($wallet->amount - $reqAmount),2) < 0){ throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); } $groupPyamentStatus = ApprovalStatus::APPROVED; } $issuer = 0; $receiver = 0; $amount = 0; $original_amount = 0; $currency_id = 0; $original_currency_id = 0; $currency_rate = 0; $tax = 0; $service_charge = 0; $group = new GroupObject( $issuer, $receiver, $amount, $original_amount, $currency_id, $original_currency_id, $currency_rate, $tax, $service_charge, $payment_method, '-', $groupPyamentStatus, ); $group = $this->createsGroup->execute($group); foreach ($invoices as $invoice) { if ($payment_method == PaymentMethodType::WALLET) { $paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $reqBankCode, false); if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){ $pL = $invoice->owner; $this->releaseGoodsToCustomerProcessor->execute($pL, $invoice); } } $issuer = $invoice->issuer; $receiver = $invoice->receiver; $amount += $invoice->amount; $original_amount += $invoice->original_amount; $currency_id = $invoice->currency_id; $original_currency_id = $invoice->original_currency_id; $currency_rate = $invoice->currency_rate; $tax += $invoice->tax; $service_charge += $invoice->service_charge; // creates group transaction $groupTransaction = new GroupTransaction(); $groupTransaction->group_id = $group->id; $groupTransaction->transaction_id = $invoice->id; $groupTransaction->save(); } if (in_array($payment_method, [PaymentMethodType::PAYMENT_GATEWAY, PaymentMethodType::CASH])) { // create only one billplz payment for wallet top up $amount2 = floatval(str_replace(',', '', $reqAmount)); Log::channel('storage_invoices')->info('CreateGroupsLogic reqAmount from client: ' .$amount2); Log::channel('storage_invoices')->info('CreateGroupsLogic amount from backend: ' .$amount); //the real amount should always be from backend $companyModuleId = $invoice->receiver; $companyModule = $this->fetchesCompanyModule->execute(['id' => $companyModuleId]); $topUpTransaction = $this->createWalletTopUpTransactionProcessor->execute($companyModule, $amount, $reqBankCode, $payment_method, $billNumber, true); $result = $topUpTransaction; } $group->issuer = $issuer; $group->receiver = $receiver; $group->reference = $payment_method === PaymentMethodType::PAYMENT_GATEWAY ? $topUpTransaction->payment_reference : $billNumber; $group->amount = $amount; $group->original_amount = $original_amount; $group->currency_id = $currency_id; $group->original_currency_id = $original_currency_id; $group->currency_rate = $currency_rate; $group->tax = $tax; $group->service_charge = $service_charge; $group->status = $groupPyamentStatus; $group->save(); return $result; } private function checkIfInvoicesAreApprove($invoices){ foreach ($invoices as $invoice) { if($invoice->status !== ApprovalStatus::APPROVED && $invoice->status !== ApprovalStatus::COMPLETED){ return false; } } return true; } }