Files

183 lines
7.5 KiB
PHP

<?php
namespace App\Classes\Modules\Accounting\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounting\Services\CreatesBankStatementTransactionOwner;
use App\Classes\Modules\Accounting\Services\FetchesBankStatementTransaction;
use App\Classes\Modules\Accounting\Processors\ListShippingPortalTransactions;
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
use App\Classes\ValueObjects\Constants\SystemType;
use App\Classes\Modules\Accounting\Processors\ChecksBillNumber;
use App\Classes\ValueObjects\Constants\ShippingTransactionType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Transaction;
use App\Models\Wallet;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\StatementTransactionOwner;
class UpdateBankStatementDetailLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Bank Statement Transactions Details',
'message' => 'You have successfully updated the Bank Statement Transactions Details'
];
}
/** @var FetchesBankStatementTransaction */
private $fetchesBankStatementTransaction;
/** @var ChecksBillNumber */
private $checksBillNumber;
/** @var UpdatesBankStatementTransactionOwnerStatus */
private $updatesBankStatementTransactionOwnerStatus;
/**
* @param FetchesBankStatementTransaction $fetchesBankStatementTransaction
* @param ChecksBillNumber $checksBillNumber
*/
public function __construct(
FetchesBankStatementTransaction $fetchesBankStatementTransaction,
ChecksBillNumber $checksBillNumber,
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus)
{
$this->fetchesBankStatementTransaction = $fetchesBankStatementTransaction;
$this->checksBillNumber = $checksBillNumber;
$this->updatesBankStatementTransactionOwnerStatus = $updatesBankStatementTransactionOwnerStatus;
}
public function logic(Request $request): JsonResponse
{
$bankStatementTransaction = $this->fetchesBankStatementTransaction->execute(['id' => $request->route('id')]);
$transactionReference = $request->input('transaction_reference');
$systemReference = $request->input('system_references');
$owner_type = $owner_id = $owner_reference = $statementTransactionOwnerType = $system = null;
$salesSystems = ['lite', 'cntr', 'probashi', 'pets'];
$allowedSystems = array_merge($salesSystems, ['exchange', 'izyim']);
if (!in_array($systemReference, $allowedSystems) && !in_array($request->input('pay_for'), ['internal_bank_transfer', 'others'])) {
throw new MalformedRequestException('System Reference not allowed');
}
switch ($request->input('pay_for')) {
case 'sales':
$owner_reference = $transactionReference;
$statementTransactionOwnerType = StatementTransactionOwnerType::SALES;
break;
case 'top_up':
$owner_reference = $transactionReference;
$statementTransactionOwnerType = StatementTransactionOwnerType::WALLET_TOP_UP;
break;
case 'internal_bank_transfer':
$statementTransactionOwnerType = StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN;
break;
case 'others':
$owner_reference = $transactionReference;
$statementTransactionOwnerType = StatementTransactionOwnerType::NON_OPERATIONAL;
break;
default:
throw new MalformedRequestException('Transaction Type Not Allowed');
}
if (in_array($systemReference, ['exchange', 'izyim'])) {
$transaction = $this->checksBillNumber->execute($transactionReference, $systemReference);
if (is_array($transaction) && empty($transaction)) {
throw new MalformedRequestException('Transaction Not Found.');
}
if($systemReference === 'exchange') {
$owner_type = Transaction::class;
$owner_id = $transaction->id;
if($transaction->type === TransactionType::TOP_UP) {
$owner_reference = $transaction->owner->owner->reference;
}
if($transaction->type === TransactionType::PAYMENT && $transaction->owner_type === Booking::class) {
$owner_reference = $transaction->owner->marking;
}
}
if($systemReference === 'izyim') {
$transaction = $transaction[0];
$payFor = $request->input('pay_for');
$transactionType = $transaction['type'];
if (($payFor === 'sales' && !in_array($transactionType, [ShippingTransactionType::PAYMENT, ShippingTransactionType::GROUP_PAYMENT]))
|| ($payFor === 'top_up' && !in_array($transactionType, [ShippingTransactionType::TOP_UP, ShippingTransactionType::GROUP_PAYMENT]))) {
throw new MalformedRequestException('Transaction Type does not match.');
}
$owner_type = Transaction::class;
$owner_id = $transaction['owner_id'];
$owner_reference = $transaction['owner_reference'];
}
}
$system = $systemReference != null ? SystemType::SYSTEM_NAMES[$systemReference] : '';
$statementTransactionOwner = $this->createBankStatementTransactionOwner($bankStatementTransaction, $statementTransactionOwnerType, $system, $owner_type, $owner_id, $owner_reference);
// this for edit a transaction already mapped
if ($request->has('editMapped')) $this->editAccountMapped($statementTransactionOwner);
return $this->response([]);
}
private function createBankStatementTransactionOwner($bankStatementTransaction, $statementTransactionOwnerType, $system, $owner_type, $owner_id, $owner_reference)
{
$ownerData = [
'type' => $statementTransactionOwnerType,
'system' => $system,
'owner_type' => $owner_type,
'owner_id' => $owner_id,
'owner_reference' => $owner_reference,
];
return $bankStatementTransaction->owners()->where('status','<>',ApprovalStatus::REJECTED)->firstOrCreate($ownerData);
}
private function editAccountMapped(StatementTransactionOwner $owner){
$this->updateOwnerStatus($owner, ApprovalStatus::APPROVED);
// update all other owners with the same system, owner type, and owner ID
$this->updateOtherOwners($owner, ApprovalStatus::REJECTED);
}
private function updateOwnerStatus(StatementTransactionOwner $owner, int $status)
{
$this->updatesBankStatementTransactionOwnerStatus->execute($owner, $status);
}
private function updateOtherOwners(StatementTransactionOwner $owner, int $status): void
{
StatementTransactionOwner::where('statement_transaction_id', $owner->statement_transaction_id)
->where('id', '!=', $owner->id)
->update(['status' => $status]);
}
}