Merge branch 'dillon/34.7-jenkins-vapor' into vapor/staging

This commit is contained in:
Dillon Ngo
2024-10-12 14:56:39 +08:00
593 changed files with 20136 additions and 2248 deletions
+8 -1
View File
@@ -35,7 +35,7 @@ MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_BUCKET=exchange-2.0-localhost
PUSHER_APP_ID=
PUSHER_APP_KEY=
@@ -68,3 +68,10 @@ VOUCHERIFY_APPLICATION_ID=""
VOUCHERIFY_CLIENT_SECRET_KEY=""
VOUCHERIFY_VERSION="v2018-08-01"
VOUCHERIFY_URL="https://as1.api.voucherify.io"
VAPOR_ENV=local
LARAVEL_VAPOR_ENABLED=false
COMMANDS_V2_ENABLED=false
SENDING_EMAIL_ENABLED=false
SENDING_EMAIL_WELCOME_VOUCHER_ENABLED=false
Vendored
+28 -2
View File
@@ -9,8 +9,10 @@
pipeline {
agent {
docker {
image 'dillonngo/docker-based-image:poc'
args "--group-add 992 -v /var/run/docker.sock:/var/run/docker.sock"
args '--group-add 992 -v /var/run/docker.sock:/var/run/docker.sock'
image '303644228504.dkr.ecr.ap-southeast-1.amazonaws.com/jenkins-pipeline-agent:latest'
registryCredentialsId "ecr:ap-southeast-1:aws-ec2-instance-iam-role"
registryUrl "https://303644228504.dkr.ecr.ap-southeast-1.amazonaws.com"
}
}
environment {
@@ -20,6 +22,7 @@ pipeline {
stage('Download source code from Git') {
steps {
script{
currentBuild.description = 'Step 1 of 6 Completed'
switch(GIT_BRANCH) {
case "vapor/production":
case "vapor/staging":
@@ -29,6 +32,7 @@ pipeline {
credentialsId: 'gitlab-jenkins-localhost',
branch: GIT_BRANCH
)
break
case "origin/dillon/34-jenkins-vapor":
git(
url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
@@ -37,6 +41,7 @@ pipeline {
)
break
}
currentBuild.description = 'Step 2 of 6 Completed'
}
}
}
@@ -44,12 +49,18 @@ pipeline {
stage('Install') {
steps {
sh 'composer update'
script{
currentBuild.description = 'Step 3 of 6 Completed'
}
}
}
stage('Tests') {
steps {
sh 'vendor/bin/phpunit tests/Unit'
script{
currentBuild.description = 'Step 4 of 6 Completed'
}
}
}
@@ -73,6 +84,20 @@ pipeline {
sh "vendor/bin/vapor deploy development --message='${gitCommitMessage}'"
break
}
currentBuild.description = 'Step 5 of 6 Completed'
}
}
}
stage('Cleanup') {
steps {
script {
try {
sh 'docker image prune -a -f'
} catch (Exception e) {
echo "Error during cleanup: ${e.message}"
}
currentBuild.description = 'Step 6 of 6 Completed'
}
}
}
@@ -87,5 +112,6 @@ String getCommitMessage(){
commitMessage = entry.msg
}
}
commitMessage = commitMessage.replace("'", "`")
return commitMessage
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\Exceptions;
use App\Classes\ValueObjects\Constants\HttpStatus;
use Illuminate\Support\Facades\Log;
final class ConnectionErrorException extends ServiceApiException {
public function __construct(?string $message = null, ?string $exceptionMessage = null, ?string $payload = null, ?string $exceptionTrace = null) {
Log::error($message. ": ". $exceptionMessage);
if($payload){
Log::error('Payload: '.$payload);
}
if($exceptionTrace){
Log::error($exceptionTrace);
}
parent::__construct($message ?? 'A connection error has occurred. Please check application logs for more information.',
HttpStatus::SERVER_ERROR);
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\General;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\Exportable;
class AWSS3Helper
{
/**
* @param string $exportFileName
* @param Exportable $exportableObject
* @return string
*/
static function S3Exportable($exportFileName, $exportableObject){
//Step 1: Upload to S3
$filePathForS3 = 'temp/' . $exportFileName;
$exportableObject->store($filePathForS3, 's3');
//Step 2: Return temporary URL from S3
$temporaryUrl = Storage::disk('s3')->temporaryUrl(
$filePathForS3,
Carbon::now()->addMinutes(10)
);
return $temporaryUrl;
}
/**
* @param string $exportFileName
* @param string|resource $contents
* @return string
*/
static function S3PDF($exportFileName, $contents){
//Step 1: Upload to S3
$filePathForS3 = 'temp/' . $exportFileName;
Storage::disk('s3')->put($filePathForS3, $contents);
//Step 2: Return temporary URL from S3
$temporaryUrl = Storage::disk('s3')->temporaryUrl(
$filePathForS3,
Carbon::now()->addMinutes(10)
);
return $temporaryUrl;
}
}
@@ -18,6 +18,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Classes\Exceptions\JobResourceNotFoundException;
use App\Classes\General\LogHelper;
abstract class AbstractControllerLogic
{
@@ -69,7 +70,7 @@ abstract class AbstractControllerLogic
} catch (ErrorException|GeneralExceptions $exception){
if ($exception instanceof JobResourceNotFoundException) {
Log::error(sprintf(
LogHelper::channel('vue_polling')->info(sprintf(
"Uncaught exception '%s' with message '%s' in %s:%d",
get_class($exception),
$exception->getMessage(),
@@ -10,7 +10,7 @@ use App\Classes\General\Interfaces\DataTransferObject;
abstract class AbstractRule
{
abstract protected function authorized(): bool;
abstract protected function authorized($object): bool;
abstract protected function validators($object): bool;
@@ -26,8 +26,8 @@ abstract class AbstractRule
*/
public function passes(?DataTransferObject $object = null): bool {
try {
if(!$this->authorized()){
throw new AccessForbiddenException('You don\'t have permission to preform this action');
if(!$this->authorized($object)){
throw new AccessForbiddenException('You don\'t have permission to perform this action');
}
$this->validators($object);
@@ -36,11 +36,11 @@ abstract class AbstractRule
return true;
} catch(AccessForbiddenException $exception){
throw new AccessForbiddenException('You don\'t have permission to preform this action');
throw new AccessForbiddenException('You don\'t have permission to perform this action');
} catch(\Exception $exception){
throw new RequestValidationException($exception->getMessage());
}
}
}
}
@@ -43,7 +43,7 @@ abstract class AbstractListRecord extends AbstractGetRecord
}
if(!empty($param)){
return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get();
return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get(); //page data from query parameters e.g ?page=1
}
else{
return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get();
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class CurrencyRateIsNotEqual implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('currency_rate', '!=', $value);
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class DoesNotHaveRefundInProgress implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDoesntHave('transactions', function ($query) {
return $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION]);
});
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class GroupByImportedDate implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->groupby('imported_date');
}
}
@@ -2,7 +2,6 @@
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
@@ -12,33 +11,17 @@ class HasActiveReward implements Filter
/**
* @param Builder $builder
* @param $value
* @return mixed
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
return $builder->where('user_id', $userId)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
return $builder->where('user_id', Auth::user()->id) //cief todo: should not use Auth::user()->id
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
});
}
else{
return $builder->where('user_id', Auth::user()->id)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
// ->orWhereDoesntHave('reward');
});
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class HasActiveRewardForAdmin implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('user_id', $value)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
});
// ->orWhereDoesntHave('reward');
});
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Database\Eloquent\Builder;
class HasPendingVerifyTransaction implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('transactions', function ($q) {
$q->where('status', ApprovalStatus::PENDING_VERIFICATION);
});
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class HasVouchersAllWithCompany implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
$user = User::where('id', $userId)->first();
$users = $user->company()->first()->employees;
$userIds = $users->pluck('id');
return $builder->whereIn('user_id', $userIds)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
});
}
else{
$user = User::where('id', Auth::user()->id)->first();
$users = $user->company()->first()->employees;
$userIds = $users->pluck('id');
return $builder->whereIn('user_id', $userIds)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class HasVouchersAllWithUser implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
return $builder->where('user_id', $userId)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
});
}
else{
return $builder->where('user_id', Auth::user()->id)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ImportedDateFrom implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('imported_date', '>=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ImportedDateTo implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('imported_date', '<=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class IsMappedFalseOrMappedButStatusIn implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where(function($q) use ($value) {
$q->whereDoesntHave('owners');
$q->orwhereDoesntHave('owner_status');
});
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class IsNotFullyRefunded implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->withSum(['transactions as total_refund_amount' => function($q) {
$q->refunds()->where('status', ApprovalStatus::APPROVED);
}], 'original_amount')
->having('total_refund_amount', '<', DB::raw('original_amount'));
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class IsPartialRefund implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owner', function ($q) use ($value) {
if ($value) {
$q->where('original_amount', '!=', DB::raw('transactions.original_amount'));
} else {
$q->where('original_amount', DB::raw('transactions.original_amount'));
}
});
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OrderByCreatedAtDescWithLimit implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->orderBy('created_at', 'desc')->take(500);
}
}
@@ -4,7 +4,7 @@ namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class RandomName implements Filter
class OrderByIdDesc implements Filter
{
/**
@@ -14,7 +14,7 @@ class RandomName implements Filter
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('is_active', $value);
return $builder->orderBy('id', 'desc');
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OwnerDoesNotHaveTransactionType implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDoesntHave('owner', function($query) use($value) {
return $query->whereHas('transactions', function($query) use($value) {
return $query->where('transactions.type', $value);
});
});
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OwnerHasTransactionType implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owner', function($query) use($value) {
return $query->whereHas('transactions', function($query) use($value) {
return $query->where('transactions.type', $value);
});
});
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ReceiverIn implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereIn('receiver', $value);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class RequestSignature implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('request_signature', $value);
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ResultNotNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereNotNull('result');
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionInvoiceReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('Invoice_reference', $value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionOwnerReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('owner_reference', $value);
});
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionPostingEnd implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('posting_date', '<=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionPostingStart implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('posting_date', '>=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionReceiptReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('receipt_reference', $value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WhereHasOwnersAndNotNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->whereNotNull($value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WhereHasOwnersAndNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->whereNull($value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Database\Eloquent\Builder;
class WithoutBillGroup implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDoesntHave('billGroup');
}
}
+20 -4
View File
@@ -3,6 +3,8 @@ namespace App\Classes\General;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
class ExcelHandel
{
@@ -67,9 +69,23 @@ class ExcelHandel
public static function generateExcel($path = '', $exceldata = '', $filename = '', $extension = '')
{
$file_info = [];
$file = \Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata);
$file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension);
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
$filePathForS3 = 'public/excels/' . $path . '/' . $filename . '.' . $extension;
Storage::disk('s3')->put($filePathForS3, $exceldata);
$temporaryUrl = Storage::disk('s3')->temporaryUrl(
$filePathForS3,
Carbon::now()->addMinutes(10)
);
$file_info['original']['file'] = $temporaryUrl; //REMINDER: This is a path to AWS S3 URL (HTTPS) as a public anonymous user, NOT an internal system path
}
else{
$file = Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata);
$file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension);
}
return $file_info;
}
@@ -84,4 +100,4 @@ class ExcelHandel
return true;
}
}
}
+9
View File
@@ -2,6 +2,7 @@
namespace App\Classes\General;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
@@ -57,4 +58,12 @@ class Helper
return $json !== null ? collect(json_decode($json))->toArray() : [];
}
/**
* @param ResourceCollection $collection
* @return array
*/
static function collectionResponse(ResourceCollection $collection){
return json_decode($collection->response()->getContent(), true);
}
}
@@ -0,0 +1,12 @@
<?php
namespace App\Classes\General\Interfaces;
use Illuminate\Database\Eloquent\Relations\MorphMany;
interface KeyValueInterface
{
public function attributesKVP(): morphMany;
}
@@ -0,0 +1,13 @@
<?php
namespace App\Classes\General\Interfaces;
use Illuminate\Database\Eloquent\Relations\MorphMany;
interface Remarkable
{
public function remarks(): morphMany;
}
+54
View File
@@ -0,0 +1,54 @@
<?php
namespace App\Classes\General;
use Illuminate\Support\Facades\Log;
class LogHelper
{
private String $channelName;
public static function channel($channelName): self
{
$logHelper = new self;
$logHelper->channelName = $channelName;
return $logHelper;
}
public function info($message)
{
$envVar = env('LARAVEL_VAPOR_ENABLED');
$isLocal = env('VAPOR_ENV') === 'local';
Log::info("LogHelper.info: {$message} channelName {$this->channelName}, envVar {$envVar}");
if ($envVar && !$isLocal) {
Log::channel($this->channelName.'_vapor')->info($message);
}
else{
Log::channel($this->channelName)->info($message);
}
}
public function warning($message)
{
$envVar = env('LARAVEL_VAPOR_ENABLED');
$isLocal = env('VAPOR_ENV') === 'local';
Log::info("LogHelper.warning: {$message} channelName {$this->channelName}, envVar {$envVar}");
if ($envVar && !$isLocal) {
Log::channel($this->channelName . '_vapor')->warning($message);
} else {
Log::channel($this->channelName)->warning($message);
}
}
public function error($message)
{
$envVar = env('LARAVEL_VAPOR_ENABLED');
$isLocal = env('VAPOR_ENV') === 'local';
Log::info("LogHelper.error: {$message} channelName {$this->channelName}, envVar {$envVar}");
if ($envVar && !$isLocal) {
Log::channel($this->channelName . '_vapor')->error($message);
} else {
Log::channel($this->channelName)->error($message);
}
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Wallet;
use Illuminate\Support\Facades\Log;
class AuditAndUpdateWallletBalanceV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Audit and Update Wallet Balance.');
$start = new Carbon();
$wallets = Wallet::all();
$i = 0;
foreach ($wallets as $wallet) {
$topups = 0;
$credit = 0;
$payments = 0;
$debit = 0;
foreach ($wallet->transactions as $transaction) {
if (!in_array((int) $transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) continue;
if ((int) $transaction->type === TransactionType::TOP_UP) {
$topups += (float) $transaction->amount;
}
if ((int) $transaction->type === TransactionType::CREDIT_NOTE) $credit += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::PAYMENT) $payments += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::DEBIT_NOTE) $debit += (float) $transaction->amount;
}
$auditBalance = ($topups + $credit) - ($payments + $debit);
$diffenrence = round((float) $wallet->amount - (($topups + $credit) - ($payments + $debit)), 2);
if ((($diffenrence == 0) || ($diffenrence == -0)) and $wallet->amount > -0.01) continue;
$i++;
Log::info($i . ". Marking: " . $wallet->owner->reference . "(" . $wallet->id . ")" . PHP_EOL . "Current Balance: " . $wallet->amount . PHP_EOL . "Audit Balance: " . ($auditBalance) . PHP_EOL . "Difference: " . $diffenrence . PHP_EOL);
Wallet::where('id', $wallet->id)->update(['amount' => $auditBalance]);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Audit and Update Wallet Balance. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,89 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\Booking;
use App\Models\Transaction;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
use App\Classes\Modules\Transactions\Services\GeneratesPurchaseOrderProducts;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class AutoFillPurchaseOrderV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Auto fill up the purchase order for booking that have payment.');
$start = new Carbon();
// 5. If purchase order not fill up in 2 month, auto fill up it
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(60)->endOfDay())
->whereHas('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})
->whereDoesntHave('transactions', function($transaction){
$transaction->where('type', TransactionType::PURCHASE_ORDER);
$transaction->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]);
})->get();
Log::info('Bookings count: '.count($bookings));
foreach ($bookings as $booking) {
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id)
->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
if (!$po) {
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
}
$products = (App()->make(GeneratesPurchaseOrderProducts::class))->execute($po, $booking->fix_amount);
$deference = $booking->fix_amount - $products->sum('total');
if($deference > -150 && $deference < 150 && $deference != 0) {
$products->push([
'description' => $deference < 0 ? 'Discount':'Shipping Fee',
'quantity' => 1,
'stockCode' => '',
'total' => $deference,
'unit_price' => $deference
]);
}
$billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('XPO-');
Log::info('Single booking billNumber: '.$billNumber);
$total = $products->sum('total');
$object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1,
1, PaymentMethodType::CASH,
$total, $total, $booking->fix_currency_id, $booking->fix_currency_id,
1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray());
(App()->make(CreatePurchaseOrderTransactionProcessor::class))->execute($booking, $object);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Auto fill up the purchase order for booking that have payment. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,63 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class DebugBillplzFailedPaymentV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Debug Billplz Failed Payment.');
$start = new Carbon();
$transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->get();
$i = 0;
$totalAmount = 0;
foreach ($transactions as $transaction){
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference);
// dd($response);
if($response->successful()){
$data = $response->json();
if($data['paid']){
if (!in_array($transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) {
$this->returnLog('Paid transaction', $transaction);
}
}
// else {
// $totalAmount += $transaction->amount;
// $this->returnLog('Unpaid Transaction', $transaction);
// }
}else{
$this->returnLog('billplz error', $transaction);
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Debug Billplz Failed Payment. ElapsedTime: ' . $elapsedTime . '.');
}
public function returnLog($text, $transaction) {
$approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;
Log::info($text . ' - id: '. $transaction->id . '. Booking Marking: '. $transaction->owner->marking . ' - Date: '.$transaction->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Current Status: ' . $approvalStatusArray[$transaction->status]);
}
}
@@ -0,0 +1,75 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class DeleteBulkInvoiceFilesV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Delete all the bulk download files.');
$start = new Carbon();
$directories = [
storage_path('app/bulk_invoice'),
storage_path('app/bulk_whiteform'),
];
foreach ($directories as $directory) {
$startInner = new Carbon();
Log::info(Carbon::now() . ' [Local] Start cleaning - ' . $directory);
if (File::isDirectory($directory)) {
File::cleanDirectory($directory);
Log::info('[Local] All files have been deleted.');
} else {
Log::info('[Local] Directory does not exist.');
}
$endInner = new Carbon();
$elapsedTime = $startInner->diff($endInner)->format('%H:%I:%S');
Log::info(Carbon::now() . ' [Local] Process ended. ElapsedTime: ' . $elapsedTime);
}
$s3 = Storage::disk('s3');
$directories = [
'bulk_invoice',
'bulk_whiteform',
];
foreach ($directories as $directory) {
$startInner = Carbon::now();
Log::info(Carbon::now() . ' [S3] Start cleaning - ' . $directory);
$objects = $s3->allFiles($directory);
foreach ($objects as $object) {
$s3->delete($object);
Log::info('[S3] Deleted object: ' . $object);
}
Log::info('[S3] All files have been deleted.');
$endInner = Carbon::now();
$elapsedTime = $startInner->diff($endInner)->format('%H:%I:%S');
Log::info(Carbon::now() . ' [S3] Process ended. ElapsedTime: ' . $elapsedTime);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Delete all the bulk download files. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,61 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Models\Bank;
use App\Models\Booking;
class DeleteDuplicate1688BankAccountV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Delete duplicate 1688 account in banks table.');
$start = new Carbon();
// account_no: 1688 LOGIN ID/EMAIL/PHONE
// holder_name: password
// bank_branch: 6-digit pin
$records = Bank::where('type', 3)->get();
$groupedBanks = $records->groupBy(function($item, $key) {
return $item['company_id'] . '-' . $item['account_no'];
});
foreach ($groupedBanks as $key => $banksWithSameUserAndAccountNo) {
// Sort banks by created_at or updated_at to find the latest one
$sortedBanks = $banksWithSameUserAndAccountNo->sortByDesc('created_at');
// Retain the latest bank
$latestBank = $sortedBanks->first();
// Get all IDs except the latest one
$idsToDelete = $sortedBanks->pluck('id')->slice(1);
foreach ($idsToDelete as $id) {
Booking::where('bank_id', $id)->update([
'bank_id' => $latestBank->id
]);
}
Log::info('for company id: ' . $latestBank->company_id . ', account no: ' . $latestBank->account_no . ', duplicated id: ' . $idsToDelete);
// Delete the rest
Bank::whereIn('id', $idsToDelete)->delete();
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Delete duplicate 1688 account in banks table. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,88 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use App\Classes\Modules\Jobs\DataTransferObjects\DeleteOrderV2CommandObject;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Booking;
class DeleteOrderV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var DeleteOrderV2CommandObject */
private $deleteOrderV2CommandObject;
/**
* DeleteOrderV2CommandJob constructor.
* @param DeleteOrderV2CommandObject $deleteOrderV2CommandObject
*/
public function __construct(DeleteOrderV2CommandObject $deleteOrderV2CommandObject)
{
$this->deleteOrderV2CommandObject = $deleteOrderV2CommandObject;
}
public function handle()
{
Log::info(Carbon::now() . ': Start job - Change refunded booking status to expired.');
$start = new Carbon();
$bookings_reference = $this->deleteOrderV2CommandObject->getBookingsReference();
// $bookings_reference = '28546,38599,44487,71086,70133,58580,42831,96028,41188,33894,95877,86732,31894,50962,44215,92894,40968,30303,89762,74693,45271,27169';
$bookings_reference = explode(',', $bookings_reference);
foreach ($bookings_reference as $reference) {
$booking = Booking::where('marking', $reference)->first();
if (!$booking) {
$this->logOutput('Booking not found: ' . $reference);
} else {
$payment = $booking->transactions()
->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->first();
$payment->status = ApprovalStatus::EXPIRED;
$payment->save();
$this->logOutput('Booking ' . $reference . ' Payment deleted: ' . $payment->id);
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Change refunded booking status to expired. ElapsedTime: ' . $elapsedTime . '.');
$this->logOutput('Process ended. ElapsedTime: ' . $elapsedTime);
}
public function logOutput($text) //cief todo: what is the purpose of this?
{
if (is_array($text)) {
$text = implode(', ', $text);
}
Log::info(Carbon::now() . ' [DeleteOrderV2] : ' . $text);
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
}
else{
$filePath = storage_path('logs/delete-orders.log');
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $text . PHP_EOL;
file_put_contents($filePath, $textToAppend, FILE_APPEND);
}
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class DummyJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Dummy.');
$start = new Carbon();
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Dummy. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,120 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use ZipArchive;
use Illuminate\Support\Facades\Log;
class EmailDoToVTV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Send do to vt nation.');
$start = new Carbon();
Auth::login(User::findOrFail(1));
$zip_file = 'do_'.Carbon::yesterday()->format('Y_m_d').'.zip';
$attachment = storage_path().'/'.$zip_file;
$startDate = Carbon::yesterday();
$endDate = Carbon::yesterday();
$bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $startDate)->whereDate('updated_at', '<=', $endDate)
->whereHas('transactions', function ($query){
return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query){
return $query->where('issuer', 2);
});
})->get();
if(!count($bookings)){ return; }
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
$zip = new ZipArchive();
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
//STEP 1: Go through each of the booking from query
foreach ($bookings as $booking) {
$file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first();
$fileContent = Storage::disk('s3')->get($file->file->file_info->original->file);
$zip->addFromString($booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);
}
$zip->close();
//STEP 2: Upload the zip file to S3
// $filePathForS3 = 'temp/'.$zip_file;
// Storage::disk('s3')->put($filePathForS3, file_get_contents($attachment));
// Log::info('DownloadBookingDocumentLogic finished processing files to zip count: '.count($bookings));
// $temporaryUrl = Storage::disk('s3')->temporaryUrl(
// $filePathForS3,
// Carbon::now()->addMinutes(10)
// );
//STEP 3: Send Email
Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){
$message->from('exchange@cief-malaysia.com');
$message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']);
$message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']);
$message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y'));
$message->attach($attachment);
});
File::delete($attachment);
Log::info('success');
//STEP 4. No Response needed because this is a job
//return response(['src' => $temporaryUrl ]);
}
}
else{
$zip = new ZipArchive();
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
foreach ($bookings as $booking) {
$file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first();
$zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y').'_'.$booking->marking.'.pdf');
}
$zip->close();
Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){
$message->from('exchange@cief-malaysia.com');
$message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']);
$message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']);
$message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y'));
$message->attach($attachment);
});
File::delete($attachment);
Log::info('success');
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Send do to vt nation. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,82 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
use Illuminate\Support\Facades\Log;
class ExpiredBookingV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Expiring booking that do not have further action by user.');
$start = new Carbon();
// 1. Cancel booking without payment & purchase order (1 month)
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(30)->endOfDay())
->where('service_id', '!=', 4)
->where(function ($query) {
$query->whereDoesntHave('transactions')
->orWhereDoesntHave('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PURCHASE_ORDER)->orWhere(function ($q) {
$q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]);
});
});
})->get();
foreach ($bookings as $booking) {
(App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED);
Log::info(Carbon::now() . " : Expired Booking without payment & purchase order, booking id: " . $booking->id);
$transactions = $booking->transactions;
foreach ($transactions as $transaction) {
$prevStatus = $transaction->status;
$transaction->status = ApprovalStatus::EXPIRED;
$transaction->save();
Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}");
}
}
// 2. Cancel booking without payment but with purchase order (2 month)
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(60)->endOfDay())
->where(function ($query) {
$query->whereDoesntHave('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]);
})->whereHas('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PURCHASE_ORDER);
});
})->get();
foreach ($bookings as $booking) {
(App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED);
Log::info(Carbon::now() . " : Expired Booking without payment but with purchase order, booking id: " . $booking->id);
$transactions = $booking->transactions;
foreach ($transactions as $transaction) {
$prevStatus = $transaction->status;
$transaction->status = ApprovalStatus::EXPIRED;
$transaction->save();
Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}");
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Expiring booking that do not have further action by user. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,171 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Transaction;
use Illuminate\Support\Facades\Log;
class ExpiredRefundedBookingV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Expiring refunded booking.');
$start = new Carbon();
// 3. Cancel fully refunded payment & cancel booking
$transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->where('payment_reference', 'LIKE', "%refund%")->get();
foreach ($transactions as $transaction) {
// get the booking marking
$payment_reference = explode(" ", trim($transaction->payment_reference));
// $marking = substr($transaction->payment_reference, -5);
$marking = trim(end($payment_reference));
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode(".", trim($transaction->payment_reference));
$marking = trim(end($payment_reference));
}
// for a special payment reference on transaction id: 140231
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode("No", trim($transaction->payment_reference));
$marking = end($payment_reference);
}
// for a special payment reference on transaction id: 152013
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode(" ", trim($transaction->payment_reference));
$marking = end($payment_reference);
$marking = prev($payment_reference);
}
if (preg_match('/^[0-9]+$/', $marking)) {
$booking = Booking::where('marking', $marking)->first();
if ($booking) {
$bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first();
if (!$bookingPayment) {
$bookingPaymentCount = $booking->transactions()->payments()->count();
if ($bookingPaymentCount > 1) {
Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking.");
foreach ($booking->transactions()->payments()->get() as $bp) {
if ($transaction->amount - $bp->amount < 0.01) {
$bookingPayment = $bp;
break;
}
}
}
if (!$bookingPayment) {
$bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->orderBy('id', 'DESC')->first();
}
}
if ($bookingPayment) {
$status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status];
Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}");
$bookingPaymentAmount = $bookingPayment->amount;
// check if the booking is fully refund
$amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7);
$isFullyRefund = false;
if (abs($amountDifference) < 0.01) {
$isFullyRefund = true;
// update fully refunded booking payment transaction
$bookingPayment->status = ApprovalStatus::REFUNDED;
$bookingPayment->save();
//expired booking
// $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED);
Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}");
// Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}");
// Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}");
} else {
Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}");
}
$refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first();
$bookingInWhiteForm = $bookingPayment->transactions()->bills()->first();
if ($refund) {
Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction");
}
if (!$refund) {
$billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('RFD-');
$object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id,
1, PaymentMethodType::CASH,
$transaction->amount, $isFullyRefund ? $bookingPayment->original_amount : $transaction->amount * $bookingPayment->currency_rate, 1,
$bookingPayment->original_currency_id, $bookingPayment->currency_rate,
0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no);
$transaction = (App()->make(CreatesTransaction::class))->execute($bookingPayment, $object);
}
if ($bookingInWhiteForm) {
$original_amount = $isFullyRefund ? $bookingPayment->original_amount : bcmul($transaction->amount, $bookingPayment->currency_rate, 7);
$supplier_refund_amount = bcdiv($original_amount, $bookingInWhiteForm->currency_rate, 7);
Log::info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}");
// if ($isFullyRefund && $bookingInWhiteForm->currency_rate == 1) {
// dd ($bookingInWhiteForm->owner_id);
// }
$refund = $bookingPayment->transactions()->supplierRefunds()->where('original_amount', $original_amount)->first();
if (!$refund) {
$billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('SRFD-');
$object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $bookingInWhiteForm->issuer,
1, PaymentMethodType::CASH,
$supplier_refund_amount, $original_amount, 1,
$bookingPayment->original_currency_id, $bookingInWhiteForm->currency_rate,
0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no);
$transaction = (App()->make(CreatesTransaction::class))->execute($bookingPayment, $object);
}
}
} else {
// $bookingPayment = $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->orderBy('id', 'DESC')->first();
// if ($bookingPayment) {
// Log::info("Credit note transaction id: {$transaction->id}, booking payment refunded");
// } else {
Log::info("Credit note transaction id: {$transaction->id}, booking payment not found, the payment reference is: {$transaction->payment_reference}");
// }
}
} else {
Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}");
}
} else {
Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}");
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Expiring refunded booking. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,54 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
class FixExpiredBookingV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Change the EXPIRED payment transaction of EXPIRED booking to REFUNDED if the payment transaction is fully refunded.');
$start = new Carbon();
$bookings = Booking::where('status', ApprovalStatus::EXPIRED)->whereHas('transactions', function ($q) {
$q->where('type', TransactionType::PAYMENT)->where('status', ApprovalStatus::EXPIRED)->whereHas('transactions', function ($q2) {
$q2->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
})->get();
foreach ($bookings as $booking) {
$payment_transactions = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($q2) {
$q2->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->get();
foreach ($payment_transactions as $payment) {
$payment_original_amount = $payment->original_amount;
$refund_original_amount = $payment->transactions()->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('original_amount');
if ($payment_original_amount - $refund_original_amount < 0.01) {
Log::info("Updated booking id: $booking->id, payment transaction id: $payment->id, from EXPIRED to REFUNDED");
$payment->status = ApprovalStatus::REFUNDED;
$payment->save();
}
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Change the EXPIRED payment transaction of EXPIRED booking to REFUNDED if the payment transaction is fully refunded. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class HouseKeepingS3FilesV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Housekeeping temporary files in S3 Bucket.');
$start = new Carbon();
$s3 = Storage::disk('s3');
$directories = [
'temp',
];
foreach ($directories as $directory) {
$startInner = Carbon::now();
Log::info(Carbon::now() . ' [HouseKeepingS3FilesV2] Start cleaning - ' . $directory);
$objects = $s3->allFiles($directory);
foreach ($objects as $object) {
$s3->delete($object);
Log::info('[HouseKeepingS3FilesV2] Deleted object: ' . $object);
}
Log::info('[HouseKeepingS3FilesV2] All files have been deleted.');
$endInner = Carbon::now();
$elapsedTime = $startInner->diff($endInner)->format('%H:%I:%S');
Log::info(Carbon::now() . ' [HouseKeepingS3FilesV2] Process ended. ElapsedTime: ' . $elapsedTime);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Housekeeping temporary files in S3 Bucket. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use App\Classes\Modules\Accounts\Services\ExpiresEmailVerificationAttempt;
use App\Models\UserEmailVerification;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class NewUserRegistrationExpireCheckV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - New user email verification expiration check.');
$start = new Carbon();
$attempts = UserEmailVerification::active()->twoDaysOld()->get();
Log::info('Carbon now()->subHours(48): '. Carbon::now()->subHours(48));
Log::info('Attempts count: '.count($attempts));
foreach ($attempts as $attempt){
(new ExpiresEmailVerificationAttempt())->execute($attempt);
Log::info('Expired: '.$attempt->email.', '.$attempt->created_at);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - New user email verification expiration check. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Models\User;
use App\Classes\ValueObjects\Constants\Vouchers;
use App\Classes\Jobs\SendWelcomeVoucherEmail;
use App\Classes\Modules\Vouchers\Services\FetchesVoucher;
use App\Classes\Jobs\SendUserVerificationEmail;
use App\Classes\Modules\Accounts\Services\GeneratesEmailVerificationAttempt;
use App\Classes\Jobs\SendResetPasswordEmail;
use App\Classes\Modules\Accounts\Services\GeneratesPasswordReset;
class OneTimeTestVoucherifyEmailV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - One time test sending voucherify email to see out of alignment issue.');
$start = new Carbon();
try{ //In case voucher got deleted unintentionally
$user = User::where('id', 3974)->first(); //5436, 3974
Log::info(json_encode($user));
$voucher = (App()->make(FetchesVoucher::class))->execute(['code' => Vouchers::WELCOME_50_PERCENT_OFF]);
Log::info(json_encode($voucher));
if($voucher) SendWelcomeVoucherEmail::dispatch($user, $voucher, 1);
// $attempt = (App()->make(GeneratesEmailVerificationAttempt::class))->execute($user);
// $this->sendUserVerificationEmail::dispatch($user, $attempt);
// $attempt = (App()->make(GeneratesPasswordReset::class))->execute($user);
// $this->sendResetPasswordEmail::dispatch($user, $attempt);
}
catch(\Exception $e){}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - One time test sending voucherify email to see out of alignment issue. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use App\Classes\Modules\Accounts\Services\ExpiresPasswordReset;
use App\Models\PasswordReset;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class PasswordResetTokenExpirationV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Password reset token expiration check.');
$start = new Carbon();
$attempts = PasswordReset::active()->oneDayOld()->get();
Log::info('PasswordReset Carbon now()->subHours(24): '. Carbon::now()->subHours(24));
Log::info('PasswordReset Attempts count: '.count($attempts));
foreach ($attempts as $attempt){
(new ExpiresPasswordReset())->execute($attempt);
Log::info('PasswordReset Expired: '.$attempt->id.', '.$attempt->created_at);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Password reset token expiration check. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\SeasonalSegment;
use App\Classes\Modules\Companies\Services\RemovesCompanyFromSegment;
use Illuminate\Support\Facades\Log;
class RemoveSeasonalSegmentCompanyV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Perform soft delete on Seasonal Segment Company.');
$start = new Carbon();
$seasonalSegment = SeasonalSegment::where('ending_on', '<=', Carbon::today())->get();
if (count($seasonalSegment)){
foreach ($seasonalSegment as $seasonalSegmentCompany) {
(new RemovesCompanyFromSegment())->execute($seasonalSegmentCompany->company, $seasonalSegmentCompany->segment);
$seasonalSegmentCompany->delete();
Log::info(Carbon::now() . ' : Deleted id: ' . $seasonalSegmentCompany->id);
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Perform soft delete on Seasonal Segment Company. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,98 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\User;
use ZipArchive;
class TestAttachingS3FileAndSendEmailV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Test to attach a file from S3 bucket and trigger an email send.');
$start = new Carbon();
Auth::login(User::findOrFail(1));
$zip_file = 'do_'.Carbon::yesterday()->format('Y_m_d').'.zip';
$attachment = storage_path().'/'.$zip_file;
Log::info("[TESTING] attachment: $attachment");
$startDate = Carbon::now()->subMonth();
Log::info("[TESTING] startDate: ".$startDate->toDateTimeString());
$endDate = Carbon::yesterday();
$bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $startDate)->whereDate('updated_at', '<=', $endDate)
->whereHas('transactions', function ($query){
return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query){
return $query->where('issuer', 2);
});
})->get();
Log::info("[TESTING] total bookings: " . count($bookings));
if(!count($bookings)){ return; }
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
$zip = new ZipArchive();
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
//STEP 1: Go through each of the booking from query
$counter = 0;
foreach ($bookings as $booking) {
$file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first();
$fileContent = Storage::disk('s3')->get($file->file->file_info->original->file);
$zip->addFromString($booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);
$counter++;
if ($counter >= 5) {
break;
}
}
$zip->close();
//STEP 2: Upload the zip file to S3
// $filePathForS3 = 'temp/'.$zip_file;
// Storage::disk('s3')->put($filePathForS3, file_get_contents($attachment));
// Log::info('DownloadBookingDocumentLogic finished processing files to zip count: '.count($bookings));
// $temporaryUrl = Storage::disk('s3')->temporaryUrl(
// $filePathForS3,
// Carbon::now()->addMinutes(10)
// );
// Log::info("[TESTING] total bookings: $temporaryUrl");
//STEP 3: Send Email
Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){
$message->from('exchange@cief-malaysia.com');
$message->to(['dillonngoweijoon@gmail.com']);
$message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y'));
$message->attach($attachment);
});
File::delete($attachment);
Log::info('success');
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Test to attach a file from S3 bucket and trigger an email send. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,153 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Transaction;
use App\Models\Wallet;
use Illuminate\Support\Facades\DB;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\General\AWSS3Helper;
use Illuminate\Support\Facades\Storage;
class TestRunningALongQueryV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - This is a test to run a long query that generates a pdf file to be uploaded to S3 bucket.');
$start = new Carbon();
////https://dev.exchange.izyim.com/company/2294/false/transaction/export
$companyId = '2294'; //$request->route('id');
$isPrecise = false; //$request->route('is_precise');
$company = Company::find($companyId);
$transactions = Transaction::where(function ($query) use ($companyId) {
$query
->where('type', TransactionType::PAYMENT)
->where('owner_type', Booking::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->where('payment_method', '!=', PaymentMethodType::WALLET)
->whereHas('booking', function ($q) use ($companyId) {
$q->where('company_id', $companyId);
});
})
->orWhere(function ($query) use ($companyId) {
$query->whereHas('owner', function ($q) use ($companyId) {
$q->where('owner_id', $companyId);
$q->where('owner_type', Company::class);
})
->where('owner_type', Wallet::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})
->orWhere(function ($query) use ($companyId) {
$query
->where('type', TransactionType::INVOICE)
->where('owner_type', Booking::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->where('payment_method', '!=', PaymentMethodType::WALLET)
->whereHas('booking', function ($q) use ($companyId) {
$q->where('company_id', $companyId);
});
})
->groupBy(
DB::raw(
'if (transactions.type = 2,transactions.owner_id,transactions.id)'
),
DB::raw(
'if (transactions.type = 2,transactions.type,transactions.id)'
)
)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->orderBy('created_at', 'asc')
->get();
$total_incoming = Transaction::where(function ($query) use ($companyId) {
$query->whereHas('owner', function ($q) use ($companyId) {
$q->where('owner_id', $companyId);
$q->where('owner_type', Company::class);
})
->where('owner_type', Wallet::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->where('type', '!=', TransactionType::PAYMENT);
})
->orWhere(function ($query) use ($companyId, $transactions) {
$query
->where('type', TransactionType::INVOICE)
->where('owner_type', Booking::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->where('payment_method', '!=', PaymentMethodType::WALLET)
->whereHas('booking', function ($q) use ($companyId) {
$q->where('company_id', $companyId);
});
})
->groupBy(
DB::raw(
'if (transactions.type = 2,transactions.owner_id,transactions.id)'
),
DB::raw(
'if (transactions.type = 2,transactions.type,transactions.id)'
)
)->get();
$total_incoming = $total_incoming->sum(function ($transaction) {
if ($transaction->type === TransactionType::INVOICE) {
return $transaction->amount / $transaction->currency_rate + $transaction->service_charge;
}
return $transaction->amount;
});
$total_outgoing = Transaction::where(function ($query) use ($companyId) {
$query
->where('type', TransactionType::PAYMENT)
->where('payment_method', '!=', PaymentMethodType::WALLET)
->where('owner_type', Booking::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->whereHas('booking', function ($q) use ($companyId) {
$q->where('company_id', $companyId);
});
})
->orWhere(function ($query) use ($companyId) {
$query->whereHas('owner', function ($q) use ($companyId) {
$q->where('owner_id', $companyId);
$q->where('owner_type', Company::class);
})
->where('owner_type', Wallet::class)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->where('type', TransactionType::PAYMENT);
})
->sum('transactions.amount');
$currentBalance = $total_incoming - $total_outgoing;
$pdf = LaravelMpdf::loadView('pages.pdfs.company_account_statement_transaction', ['transactions' => $transactions, 'runningBalance' => $currentBalance, 'company' => $company, 'isPrecise' => $isPrecise == 'true']);
$exportFileName = "{$company->reference}_account_statement_transactions.pdf";
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
$pdfContent = $pdf->output();
$temporaryUrl = AWSS3Helper::S3PDF($exportFileName, $pdfContent);
Log::info('Temporary S3 Url: ' . $temporaryUrl );
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - This is a test to run a long query that generates a pdf file to be uploaded to S3 bucket. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,121 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Transactions\ControllersLogic\UpdateGroupLogic;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\BillGroup;
use App\Models\Group;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as FacadesRoute;
class UpdateBillGroupAndMoreV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Update bill group and group to include transfer fee calculation.');
$start = new Carbon();
// update group to include transfer fee
$groups = Group::where('created_at', '>=', '2024-06-01')->get();
foreach ($groups as $group) {
$group_transfer_fee = 0;
$morph_transaction = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();
if ($morph_transaction) {
$group_transfer_fee = $morph_transaction->original_amount;
}
$originalTransferFees = (float)Transaction::where('type', TransactionType::TRANSFER_FEE)->whereIn('owner_id', $group->transactions->pluck('id'))->sum('service_charge');
$correctOriginalAmount = $group->transactions()->sum('original_amount');
$correctOriginalAmount = $correctOriginalAmount + $originalTransferFees + $group_transfer_fee;
$correctAmount = $group->transactions()->sum('amount');
$transferFees = $originalTransferFees / $group->currency_rate;
$correctAmount = $correctAmount + $transferFees + ($group_transfer_fee / $group->currency_rate) + $group->service_charge;
if ($group->original_amount != $correctOriginalAmount || $group->amount != $correctAmount) {
$group->original_amount = $correctOriginalAmount;
$group->amount = $correctAmount;
$group->save();
Log::info("updated group id: {$group->id}, added transfer fee CNY {$correctOriginalAmount}");
}
}
// update group calculation to include individual group transfer fee
// $groups = Group::whereHas('morphTransactions', function ($q) {
// $q->where('type', TransactionType::TRANSFER_FEE);
// })->get();
// foreach ($groups as $group) {
// $route = FacadesRoute::getRoutes()->getByName('api.transaction.group.update');
// $request = Request::create(route('api.transaction.group.update', $group->id));
// $uri = $route->uri;
// $request->setRouteResolver(function () use ($request, $uri) {
// // Associate Route to request so we can access route parameters.
// return (new Route('PUT', $uri, []))->bind($request);
// });
// $request['rate'] = $group->currency_rate;
// $request['supplier_id'] = $group->issuer;
// $this->updateGroupLogic->execute($request);
// $group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();
// Log::info("updated group id: {$group->id}, added transfer fee to individual white form CNY {$group_transfer_fee->original_amount}");
// }
// update bill group calculation to include individual group transfer fee
$billGroups = BillGroup::all();
foreach ($billGroups as $billGroup) {
// ignore those has bill group refund
if ($billGroup->billRefunds()->count() > 0) {
continue;
}
$totalOriginal = round($billGroup->groups()->sum('original_amount'), 2);
$total = round($billGroup->groups()->sum('amount') + $billGroup->service_charge, 2);
// update bill group payment transaction amount if there is only 1 payment transaction
$payment_transactions = $billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
if ($payment_transactions->count() === 1) {
$payment_transaction = $payment_transactions->first();
if ($payment_transaction->amount - ($billGroup->amount + $billGroup->service_charge) < 0.01) {
$payment_transaction->original_amount = $total;
$payment_transaction->amount = $total;
$payment_transaction->save();
Log::info("updated bill group payment transaction id: {$payment_transaction->id}, update original amount to CNY {$totalOriginal}");
}
}
// update bill group amount and original amount
$billGroup->original_amount = $totalOriginal;
$billGroup->amount = $total;
$billGroup->save();
Log::info("updated bill group id: {$billGroup->id}, added transfer fee, final original amount is CNY {$totalOriginal}");
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Update bill group and group to include transfer fee calculation. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,56 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Booking;
use App\Models\Transaction;
use Illuminate\Console\Command;
class UpdateWrongFullyRefundPaymentReferenceV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Update those payment reference that actually should be showing partially refund instead of fully refund.');
$start = new Carbon();
$transactions = Transaction::where('payment_reference', 'LIKE', '%Fully Refund%')->whereDate('created_at', '>=', Carbon::createFromDate(2024, 4, 2))->get();
foreach ($transactions as $transaction) {
$booking_marking = trim(explode('.', $transaction->payment_reference)[1]);
$booking = Booking::where('marking', $booking_marking)->first();
if ($booking) {
$payments = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED])->get();
if ($payments->count() === 0) {
Log::info("Booking ID: {$booking->id}, payment not found");
} else if ($payments->count() > 1) {
Log::info("Booking ID: {$booking->id}, more than 1 payment found");
} else {
$payment = $payments->first();
if (!($payment->amount - $transaction->amount < 0.01)) {
$transaction->payment_reference = str_replace('Fully', 'Partially', $transaction->payment_reference);
$transaction->save();
Log::info("Updated Payment Reference of Transaction ID: {$transaction->id}, corrected from Fully Refund to Partially Refund");
}
}
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Update those payment reference that actually should be showing partially refund instead of fully refund. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,106 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Document;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Group;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
class UpdateWrongGroupCurrencyRateV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Update those group with currency rate more than 100.');
$start = new Carbon();
$groups = Group::where('currency_rate', '>', 100)->get();
foreach ($groups as $group) {
$transactions = $group->transactions()->get();
$rate = DB::table('transaction_logs')->where('transaction_id', $transactions->first()->id)->latest('updated_at')->first()->currency_rate;
$supplier = $group->issuerCompany;
foreach ($transactions as $transaction) {
$transaction->currency_rate = $rate;
$transaction->amount = $transaction->original_amount / $rate;
$transaction->save();
$supplierRefundTransactions = $transaction->owner->transactions()->supplierRefunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->get();
foreach ($supplierRefundTransactions as $supplierRefundTransaction) {
$claimBefore = $supplierRefundTransaction->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->exists();
if (!$claimBefore) {
$supplierRefundTransaction->currency_rate = $rate;
$supplierRefundTransaction->amount = $supplierRefundTransaction->original_amount / $rate;
$supplierRefundTransaction->save();
}
}
}
$group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();
$group_transfer_fee_original_amount = 0;
if ($group_transfer_fee) {
$group_transfer_fee_original_amount = $group_transfer_fee->original_amount;
}
$transferFeeTransactions = $group->transactions()->with([
'transactions' => function ($transaction) {
return $transaction->where('type', TransactionType::TRANSFER_FEE);
}
])->get()->pluck('transactions')->flatten();
$group->original_amount = $group->transactions()->sum('original_amount') + ((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount);
$group->amount = $group->transactions()->sum('amount') + (((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount) / $rate) + $group->transactions()->sum('service_charge');
$group->currency_rate = $rate;
$group->tax = $group->transactions()->sum('tax');
$group->service_charge = $group->transactions()->sum('service_charge');
$group->save();
$group->documents()->delete();
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $group->transactions, 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier, 'groupTransferFeeOriginalAmount' => $group_transfer_fee_original_amount]);
$object = new DocumentObject(
DocumentType::CURRENCY_VENDOR_ORDER,
[chunk_split('data:application/pdf;base64,' . base64_encode($pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'currency_vendor_order'
);
/** @var Document $document */
$document = (App()->make(CreatesDocument::class))->execute($group, $object);
(App()->make(CreatesFiles::class))->execute($document, $object);
Log::info("Group ID: {$group->id} updated to currency rate {$rate}");
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Update those group with currency rate more than 100. ElapsedTime: ' . $elapsedTime . '.');
}
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Bookings\Processors\ListBookingJobProcessor;
use App\Classes\Modules\Generic\DataTransferObjects\ListGenericJobObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\JobResult;
use Illuminate\Support\Facades\Log;
class ListBookings implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var ListGenericJobObject */
private $listGenericJobObject;
private $jobId;
/**
* ListBookings constructor.
* @param ListGenericJobObject $listGenericJobObject
*/
public function __construct(ListGenericJobObject $listGenericJobObject)
{
$this->listGenericJobObject = $listGenericJobObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->listGenericJobObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListBookingJobProcessor::class))->execute($this->listGenericJobObject);
}
public function getJobId(){
return $this->job->getJobId();
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Bookings\Processors\ListBookingsJobProcessor;
use App\Classes\Modules\Jobs\DataTransferObjects\JobSubmissionObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\JobResult;
use Illuminate\Support\Facades\Log;
class ListBookingsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
/** @var JobSubmissionObject */
private $jobSubmissionObject;
private $jobId;
/**
* ListBookingsJob constructor.
* @param JobSubmissionObject $jobSubmissionObject
*/
public function __construct(JobSubmissionObject $jobSubmissionObject)
{
$this->jobSubmissionObject = $jobSubmissionObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->jobSubmissionObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->jobSubmissionObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListBookingsJobProcessor::class))->execute($this->jobSubmissionObject);
}
public function getJobId(){
return $this->job->getJobId();
}
}
-61
View File
@@ -1,61 +0,0 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Documents\Processors\ListDocumentJobProcessor;
use App\Classes\Modules\Generic\DataTransferObjects\ListGenericJobObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\JobResult;
use Illuminate\Support\Facades\Log;
class ListDocuments implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var ListGenericJobObject */
private $listGenericJobObject;
private $jobId;
/**
* ListDocuments constructor.
* @param ListGenericJobObject $listGenericJobObject
*/
public function __construct(ListGenericJobObject $listGenericJobObject)
{
$this->listGenericJobObject = $listGenericJobObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->listGenericJobObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListDocumentJobProcessor::class))->execute($this->listGenericJobObject);
//cief todo: Insert into DB: job id, query result, timestamp
// Store the result in the job_results table
//cief todo: why cannot save data in table like this
// $model = new JobResult();
// $model->job_id = $this->job->getJobId();
// $model->result = json_encode($result);
// $model->save();
// Log::error(json_encode($model->id));
}
public function getJobId(){
return $this->job->getJobId();
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Documents\Processors\ListDocumentsJobProcessor;
use App\Classes\Modules\Jobs\DataTransferObjects\JobSubmissionObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ListDocumentsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
/** @var JobSubmissionObject */
private $jobSubmissionObject;
private $jobId;
/**
* ListDocumentsJob constructor.
* @param JobSubmissionObject $JobSubmissionObject
*/
public function __construct(JobSubmissionObject $jobSubmissionObject)
{
$this->jobSubmissionObject = $jobSubmissionObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->jobSubmissionObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->jobSubmissionObject->setJobCommand($rawPayload['data']['command']);
}
(App()->make(ListDocumentsJobProcessor::class))->execute($this->jobSubmissionObject);
}
public function getJobId(){
return $this->job->getJobId();
}
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Transactions\Processors\ListTransactionJobProcessor;
use App\Classes\Modules\Generic\DataTransferObjects\ListGenericJobObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\JobResult;
use Illuminate\Support\Facades\Log;
class ListTransactions implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var ListGenericJobObject */
private $listGenericJobObject;
private $jobId;
/**
* ListTransactions constructor.
* @param ListGenericJobObject $listGenericJobObject
*/
public function __construct(ListGenericJobObject $listGenericJobObject)
{
$this->listGenericJobObject = $listGenericJobObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->listGenericJobObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListTransactionJobProcessor::class))->execute($this->listGenericJobObject);
}
public function getJobId(){
return $this->job->getJobId();
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Transactions\Processors\ListTransactionsJobProcessor;
use App\Classes\Modules\Jobs\DataTransferObjects\JobSubmissionObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\JobResult;
use Illuminate\Support\Facades\Log;
class ListTransactionsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
/** @var JobSubmissionObject */
private $jobSubmissionObject;
private $jobId;
/**
* ListTransactionsJob constructor.
* @param JobSubmissionObject $jobSubmissionObject
*/
public function __construct(JobSubmissionObject $jobSubmissionObject)
{
$this->jobSubmissionObject = $jobSubmissionObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->jobSubmissionObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->jobSubmissionObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListTransactionsJobProcessor::class))->execute($this->jobSubmissionObject);
}
public function getJobId(){
return $this->job->getJobId();
}
}
@@ -0,0 +1,70 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
use App\Classes\Notifications\WelcomeVoucherEmail;
use App\Models\User;
use App\Models\Voucher;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendWelcomeVoucherEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var User */
private $user;
/** @var Voucher */
private $voucher;
/** @var int */
private $emailSentCount;
/**
* SendWelcomeVoucherEmail constructor.
* @param User $user
* @param Voucher $voucher
* @param int $emailSentCount
*/
public function __construct(User $user, Voucher $voucher, int $emailSentCount = 1)
{
$this->user = $user;
$this->voucher = $voucher;
$this->emailSentCount = $emailSentCount;
}
public function handle()
{
$currentDatetime = Carbon::now();
$dateToCompare = Carbon::parse($this->voucher->end_date);
if (!$this->user->hasAttribute($this->voucher->code."_EMAIL_COUNT")
&& $this->user->rewards->where('voucher_id', $this->voucher->id)->count() > 0
&& $currentDatetime->isBefore($dateToCompare))
{
//Key #1
$keyValuePairObject = new KeyValuePairObject(
$this->voucher->code."_EMAIL_COUNT",
$this->emailSentCount
);
(App()->make(CreatesKeyValuePair::class))->execute($this->user, $keyValuePairObject);
//Key #2
$keyValuePairObject = new KeyValuePairObject(
$this->voucher->code."_EMAIL_DATE_".$this->emailSentCount,
Carbon::now()
);
(App()->make(CreatesKeyValuePair::class))->execute($this->user, $keyValuePairObject);
$this->user->notify(new WelcomeVoucherEmail($this->user, $this->voucher));
}
}
}
+4 -4
View File
@@ -20,6 +20,7 @@ use Illuminate\Queue\SerializesModels;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use App\Classes\General\Helper;
use App\Classes\General\LogHelper;
class UpdatePerfexCRMInvoice implements ShouldQueue
{
@@ -57,16 +58,15 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
$number = 'EXC-'.$number;
$invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $number);
Log::error(json_encode('UpdatePerfexCRMInvoice debug $number: '.$number));
LogHelper::channel('perfex_crm')->info(('UpdatePerfexCRMInvoice debug $number: '.$number));
if(is_null($invoice)){
$result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction);
if ($result) {
$invoiceId = $result->payload['id'];
} else {
// Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'));
$log['message'] = 'UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed';
Helper::debugLogger($log);
LogHelper::channel('perfex_crm')->info($log);
}
}
else{
@@ -75,7 +75,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
//This only run when invoice already exist and the invoice does not have a PAID status
if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){
Log::error(json_encode('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId()));
LogHelper::channel('perfex_crm')->info('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId());
//update invoice
(App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId());
+5 -1
View File
@@ -41,7 +41,11 @@ class UpdatePerfexCRMPrelude implements ShouldQueue
{
$serviceTypeName = $this->transaction->owner->company->services()->where('id', $this->transaction->owner->service_id)->first()->name;
$booking = $this->transaction->booking;
$bankDetails = $this->generateBankDetails($booking->bank);
$bank = $booking->bank; //cief todo: 66
if($this->transaction->bank){
$bank = $this->transaction->bank;
}
$bankDetails = $this->generateBankDetails($bank);
$data = [
'amount' => number_format($this->transaction->amount, 2, '.', ''),
@@ -62,7 +62,7 @@ class GroupApproveStatementTransactionLogic extends AbstractControllerLogic
$statementTransactions = $this->listsBankStatementTransactions->execute($filters);
foreach ($statementTransactions as $statementTransaction) {
$owners = $statementTransaction->owners;
$owners = $statementTransaction->owners()->where('status', ApprovalStatus::PENDING_VERIFICATION)->get();
if (count($owners)) {
$this->updatesBankStatementTransactionOwnerStatus->execute($owners->first(), ApprovalStatus::APPROVED);
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\Modules\Accounting\ControllersLogic;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\TransactionMappingLogResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounting\Services\ListTransactionMappingLogs;
class HistoryImportedTransactionMappedControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Retrieved History Imported Invoices',
'message' => 'You have successfully retrieved history imported invoices'
];
}
/** @var ListTransactionMappingLogs */
private $listTransactionMappingLogs;
/**
* UpdateAnnouncementLogic constructor.
* @param ListTransactionMappingLogs $listTransactionMappingLogs
*/
public function __construct(
ListTransactionMappingLogs $listTransactionMappingLogs
) {
$this->listTransactionMappingLogs = $listTransactionMappingLogs;
}
/**
* @param Request $request
* @return JsonResponse
*/
public function logic(Request $request): JsonResponse
{
$query = $this->listTransactionMappingLogs->execute($this->listTransactionMappingLogs->deserializeFilters($request->input('filters')));
return $this->collectionResponse(TransactionMappingLogResource::collection($query));
}
}
@@ -157,7 +157,7 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic
'owner_reference' => $owner_reference,
];
return $bankStatementTransaction->owners()->firstOrCreate($ownerData);
return $bankStatementTransaction->owners()->where('status','<>',ApprovalStatus::REJECTED)->firstOrCreate($ownerData);
}
private function editAccountMapped(StatementTransactionOwner $owner){
@@ -2,16 +2,14 @@
namespace App\Classes\Modules\Accounting\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
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 Illuminate\Http\JsonResponse;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Http\Resources\BankStatementTransactionOwnerResource;
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
use App\Classes\Modules\Accounting\Services\FetchesBankStatementTransactionOwner;
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
{
@@ -27,29 +25,23 @@ class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
];
}
/** @var FetchesBankStatementTransaction */
private $fetchesBankStatementTransaction;
/** @var FetchesBankStatementTransactionOwner */
private $fetchesBankStatementTransactionOwner;
/** @var UpdatesBankStatementTransactionOwnerStatus */
private $updatesBankStatementTransactionOwnerStatus;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/**
* UpdateAnnouncementLogic constructor.
* @param FetchesBankStatementTransaction $fetchesBankStatementTransaction
* @param FetchesBankStatementTransactionOwner $fetchesBankStatementTransactionOwner
* @param UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus
* @param UpdatesTransactionStatus $updatesTransactionStatus
*/
public function __construct(
FetchesBankStatementTransaction $fetchesBankStatementTransaction,
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus,
UpdatesTransactionStatus $updatesTransactionStatus
FetchesBankStatementTransactionOwner $fetchesBankStatementTransactionOwner,
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus
) {
$this->fetchesBankStatementTransaction = $fetchesBankStatementTransaction;
$this->fetchesBankStatementTransactionOwner = $fetchesBankStatementTransactionOwner;
$this->updatesBankStatementTransactionOwnerStatus = $updatesBankStatementTransactionOwnerStatus;
$this->updatesTransactionStatus = $updatesTransactionStatus;
}
/**
@@ -61,21 +53,10 @@ class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
*/
public function logic(Request $request): JsonResponse
{
$statementTrasaction = $this->fetchesBankStatementTransaction->execute(['id' => $request->route('id')]);
$statementTrasactionOwner = $statementTrasaction->owners->first();
$statementTrasactionOwner = $this->fetchesBankStatementTransactionOwner->execute(['id' => $request->route('id')]);
$this->updatesBankStatementTransactionOwnerStatus->execute($statementTrasactionOwner, $request->route('status') == 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
// todo-new: approve payments status, need to check the owner(if system is shipping, need to api with shipping portal)
// if ($request->route('status') == 'approve') {
// if ($statementTrasactionOwner->transaction->type === StatementTransactionOwnerType::SALES) {
// if ($statementTrasactionOwner->owner->status === ApprovalStatus::PENDING_VERIFICATION) {
// $this->updatesTransactionStatus->execute($statementTrasactionOwner->owner, ApprovalStatus::APPROVED);
// }
// }
// }
return $this->resourceResponse(new BankStatementTransactionResource($statementTrasaction));
return $this->resourceResponse(new BankStatementTransactionOwnerResource($statementTrasactionOwner));
}
}
@@ -28,6 +28,7 @@ class CreateBankStatementTransactionOwnersProcessor
// $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get();
foreach ($transactions as $transaction) {
$mapped = false;
$keywords = array_filter(explode(" ", $transaction->transaction_description . " " . $transaction->transaction_description_2));
if($transaction->amount > 0){
@@ -36,7 +37,7 @@ class CreateBankStatementTransactionOwnersProcessor
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($creditTransactions as $creditTransaction) {
$isArray = is_array($creditTransaction);
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::SALES,
'system' => 'EXCHANGE',
'owner_type' => Transaction::class,
@@ -45,12 +46,11 @@ class CreateBankStatementTransactionOwnersProcessor
]);
}
// Shipping Portal Sales
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2, PaymentMethodType::WALLET);
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [2], PaymentMethodType::WALLET);
foreach ($creditTransactions as $creditTransaction) {
if($creditTransaction['owner_type'] === Wallet::class) continue;
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::SALES,
'system' => 'SHIPPING_PORTAL',
'owner_type' => $creditTransaction['owner_type'],
@@ -63,7 +63,7 @@ class CreateBankStatementTransactionOwnersProcessor
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($creditTransactions as $creditTransaction) {
$isArray = is_array($creditTransaction);
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
'system' => 'EXCHANGE',
'owner_type' => Transaction::class,
@@ -72,9 +72,9 @@ class CreateBankStatementTransactionOwnersProcessor
]);
}
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5, null);
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [5,15], null);
foreach ($creditTransactions as $creditTransaction) {
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
'system' => 'SHIPPING_PORTAL',
'owner_type' => $creditTransaction['owner_type'],
@@ -85,7 +85,7 @@ class CreateBankStatementTransactionOwnersProcessor
// fpx charge refund
if($transaction->transaction_description === 'DUITNOW S/CHRG REFUND'){
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::FPX_CHARGE_REFUND
]);
}
@@ -94,7 +94,7 @@ class CreateBankStatementTransactionOwnersProcessor
// INTERNAL_BANK_TRANSFER_IN
if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE')){
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN
]);
}
@@ -119,7 +119,7 @@ class CreateBankStatementTransactionOwnersProcessor
->where('amount', '<=', (($transaction->amount * -1) + 0.01))->whereDate('created_at', '>=', $paymentDateStart)->whereDate('created_at', '<=', $paymentDateEnd)->get();
foreach ($debitTransactions as $debitTransaction) {
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::SUPPLIER_PAYMENT,
'system' => 'EXCHANGE',
'owner_type' => Group::class,
@@ -135,7 +135,7 @@ class CreateBankStatementTransactionOwnersProcessor
$debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($debitTransactions as $debitTransaction) {
$isArray = is_array($creditTransaction);
$transaction->owners()->firstOrCreate([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL,
'system' => 'EXCHANGE',
'owner_type' => Transaction::class,
@@ -148,50 +148,52 @@ class CreateBankStatementTransactionOwnersProcessor
// 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([
$data = $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([
$data = $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([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::BANK_CHARGE
]);
}
// CREDIT_CARD_PAYMENT
if(str_contains($transaction->transaction_description_2, 'VISA CARD')){
$transaction->owners()->firstOrCreate([
$data = $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([
$data = $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([
$data = $transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::NON_OPERATIONAL
]);
}
}
if (isset($data) && $data->wasRecentlyCreated) $mapped = true;
$this->updateMappedRate($transaction, $mapped);
}
}
}
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
$dateRange = $this->getDateRange($date, 4);
if (App::environment(['production'])) {
$query = $model::whereIn('status', $statuses)
@@ -318,7 +320,7 @@ class CreateBankStatementTransactionOwnersProcessor
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]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":['.$type.']}');
$response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":'.json_encode($type).'}');
$body = $response->getBody();
$data = json_decode($body, true);
$payload = $data['payload'];
@@ -345,4 +347,11 @@ class CreateBankStatementTransactionOwnersProcessor
'end_date' => $nextDay,
];
}
private function updateMappedRate($transaction, $mapped) {
$statement = $transaction->statement;
$statement->total_rows = StatementTransaction::where('account_statement_id',$transaction->account_statement_id)->count();
$statement->mapped_rows = $mapped ? $statement->mapped_rows+1 : $statement->mapped_rows;
$statement->save();
}
}
@@ -13,6 +13,7 @@ class ListShippingPortalTransactions
{
try {
$url = 'https://izyim.cief-malaysia.com/public/api/v1/transactions/mappable/query/with-details';
// $url = 'http://127.0.0.1:8001/public/api/v1/transactions/mappable/query/with-details';
$client = new \GuzzleHttp\Client(['verify' => false]);
$response = $client->request('GET', $url . '?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters=' . json_encode($filters));
$body = $response->getBody();
@@ -0,0 +1,31 @@
<?php
namespace App\Classes\Modules\Accounting\Services;
use App\Models\StatementTransactionOwner;
use Illuminate\Database\Eloquent\Builder;
use App\Classes\General\Eloquent\AbstractFetchRecord;
class FetchesBankStatementTransactionOwner extends AbstractFetchRecord
{
/** @var StatementTransactionOwner */
private $repository;
/**
* FetchesBankStatementDetails constructor.
* @param StatementTransactionOwner $repository
*/
public function __construct(StatementTransactionOwner $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Accounting\Services;
use App\Models\TransactionMappingLog;
use Illuminate\Database\Eloquent\Builder;
use App\Classes\General\Eloquent\AbstractListRecord;
class ListTransactionMappingLogs extends AbstractListRecord
{
/** @var TransactionMappingLog */
private $repository;
/**
* ListsBankStatementDetails constructor.
* @param TransactionMappingLog $repository
*/
public function __construct(TransactionMappingLog $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -16,6 +16,7 @@ use App\Classes\Modules\Vouchers\Processors\Voucherify\NewCustomerToVoucherifyPr
use App\Classes\Modules\Vouchers\Processors\CreateVoucherProcessor;
use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateLeadPerfexCRMObject;
use App\Classes\Modules\Rewards\Services\CreatesUserReward;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\CompanyType;
@@ -30,6 +31,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment;
use App\Classes\ValueObjects\Constants\Vouchers;
class CreateCustomerLogic extends AbstractControllerLogic
{
@@ -77,6 +79,9 @@ class CreateCustomerLogic extends AbstractControllerLogic
/** @var CreateVoucherProcessor */
private $createVoucherProcessor;
/** @var CreatesUserReward */
private $createsUserReward;
/**
* CreateCustomerLogic constructor.
* @param CreateUserProcessor $createUserProcessor
@@ -90,9 +95,10 @@ class CreateCustomerLogic extends AbstractControllerLogic
* @param CheckMilestonesForRewardProcessor $checkMilestonesForRewardProcessor
* @param NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor
* @param CreateVoucherProcessor $createVoucherProcessor
* @param CreatesUserReward $createsUserReward
*/
public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateContactProcessor $createContactProcessor, AssignEmployeeProcessor $assignEmployeeProcessor, AssignSegmentProcessor $assignSegmentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor,
CreatesSeasonalSegment $createsSeasonalSegment, CheckMilestonesForRewardProcessor $checkMilestonesForRewardProcessor, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor, CreateVoucherProcessor $createVoucherProcessor)
CreatesSeasonalSegment $createsSeasonalSegment, CheckMilestonesForRewardProcessor $checkMilestonesForRewardProcessor, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor, CreateVoucherProcessor $createVoucherProcessor, CreatesUserReward $createsUserReward)
{
$this->createUserProcessor = $createUserProcessor;
$this->createCompanyProcessor = $createCompanyProcessor;
@@ -105,6 +111,7 @@ class CreateCustomerLogic extends AbstractControllerLogic
$this->checkMilestonesForRewardProcessor = $checkMilestonesForRewardProcessor;
$this->newCustomerToVoucherifyProcessor = $newCustomerToVoucherifyProcessor;
$this->createVoucherProcessor = $createVoucherProcessor;
$this->createsUserReward = $createsUserReward;
}
/**
@@ -155,11 +162,20 @@ class CreateCustomerLogic extends AbstractControllerLogic
CreatePerfexCRMCustomer::dispatch($createLeadPerfexCRMObject);
}
// $this->generateEmailVerificationAttemptProcessor->execute($user); //cief todo
$isSendingEmailEnabled = env('SENDING_EMAIL_ENABLED', false);
if($isSendingEmailEnabled){
$this->generateEmailVerificationAttemptProcessor->execute($user);
}
$this->newCustomerToVoucherifyProcessor->execute($company->id, $user, true);
$this->createVoucherProcessor->execute($user, 'WELCOME50%OFF');
$voucher = $this->createVoucherProcessor->execute($user, Vouchers::WELCOME_50_PERCENT_OFF);
if($voucher){
$voucherCount = $user->rewards->where('voucher_id', $voucher->id)->count();
if($voucherCount === 0){
$this->createsUserReward->execute(null, $user, $voucher->id);
}
}
return $this->response($this->authenticationProcessor->execute($request, false));
@@ -76,11 +76,11 @@ class GeneratePasswordResetLogic extends AbstractControllerLogic
$attempt = $this->generatesPasswordReset->execute($user);
$this->passwordResetTokenExpiration::dispatch($attempt)->delay(now()->addHours(24));
//$this->passwordResetTokenExpiration::dispatch($attempt)->delay(now()->addHours(24)); //converted to schedule task
$this->sendResetPasswordEmail::dispatch($user, $attempt);
return $this->response(['email' => $object->getEmail()]);
}
}
}
}
@@ -9,6 +9,9 @@ use App\Classes\Modules\Accounts\Services\CompletesEmailVerificationAttempt;
use App\Classes\Modules\Accounts\Services\FetchesEmailVerificationAttempt;
use App\Classes\Modules\Accounts\Services\VerifiesUser;
use App\Classes\Modules\Accounts\Standards\Criteria\EmailVerificationActiveAttemptExists;
use App\Classes\Modules\Vouchers\Services\FetchesVoucher;
use App\Classes\Jobs\SendWelcomeVoucherEmail;
use App\Classes\ValueObjects\Constants\Vouchers;
use App\Models\UserEmailVerification;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -36,19 +39,29 @@ class UserEmailVerificationLogic extends AbstractControllerLogic
/** @var VerifiesUser */
private $verifiesUser;
/** @var SendWelcomeVoucherEmail */
private $sendWelcomeVoucherEmail;
/** @var FetchesVoucher */
private $fetchesVoucher;
/**
* UserEmailVerificationLogic constructor.
* @param EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists
* @param CompletesEmailVerificationAttempt $completesEmailVerificationAttempt
* @param FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt
* @param VerifiesUser $verifiesUser
* @param SendWelcomeVoucherEmail $sendWelcomeVoucherEmail
* @param FetchesVoucher $fetchesVoucher
*/
public function __construct(EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists, CompletesEmailVerificationAttempt $completesEmailVerificationAttempt, FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt, VerifiesUser $verifiesUser)
public function __construct(EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists, CompletesEmailVerificationAttempt $completesEmailVerificationAttempt, FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt, VerifiesUser $verifiesUser, SendWelcomeVoucherEmail $sendWelcomeVoucherEmail, FetchesVoucher $fetchesVoucher)
{
$this->emailVerificationActiveAttemptExists = $emailVerificationActiveAttemptExists;
$this->completesEmailVerificationAttempt = $completesEmailVerificationAttempt;
$this->fetchesEmailVerificationAttempt = $fetchesEmailVerificationAttempt;
$this->verifiesUser = $verifiesUser;
$this->sendWelcomeVoucherEmail = $sendWelcomeVoucherEmail;
$this->fetchesVoucher = $fetchesVoucher;
}
/**
@@ -68,9 +81,19 @@ class UserEmailVerificationLogic extends AbstractControllerLogic
$this->completesEmailVerificationAttempt->execute($attempt);
$this->verifiesUser->execute($attempt->user);
$user = $attempt->user;
$this->verifiesUser->execute($user);
// if (env('SENDING_EMAIL_WELCOME_VOUCHER_ENABLED', false)){
if (app()->environment('production') && env('SENDING_EMAIL_WELCOME_VOUCHER_ENABLED', false)){
try{ //In case voucher got deleted unintentionally
$voucher = $this->fetchesVoucher->execute(['code' => Vouchers::WELCOME_50_PERCENT_OFF]);
if($voucher) $this->sendWelcomeVoucherEmail::dispatch($user, $voucher, 1);
}
catch(\Exception $e){}
}
return $this->response([]);
}
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\Modules\Accounts\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class KeyValuePairObject implements DataTransferObject
{
/** @var string */
private $key;
/** @var string */
private $value;
/**
* KeyValuePairObject constructor.
* @param string $key
* @param string $value
*/
public function __construct(string $key, string $value)
{
$this->key = $key;
$this->value = $value;
}
/**
* @return string
*/
public function getKey(): string
{
return $this->key;
}
/**
* @return string
*/
public function getValue(): string
{
return $this->value;
}
}
@@ -81,7 +81,7 @@ class AuthenticationProcessor
$this->newCustomerToVoucherifyProcessor->execute(0, $user, false);
}
//cief todo: case study 1
//cief todo: case study 1 voucherify
//$this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_1]);
return ['access_token' => $this->generatesAuthenticationToken->execute($user), 'redirect_url' => $this->authenticationRedirect->url($user)];
@@ -50,10 +50,10 @@ class GenerateEmailVerificationAttemptProcessor
$attempt = $this->generatesEmailVerificationAttempt->execute($user);
$this->emailVerificationAttemptExpiration::dispatch($attempt)->delay(now()->addHours(48));
// $this->emailVerificationAttemptExpiration::dispatch($attempt)->delay(now()->addHours(48)); //converted to schedule task
$this->sendUserVerificationEmail::dispatch($user, $attempt);
}
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Classes\General\Interfaces\KeyValueInterface;
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
use App\Models\KeyValuePair;
class CreatesKeyValuePair extends AbstractUpdateRelationshipRecord
{
/**
* @param KeyValueInterface $kv
* @param KeyValuePairObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(KeyValueInterface $kv, KeyValuePairObject $object) {
$model = new KeyValuePair();
$model->key = $object->getKey();
$model->value = $object->getValue();
return $this->handler($kv->attributesKVP(), $model);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractDeleteRecord;
use App\Models\KeyValuePair;
class DeletesKeyValuePair extends AbstractDeleteRecord
{
/**
* @param KeyValuePair $model
* @return mixed
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(KeyValuePair $model) {
return $this->handler($model);
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
use App\Models\KeyValuePair;
class UpdatesKeyValuePair extends AbstractUpdateRecord
{
/**
* @param KeyValuePair $model
* @param KeyValuePairObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(KeyValuePair $model, KeyValuePairObject $object) {
$model->key = $object->getKey();
$model->value = $object->getValue();
return $this->handler($model);
}
}
@@ -26,7 +26,7 @@ class CanAuthenticateUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -26,7 +26,7 @@ class CanCreateUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;
@@ -10,7 +10,7 @@ class CanDeleteUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;
@@ -12,7 +12,7 @@ class CanFetchUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -33,7 +33,7 @@ class CanGeneratePasswordReset extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -13,7 +13,7 @@ class CanListUsers extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -24,7 +24,7 @@ class CanRegisterUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;
@@ -13,7 +13,7 @@ class CanResendEmailVerification extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -34,7 +34,7 @@ class CanResetPassword extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
return true;
@@ -26,7 +26,7 @@ class CanUpdateUser extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;
@@ -81,7 +81,7 @@ class CreateAddressLogic extends AbstractControllerLogic
$company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]);
$query = $this->createsAddress->execute($company, $object);
//cief todo: case study 6
//cief todo: case study 6 voucherify
// $user = $company->employees()->first();
// $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_6]);
@@ -26,7 +26,7 @@ class CanCreateAddress extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;
@@ -13,7 +13,7 @@ class CanDeleteAddress extends AbstractRule
/**
* @return bool
*/
protected function authorized(): bool
protected function authorized($object): bool
{
// TODO Set Authorization rules
return true;

Some files were not shown because too many files have changed in this diff Show More