Files
exchange-2.0/app/Classes/Modules/Accounting/ControllersLogic/ApproveDuplicateBankStatementDetailsStatusLogic.php
T

284 lines
11 KiB
PHP

<?php
namespace App\Classes\Modules\Accounting\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounting\Standards\Rules\CanApproveDuplicateBankStatementDetailsStatus;
use App\Classes\Modules\Accounting\Services\FetchesBankStatementTransaction;
use App\Http\Resources\BankStatementTransactionResource;
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Accounting\Services\FetchesBankStatementDetails;
use App\Classes\Modules\Accounting\Services\ListsBankStatementDetails;
use App\Models\StatementTransactionOwner;
use Illuminate\Support\Collection;
class ApproveDuplicateBankStatementDetailsStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Update Duplicate Bank Statement Details Status',
'message' => 'You have successfully updated the Statement Transation Status'
];
}
/** @var UpdatesBankStatementTransactionOwnerStatus */
private $updatesBankStatementTransactionOwnerStatus;
/** @var CanApproveDuplicateBankStatementDetailsStatus */
private $canApproveDuplicateBankStatementDetailsStatus;
/**
* @param UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus
* @param CanApproveDuplicateBankStatementDetailsStatus $canApproveDuplicateBankStatementDetailsStatus
*/
public function __construct(UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus, CanApproveDuplicateBankStatementDetailsStatus $canApproveDuplicateBankStatementDetailsStatus)
{
$this->updatesBankStatementTransactionOwnerStatus = $updatesBankStatementTransactionOwnerStatus;
$this->canApproveDuplicateBankStatementDetailsStatus = $canApproveDuplicateBankStatementDetailsStatus;
}
// /**
// * Perform logic for approving or rejecting a statement transaction owner and handle matching records.
// *
// * @param Request $request The request object containing route parameters and data.
// * @return JsonResponse The JSON response indicating the result of the logic.
// */
// public function logic(Request $request): JsonResponse
// {
// // Determine the status based on the 'status' route parameter
// $status = $request->route('status') == 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED;
//
// // Find the statement transaction owner based on the 'id' route parameter
// $owner = StatementTransactionOwner::find($request->route('id'));
//
// // Execute an update action to change the status of the owner
// $this->updatesBankStatementTransactionOwnerStatus->execute($owner, $status);
//
// // If the status is 'approved', reject all other owners with the same system, owner type, and owner ID
// if ($status === ApprovalStatus::APPROVED) {
// StatementTransactionOwner::where('system', $owner->system)
// ->where('owner_type', $owner->owner_type)
// ->where('owner_id', $owner->owner_id)
// ->where('id', '!=', $owner->id)
// ->update(['status' => ApprovalStatus::REJECTED]);
// }
//
// // Find all siblings (owners with the same statement transaction ID)
// $siblings = StatementTransactionOwner::where('statement_transaction_id', $owner->statement_transaction_id)
// ->where('id', '!=', $owner->id)
// ->get();
//
// // Process each sibling
// foreach ($siblings as $sibling) {
//
// // If the status is 'approved', reject the sibling and save the changes
// if ($status === ApprovalStatus::APPROVED) {
// $sibling->status = ApprovalStatus::REJECTED;
// $sibling->save();
// }
//
// // Find all twins (owners with the same system, owner type, and owner ID)
// $twins = StatementTransactionOwner::where('system', $sibling->system)
// ->where('owner_type', $sibling->owner_type)
// ->where('owner_id', $sibling->owner_id)
// ->where('id', '!=', $sibling->id)
// ->get();
//
// // Process each twin
// foreach ($twins as $twin) {
// // Find all owners with the same statement transaction ID as the twin
// $owners = StatementTransactionOwner::where('statement_transaction_id', $twin->statement_transaction_id)
// ->where('id', '!=', $twin->id)
// ->get();
//
// // If there is only one owner (the twin itself), execute an update action to change its status to 'approved'
// if (count($owners) === 1) {
// $this->updatesBankStatementTransactionOwnerStatus->execute($twin, ApprovalStatus::APPROVED);
// }
// }
// }
//
// // Find all remaining matching owners for the related transaction
// $remainingMatches = StatementTransactionOwner::where('system', $owner->system)
// ->where('owner_type', $owner->owner_type)
// ->where('owner_id', $owner->owner_id)
// ->where('status', ApprovalStatus::PENDING_VERIFICATION) // Consider only pending owners
// ->get();
//
// // Process each remaining match
// foreach ($remainingMatches as $match) {
// // Find all owners with the same statement transaction ID as the match
// $owners = StatementTransactionOwner::where('statement_transaction_id', $match->statement_transaction_id)
// ->where('id', '!=', $match->id)
// ->get();
//
// // If there is only one owner (the match itself), execute an update action to change its status to 'approved'
// if (count($owners) === 1) {
// $this->updatesBankStatementTransactionOwnerStatus->execute($match, ApprovalStatus::APPROVED);
// }
// }
//
// // Return an empty response
// return $this->response([]);
// }
/**
* Perform logic for approving or rejecting a statement transaction owner and handle matching records.
*
* @param Request $request The request object containing route parameters and data.
* @return JsonResponse The JSON response indicating the result of the logic.
*/
public function logic(Request $request): JsonResponse
{
$this->canApproveDuplicateBankStatementDetailsStatus->passes();
// Determine the approval status
$status = $this->getConstantStatus($request->route('status'));
// Find the statement transaction owner
$owner = $this->getOwner($request);
// Update owner status
$this->updateOwnerStatus($owner, $status);
// handle the siblings process
$this->handleSiblingsStatus($owner, $this->getSiblingsStatus($status));
// Check and approve remaining matches if any
$this->checkAndApproveRemainingMatches($owner, $status);
// Return an empty response
return $this->response([]);
}
private function getConstantStatus(String $statusName=null): int
{
switch ($statusName) {
case 'approve':
return ApprovalStatus::APPROVED;
case 'pending_verification':
return ApprovalStatus::PENDING_VERIFICATION;
default:
return ApprovalStatus::REJECTED;
}
}
private function getSiblingsStatus(int $status): int
{
return $status == ApprovalStatus::APPROVED ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
}
private function getOwner(Request $request): StatementTransactionOwner
{
return StatementTransactionOwner::find($request->route('id'));
}
private function updateOwnerStatus(StatementTransactionOwner $owner, int $status): void
{
$this->updatesBankStatementTransactionOwnerStatus->execute($owner, $status);
}
private function handleSiblingsStatus(StatementTransactionOwner $owner, int $siblingStatus): void
{
// update all other owners with the same system, owner type, and owner ID
$this->updateOtherOwners($owner, $siblingStatus);
// Find all siblings and process them
$siblings = $this->getSiblings($owner);
foreach ($siblings as $sibling) {
$this->processSibling($sibling, $siblingStatus);
}
}
private function updateOtherOwners(StatementTransactionOwner $owner, int $status): void
{
StatementTransactionOwner::getSiblingsOwner()
->where('id', '!=', $owner->id)
->update(['status' => $status]);
}
private function getSiblings(StatementTransactionOwner $owner): Collection
{
return StatementTransactionOwner::where('statement_transaction_id', $owner->statement_transaction_id)
->where('id', '!=', $owner->id)
->get();
}
private function processSibling(StatementTransactionOwner $sibling, int $siblingStatus): void
{
// Reject the sibling and save the changes
$sibling->status = $siblingStatus;
$sibling->save();
// Find all twins and process them
$twins = $this->getTwins($sibling);
foreach ($twins as $twin) {
$this->processTwin($twin);
}
}
private function getTwins(StatementTransactionOwner $sibling): Collection
{
return StatementTransactionOwner::getSiblingsOwner()
->where('id', '!=', $sibling->id)
->get();
}
private function processTwin(StatementTransactionOwner $twin): void
{
// Find all owners with the same statement transaction ID as the twin
$owners = $this->getSiblings($twin);
// If there is only one owner (the twin itself), approve it
if ($owners->count() === 1) {
$this->updateOwnerStatus($twin, $this->getConstantStatus(request()->route('status')));
}
}
private function checkAndApproveRemainingMatches(StatementTransactionOwner $owner, int $status): void
{
// Find all remaining matching owners for the related transaction
$checkStatus = ($status == ApprovalStatus::APPROVED ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::APPROVED);
$remainingMatches = $this->getRemainingMatches($owner, $checkStatus);
// Process each remaining match
foreach ($remainingMatches as $match) {
$this->processRemainingMatch($match, $status);
}
}
private function getRemainingMatches(StatementTransactionOwner $owner, int $checkStatus): Collection
{
return StatementTransactionOwner::getSiblingsOwner()
->where('status', $checkStatus)
->get();
}
private function processRemainingMatch(StatementTransactionOwner $match, int $status): void
{
// Find all owners with the same statement transaction ID as the match
$owners = $this->getSiblings($match);
// If there is only one owner (the match itself), approve it
if ($owners->count() === 1) {
$this->updateOwnerStatus($match, $status);
}
}
}