mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
292 lines
14 KiB
PHP
292 lines
14 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\StatementTransactionOwnerType;
|
|
use App\Classes\ValueObjects\Constants\TransactionType;
|
|
use App\Models\Booking;
|
|
use App\Models\Company;
|
|
use App\Models\Group;
|
|
use App\Models\StatementTransaction;
|
|
use App\Models\Transaction;
|
|
use App\Models\Wallet;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class CreateBankStatementTransactionOwnersProcessor
|
|
{
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public function execute() {
|
|
|
|
$transactions = StatementTransaction::whereDoesntHave('owners', function($query){
|
|
return $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
|
})->orderBy('posting_date')->get();
|
|
|
|
// $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get();
|
|
|
|
foreach ($transactions as $transaction) {
|
|
|
|
if($transaction->amount > 0){
|
|
|
|
// Exchange Sales
|
|
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
|
foreach ($creditTransactions as $creditTransaction) {
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::SALES,
|
|
'system' => 'EXCHANGE',
|
|
'owner_type' => Transaction::class,
|
|
'owner_id'=> $creditTransaction->id,
|
|
'owner_reference'=> $creditTransaction->owner->marking,
|
|
]);
|
|
}
|
|
|
|
|
|
// Shipping Portal Sales
|
|
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date), 2);
|
|
foreach ($creditTransactions as $creditTransaction) {
|
|
if($creditTransaction['owner_type'] === Wallet::class) continue;
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::SALES,
|
|
'system' => 'SHIPPING_PORTAL',
|
|
'owner_type' => $creditTransaction['owner_type'],
|
|
'owner_id'=> $creditTransaction['owner_id'],
|
|
'owner_reference'=> $creditTransaction['owner_reference'],
|
|
]);
|
|
}
|
|
|
|
// Exchange Wallet Top Up
|
|
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
|
foreach ($creditTransactions as $creditTransaction) {
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
|
|
'system' => 'EXCHANGE',
|
|
'owner_type' => Transaction::class,
|
|
'owner_id'=> $creditTransaction->id,
|
|
'owner_reference'=> $creditTransaction->owner->owner->reference,
|
|
]);
|
|
}
|
|
|
|
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date), 5);
|
|
foreach ($creditTransactions as $creditTransaction) {
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
|
|
'system' => 'SHIPPING_PORTAL',
|
|
'owner_type' => $creditTransaction['owner_type'],
|
|
'owner_id'=> $creditTransaction['owner_id'],
|
|
'owner_reference'=> $creditTransaction['owner_reference'],
|
|
]);
|
|
}
|
|
|
|
// fpx charge refund
|
|
if($transaction->transaction_description === 'DUITNOW S/CHRG REFUND'){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::FPX_CHARGE_REFUND
|
|
]);
|
|
}
|
|
|
|
// Customer Refund
|
|
|
|
// INTERNAL_BANK_TRANSFER_IN
|
|
if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN
|
|
]);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
if($transaction->amount < 0){
|
|
|
|
// Supplier Purchase Order Payments
|
|
foreach (['YSN', 'HCK', 'ATVANTIC', 'HIGH HILL'] as $reference){
|
|
if(str_contains($transaction->transaction_description.' '.$transaction->transaction_description_2.' '.$transaction->transaction_description_3.' '.$transaction->transaction_description_4.' '.$transaction->transaction_description_5 , $reference)) {
|
|
$paymentDateStart = $transaction->posting_date->startOfDay()->subDays(1);
|
|
$paymentDateEnd = $transaction->posting_date->endOfDay();
|
|
|
|
if($paymentDateStart->dayOfWeek === Carbon::SUNDAY){
|
|
$paymentDateStart->subDays(2);
|
|
}
|
|
$issuer = Company::where('name', 'like', '%'.$reference.'%')->get()->pluck('id');
|
|
|
|
$debitTransactions = Group::whereIn('issuer', $issuer)->where('amount', '>=', (($transaction->amount * -1) - 0.01))
|
|
->where('amount', '<=', (($transaction->amount * -1) + 0.01))->whereDate('created_at', '>=', $paymentDateStart)->whereDate('created_at', '<=', $paymentDateEnd)->get();
|
|
|
|
foreach ($debitTransactions as $debitTransaction) {
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::SUPPLIER_PAYMENT,
|
|
'system' => 'EXCHANGE',
|
|
'owner_type' => Group::class,
|
|
'owner_id'=> $debitTransaction->id,
|
|
'owner_reference'=> $debitTransaction->reference
|
|
]);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// Exchange Wallet Withdrawal
|
|
$debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
|
foreach ($debitTransactions as $debitTransaction) {
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL,
|
|
'system' => 'EXCHANGE',
|
|
'owner_type' => Transaction::class,
|
|
'owner_id'=> $debitTransaction->id,
|
|
'owner_reference'=> $debitTransaction->owner->owner->marking,
|
|
]);
|
|
}
|
|
|
|
// SALARY
|
|
|
|
// STATUTORY
|
|
if(str_contains($transaction->transaction_description_2, 'PEMBANGUNAN SUMBER') || str_contains($transaction->transaction_description_2, 'HASIL') || str_contains($transaction->transaction_description_2, 'PERTUBUHAN KESELAMAT') || str_contains($transaction->transaction_description_2, 'KUMPULAN WANG SIMPAN')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::STATUTORY
|
|
]);
|
|
}
|
|
|
|
// FPX_CHARGE
|
|
if($transaction->transaction_description === 'DR DUITNOW S/CHRG' || str_contains($transaction->transaction_description, 'Manual FPX') || str_contains($transaction->transaction_description, 'CMS - DR FPX CHG')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::FPX_CHARGE
|
|
]);
|
|
}
|
|
|
|
// BANK_CHARGE
|
|
if($transaction->transaction_description === 'CMS - DR CORP CHG' || $transaction->transaction_description === 'MONTHLY PROFIT DEBIT'){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::BANK_CHARGE
|
|
]);
|
|
}
|
|
|
|
// CREDIT_CARD_PAYMENT
|
|
if(str_contains($transaction->transaction_description_2, 'VISA CARD')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::CREDIT_CARD_PAYMENT
|
|
]);
|
|
}
|
|
|
|
// INTERNAL_BANK_TRANSFER_OUT
|
|
if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE') || str_contains($transaction->transaction_description_2, 'CIEF WORLWIDE') || str_contains($transaction->transaction_description_2, 'IZYIM GLOBAL')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_OUT
|
|
]);
|
|
}
|
|
|
|
// non-operational charges
|
|
if(str_contains($transaction->transaction_description_2, 'HIRE PURCHASE') || str_contains($transaction->transaction_description_2, 'TENAGA NASIONAL') || str_contains($transaction->transaction_description, 'CABLE CHARGE') || str_contains($transaction->transaction_description_2, 'CTOS DATA SYSTEMS') || str_contains($transaction->transaction_description_2, 'MAXIS')){
|
|
$transaction->owners()->firstOrCreate([
|
|
'type' => StatementTransactionOwnerType::NON_OPERATIONAL
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
|
|
if (App::environment(['production'])) {
|
|
$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();
|
|
} else {
|
|
$dateRange = $this->getDateRange($date);
|
|
$result = $this->getTransactionsFromExchange($amount, $dateRange, $type, $ownerType, $paymentMethod);
|
|
$transactionsId = Arr::pluck($result, 'owner_id');
|
|
$query = $model::whereIn('id', $transactionsId);
|
|
|
|
return $query->get();
|
|
}
|
|
}
|
|
|
|
private function getTransactionsFromExchange($amount, $dateRange, $type, $ownerType, $paymentMethod){
|
|
$url = 'https://exchange.cief-malaysia.com/public/api/v1/transactions/mappable/query';
|
|
return $this->getFromExchange($url, $amount, $dateRange, $type, $ownerType, $paymentMethod);
|
|
}
|
|
|
|
private function getFromExchange($url, $amount, $dateRange, $type, $ownerType, $paymentMethod){
|
|
$paymentMethodFilter = "";
|
|
if ($paymentMethod) {
|
|
$paymentMethodFilter = ',"payment_method_not_in":['.$paymentMethod.']';
|
|
}
|
|
$ownerType = addslashes($ownerType);
|
|
try{
|
|
$client = new \GuzzleHttp\Client(['verify' => false]);
|
|
$response = $client->request('GET', $url.'?api-key=abc&filters={"order_by":{"column":"id","DESC":true},"status_in":[2,3],"owner_type":"'. $ownerType . '"' . $paymentMethodFilter.',"type":'.$type.',"created_after_or_equal":"'.$dateRange['start_date'].'","created_before_or_equal":"'.$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 getTransactionsFromShippingPortal($amount, $dateRange, $type){
|
|
$url = 'https://izyim.cief-malaysia.com/public/api/v1/transactions/mappable/query';
|
|
return $this->getFromShippingPortal($amount, $dateRange, $url, $type);
|
|
}
|
|
|
|
private function getGroupsFromShippingPortal($amount, $dateRange, $type){
|
|
$url = 'https://izyim.cief-malaysia.com/public/api/v1/groups/query';
|
|
return $this->getFromShippingPortal($amount, $dateRange, $url, $type);
|
|
}
|
|
|
|
private function getFromShippingPortal($amount, $dateRange, $url, $type){
|
|
try{
|
|
|
|
$client = new \GuzzleHttp\Client(['verify' => false]);
|
|
$response = $client->request('GET', $url.'?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).',"type_in:"['.$type.']}');
|
|
$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', strtotime('-1 day', $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,
|
|
];
|
|
}
|
|
}
|