Files
exchange-2.0/app/Classes/Modules/Accounting/Processors/CreateBankStatementDetailsProcessor.php
T

213 lines
8.0 KiB
PHP

<?php
namespace App\Classes\Modules\Accounting\Processors;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\AccountStatement;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Group;
use App\Models\StatementTransactionsDetail;
use App\Models\Transaction;
use App\Models\Wallet;
use Illuminate\Support\Facades\Log;
use DateTime;
class CreateBankStatementDetailsProcessor
{
/**
* @param $transactions
* @return true
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(AccountStatement $statement) {
$transactions = $statement->transactions();
$transactions = $transactions->get();
$headers = [
'Date',
'Bank',
'Description',
'Credit',
'Debit',
'Pay For',
'System',
'System Reference',
'Human Reference',
'Multiple',
'Match?',
'System Amount'
];
$branches = [
0 => 'MBB Cyber',
1 => 'MBB SS2',
];
$yes = 'Yes';
$no = 'No';
$table = '<table><tr><th>'.implode('</th><th>', $headers).'</th></tr>';
$count = 0;
foreach ($transactions as $row) {
$existingRecord = StatementTransactionsDetail::where('statement_transaction_id', $row->id)->first();
if ($existingRecord && $existingRecord->pay_for != "") {
continue;
}
$count++;
$credit = 0.00;
$debit = 0.00;
$date = new DateTime($row['posting_date']);
$description = $row['transaction_description_2'];
if($row['amount'] < 0){
$debit = (float) $row['amount'];
}
else{
$credit = (float) $row['amount'];
}
$creditTransactions = [];
$debitTransactions = [];
$system = [];
$systemReference = null;
$systemAmount = null;
if($credit){
$creditTransactions = $this->getTransactions($date, $credit, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
foreach ($creditTransactions as $transaction) {
$systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
$systemAmount[] = $transaction->amount;
$system[] = 'EXCHANGE';
}
$creditTransactions = $this->getTransactions($date, $credit, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
foreach ($creditTransactions as $transaction) {
$systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
$systemAmount[] = $transaction->amount;
$system[] = 'EXCHANGE';
}
$creditTransactions = $this->getTransactionsFromShippingPortal($credit, $this->getDateRange($row['posting_date']));
foreach ($creditTransactions as $transaction) {
$systemReference[] = $transaction['order']['reference'];
$systemAmount[] = $transaction['amount'];
$system[] = 'SHIPPING';
}
}
if($debit){
$debitTransactions = $this->getTransactions($date, $debit, null, null, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], Group::class);
if(!count($debitTransactions)) {
foreach (['YSN', 'HCK', 'ATVANTIC', 'HIGH HILL'] as $reference){
if(str_contains($description, $reference)) {
$paymentDate = date('Y-m-d', strtotime('+1 day', strtotime($row['posting_date']))); //$date->addDays(1)->format('Y-m-d');
if($reference = 'ATVANTIC'){
$paymentDate = date('Y-m-d', strtotime($row['posting_date']));//$date->format('Y-m-d');
}
$issuer = Company::where('name', 'like', '%'.$reference.'%')->get()->pluck('id');
$debitTransactions = Group::whereIn('issuer', $issuer)->whereDate('created_at', $paymentDate)->get();
break;
}
}
}
foreach ($debitTransactions as $transaction) {
$systemReference[] = $transaction->reference;
$systemAmount[] = $transaction->amount;
$system[] = 'EXCHANGE';
}
}
$multiple = count($creditTransactions) + count($debitTransactions) > 1 ? $yes : $no;
$systemReference = $systemReference ? implode(',', $systemReference) : null;
$systemAmount = $systemAmount ? implode(',', $systemAmount) : null;
$system = $system ? implode(',', $system) : null;
$matches = $systemReference == $row['remarkreferences'] ? $yes : $no;
StatementTransactionsDetail::updateOrCreate(
['statement_transaction_id' => $row->id],
[
'date' => $date,
'pay_for' => is_null($system) ? "" : $system,
'system_references' => is_null($systemReference) ? "" : $systemReference,
'system_amounts'=> is_null($systemAmount) ? "" : $systemAmount,
'remark_references'=> is_null($row['remarkreferences']) ? "" : $row['remarkreferences'],
]
);
// if($count == 10){
// break;
// }
}
}
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
$query = $model::whereIn('status', $statuses)
->where(function ($query) use ($ownerType, $paymentMethod, $type) {
if ($ownerType) {
$query->where('owner_type', $ownerType);
}
if ($paymentMethod) {
$query->where('payment_method', '!=', $paymentMethod);
}
if ($type) {
$query->where('type', $type);
}
})
->whereDate('created_at', $date->format('Y-m-d'))
->where('amount', '>', ($amount - 0.01))
->where('amount', '<', ($amount + 0.01));
return $query->get();
}
private function getTransactionsFromShippingPortal($amount, $dateRange){
try{
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://izyim.cief-malaysia.com/public/api/v1/list?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2],"type":2,"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).'}');
$body = $response->getBody();
$data = json_decode($body, true);
$payload = $data['payload'];
$transactions2 = $payload['data'];
return $transactions2;
}catch(\Exception $exception){
Log::error($exception);
return [];
}
}
private function getDateRange(string $dateStr) {
// Create a DateTime object from the input string
$date = strtotime($dateStr);
// Get the first day of the month
$today = date('Y-m-d', $date);
// Get the first day of the next month
$nextDay = date('Y-m-d', strtotime('+1 day', $date));
return [
'start_date' => $today,
'end_date' => $nextDay,
];
}
}